Automation pipeline that ingests research and product links, enriches them with LLM generated metadata, and renders a weekly AI newsletter.
- Python 3.10+
piporpipx- Redis 6+ (for Celery broker/result backend)
- OpenRouter API access (key + model configuration)
- Jina Reader API key
-
Create and activate a virtual environment:
python -m venv .venv source .venv/bin/activate -
Install the project in editable mode with development dependencies:
pip install -e .[dev]
-
Duplicate the example environment file and populate secrets:
cp .env.example .env
-
Edit
.envwith your credentials and configuration:OPENROUTER_BASE_URL: Base URL for the OpenRouter gateway (defaulthttps://openrouter.ai/api/v1).OPENROUTER_KEY: API key used to authenticate with OpenRouter.OPENROUTER_MODEL: Default model identifier (e.g.,anthropic/claude-3.5-sonnet).JINA_READER_BASE_URL: Base URL for the Jina Reader fetch service (defaulthttps://r.jina.ai).JINA_READER_API_KEY: API token for the Jina Reader API.NEWSLETTER_OUTPUT_DIR: Directory path for rendered newsletter artifacts (default./output).NEWSLETTER_LOG_LEVEL: Logging verbosity (DEBUG,INFO,WARNING, etc.).
-
Load environment variables during development:
export $(grep -v '^#' .env | xargs)
-
Run the CLI workflow directly when you just need Markdown output:
python -m newsletter.cli path/to/urls.txt --output-dir ./output # Add --dry-run to preview markdown without writing to disk.
-
Ensure Redis is available locally:
redis-server
-
In a separate terminal, start the Celery worker:
CELERY_BROKER_URL=redis://localhost:6379/0 \\ CELERY_RESULT_BACKEND=redis://localhost:6379/0 \\ DATABASE_PATH=./data/newsletter_tasks.db \\ celery -A newsletter.api.celery_app.celery_app worker --loglevel=info
-
Launch the FastAPI application (served on http://127.0.0.1:8000/ by default):
DATABASE_PATH=./data/newsletter_tasks.db \\ uvicorn newsletter.api.app:app --reload -
Open the root page to access the single-page interface. Paste or upload URLs, tweak options, and watch the Server-Sent Events (SSE) status stream render live progress and Markdown previews.
Key variables recognised by the web stack:
CELERY_BROKER_URL/CELERY_RESULT_BACKEND: Redis connection strings used by Celery.DATABASE_PATH: Absolute path to the SQLite database that persists task metadata.CELERY_TASK_ALWAYS_EAGER: Set totrueto run Celery tasks synchronously (handy for tests/demo).- Existing
.envsettings (OPENROUTER_*,JINA_READER_*,NEWSLETTER_*) continue to configure the LLM pipeline.
render.yaml provisions three services: the FastAPI web app, a Celery worker, and a managed Redis instance. The web and worker services share a persistent disk mounted at /var/data for the SQLite task store. Deploy via:
render deploy --from render.yamlUpdate the synced environment variables in Render's dashboard with your API keys before triggering the first deploy.
- Run
make lint,make format,make typecheck, ormake testfor focused commands. - Run
make checkto execute linting, mypy, and pytest in one pass. - Direct commands are still available if you prefer:
- Ruff lint:
ruff check src tests - Ruff format:
ruff format src tests - Type checks:
mypy src
- Ruff lint:
- Tests:
pytest
Note: The test suite and runtime require Python 3.10+ because the codebase uses modern typing features (
bool | None, etc.). Running the tests under 3.9 will fail during import-time validation.
Implementation is ongoing; consult tasks/Task-PRD-supplement.md for the active task list.