New class or new .py Python
Question:
I’m writing a Python script to check if a file is added to a folder with watchdog, that file is going to be added to a queue.
My idea is to add the filename to a txt, then either run a new class that watches the txt and then executes a line in cmd and start for example FME.
Is it the best way to write a new .py for every new program I want to open. For example one for FME and one for notepad.
I still want the watchdog class to go into the background.
- looking_for_files_and_adding_to_queue py
- looking_in_queue_for_the_next_in_line_and_direct_to_3_party py
- FME py
- Notepad py
and so on…
Or on all.py
class looking_for_files_and_adding_to_queue
class looking_in_queue_for_the_next_in_line_and_direct_to_3_party
class FME
class Notepad
Today my script looks like this:
import time
import sys
import os
import datetime
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
class MyHandler(PatternMatchingEventHandler):
patterns = ["*.tif"]
count_move = 0
def process(self, event):
if self.count_move == 1:
# the file will be processed there
folder = "P:\03_auto\Indata"
indata = event.src_path
#Makes a new folder in Utdata based on filename
newfolder = os.path.join(folder[:11], str("Utdata\orto"), event.src_path[18:29])
if not os.path.exists(newfolder):
os.makedirs(newfolder)
#Logg and print start of FME
print(time.strftime('%a %H:%M:%S') + ": FME " + event.src_path[18:] + " startats i FME.")
log_file = open("P:\03_auto\log.txt", "a")
log_file.write(time.strftime('%a %H:%M:%S') + ": FME " + event.src_path[18:] + " startats i FME.n")
log_file.close()
#Starting and excequting FME
var_fme = str('fme.exe "P:\03_auto\Script\tiff_to_milti_jpg_tiff\tif_to_multi-jpg-tiff.fmw" --SourceDataset_TIFF "') + indata + str('" --FEATURE_TYPES "" --DestDataset_JPEG "') + newfolder + str('" --DestDataset_JPEG_5 "') + newfolder + str('" --DestDataset_JPEG_4 "') + newfolder + str('" --DestDataset_GEOTIFF "') + newfolder + str('" --DestDataset_GEOTIFF_3 "') + newfolder + str('"')
os.system(var_fme)
#Logg and pring move file
print(time.strftime('%a %H:%M:%S') + ": Flytt " + event.src_path[18:] + " har flyttats till" + newfolder + "nTransformering klarn")
log_file = open("P:\03_auto\log.txt", "a")
log_file.write(time.strftime('%a %H:%M:%S') + ": Flytt " + event.src_path[18:] + " har flyttats till" + newfolder + "nTransformering klarnn")
log_file.close()
#Move org file to Utdataorto
file_move = newfolder + indata[17:]
os.rename(indata, file_move)
#Restets script
self.count_move = 0
else:
#Logg and pring loadning file while transfering
print(time.strftime('%a %H:%M:%S') + ": Laddar " + event.src_path[18:] + " startar inladdning.")
log_file = open("P:\03_auto\log.txt", "a")
log_file.write(time.strftime('%a %H:%M:%S') + ": Laddar " + event.src_path[18:] + " startar inladdning.n")
log_file.close()
#Sets counter to 1 which enables the FME part
self.count_move += 1
def on_modified(self, event):
self.process(event)
if __name__ == '__main__':
path = "P:\03_auto\Indata"
observer = Observer()
observer.schedule(MyHandler(), path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Answers:
tl;dr keep everything in one file for now, split subsequently while refactoring when the file becomes huge.
Python does not force you split classes / functions into modules. We as programmers make that call for solely the purpose of readability and maintainability.
While refactoring I personally look at functions with more ~40 – 50 lines and files with ~ 1000 lines to split and try to keep closely related things together.
high cohesion and low coupling.
is a characteristic feature of good software.
Also, since you seem to be starting out with this project I would recommend you to first concentrate on making a version that works, thereafter refactor it to improve code quality.
premature optimization is the root of all evil.
I am assuming that you are looking for suggestions to improve code quality here, so here are a few things you might be also be interested in:
- follow pep8 standards: https://pep8.org
- make your functions / methods accept parameters instead of hardcoding them eg the path of the folder you are watching.
- make your program capable of resuming operations even after erroneous / abrupt termination: eg store state with a file or database
- instead of trying to implement a queue yourself use robust systems like rabbitmq or redis.
- write functions / methods that perform only one operation and do it well.
This it how far I have done. Now I have to get the files from the que to FME
import time
import sys
import os
import datetime
import arrow
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
from shutil import copy
class Queue:
def __init__(self):
self.items =[]
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0, item)
def dequeue(self):
self.items.pop()
def size(self):
return len(self.items)
def printqueue(self):
i = 0
for items in self.items:
i += 1
print(str(i) + ": " + items)
class MyHandler(PatternMatchingEventHandler):
patterns = ["*.tif","*.pdf"]
q = Queue()
def on_created(self, event):
file_name = os.path.basename(event.src_path)
file_type = file_name.split(".")[-1]
file_path = "path"
file_name_path = event.src_path
endwith = file_name.endswith("_mosaic_group1.tif")
new_folder = "C:\FME_workdir\"
new_path = new_folder + file_name
#create new temp folder for FME
if not os.path.exists(new_folder):
os.makedirs(new_folder)
#get tif file from project
if file_name.endswith("_mosaic_group1.tif") and not os.path.exists(new_path):
print("Queue:")
self.q.enqueue("[" + file_name + ", " + file_name_path + ", " + new_path + ", " + file_type + "]")
self.q.printqueue()
print("n")
#fme = Fme()
#return fme.runfme(file_name, file_path, file_name_path)
#copy file to FME folder
if not os.path.exists(new_path):
copy(file_name_path, new_path)
#get the PDF report
elif file_name.endswith("_report.pdf") and "1_initial" in file_name_path:
pdf_path = os.path.dirname(file_name_path)
pdf_path_new_path = "\".join(pdf_path.split("\")[:3])
pdf_path_new_dir = "\".join(pdf_path.split("\")[5:6])
date_now = str(time.strftime("%y%m%d"))
pdf_new_path = pdf_path_new_path + "\03_leverans\" + pdf_path_new_dir + "_" + date_now
pdf_new_path_filename = pdf_new_path + "\" + file_name
if not os.path.exists(pdf_new_path):
os.makedirs(pdf_new_path)
copy(file_name_path, pdf_new_path_filename)
#put inte que system
self.q.enqueue("[" + file_name + ", " + file_name_path + ", " + pdf_new_path + ", " + file_type + "]")
self.q.printqueue()
class Fme:
def runfme(self, file_name, file_path, file_name_path):
print("FME: " + self.file_name)
if __name__ == '__main__':
path = "P:\"
observer = Observer()
observer.schedule(MyHandler(), path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
print("stop")
observer.join()
input('Press ENTER to exit')
I’m writing a Python script to check if a file is added to a folder with watchdog, that file is going to be added to a queue.
My idea is to add the filename to a txt, then either run a new class that watches the txt and then executes a line in cmd and start for example FME.
Is it the best way to write a new .py for every new program I want to open. For example one for FME and one for notepad.
I still want the watchdog class to go into the background.
- looking_for_files_and_adding_to_queue py
- looking_in_queue_for_the_next_in_line_and_direct_to_3_party py
- FME py
- Notepad py
and so on…
Or on all.py
class looking_for_files_and_adding_to_queue
class looking_in_queue_for_the_next_in_line_and_direct_to_3_party
class FME
class Notepad
Today my script looks like this:
import time
import sys
import os
import datetime
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
class MyHandler(PatternMatchingEventHandler):
patterns = ["*.tif"]
count_move = 0
def process(self, event):
if self.count_move == 1:
# the file will be processed there
folder = "P:\03_auto\Indata"
indata = event.src_path
#Makes a new folder in Utdata based on filename
newfolder = os.path.join(folder[:11], str("Utdata\orto"), event.src_path[18:29])
if not os.path.exists(newfolder):
os.makedirs(newfolder)
#Logg and print start of FME
print(time.strftime('%a %H:%M:%S') + ": FME " + event.src_path[18:] + " startats i FME.")
log_file = open("P:\03_auto\log.txt", "a")
log_file.write(time.strftime('%a %H:%M:%S') + ": FME " + event.src_path[18:] + " startats i FME.n")
log_file.close()
#Starting and excequting FME
var_fme = str('fme.exe "P:\03_auto\Script\tiff_to_milti_jpg_tiff\tif_to_multi-jpg-tiff.fmw" --SourceDataset_TIFF "') + indata + str('" --FEATURE_TYPES "" --DestDataset_JPEG "') + newfolder + str('" --DestDataset_JPEG_5 "') + newfolder + str('" --DestDataset_JPEG_4 "') + newfolder + str('" --DestDataset_GEOTIFF "') + newfolder + str('" --DestDataset_GEOTIFF_3 "') + newfolder + str('"')
os.system(var_fme)
#Logg and pring move file
print(time.strftime('%a %H:%M:%S') + ": Flytt " + event.src_path[18:] + " har flyttats till" + newfolder + "nTransformering klarn")
log_file = open("P:\03_auto\log.txt", "a")
log_file.write(time.strftime('%a %H:%M:%S') + ": Flytt " + event.src_path[18:] + " har flyttats till" + newfolder + "nTransformering klarnn")
log_file.close()
#Move org file to Utdataorto
file_move = newfolder + indata[17:]
os.rename(indata, file_move)
#Restets script
self.count_move = 0
else:
#Logg and pring loadning file while transfering
print(time.strftime('%a %H:%M:%S') + ": Laddar " + event.src_path[18:] + " startar inladdning.")
log_file = open("P:\03_auto\log.txt", "a")
log_file.write(time.strftime('%a %H:%M:%S') + ": Laddar " + event.src_path[18:] + " startar inladdning.n")
log_file.close()
#Sets counter to 1 which enables the FME part
self.count_move += 1
def on_modified(self, event):
self.process(event)
if __name__ == '__main__':
path = "P:\03_auto\Indata"
observer = Observer()
observer.schedule(MyHandler(), path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
tl;dr keep everything in one file for now, split subsequently while refactoring when the file becomes huge.
Python does not force you split classes / functions into modules. We as programmers make that call for solely the purpose of readability and maintainability.
While refactoring I personally look at functions with more ~40 – 50 lines and files with ~ 1000 lines to split and try to keep closely related things together.
high cohesion and low coupling.
is a characteristic feature of good software.
Also, since you seem to be starting out with this project I would recommend you to first concentrate on making a version that works, thereafter refactor it to improve code quality.
premature optimization is the root of all evil.
I am assuming that you are looking for suggestions to improve code quality here, so here are a few things you might be also be interested in:
- follow pep8 standards: https://pep8.org
- make your functions / methods accept parameters instead of hardcoding them eg the path of the folder you are watching.
- make your program capable of resuming operations even after erroneous / abrupt termination: eg store state with a file or database
- instead of trying to implement a queue yourself use robust systems like rabbitmq or redis.
- write functions / methods that perform only one operation and do it well.
This it how far I have done. Now I have to get the files from the que to FME
import time
import sys
import os
import datetime
import arrow
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
from shutil import copy
class Queue:
def __init__(self):
self.items =[]
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0, item)
def dequeue(self):
self.items.pop()
def size(self):
return len(self.items)
def printqueue(self):
i = 0
for items in self.items:
i += 1
print(str(i) + ": " + items)
class MyHandler(PatternMatchingEventHandler):
patterns = ["*.tif","*.pdf"]
q = Queue()
def on_created(self, event):
file_name = os.path.basename(event.src_path)
file_type = file_name.split(".")[-1]
file_path = "path"
file_name_path = event.src_path
endwith = file_name.endswith("_mosaic_group1.tif")
new_folder = "C:\FME_workdir\"
new_path = new_folder + file_name
#create new temp folder for FME
if not os.path.exists(new_folder):
os.makedirs(new_folder)
#get tif file from project
if file_name.endswith("_mosaic_group1.tif") and not os.path.exists(new_path):
print("Queue:")
self.q.enqueue("[" + file_name + ", " + file_name_path + ", " + new_path + ", " + file_type + "]")
self.q.printqueue()
print("n")
#fme = Fme()
#return fme.runfme(file_name, file_path, file_name_path)
#copy file to FME folder
if not os.path.exists(new_path):
copy(file_name_path, new_path)
#get the PDF report
elif file_name.endswith("_report.pdf") and "1_initial" in file_name_path:
pdf_path = os.path.dirname(file_name_path)
pdf_path_new_path = "\".join(pdf_path.split("\")[:3])
pdf_path_new_dir = "\".join(pdf_path.split("\")[5:6])
date_now = str(time.strftime("%y%m%d"))
pdf_new_path = pdf_path_new_path + "\03_leverans\" + pdf_path_new_dir + "_" + date_now
pdf_new_path_filename = pdf_new_path + "\" + file_name
if not os.path.exists(pdf_new_path):
os.makedirs(pdf_new_path)
copy(file_name_path, pdf_new_path_filename)
#put inte que system
self.q.enqueue("[" + file_name + ", " + file_name_path + ", " + pdf_new_path + ", " + file_type + "]")
self.q.printqueue()
class Fme:
def runfme(self, file_name, file_path, file_name_path):
print("FME: " + self.file_name)
if __name__ == '__main__':
path = "P:\"
observer = Observer()
observer.schedule(MyHandler(), path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
print("stop")
observer.join()
input('Press ENTER to exit')