Error using win32com & pttsx3 for Python Voice Recognition - python-3.x

'''
Please help me out at this stage.i want to do this program with win32com & pyttsx 3. tried both but not working . Below is my code please check and help.
I want program to answer me back as as per defined answers.
Program is working fine and replying as a text but i am not getting any response by voice..
'''
# audio.py File
import pyaudio
import speech_recognition as sr
import pyglet
from commands import Commander
import subprocess
import win32com.client as wincl
import wave
import pyttsx3
running = True #ss
def say(text):
speak = wincl("SAPI.SpVoice")
speak.Speak('say ' + text, shell=True)
def play_audio(filename):
chunk = 1024
wf = wave.open(filename, 'rb')
pa = pyaudio.PyAudio()
stream = pa.open(
format=pa.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True
)
data_stream = wf.readframes(chunk)
while data_stream:
stream.write(data_stream)
data_stream = wf.readframes(chunk)
stream.close()
pa.terminate()
play_audio("./audio/after.wav")
# Upper part is to play sound using pyaudio
r = sr.Recognizer()
cmd = Commander() #
def initSpeech():
print("Listening.....")
play_audio("./audio/before.wav")
with sr.Microphone() as source:
print("Say Something")
audio = r.listen(source)
play_audio("./audio/before.wav")
command = ""
try:
command = r.recognize_google(audio)
except:
print("Couldn't understand you bro. ")
print("Your Command: ")
print(command)
if command == "quit":
running = False #
#echo('You Said: ' + command)
cmd.discover(command) #
#speak.Speak('You Said: ' + command) -------> no comment
while running == True:
initSpeech()
-----------------------------------------------------------------------------------------------------
# commands.py File
import subprocess
import os
class Commander:
def __init__(self):
self.confirm = ["yes", "affirmative", "si", "sure", "do it", "yeah", "confirm"]
self.cancel = ["no", "negative", "negative soldier", "don't", "wait", "cancel"]
def discover(self, text):
if "what" in text and "your name" in text:
if "my" in text:
self.respond("You haven't told your name yet")
self.respond("My name is python commander. How are you")
def respond(self, response):
print(response)
speak.Speak('say ' + response, shell=True) # This Speak is
from pywin32

Related

i am trying to make a voice assistant to control my room and the response times are very slow

