- Notifications
You must be signed in to change notification settings - Fork374
🚀 Cookiecutter Template for FastAPI + React Projects. Using PostgreSQL, SQLAlchemy, and Docker
License
Buuntu/fastapi-react
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A cookiecutter template for bootstrapping a FastAPI and React project using amodern stack.
- FastAPI (Python 3.8)
- JWT authentication usingOAuth2 "passwordflow" andPyJWT
- React (with Typescript)
- react-router v5 to handle routing
- Utility functions andhigher-ordercomponents for handling authentication
- PostgreSQL for the database
- SqlAlchemy for ORM
- Celery forbackgroundtasks andRedis as a message broker
- IncludesFlower for taskmonitoring
- Alembic for databasemigrations
- Pytest for backend tests
- Includes test database, transaction rollbacks after each test, and reusablePytest fixtures.
- Prettier/ESLint (Airbnbstyle guide)
- Docker Compose for development
- Nginx as a reverse proxy to allowbackend/frontend on the same port
- MaterialUI using recommendedCSS-in-JS styling.
- react-admin for the admindashboard
- Using the same token based authentication as FastAPI backend (JWT)
- Background
- Quick Start
- Develop
- Admin Dashboard
- Security
- Testing
- Background Tasks
- Frontend Utilities
- Deployment
- Contributing
It is often laborsome to start a new project. 90% of the time you have to decidehow to handle authentication, reverse proxies, docker containers, testing,server-side validation, linting, etc. before you can even get started.
FastAPI-React serves to streamline and give you that functionality out ofthe box.
It is meant as a lightweight/React alternative toFastAPI's official fullstackproject. If you wanta more comprehensive project in Vue, I would suggest you start there. A lot ofthe backend code is taken from that project or theFastAPI officialdocs.
First, install cookiecutter if you don't already have it:
pip3 install cookiecutter
Second, install docker-compose if you don't already have it:
docker-compose installation officialdocs.
Then, in the directory you want your project to live:
cookiecutter gh:Buuntu/fastapi-react
You will need to put in a few variables and it will create a project directory(called whatever you set forproject_slug
).
Input Variables
- project_name [default fastapi-react-project]
- project_slug [default fastapi-react-project] - this is your project directory
- port [default 8000]
- postgres_user [default postgres]
- postgres_password [default password]
- postgres_database [default app]
- superuser_email [defaultadmin@fastapi-react-project.com]
- superuser_password [default password]
- secret_key [default super_secret]
Change into your project directory and run:
chmod +x scripts/build.sh./scripts/build.sh
This will build and run the docker containers, run the alembic migrations, andload the initial data (a test user).
It may take a while to build the first time it's run since it needs to fetch allthe docker images.
Once you've built the images once, you can simply use regulardocker-compose
commands to manage your development environment, for example to start yourcontainers:
docker-compose up -d
Once this finishes you can navigate to the port set during setup (default islocalhost:8000
), you should see the slightly modified create-react-app page:
Note: If you see an Nginx error at first with a502: Bad Gateway
page, youmay have to wait for webpack to build the development server (the nginxcontainer builds much more quickly).
The backend docs will be athttp://localhost:8000/api/docs
.
This project usesreact-admin for a highlyconfigurable admin dashboard.
After starting the project, navigate tohttp://localhost:8000/admin
. Youshould see a login screen. Use the username/password you set for the superuseron project setup.
NOTE: regular users will not be able to access the admin dashboard
You should now see a list of users which you can edit, add, and delete. Thetable is configured with the REST endpoints to the FastAPI/users
routes inthe backend.
The admin dashboard is kept in thefrontend/src/admin
directory to keep itseparate from the regular frontend.
To generate a secure key used for encrypting/decrypting the JSON Web Tokens, youcan run this command:
openssl rand -hex 32
The default is fine for development but you will want something more secure forproduction.
You can either set this on project setup assecret_key
or manually edit thePythonSECRET_KEY
variable inbackend/app/core/security.py
.
This project comes with Pytest and a few Pytest fixtures for easier mocking. Thefixtures are all located inbackend/conftest.py
within your project directory.
All tests are configured to run on a test database usingSQLAlchemytransactions toreset the testing state on each function. This is to avoid a database callaffecting the state of a different test.
These fixtures are included inbackend/conftest.py
and are automaticallyimported into any test files that being withtest_
.
Thetest_db
fixture is an empty test database and an instance of a SQLAlchemySession class.
deftest_user(test_db):asserttest_db.query(models.User).all()
deftest_user_exists(test_user):asserttest_user.email=="admin@example.com"
deftest_superuser(client,test_superuser):asserttest_superuser.is_superuser
To use an unauthenticated test client, useclient
:
deftest_get_users(client):client.get("/api/v1/users")assertresponse.status_code==200
If you need an authenticated client using OAuth2 and JWTs:
deftest_user_me(client,user_token_headers):response=client.get("/api/v1/users/me",headers=user_token_headers, )assertresponse.status_code==200
Since OAuth2 expects the access token in the headers, you will need to pass inuser_token_headers
as theheaders
argument in any client request thatrequires authentication.
deftest_user_me(client,superuser_token_headers):response=client.get("/api/v1/users",headers=superuser_token_headers, )assertresponse.status_code==200
This template comes with Celery and Redis Docker containers pre-configured foryou. For any long running processes, it's recommended that you handle theseusing a task queue like Celery to avoid making the client wait for a request tofinish. Some examples of this might be sending emails, uploading large files, orany long running, resource intensive tasks.
There is an example task inbackend/app/tasks.py
and an example Celery test inbackend/app/tests/test_tasks.py
. This test runs synchronously, which is whatCelery docs recommend.
If you are not happy with Celery or Redis, it should be easy to swap thesecontainers out with your favorite tools. Some suggested alternatives might beHuey as the task queue andRabbitMQ for the message broker.
You can monitor tasks using Flower by going tohttp://localhost:5555
There are a few helper methods to handle authentication infrontend/src/utils
.These store and access the JWT returned by FastAPI in local storage. Even thoughthis doesn't add any security, we prevent loading routes that might be protectedon the frontend, which results in a better UX experience.
// in src/utils/auth.ts/** * Handles authentication with backend and stores in JWT in local storage **/constlogin=(email:string,password:string)=>boolean;
// in src/utils/auth.ts// clears token from local storageconstlogout=(email:string,password:string)=>void;
// Checks authenticated state from JWT tokensconstisAuthenticated=()=>boolean;
Some basic routes are included (and handled infrontend/Routes.tsx
).
/login
- Login screen/logout
- Logout/
- Home/protected
- Example of protected route
This handles routes that require authentication. It will automatically checkwhether the correct token with the "user" permissions is present or redirect tothe home page.
// in src/Routes.tsximport{Switch}from'react-router-dom';// Replace this with your componentimport{ProtectedComponent}from'components';constRoutes=()=>(<Switch><PrivateRoutepath="/protected_route"component={ProtectedComponent}/></Switch>);
This stack can be adjusted and used with several deployment options that arecompatible with Docker Compose, but it may be easiest to use Docker in SwarmMode with an Nginx main load balancer proxy handling automatic HTTPScertificates, using the ideas from DockerSwarm.rocks.
Please refer to DockerSwarm.rocks to see how to deploy such a cluster easily.You will have to change the Traefik examples to Nginx or update yourdocker-compose file.
Contributing is more than welcome. Please read theContributingdoc to find out more.
About
🚀 Cookiecutter Template for FastAPI + React Projects. Using PostgreSQL, SQLAlchemy, and Docker
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors13
Uh oh!
There was an error while loading.Please reload this page.