Skip to content

Instantly share code, notes, and snippets.

@vielhuber
Last active May 29, 2025 09:45
Show Gist options
  • Save vielhuber/4fde83462c8cc801448b2732862c8629 to your computer and use it in GitHub Desktop.
Save vielhuber/4fde83462c8cc801448b2732862c8629 to your computer and use it in GitHub Desktop.
basics #python

virtual environments

setup

  • python -m venv venv
  • pip install ...

activate

  • source venv/bin/activate

deactivate

  • deactivate

package management

install package

  • pip install <paket>
  • echo "<paketname>" >> requirements.txt

install all packages

  • pip install -r requirements.txt

create requirements

option 1

  • pip install pipreqs
  • pipreqs . --force --ignore venv

option 2

  • pip freeze > requirements.txt

.gitignore

/venv
/.env
__pycache__
*.pyc

watchers

  • watcher.py
import subprocess, sys, time, signal, os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

SCRIPT = "script.py"

class RestartOnChange(FileSystemEventHandler):
    def __init__(self, runner): self.runner = runner; self.last = 0
    def on_modified(self, e):
        if e.src_path.endswith(".py") and time.time() - self.last > 1:
            self.last = time.time()
            print(f"πŸ” File changed: {e.src_path}")
            self.runner.restart()

class Runner:
    def __init__(self, script): self.script = script; self.proc = None
    def start(self):
        print(f"πŸš€ Starting {self.script}")
        self.proc = subprocess.Popen([sys.executable, self.script])
    def stop(self):
        if self.proc and self.proc.poll() is None:
            print("πŸ›‘ Sending SIGINT...")
            self.proc.send_signal(signal.SIGINT)
            try: self.proc.wait(timeout=5)
            except subprocess.TimeoutExpired:
                self.proc.kill()
        self.proc = None
    def restart(self): self.stop(); self.start()
    def watch(self):
        obs = Observer()
        obs.schedule(RestartOnChange(self), ".", recursive=True)
        obs.start()
        try:
            self.start()
            while True:
                time.sleep(1)
                if self.proc and self.proc.poll() is not None:
                    code = self.proc.returncode
                    if code == 0:
                        print("βœ… Script exited cleanly. Shutting down watcher.")
                        break
                    print(f"πŸ’₯ Script crashed (exit {code}). Restarting...")
                    self.start()
        except KeyboardInterrupt:
            print("πŸ‘‹ Ctrl+C – stopping everything.")
        finally:
            obs.stop(); obs.join(); self.stop()
            print("🧼 Watcher exited.")
            sys.exit(0)

if __name__ == "__main__":
    Runner(SCRIPT).watch()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment