Backend/scripts based on cookiecutter fastapi-react
- FastAPI with Python 3.9, totally asynchronous
- React 17
- create-react-app with Typescript
- Postgres
- Redis (PubSub and TimeSeries)
- Celery + Beat
- SQLAlchemy with Alembic for migrations and asynchronous I/O (asyncio) support
- Pytest for backend tests
- Docker compose for easier development
- Nginx as a reverse proxy to allow backend and frontend on the same port
Parallel database queries with synchronous access
➜ ~ wrk -c30 -t3 -d10s -H "Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhcnRlbS5rdXN0aWtvdkBnbWFpbC5jb20iLCJ1aWQiOjUsImZuIjpudWxsLCJsbiI6bnVsbCwicGVybWlzc2lvbnMiOiJ1c2VyIiwiZXhwIjoxNjU0MDIxODg2fQ.439CjqvKtBMvIXBEmH0FLW98Te51ur-VBlTsaS7AkhI" http://localhost:8888/api/users/me --timeout 5
Running 10s test @ http://localhost:8888/api/users/me
3 threads and 30 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 49.86ms 23.51ms 167.93ms 67.88%
Req/Sec 201.13 28.65 343.00 71.00%
6013 requests in 10.01s, 1.18MB read
Requests/sec: 600.77
Transfer/sec: 121.03KB
Parallel database queries with asynchronous access
wrk -c500 -t25 -d10s -H "Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbkBmYXN0YXBpLXJlYWN0LXByb2plY3QuY29tIiwidWlkIjoxLCJmbiI6IkFkbWluIiwibG4iOm51bGwsInBlcm1pc3Npb25zIjoiYWRtaW4iLCJleHAiOjE2NTQwMzQxOTd9.ivCnw0uwce81JdxV7ZHMtl38jVaHUIoD2G95791P634" http://localhost:8888/api/users/me
Running 10s test @ http://localhost:8888/api/users/me
25 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 585.91ms 509.32ms 1.99s 79.50%
Req/Sec 30.16 17.33 160.00 61.57%
7098 requests in 10.07s, 1.59MB read
Socket errors: connect 0, read 0, write 0, timeout 316
Requests/sec: 704.59
Transfer/sec: 161.25KB
The only dependencies for this project are docker and docker-compose.
Starting the project with hot-reloading enabled (the first time it will take a while):
docker-compose run backend alembic upgrade head
docker-compose run backend python app/initial_data.py
docker-compose up -d
And navigate to http://localhost:8000
Note: If you see an Nginx error at first with a 502: Bad Gateway
page, you may have to wait for webpack to build the development server (the nginx container builds much more quickly).
Auto-generated docs will be at http://localhost:8000/api/docs
docker-compose build
docker-compose restart
docker-compose down --remove-orphans
docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q)
cd frontend
npm install
npm test
Migrations are run using alembic. To run all migrations and load init data:
docker-compose run backend alembic upgrade head
docker-compose run backend python app/initial_data.py
To create a new migration:
alembic revision -m "create users table"
And fill in upgrade
and downgrade
methods. For more information see
Alembic's official documentation.
There is a helper script for both frontend and backend tests:
./scripts/test.sh
docker-compose run backend pytest
any arguments to pytest can also be passed after this command
docker-compose run frontend npm run test:all
This is the same as running npm test from within the frontend directory
backend
└── app
├── alembic
│ └── versions # where migrations are located
├── api
│ └── base
│ └── endpoints
│ └── v2
│ └── endpoints
├── core # config
├── db # db models
├── tests # pytest
└── main.py # entrypoint to backend
frontend
└── public
└── src
├── components
│ └── Home.tsx
├── config
│ └── index.tsx # constants
├── __tests__
│ └── test_home.tsx
├── index.tsx # entrypoint
└── App.tsx # handles routing