Development & Deployment Workflow
Version 1 · Initial workflow page covering local dev setup, running locally, building the exe/service, and the third run_api.cmd deployment path
SmartMail Development & Deployment Workflow
Local development setup
python -m venv .venvthen activate it.pip install -r requirements.txt— note this file does not includepyinstaller,pywin32, orwaitress, even thoughrun.py/service_wrapper.py/run_api.cmdall need them and the.specfiles need PyInstaller/pywin32. Install separately:pip install pyinstaller pywin32 waitress- Create/fill an env file under
env/—config/load_config.pypicksenv/.env.<APP_ENV>(defaultdevelopment;.development/.staging/.productionvariants all exist as files already). Required keys includeCLIENT_ID,TENANT_ID,CLIENT_SECRET,REDIRECT_URI,SCOPES,MONGO_URI,MONGO_DB,DB_BACKEND,OPENAI_API_KEY,OPENAI_MODEL_SUMMARY/_EXTRACT/_REPLY, plus webhook/logging/Redis settings. - Review
config/config.inifor non-secret per-environment settings ([default],[dev],[staging],[prod]sections: host/port, log level, Graph base URL/scopes, feature flags). Noteconfig/schema.jsonis currently an empty file and validates nothing. - Validate config before going further:
Checkspython scripts/check_config.pyTENANT_ID/CLIENT_ID/GRAPH_SCOPESare set (exits 1 if not) and warns ifENABLE_GPT=truebutOPENAI_API_KEYis empty. - Initialize the database:
python -m app.main init-db - Authenticate against Microsoft 365 (device-code/interactive):
python -m app.main login
See Database for what step 6 actually creates, and Architecture §4
for why step 7's token cache location matters (app/auth.py uses a CWD-relative cache.bin, not
app/config.TOKEN_CACHE_PATH).
Running locally
Two different entry points, on two different ports:
python run.py— emulates the packaged desktop exe: starts waitress on0.0.0.0:5001, opens the browser at/outlook.python run.py loginruns just the auth flow and exits.python -m app.main weborpython -m app.main dashboard(or runningapp/main.pywith no subcommand) — starts the Flask dev server directly on port 5002 instead.
Pick run.py to test the shipped experience; use the app.main CLI entry for quick iteration or
any of its other subcommands (inbox, create-draft, gpt-classify, etc. — see
CLI Quick Reference).
Building the desktop executable
pyinstaller SmartMail.spec
Entry point run.py; bundles only env/.env.development as data (everything else resolved via
normal import discovery). Produces dist/SmartMail.exe (console app, one-file, UPX-compressed).
Building / installing the Windows service
pyinstaller SmartMail_Service.spec
Entry point service_wrapper.py; bundles env/.env.development and the whole app/
directory, plus explicit pywin32 hidden-imports (win32timezone, win32service,
win32serviceutil, win32event, servicemanager). Produces dist/SmartMailService.exe.
Install/manage (run as Administrator), standard win32serviceutil conventions:
SmartMailService.exe install
SmartMailService.exe start
SmartMailService.exe stop
SmartMailService.exe remove
Service name SmartMailService, listens on 0.0.0.0:5001 via waitress, logs to
service_debug.log (overwritten on every start — no rotation). Unlike the desktop exe, the
service does not check for a valid token at startup — it will start and simply serve 401s from
Graph-backed routes until login has been run separately.
A third deployment path: run_api.cmd + wsgi.py
wsgi.py is a plain WSGI entrypoint (application = app), not referenced by either .spec file.
run_api.cmd uses it directly:
D:\GITHUB\SmartMail\.venv\Scripts\waitress-serve.exe --listen=124.43.18.139:5002 wsgi:application
appending logs to logs\api.log. This is a plain batch launcher (not a registered Windows
service) bound to a specific internal IP on port 5002 — presumably intended for a server host
where it's started manually or via a scheduled task. ⚠ The script's hardcoded path
(D:\GITHUB\SmartMail) doesn't match this checkout's actual path (D:\SmartMail) — update it
before relying on this script, or it will fail to find the venv/working directory.
What's gitignored (must be recreated locally, not present on a fresh clone)
Per .gitignore: app/cache.bin, .env, .venv, __pycache__/, *.pyc, *.bin, *.log,
logs, *.db//smartmail.db, /token_cache.json, build, *.exe. A fresh clone needs steps
1–7 above run from scratch; don't expect smartmail.db, log files, or the token cache to already
exist.
Not found in the repo
No CI configuration (.github/workflows, Azure Pipelines, etc.) was found — builds and deploys
described above are run manually today.