|
1 | 1 | # Dynamic Pricing |
2 | 2 |
|
3 | | -## Introduction |
| 3 | +**Measure the revenue impact of time-of-day menu pricing on a Deliveroo restaurant.** |
4 | 4 |
|
5 | | -This project is a mix of three parts: a webhook that satifies the requirements of the [Deliveroo Orders API](https://api-docs.deliveroo.com/docs/introduction), a simple Order Management System that interacts directly with the Orders DB, and Jupyter Notebooks for data analysis to measure the impact of Dynamic Pricing. |
| 5 | +Most restaurants set one price and leave it. But demand isn't flat — lunch rushes look nothing like a 3pm lull, and weekends diverge from weekdays. This repo ingests live orders from Deliveroo, normalizes them into a Postgres schema, and ships a notebook analysis layer to segment orders by time window, day of week, and pricing period — so "before" and "after" are directly comparable on the same store. |
6 | 6 |
|
7 | | -## Deliveroo |
| 7 | +## Architecture |
8 | 8 |
|
9 | | -All the Deliveroo related decisions in this codebase are based on requirements from [Deliveroo Orders API](https://api-docs.deliveroo.com/docs/introduction). |
| 9 | +Three pieces, each independently useful: |
10 | 10 |
|
11 | | -## Requirements |
| 11 | +``` |
| 12 | +Deliveroo Orders API ──webhook──> Flask app ──> PostgreSQL |
| 13 | + | ^ |
| 14 | + v | |
| 15 | + OAuth2 sync OMS |
| 16 | + (status ACKs) (upsert layer) |
| 17 | + | |
| 18 | + v |
| 19 | + Jupyter notebooks |
| 20 | + (metrics + plots) |
| 21 | +``` |
| 22 | + |
| 23 | +1. **Webhook** (`src/dynamic_pricing/webhook/`) — Flask endpoints (`/dev-webhook`, `/prod-webhook`) that receive order events, validate `pos_item_id` on every line, ACK `order.status_update` events back to Deliveroo via OAuth2 client-credentials, and forward the payload to the OMS. |
| 24 | +2. **Order Management System** (`src/dynamic_pricing/core/`) — SQLAlchemy upsert layer over seven related tables (customers, partners, orders, items, modifiers, order_items, order_item_modifiers). `db_init.py` provisions the schema; `order_manager.py` handles webhook-driven and backfill inserts. |
| 25 | +3. **Analysis** (`src/dynamic_pricing/analysis/`) — metrics and plotters for orders-per-interval, revenue-per-interval, prep-time, day-of-week splits, and a popularity-vs-profitability menu matrix (Star / Puzzle / Cash Cow / Dud). Three notebooks: wraps, non-wraps, and a Prophet seasonality pass. |
12 | 26 |
|
13 | | -- Python 3.10 |
14 | | -- Key Dependencies: See `requirements.txt` |
| 27 | +## Tech stack |
15 | 28 |
|
16 | | -## Installation |
| 29 | +Python 3.10 - Flask 2.2 - gunicorn - PostgreSQL - SQLAlchemy 2.0 - psycopg - pandas - plotly - prophet - JupyterLab - pytest - pytest-postgresql - black - pylint - pre-commit. |
17 | 30 |
|
18 | | -You can install the Dynamic Pricing API by cloning the repository and installing the required dependencies. |
| 31 | +## Quick start |
19 | 32 |
|
20 | 33 | ```bash |
21 | | -git clone https://github.com/Sree5835/dynamic_pricing |
| 34 | +git clone https://github.com/zalatar242/dynamic_pricing |
22 | 35 | cd dynamic_pricing |
23 | | -``` |
24 | | - |
25 | | -## Creating a virtual environment within the project |
26 | 36 |
|
27 | | -Using a virtual environment allows for a clean and isolated environment for you to install project dependencies and run code. To create a virtual environment within the project, run (depending on whether your Python command is `python` or `python3`): |
28 | | - |
29 | | -``` |
30 | 37 | python -m venv .venv |
31 | | -``` |
| 38 | +source .venv/bin/activate # Windows: .venv\Scripts\activate |
32 | 39 |
|
33 | | -You can activate your virtual environment with: |
34 | | - |
35 | | -``` |
36 | | -source .venv/bin/activate |
37 | | -``` |
38 | | - |
39 | | -With Windows, use: |
| 40 | +pip install -r requirements.txt |
| 41 | +pip install . |
40 | 42 |
|
41 | | -``` |
42 | | -.venv\Scripts\activate |
| 43 | +cp .env.sample .env # fill in Deliveroo creds + DB vars |
| 44 | +pre-commit install |
43 | 45 | ``` |
44 | 46 |
|
45 | | -You can then install all dependencies and build within the virtual environment when activated. To deactivate, run: |
| 47 | +Initialize the schema (destructive — drops existing tables): |
46 | 48 |
|
| 49 | +```bash |
| 50 | +python src/dynamic_pricing/core/db_init.py |
47 | 51 | ``` |
48 | | -deactivate |
49 | | -``` |
50 | | - |
51 | | -## Installing Dependencies |
52 | 52 |
|
53 | | -This project not only has exter dependencies in `requirements.txt`, it also has a dynamic_pricing package that is set up using the `setup.py`. Therefore, to install all depdencies and build, run: |
| 53 | +Run the webhook locally, or via Procfile for production: |
54 | 54 |
|
| 55 | +```bash |
| 56 | +python src/dynamic_pricing/webhook/app.py |
| 57 | +gunicorn src.dynamic_pricing.webhook.app:app |
55 | 58 | ``` |
56 | | -pip install -r requirements.txt |
57 | | -pip install . |
58 | | -``` |
59 | | - |
60 | | -## Set up pre-commit |
61 | 59 |
|
62 | | -This repository uses the pre-commit library to enable pre-commit hooks with the project. These hooks allow for various checks to be completed when you run git commit, ensuring that no un-linted and un-formatted code is persisted to the remote repositories. We have two main hooks set up: |
| 60 | +## Testing |
63 | 61 |
|
64 | | - Black (formatter) |
65 | | - Pylint (linting) |
66 | | - |
67 | | -You only need to set up pre-commit once when you clone this repo, by running: |
68 | | - |
69 | | -``` |
70 | | -pre-commit install |
| 62 | +```bash |
| 63 | +pytest # unit tests |
| 64 | +pytest --cov=src --cov-report=html # coverage report |
71 | 65 | ``` |
72 | 66 |
|
73 | | -## Setting environment variables |
| 67 | +`pytest-postgresql` spins up an ephemeral Postgres for DB tests — no external database required. |
74 | 68 |
|
75 | | -This repository contains an `.env.example` file with example environment variables for usage in the code. The code will attempt to read from `.env` file at the top level of the repository. To ensure this file is present, run: |
| 69 | +## Docker |
76 | 70 |
|
77 | | -``` |
78 | | -cp .env.example .env |
| 71 | +```bash |
| 72 | +docker build -t dynamic_pricing . |
| 73 | +docker run -p 80:80 --env-file .env dynamic_pricing |
79 | 74 | ``` |
80 | 75 |
|
81 | | -## Running test |
| 76 | +Point Deliveroo's webhook configuration at `http(s)://<host>/dev-webhook` (sandbox) or `/prod-webhook` (production). |
82 | 77 |
|
83 | | -This project uses `pytest` as the unit testing framework. To run the unit tests, you can run: |
| 78 | +## Environment |
84 | 79 |
|
85 | | -``` |
86 | | -pytest |
87 | | -``` |
88 | | - |
89 | | -We use pytest-cov as our coverage plugin. To run pytest and generate a HTML coverage report, you can run: |
90 | | - |
91 | | -``` |
92 | | -pytest --cov=src --cov-report=html |
93 | | -``` |
| 80 | +See `.env.sample`: `DEV_CLIENT_ID` / `DEV_SECRET` and `PROD_CLIENT_ID` / `PROD_SECRET` (Deliveroo OAuth2), `AWS_DB_*` (Postgres), `PARTNER1` / `PARTNER2` (tracked restaurants). All Deliveroo integration follows the [Orders API](https://api-docs.deliveroo.com/docs/introduction) spec. |
0 commit comments