This page describes the directory layout and the application structure of GeniePy.

Project Layout

The initial directory structure looks as follows:

~/W/p/geniepy/code main ❯ tree -a -L 1 .
├── .ci.env
├── .dockerignore
├── .github
├── .gitignore
├── .gitlab-ci.yml
├── .pre-commit-config.yaml
├── .test.env
├── Dockerfile
├── Makefile
├── Procfile
├── app
├── dist
├── docker-compose.yml
├── fly.toml
├── heroku.yml
├── litestream.yml
├── pyproject.toml
├── render.yaml
├── requirements.txt
├── sample.env
├── secrets
├── setup.cfg

5 directories, 21 files


This file contains CI specific environment variables used on Github Actions and Gitlab CI for the tests to work in this environment.


An initial .dockerignore file for the project.


GeniePy support Github Actions as one of the continuous integration targets.

This directory contains the workflow definitions that will enable continuous testing for your application, if you've chosen Github as the source code hosting service.


An initial gitignore file for the project.


GeniePy support Gitlab CI as one of the continuous integration targets.

This directory contains the job/pipeline definitions that will enable continuous testing for your application, if you've chosen Gitlab as the source code hosting service.


We use the pre-commit framework for managing Git's pre-commit hooks.

This YAML file specifies pre-commit's configuration.


The .test.env file contains environment variables specific to running tests (eg. the database URL pointing to the test database instance, etc.).


This Dockerfile defines the container image for the Starlette / Uvicorn application.


Make is a build automation tool that also acts as a great task runner.

In Makefile we've defined shortcuts for a few commands that you would need to initialize the local development environment and to maintain the pip dependency files.

The rest of the task definitions are specified using Invoke.


This file is mainly for use for Heroku and lets Heroku know which processes to run in the server environment and how to run them.

This file contains the project's README. We've left the file empty so you can fill it up with details about your project.


The app directory contains all the application source code. We'll talk about this in detail in a later section.


As mentioned before, we're using docker-compose for local development. docker-compose.yml specifies the containers to start.

The default configuration GeniePy ships with includes the following 2 containers:

  1. postgres: PostgreSQL container that the app process connects to for persisting data
  2. postgres_test: similar to the postgres container, but only used for hosting the test database

The main uvicorn process runs on the host machine (i.e. outside of Docker).


GeniePy supports as one of the deployment targets. allows developers to configure their application stacks using TOML configuration files. We've added an initial configuration to fly.toml which you're welcome to extend if you use this deployment target.


GeniePy supports Heroku as one of the deployment targets.

Heroku allows developers to deploy their applications inside containers. We've included an initial build configuration to heroku.yml that lets Heroku know how to build the application (which is through Docker).

If you choose Heroku as your deployment target, you're welcome to extend this file depending on your application's needs.


GeniePy supports replicating SQLite databases to cloud storage instances using [Litestream].

This file contains an initial configuration for this setup, if you choose to use it. More instructions for this can be found on how to integrate Litestream.


pyproject.toml is a (relatively) new standard introduced in the Python community to specify build system information for Python projects.

This file also supports adding configuration for different Python tools. This is also what GeniePy uses this file for.

At the time of this writing, GeniePy specifies the configuration for isort in this file under a tool.isort table.


GeniePy supports Render as one of the deployment targets.

Render supports the Infrastructure as Code philosophy by letting users define their services inside a render.yaml file. We've specified the base configuration in this file, which you're welcome to extend if you are deploying your app on Render.

GeniePy uses pip-tools to help you keep your project's dependencies pinned and fresh. specifies the project's (first-level) dependencies pinned to their exact versions. The contents of this file are specified in the requirements.txt file format which pip understands.

Using this file as input, the pip-compile CLI bundled in pip-tools helps us generate the entire dependency tree with all the dependencies pinned to their exact versions.


The requirements.txt file contains the entire dependency tree of our project.

This file is auto-generated using the pip-compile CLI, and as such, should NOT be edited by hand.

If you have adjusted and would like to have requirements.txt reflect the change, please run make pip-compile.


This file acts as a starting point for the environment variables for your application.

If you're initializing a new application, copy this file to .env and edit .env to have your application reflect the changes.


This folder is intended to hold configuration files that your application needs but which should not be checked into the git repository. An example is the service account files for Google Cloud Platform integration.


The setup.cfg file is another way to store configuration for Python tools. GeniePy stores the flake8 configuration in this file.

The file defines the common development task definitions you'll usually run during the course of your project. This includes, for instance, running style checks, running tests using pytest, executing database migrations, etc.

Run invoke --list to see a full list of what's available.