# Python PostgreSQL daily sales report

A daily sales desk shows yesterday's revenue, order count, weekly change, and leading products beside an archive of earlier reports. Tokay runs the generator every morning and keeps the Flask viewer live as a Web Service.

The two Python entry points share one PostgreSQL database, which is a useful shape when scheduled work creates something people return to later. Ninety days of fictional orders make the first report meaningful without another account.

## Facts

- Runtime: Python
- Framework: Flask
- Service types: Web Service, Scheduled Service
- Resources: PostgreSQL
- Required secrets: None

## What it does

The viewer opens with a clear prompt when no report has run yet.

After the generator finishes, the latest report shows revenue, orders, change from the prior week, and the three products that earned the most. **Report history** links back through earlier dates.

Run the same reporting date again and the existing report refreshes instead of producing a duplicate.

## Deploy it

Bring this folder to Tokay any way you like. Paste or upload it in the dashboard, push it with git, or hand it to your AI agent along with [our agent instructions](https://app.tokay.io/llms.txt). Tokay figures out the rest.

Working in Claude, ChatGPT, VS Code, or another MCP client? Connect the [Tokay MCP server](https://tokay.io/docs/platform-mcp) and ask your agent to deploy this example. It signs in through your browser, so there is no token to paste.

New to Tokay? The [getting started guide](https://tokay.io/getting-started) walks you through your first deploy.

## Try it

1. Open the generator Service and choose **Run Now**.
2. Refresh the viewer and open yesterday's report from **Report history**.
3. Run the generator again. The same dated report gets a new generated time rather than a duplicate row.

## How it works

You only need one schema owner. The viewer applies the Alembic migration and seeds fictional orders, while the generator reads those tables, calculates its reporting windows, saves one dated result, and exits.

Tokay starts that short process on schedule and keeps every run result. If the calculation fails, the error remains attached to the run instead of disappearing into a long lived server log.

## Secrets

You do not need to add a secret. Tokay supplies the shared `DATABASE_URL` to both Services.

## Grow from here

Try the [uptime monitor](/examples/python-uptime-monitor) when a scheduled job should keep lightweight history with the Service.

## Source files

- [generator/generate\_report.py](https://tokay.io/examples/src/python-postgres-daily-sales-report/generator/generate_report.py)
- [generator/requirements.txt](https://tokay.io/examples/src/python-postgres-daily-sales-report/generator/requirements.txt)
- [viewer/alembic.ini](https://tokay.io/examples/src/python-postgres-daily-sales-report/viewer/alembic.ini)
- [viewer/app.py](https://tokay.io/examples/src/python-postgres-daily-sales-report/viewer/app.py)
- [viewer/migrations/env.py](https://tokay.io/examples/src/python-postgres-daily-sales-report/viewer/migrations/env.py)
- [viewer/migrations/versions/20260718\_01\_create\_sales\_reports.py](https://tokay.io/examples/src/python-postgres-daily-sales-report/viewer/migrations/versions/20260718_01_create_sales_reports.py)
- [viewer/requirements.txt](https://tokay.io/examples/src/python-postgres-daily-sales-report/viewer/requirements.txt)
- [viewer/static/site.css](https://tokay.io/examples/src/python-postgres-daily-sales-report/viewer/static/site.css)
- [viewer/templates/reports.html](https://tokay.io/examples/src/python-postgres-daily-sales-report/viewer/templates/reports.html)

## Download and source

- [Download the complete project](https://tokay.io/examples/downloads/python-postgres-daily-sales-report.zip)
- Last updated: 2026-07-31
- Example revision: `52c7b7f`
- [View this revision on GitHub](https://github.com/tokayio/tokay-examples/tree/52c7b7ffd52e157375b08f1f11ff4fbe6c498642/python-postgres-daily-sales-report)
- [Run a Python script every day](https://tokay.io/use-cases/run-python-script-every-day)