I got a basic code on the internet and edited it to fit my requirements, on the hardware side I used Arduino uno, relays, and esp8266 esp01 wifi module, and controlled it using blynk and ifttt
the problem is that the assistant is very slow, I first thought that maybe google text to speech is the problem so I tried the pyttsx3 module to do that offline but that didn't help.
so I thought maybe the if statements are a problem so I made each one of them into a function and tried multi-threading but that didn't help either...
so I thought that it has to listen and process all I speak .. so I added a trigger word so only after the trigger word is used it starts to listen for commands,
sometimes it will work properly at first then get slower
I don't know what else to do
here is the code I am using:
import pyttsx3
import speech_recognition as sr
import datetime
import wikipedia
import webbrowser
import os
import requests
import time
import smtplib
from goto import goto, label
engine = pyttsx3.init('sapi5')
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[0].id)
def speak(audio):
engine.say(audio)
engine.runAndWait()
def wishMe():
speak("Hello sir ,Assistant booting up")
def takeCommand():
r = sr.Recognizer()
with sr.Microphone() as source:
print("Listening...")
r.pause_threshold = 0.5
audio = r.listen(source)
print("saving")
try:
print("Recognizing...")
query = r.recognize_google(audio, language='en-in')
print(f"User said: {query}\n")
except Exception as e:
print(e)
print("Say that again please...")
return
return query
i=0
j=0
if __name__ == "__main__":
wishMe()
while True:
print("iteration jarvis",i)
i=i+1
r = sr.Recognizer()
with sr.Microphone() as source:
print("waiting...")
r.pause_threshold = 0.5
audio = r.listen(source)
try:
query = r.recognize_google(audio, language='en-in')
print(f"User said: {query}\n")
if 'Jarvis' in query:
query=takeCommand().lower()
except Exception as e:
print(e)
print("jaris not called")
continue
print("iteration command",j)
j=j+1
if 'how are you' in query:
speak("good")
elif 'open google' in query:
webbrowser.open("google.com")
speak("There you go!")
elif 'lights on' in query:
requests.post("https://maker.ifttt.com/trigger/light_on/with/key/d*************")
speak("ok sure")
elif 'lights off' in query:
requests.post("https://maker.ifttt.com/trigger/lights_off/with/key/d************")
speak("with pleasure")
elif 'play music' in query:
music_dir = 'D:\\Non Critical\\songs\\Favorite Songs2'
songs = os.listdir(music_dir)
print(songs)
os.startfile(os.path.join(music_dir, songs[0]))
elif 'stop listening' in query:
speak("going offline")
exit()
You might want to only initialize your recognizer once.
I took the liberty of cleaning up and refactoring the code a little too.
from itertools import count
import pyttsx3
import speech_recognition as sr
import webbrowser
import os
import requests
engine = pyttsx3.init("sapi5")
voices = engine.getProperty("voices")
engine.setProperty("voice", voices[0].id)
recognizer = sr.Recognizer()
recognizer.pause_threshold = 0.5
def speak(audio):
engine.say(audio)
engine.runAndWait()
def takeCommand():
with sr.Microphone() as source:
print("Listening...")
audio = recognizer.listen(source)
print("saving")
print("Recognizing...")
query = recognizer.recognize_google(audio, language="en-in")
print(f"User said: {query}\n")
return query
def process_query(query):
if "how are you" in query:
speak("good")
elif "open google" in query:
webbrowser.open("google.com")
speak("There you go!")
elif "lights on" in query:
requests.post("https://maker.ifttt.com/trigger/light_on/with/key/d*************")
speak("ok sure")
elif "lights off" in query:
requests.post("https://maker.ifttt.com/trigger/lights_off/with/key/d************")
speak("with pleasure")
elif "play music" in query:
music_dir = "D:\\Non Critical\\songs\\Favorite Songs2"
songs = os.listdir(music_dir)
print(songs)
os.startfile(os.path.join(music_dir, songs[0]))
elif "stop listening" in query:
speak("going offline")
exit()
def main():
speak("Hello sir ,Assistant booting up")
for iteration in count(1):
print("iteration jarvis", iteration)
try:
query = takeCommand()
except Exception as e:
print(e)
speak("Recognition error: {}".format(e))
else:
try:
process_query(query)
except Exception as e:
print(e)
speak("Processing error: {}".format(e))
if __name__ == "__main__":
main()

Import variable from pythonscript --> solve caused TypeError

