This boilerplate offers a quickstart for building a Python-Flask RESTful API, with built-in support for PostgreSQL, using SQLAlchemy as an ORM. It also makes use of Flask-Security in order to control Users and Roles, as well as Flask-Migrate, to manage database migrations.
This project is a simple Dog-Owner tracker. The owners are considered Users, and we've set up Users, and roles (among other things) through Flask-Security
. The models (found in db > models.py
) are declared and managed using SQLAlchemy
. The Flask-Restful
API can be seen throughout the project, though the dog.py
and owner.py
files in the resources
directory will be of most use when figuring out how to set up the HTTP methods through class-based methods.
We're using Flask-JWT
for authentication and authorization.
The configuration for Flask-migrate
can be seen in the migrate.py
file in the project root.
We make use of marshmallow
and marshmallow_jsonapi
for JSON and data validation. Schemas are declared for every model in the models.py
file, and validation is performed in the different resource files.
- Add Poetry packages manager
- Dockerize project for dev
- Create models and migrations
- Create more api endpoints
- Implement Webhooks
- Implement Redis Queue Worker
- Add supervisor for fast startup and webhook worker
- Implement Factory Pattern
- Log webhooks
- Setup Flask-Mail queue
- Add Login/Register Routes with jwt_extended (implement single token settings config)
- Add api endpoints documentation (/docs)
- Implement custom commands
- Add blockchain commands group
- Setup modex blockchain api config
- create modex entities, and handle auth token
- implement modex blockchain webhooks
- flask
- flask-security
- flask-restful
- flask-cors
- flask-sqlalchemy
- flask-migrate
- flask-script
- flask-marshmallow
- flask-jwt
- marshmallow
- marshmallow_jsonapi
- marshmallow-sqlalchemy
- typing-extensions
- psycopg2-binary
- rq
- redis
- gunicorn
- python-dotenv
- flask-rq2
- flasgger
Create your DB in Postgres using the credentials stored in the config/base_settings.py
file (see the setup.md
file for instructions on doing this), and then run the following from the project root:
Join API docker container shell and execute:
python3 console.py db init (once)
python3 console.py db migrate (on every model change)
python3 console.py db upgrade (to execute migrations)
Add blockchain custom commands:
root@9928cf683f5b:/app# python3 console.py
Usage: console.py [OPTIONS] COMMAND [ARGS]...
Options:
--version Show the flask version
--help Show this message and exit.
Commands:
blockchain Perform blockchain operations.
db Perform database migrations.
Endpoint Methods Rule
------------------------------- ------- -----------------------------------
flasgger.<lambda> GET /apidocs/index.html
flasgger.apidocs GET /api/v1/docs/
flasgger.apispec_1 GET /api/v1/docs/apispec_1.json
flasgger.static GET /api/v1/docs/static/<path:filename>
v1.clientcreate POST /api/v1/clients
v1.clientupdate PATCH /api/v1/clients/<int:id>
v1.homepage GET /api/v1/
v1.logoutuser POST /api/v1/logout
v1.ordercreate POST /api/v1/orders
v1.refreshtoken POST /api/v1/token/refresh
v1.show POST /api/v1/client-webhook-1
v1.transactionblockchainwebhook POST /api/v1/webhooks/transactions
v1.userlogin POST /api/v1/login
POST REQUEST
{
"data": {
"type": "client",
"attributes": {
"name": "FirmaMareCuMMar2e",
"client_type": 1,
"webhook_url": "https://41ae-213-233-108-217.ngrok.io/api/v1/webhook-client-1/",
"webhook_key": "xuoksiud234"
}
}
}
PATCH REQUEST
{
"data": {
"type": "client",
"attributes": {
"webhook_url": "anulat",
"webhook_key": "xuoksiud2343"
}
}
}
POST REQUEST
- buyer_id, seller_id - clients id
{
"data": {
"type": "order",
"attributes": {
"buyer_id": 2,
"order_type": "good",
"seller_id": 1,
"order_details": "nu a venit cu ketchup"
}
}
}
Note: If make sure the value for the "type" key matches the "type" value in the Meta
class of whatever Schema
used to validate your object. You also can input however many attributes for your object as you'd like in the "attributes" dictionary.
Authorization : Bearer AUTH_TOKEN
You'll notice that there are several lines of code under the "Bootstrap Several Users" section in main.py
. These users will be created if there are no users in the database, once you run the server, and hit an endpoint. I recommend using Postman to hit the endpoint localhost:5000/api/v1/orders
to get these users started.
Note: Make sure that once you're aware of this code there and the users that they create if using this boilerplate for a production-level application!
Authentication
As you can see in the user.py
file, all of the CRUD features for the User
class are protected by the decorator jwt_required()
. This means that a valid Authorization token is needed in order to reach those endpoints and perform that logic. In order to get a valid auth token, send a POST request to this url: /api/v1/auth
with the Content-Type Header of application/json
, passing in the following:
{
"username": "EMAIL",
"password": "PASSWORD"
}
Once you send that request, you should get the following back:
{
"access_token": "AUTH_TOKEN"
}
Using this token, you can then call the protected endpoints by adding the following headers to your calls:
- Add ReactJs Typescript boilerplate (done)