A Flask-based web application for managing recipes with ingredients, images, and unit conversions.
I'm hosting this repo on my gitea instance. All commits to either remote and CI should sync between GitHub and Gitea.
Part of the README for this repo has been generated AI and modified, because I would prefer to focus on development over writing the README. It should still be okay.
- Recipe management with ingredients and directions
- Image upload and storage (currently stored in filesystem with abstractions to be moved to bucket later)
- Unit conversions for recipe ingredients
- Ingredient density tracking for weight calculations
Obviously, software development help would be great, but feature requests are really great too! At some point, I will be happy with this repo and need more feature requests to work on. Please create a discussion post or issue.
- Python 3.10+
- Node.js 20+ (for SCSS compilation)
- pnpm package manager
- Docker & Docker Compose (optional, for containerized deployment)
The application uses environment variables for configuration:
DATABASE_URL: Database connection string (defaults to SQLite for local dev)SECRET_KEY: Flask secret key for session management and security
If you have PostgreSQL running locally and want to use it, you probably know how to set up Docker Compose. Skip to Use an existing PostgreSQL server
### 1. Clone the repository
```bash
git clone https://github.com/EReaso/cookbook.git
cd cookbook
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activatepip install -r requirements.txtFor development (includes testing and linting tools):
pip install -r requirements-dev.txtpnpm installflask db upgradepnpm run buildThe easiest way to get started is with the quickstart script:
./scripts/quickstart.shThis script will:
- Create a
.envfile with generated SECRET_KEY and POSTGRES_PASSWORD - Create a protected external Docker volume for PostgreSQL data
- Provide you with the command to start the application
After running the script, start the application with this command:
docker compose --profile local up --buildThe application will be available at http://localhost:5000 depending on your environment.
If you prefer manual setup or the script doesn't work for your environment:
- Set up environment variables:
cp .env.example .env
# Generate a secure SECRET_KEY and update .env
python -c "import secrets; print(secrets.token_hex(32))"- Create a protected database volume:
docker volume create cookbook_postgres_data- Start the application:
docker compose --profile local up --build- Stop the application:
docker compose downTo remove regular Compose volumes:
docker compose down -vData Persistence:
The application uses Docker volumes to persist data across container restarts:
postgres_data: PostgreSQL database datainstance_data: Flask instance directory, which includes uploaded image files stored in/app/instance/storage
postgres_data is configured as an external named volume (cookbook_postgres_data by default), so
docker compose down -v does not remove it. This makes accidental DB deletion much harder.
To intentionally delete DB data, remove that volume explicitly:
docker volume rm cookbook_postgres_dataIf you already run Postgres elsewhere, set DATABASE_URL in .env and start only the app service:
docker compose up --build webFor local development without Docker:
python wsgi.pyThe application will be available at http://localhost:5000
Use gunicorn:
gunicorn wsgi:wsgi_apppytestpytest --cov=app --cov-report=htmlView coverage report by opening htmlcov/index.html in your browser.
pytest tests/test_models.pyTo run the same screenshot generation step locally as CI:
python -m playwright install --with-deps chromium
python scripts/take_screenshots.py --config screenshots.yml --output-dir screenshotsThis project uses Ruff for both linting and formatting:
- 4-space indentation
- Line length: 120 characters
- Import sorting via Ruff's isort-compatible rules
Format code with Ruff:
ruff format .Auto-fix lint issues:
ruff check --fix .Lint code with Ruff:
ruff check .Install pre-commit hooks:
pre-commit installRun hooks manually:
pre-commit run --all-filesCreate a new migration:
flask db migrate -m "Description of changes"Apply migrations:
flask db upgradeRollback migration:
flask db downgradeThis project uses GitHub Actions for continuous integration:
- Tests: Runs on Python 3.12
- Linting: Checks code quality with Ruff
- Coverage: Uploads coverage reports to Codecov
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and linting
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is open source and available under the AGPL 3.0 License.