ho fatto una serie di modifiche seguendo anche altri tutorial.
ho spostato l'Observer direttamente dentro al "monitor", in modo da avere accesso diretto:
codice:
import time
import shutil
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
from utils import get_first_file

class MonitorFile(FileSystemEventHandler):

    observer = Observer()

    def crea_semaforo(self):
        file = get_first_file('./csv')

        if file != 'ND':
            shutil.move('./csv/' + file, './test_file/' + file)
            time.sleep(1)

            f = open('./test_semaforo/semaforo', "a")
            f.write("")
            f.close()
        else:
            self.observer.stop()
            time.sleep(1)
            print("ESCO") # VIENE VISUALIZZATO
            exit(0) # PROCESSO RIMANE ATTIVO

    def run_observer(self):
        self.observer.schedule(self, path='./test_semaforo', recursive=False)
        self.observer.start()

        try:
            while (True):
                time.sleep(1)
        except (KeyboardInterrupt, SystemExit):
            self.observer.stop()
            time.sleep(1)

        self.observer.join()

    def on_deleted(self, event):
        if event.src_path == './test_semaforo\semaforo':
            self.crea_semaforo()
poi richiamo tutto così:
codice:
if __name__ == '__main__':
    fatture()

    event_handler = MonitorFile()
    event_handler.crea_semaforo()
    event_handler.run_observer()
come già messo nel commento, il print ESCO viene visualizzato.
quindi intercetta correttamente il valore ND.
solo che non esce dal programma e sembra rimanere appeso li.

qualche idea??