https://github.com/freelancer/esapyi
A dockerized and production ready python API template with no setup required.
https://github.com/freelancer/esapyi
docker flask-api python-template python3
Last synced: about 2 months ago
JSON representation
A dockerized and production ready python API template with no setup required.
- Host: GitHub
- URL: https://github.com/freelancer/esapyi
- Owner: freelancer
- License: lgpl-3.0
- Created: 2019-08-19T07:58:10.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2023-08-25T03:33:40.000Z (almost 2 years ago)
- Last Synced: 2023-08-25T05:48:57.154Z (almost 2 years ago)
- Topics: docker, flask-api, python-template, python3
- Language: Python
- Homepage:
- Size: 599 KB
- Stars: 7
- Watchers: 6
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# esapyi · [](https://github.com/freelancer/esapyi/actions/workflows/ci.yml)
A dockerized and production ready python API template with no setup required.This project aims to provide a pre-configured python API server template based on the Flask python framework.
| Table of Contents |
| ------------------------------------------------------------------------------------------- |
| [Quickstart Guide](#Quickstart-guide) |
| [The Hitchhicker's Guide to `api_boilerplate`](#The-Hitchhickers-Guide-to-api_boilerplate) |
| [Developer Guide](#Developer-Guide) |## Quickstart guide
1. Ensure that you have [docker](https://docs.docker.com/install/) installed on your system.
2. Clone this repository using `git clone https://github.com/freelancer/esapyi.git`
3. (Optional) Pick a new name for your project and run `./project_rename.sh "my_project_name"`
4. Start the python server using `./run.sh dev`## The Hitchhicker's Guide to `api_boilerplate`
This section will take you through the following* [Project Structure](#Project-Structure)
* Writing versioned APIs (TODO)### Project Structure
api_boilerplate
├── app.py
├── config
│ ├── __init__.py
│ ├── local_development.py
│ ├── prod.py
│ └── testing.py
├── exceptions
├── handlers
├── healthcheck
├── models
├── utils
└── v1
├── exceptions
├── handlers
├── input_schemas.py
├── output_schemas.py## Developer Guide
This section goes through the various tools and procedures a developer would need when developing using this setup.**Contents**
- [Commands Quickstart](#Commands): Getting the most out of the utility scripts
- [Linting](#Linting): The linter setup and now to customize it
- [Testing](#Testing): Getting the most out of the test setup
- [Database Migrations](#Database-Migrations): How to track and alter the database schema
- [Production Deployment](#Production-Deployment): The ideal way of running the production server### Commands Quickstart
All of the common development tasks that need to be performed are done through the `run.sh` script located at the root of the project.
`run.sh` has the following commands
- `run.sh dev` - start the local db and python development server at port *8080*
- `run.sh prod` - start the local db and the production [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/) python server at port *8080*
- `run.sh lint` - lint the entire project
- `run.sh test` - run the entire test suite for the project
- `run.sh check` - run the *lint* and *test* command in succession
- `run.sh dev db` - spin up and connect to the local dev database
- `run.sh alembic` - proxy to the [alembic](https://alembic.sqlalchemy.org) cli### Linting
This project uses 2 main linting programs
- [pyright](https://microsoft.github.io/pyright/#/) - a static type-checker
- [ruff](https://ruff.rs/) - a code quality checkerIf you want to customize the lint configuration, modify the following files
- [pyproject.toml](pyproject.toml) - to customize the mypy setup
- [pyproject.toml](pyproject.toml) - to customize the ruff setup### Testing
This project uses the [pytest](https://docs.pytest.org/en/latest/) framework for writing and maintaining unit tests.
- In order to configure pytest, use the [pytest.ini](pytest.ini) fileThe unit tests also spin up a dockerized MySQL database. Every `run.sh test` call will kill and re-create the database to ensure tests are running in a fresh environment.
There are 3 base test classes which you should extend when writing tests.
* [BaseTestCase](tests/conftest.py#L10)
* An empty class that extends [unittest.TestCase](https://docs.python.org/3/library/unittest.html#unittest.TestCase)
* [AppContextTestCase](tests/conftest.py#L14)
* A class makes a [flask test client](https://flask.palletsprojects.com/en/1.0.x/testing/#the-testing-skeleton) available at `self.client`
* [DbContextTestCase](tests/conftest.py#L22)
* Waits for the database to become available if it's not
* Re-sets the database after every test using [alembic](https://alembic.sqlalchemy.org/en/latest/tutorial.html#downgrading).### Database Migrations
This project uses [alembic](https://alembic.sqlalchemy.org/en/latest/) as a database migrations tool. This tool essentially acts as a version control for your database schema. Any changes that need to be made should be tracked and done through alembic.
**Example: Adding a new column**
Say we want to add a new column to our users table - `first_name`.
To do so, follow these steps1. Modify the [user model](api_boilerplate/models/user.py) and add the first_name column
```python
first_name = Column(Text, nullable=False)
```
2. Run the alembic command to [autogenerate](https://alembic.sqlalchemy.org/en/latest/autogenerate.html) a revision
* This command creates a new file under the migrations/versions folder which contains code to create this new column in the db
```bash
./run.sh alembic revision --autogenerate -m"add_fname_to_user"
```
3. Run the alembic command to upgrade the database
```bash
./run.sh alembic upgrade head
```
4. That's it! The user table in the local docker database now has a first_name column. Remember to commit the generated migration file to git.### Production Deployment
It is recommended that you deploy this API as a docker container on your production server.
In order to help build this container there is a production ready [dockerfile](lib/docker/prod_app/Dockerfile) provided.In production, the python app is run using [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/). The configuration for this uWSGI server is in [uwsgi_prod_app_config.ini](uwsgi_prod_app_config.ini).