I've been trying to build a speech-recognition application with gtts. What I want to do now is to use a variable from another python script so I can update a tk Label. I tried to put my code in a structure of a class to access the variable. I've added a smaller program to showcase my problem.
(These programs are ment to be running at the same time)
I'am a beginner in Python so I hope you guys can teach me how to do it better. :)
Thank you in advance!!
Error:
S = SuperAssistant()
TypeError: __init__() missing 1 required positional argument: 'audio'
basic example that showcases my problem:
from try_access_var import myfunction
print(myfunction.audio)
Then in my other pyscript called try_access_var:
def myfunction():
audio = 1
(My program where I want to implement the Solution I might get)
`from gtts import gTTS
import speech_recognition as sr
from playsound import playsound
import os
import re
import webbrowser
from tkinter import *
import smtplib
import requests
import sys
import subprocess
from subprocess import Popen
import time
import datetime as dt
from datetime import timedelta
import keyboard
import mouse
import pyaudio
import tkinter as tk
from tkinter import filedialog, Text
import csv
Note that "Class SuperAssistant" belongs to the code
class SuperAssistant:
def __init__(self):
self.audio = audio
def talkToMe(self):
"speaks audio passed as argument"
#SuperAssistant.audio = audio
print(self.audio)
tts = gTTS(text=audio, lang='en')
tts.save("good.mp3")
#os.system("cd C://Users//johan//OneDrive - Departement Bildung, Kultur und Sport Kanton Aargau-7988362-Kantonsschule Zofingen//DATA_SHAR//desktopAssistant-master")
#os.system("python -i C://Users//johan//OneDrive - Departement Bildung, Kultur und Sport Kanton Aargau-7988362-Kantonsschule Zofingen//DATA_SHAR//desktopAssistant-master//tkinter_samentha_tricks.py")
#os.system("python -i tkinter_samentha_tricks.py")
#force it to have no console
DETACHED_PROCESS = 0x00000008
subprocess.Popen("python -i tkinter_samentha_tricks.py") #creationflags=DETACHED_PROCESS)
while playsound("good.mp3"):
pass
os.remove("good.mp3")
#print(audio)
#for line in audio.splitlines():
# os.system("say " + audio)
#use the system's inbuilt say command instead of mpg123
#text_to_speech = gTTS(text=audio, lang='en')
#text_to_speech.save('audio.mp3')
#os.system('mpg123 audio.mp3')
def myCommand(self, x):
"listens for commands"
r = sr.Recognizer()
#mic_version= open("C:/Users/johan/OneDrive - Departement Bildung, Kultur und Sport Kanton Aargau-7988362-Kantonsschule Zofingen/DATA_SHARE/desktopAssistant-master/choose_mic_text.txt", "r")
#mic_integer=mic_version
#mic = sr.Microphone(device_index=mic_integer)
with sr.Microphone() as source:
print('Ready...')
r.pause_threshold = 1
r.adjust_for_ambient_noise(source, duration=1)
audio = r.listen(source)
if x == 1:
try:
command = r.recognize_google(audio).lower()
#talkToMe('You said: ' + command + '\n')
#add silent mode. for now: print only
print('You said: ' + command + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
command = SuperAssistant.myCommand(1);
return command
if x == 2:
try:
command02 = r.recognize_google(audio).lower()
#talkToMe('You said: ' + command + '\n')
#add silent mode. for now: print only
print('You said: ' + command02 + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
command02 = SuperAssistant.myCommand(2);
return command02
if x == 3:
try:
command03 = r.recognize_google(audio).lower()
#talkToMe('You said: ' + command + '\n')
#add silent mode. for now: print only
print('You said: ' + command03 + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
command03 = SuperAssistant.myCommand(3);
return command03
if x == 4:
try:
command04 = r.recognize_google(audio).lower()
#talkToMe('You said: ' + command + '\n')
#add silent mode. for now: print only
print('You said: ' + command04 + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
command04 = SuperAssistant.myCommand(4);
return command04
if x == 5:
try:
command05 = r.recognize_google(audio).lower()
#talkToMe('You said: ' + command + '\n')
#add silent mode. for now: print only
print('You said: ' + command05 + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
command05 = SuperAssistant.myCommand(5);
return command05
if x == 6:
try:
command06 = r.recognize_google(audio).lower()
#talkToMe('You said: ' + command + '\n')
#add silent mode. for now: print only
print('You said: ' + command06 + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
command06 = SuperAssistant.myCommand(6);
return command06
def time_greeting():
if 12 > dt.datetime.now().hour:
SuperAssistant.talkToMe('Good morning sir.')
elif 12 == dt.datetime.now().hour:
SuperAssistant.talkToMe('It is high noon, hope you are ready for your duel!')
elif (12 < dt.datetime.now().hour) and (18 > dt.datetime.now().hour):
SuperAssistant.talkToMe('Good afternoon sir.')
elif 18 < dt.datetime.now().hour:
SuperAssistant.talkToMe('Good evening sir.')
def time_bye():
if 12 > dt.datetime.now().hour:
SuperAssistant.talkToMe('wish you a nice morning sir.')
elif 12 == dt.datetime.now().hour:
SuperAssistant.talkToMe('wish you a good lunce sir.!')
elif (12 < dt.datetime.now().hour) and (18 > dt.datetime.now().hour):
SuperAssistant.talkToMe('wish you a good afternoon sir.')
elif 18 < dt.datetime.now().hour:
SuperAssistant.talkToMe('wish you good evening sir.')
def welcome():
SuperAssistant.talkToMe('My systems are booting up. Systems successfully booted!')
SuperAssistant.time_greeting()
SuperAssistant.talkToMe('How should I call you? Please tell me your name.')
global name
name = SuperAssistant.myCommand(1)
SuperAssistant.talkToMe('Nice to meet you ' + name +'.')
file=open("C://Users//johan//OneDrive - Departement Bildung, Kultur und Sport Kanton Aargau-7988362-Kantonsschule Zofingen//DATA_SHARE//desktopAssistant-master//userprofiles.txt", "r")
with open("C://Users//johan//OneDrive - Departement Bildung, Kultur und Sport Kanton Aargau-7988362-Kantonsschule Zofingen//DATA_SHARE//desktopAssistant-master//userprofiles.txt", "r") as profiles:
for line in profiles:
if name in line:
pass
for profiles in file.readlines():
print(profiles)
if name in profiles:
SuperAssistant.talkToMe('welcome back.')
file.close()
else:
SuperAssistant.talkToMe('Should I create a new profile?')
profilcreation=myCommand(2)
if 'yes' in profilcreation:
#questions to ask to create new profil
SuperAssistant.talkToMe('I am going to ask you some questions...')
SuperAssistant.talkToMe('What is your favorite color?')
question01_profilcreation=myCommand(3)
SuperAssistant.talkToMe('What is your favorid food?')
question02_profilcreation=myCommand(3)
SuperAssistant.talkToMe('When were you born?')
question03_profilcreation=myCommand(3)
file=open("C:/Users/johan/OneDrive - Departement Bildung, Kultur und Sport Kanton Aargau-7988362-Kantonsschule Zofingen/DATA_SHARE/desktopAssistant-master/userprofiles.txt", "a")
file.write('\n'+'['+'"'+name+'"'+','+'"'+question01_profilcreation+'"'+','+'"'+question02_profilcreation+'"'+','+'"'+question03_profilcreation+'"'+']')
elif 'no' in profilcreation:
SuperAssistant.talkToMe('profilcreation denied')
file.close()
return name
def load(element):
with open("C://Users//johan//OneDrive - Departement Bildung, Kultur und Sport Kanton Aargau-7988362-Kantonsschule Zofingen//DATA_SHARE//desktopAssistant-master//userprofiles.txt", "r") as profiles:
for line in profiles:
if name in line:
hole_item=line
#hole_item.append(line)
#profil_item=hole_item[element]
profil=hole_item.split(",")
print(profil)
profiles.close()
return profil[element]
all_the_lines = profiles.readlines()
items = []
for i in all_the_lines:
items.append(i)
print(items)
def assistant(command):
"if statements for executing commands"
global name
global check
if 'samantha' in command:
if (check == 0):
check = 1
SuperAssistant.welcome()
else:
SuperAssistant.talkToMe("What can I do for you")
command02 = SuperAssistant.myCommand(2)
if 'open reddit' in command02:
reg_ex = re.search('open reddit (.*)', command02)
url = 'https://www.reddit.com/'
if reg_ex:
subreddit = reg_ex.group(1)
url = url + 'r/' + subreddit
webbrowser.open(url)
print('Done!')
elif 'open youtube' in command02:
reg_ex = re.search('open website (.+)', command02)
print(command02)
song_title=command02[12:]
print(song_title)
url='https://www.youtube.com/results?search_query='+song_title
webbrowser.open(url)
talkToMe('Done!')
command03 = SuperAssistant.myCommand(3)
if 'play' in command03:
keyboard.press_and_release('tab','tab')
keyboard.press_and_release('enter')
command04 = SuperAssistant.myCommand(4)
if 'stop' in command04:
keyboard.press_and_release('space')
command04 = SuperAssistant.myCommand(4)
elif 'continue' in command04:
keyboard.press_and_release('space')
command04 = myCommand(4)
elif 'exit' in command03:
talkToMe('exit')
command = SuperAssistant.myCommand(1)
elif 'help' in command02:
talkToMe('I\'ve got some information for you.')`
This here is my code at the end of the function/class:
if __name__ == "__main__":
S = SuperAssistant()
S.talkToMe('I am ready for your command')
#loop to continue executing multiple commands
while True:
SuperAssistant.assistant(SuperAssistant.myCommand(1))
the code of the smaller program (show tk window) I opened with subprocess.Popen(....)
#importing the class/function
from desktopAssistant_wakeup import SuperAssistant
from tkinter import *
#printing out imported variable (if classes are used: object)
print(#way to print audio)
SuperAssistent does not have a class attribute named audio. For this you would have to set it somewhere in your class. For example, you could do something like SuperAssistent.audio = audio in talkToMe.
Is it on purpose that you use class methods only and do not instantiate SuperAudio? If that is not the case you should add a constructor and add self as first arguments of all methods that are not class methods.
I suggest to go through an introduction for Python classes/objects like this one on w3schools if that is the case.
Update:
Here is an example for setting and accessing class and instance attributes with split up files for script and class definition:
example.py:
class Foo():
class_attribute = 'class attribute: initial value'
def __init__(self):
self.instance_attribute = \
'instance attribute ({:X}): initial value'.format(id(self))
def do_something(self = None):
Foo.class_attribute = 'class_attribute: modified value'
if self is not None:
self.instance_attribute = \
'instance attribute ({:X}): modified value'.format(id(self))
script.py
#!/usr/bin/env python3
from example import Foo
a = Foo()
b = Foo()
print(Foo.class_attribute)
print(a.instance_attribute)
print(b.instance_attribute)
print('\nChanging attributes..\n')
Foo.do_something()
a.do_something()
b.do_something()
print(Foo.class_attribute)
print(a.instance_attribute)
print(b.instance_attribute)
Executing script.py gives the following output (note that IDs change between machines and executions:
class attribute: initial value
instance attribute (7F640ACF56A0): initial value
instance attribute (7F640AC2AB50): initial value
Changing attributes..
class_attribute: modified value
instance attribute (7F640ACF56A0): modified value
instance attribute (7F640AC2AB50): modified value

Why is my code not reaching the While Loop to register my Voice Assistant Wakeword?

I'm creating a Voice Assistant using Python. I'm using pyttsx3 for Text-to-Speech and I have a wakeword set up to activate the Voice Assistant. I'm using the Voice Assistant to do things such as read my calendar and such in a While Loop. But suddenly, the wakeword stops working. What is stopping my code from reaching the While Loop and the rest of the code?
Here is some of the code for my project:
from __future__ import print_function
import subprocess
import pytz
import speech_recognition as sr
import pyttsx3
import time
import os
import datetime
import pickle
import os.path
def speak(text):
engine = pyttsx3.init()
engine.say(text)
engine.runAndWait()
def get_audio():
r = sr.Recognizer()
with sr.Microphone() as source:
audio = r.listen(source)
said = ""
try:
said = r.recognize_google(audio)
print(said)
except Exception as e:
print("Exception: " + str(e))
return said.lower()
WAKE = "Jarvis"
print("Jarvis is ready")
while True:
print("Jarvis is listening...")
text = get_audio()
if text.count(WAKE) > 0:
speak("Hello Sir, what would you like?")
text = get_audio()
DONE = ["never mind", "goodbye", "I'm done now"]
for phrase in DONE:
if phrase in text:
speak("Alright sir. Goodbye!")
quit()
NOTE_STRS = ["make a note", "write this down", "remember this"]
for phrase in NOTE_STRS:
if phrase in text:
speak("Sure. What would you like me to write down?")
note_text = get_audio()
note(note_text)
speak("Done Sir. I've made a note of that.")
TIME = ["time"]
for phrase in TIME:
if phrase in text:
import datetime
now = datetime.datetime.now()
speak("The current time is %d hours %d minutes" % (now.hour, now.minute))
Please tell me if any code is missing and I can send it to help solve the problem!
HyperionBlaze - What is happening with authenticate_google(). Is there any exception on that call?

python3 error JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock in Ubuntu

Im trying to do speech recognition but every time I run it I get this error.
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Here is my code.
from gtts import gTTS
import playsound as ps
import speech_recognition as sr
sr.Microphone.list_microphone_names()
text=('text')
mic = sr.Microphone(device_index=20)
r = sr.Recognizer()
with mic as source:
audio = r.listen(source)
re = r.recognize_google(audio)
def rSpeak():
tts = gTTS(text)
tts.save('hello.mp3')
ps.playsound('hello.mp3', True)
rSpeak()
any help very appreciated
You should try to speak using this:
import pyttsx3
engine = pyttsx3.init('sapi5')
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[0].id)
def speak(audio):
engine.say(audio)
engine.runAndWait()
speak('Hello, Sir.')
And if you want to recognize a voice then go with this:
import speech_recognition as sr
def takeCommand():
#It takes microphone input from the user and returns string output
r = sr.Recognizer()
with sr.Microphone() as mic:
print("Listening...")
r.adjust_for_ambient_noise(mic)
audio = r.listen(mic)
try:
print("Recognizing...")
query = r.recognize_google(audio, language='en-in')
print(f"User said: {query}\n")
except Exception:
print("Say that again please...")
return "None"
return query
query = takeCommand().lower() #lower() is used to keep all your queries in lowercase.
And then you can match your query variable to match with the command you want to follow.

Python watchdog module duplicate events (edit: was not an watchdog issue)

I am creating a python script that will identify changes to a log file and print some data from the new logs.
I use watchdog to create an event handler and everything seems to work fine except from that, I get duplicate events every time I modify the file. I checked creation and delete, they both work as expected and trigger one time.
I have read the similar question which explains having a created and a modified event when I save a file but this is not my case. I just get two modification events.
Here is my code:
import os, sys, time
import subprocess
import threading
import win32print
from tkinter import filedialog
from tkinter import *
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class Handler(FileSystemEventHandler):
# docstring for FileSystemEventHandler
def __init__(self, observer, filename, dirname):
# super(Handler, FileSystemEventHandler).__init__(self,)
self.observer = observer
self.filename = filename
self.dirname = dirname
print("Handler filename = " , self.filename)
print("Handler dirname = " , self.dirname)
def on_modified(self, event):
if self.filename == event.src_path:
print("The file was modified")
print (event.src_path)
# go get the last line and print the data
# try:
# hJob = win32print.StartDocPrinter (hPrinter, 1, ("test of raw data", None, "RAW"))
# try:
# win32print.StartPagePrinter (hPrinter)
# win32print.WritePrinter (hPrinter, raw_data)
# win32print.EndPagePrinter (hPrinter)
# finally:
# win32print.EndDocPrinter (hPrinter)
# finally:
# win32print.ClosePrinter (hPrinter)
def on_created(self, event):
print("A file was created (", event.src_path, ")")
def on_deleted(self, event):
print("A file was deleted (", event.src_path, ")")
if __name__ == "__main__":
Flags=2
Name=None
Level=1
printers = win32print.EnumPrinters(Flags, Name, Level)
print("\nChoose a printer to use:")
i=1
for p in printers:
print(i,')' , p[2])
i = i+1
if sys.version_info >= (3,):
raw_data = bytes ("This is a test", "utf-8")
else:
raw_data = "This is a test"
printer = int(input())
printer_name = printers[printer-1][2] #win32print.GetDefaultPrinter ()
print("You chose ", printer_name, "\nI will now print from the specified file with this printer")
hPrinter = win32print.OpenPrinter (printer_name)
# root = Tk()
# root.filename = filedialog.askopenfilename(initialdir = "/Desktop",title = "Select file",filetypes = (("log files","*.log"),("all files","*.*")))
file_path = "some_file_path" # root.filename
file_directory = os.path.dirname(file_path)
# print (file_path)
print (file_directory)
observer = Observer()
event_handler = Handler(observer, file_path, file_directory)
observer.schedule(event_handler, path=file_directory, recursive=False)
observer.start()
observer.join()
any ideas would be appreciated
EDIT:
After some debugging I found out that Windows10 is changing the file modification time twice every time I save it.
The proof of concept code is this:
prev_modification_time = os.path.getmtime(file_path)
while True:
current_mod_time = os.path.getmtime(file_path)
if prev_modification_time != current_mod_time :
print ("the file was modified, last modification time is: ", current_mod_time)
prev_modification_time = current_mod_time
pass
Final edit:
After testing my code on linux (Debian Stretch to be exact) it worked like a charm. So this combined with the previous edit probably shows that watchdog works fine and it is windows10 that has some issue. Should I post it on a different question or here?

Resources