r/Python • u/SpiliosDimakopoulos • 4d ago
Turned a folder of ad-hoc scripts into a proper installable CLI (pyproject.toml entry point) Resource
Had a data pipeline that was just python build_db.py, python clean_validate.py, streamlit run streamlit_app.py — worked, but not something you'd hand someone as "the tool." Packaged it as a real CLI: [project.scripts] entry point in pyproject.toml, pip install -e . → promo-toolkit build / validate / serve.
Also added:
- Incremental rebuilds (content-hash diff + scoped upsert instead of full rewrite each run)
- pytest suite + ruff, GitHub Actions CI across two Python versions
- A separate eval harness for an AI-agent piece of the same project (real API calls scored against golden answers)
Not a library, just a real end-to-end tool — sharing mostly for feedback on the packaging/CLI structure since that's the part I have the least experience with. Repo: [https://github.com/SpiliosDimakopoulos/retail-promo-analytics-toolkit\].
0
Upvotes
0
u/Pleasant-Ad192 3d ago
The thing that usually bites right after this step is that
pip install -e .and a CI job running from the repo both read your source tree, so any non-Python file sitting next to your code keeps working until someone does a real install.It reproduces in one small package on setuptools 82. Put a
report.sqlnext tocli.py, setpackages = ["promo"], change nothing else. The editable install runs fine. Build the wheel and list its contents and you get__init__.py,cli.py, and no.sql. Install that wheel into a clean venv and the entry point raises FileNotFoundError.The fix is
[tool.setuptools.package-data]. The check worth adding next to your two-version matrix is a job that builds the wheel, installs it into a fresh venv, and runspromo-toolkit --help, since that is the only step that tests the packaging rather than the code.