Async Web API with FastAPI + Prisma + GraphQL

This is a sample project of Async Web API with FastAPI + Prisma.

If you want to use sqlalchemy instead of prisma, see rhoboro/async-fastapi-sqlalchemy.

Setup

Install

$ python3 -m venv venv --upgrade-deps
$ . venv/bin/activate
(venv) $ pip install -r requirements.lock --no-binary pydantic --use-pep517 --no-cache --use-feature=no-binary-enable-wheel-cache

Setup a database and create tables

(venv) $ docker run -d --name db \
  -e POSTGRES_PASSWORD=password \
  -e PGDATA=/var/lib/postgresql/data/pgdata \
  -v $(pwd)/pgdata:/var/lib/postgresql/data \
  -p 5432:5432 \
  postgres:14.4-alpine

(venv) $ DATABASE_URL=postgresql://postgres:password@localhost:5432 prisma db push
Prisma schema loaded from schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "localhost:5432"

🚀  Your database is now in sync with your schema. Done in 638ms

✔ Generated Prisma Client Python (v0.7.0) to ./app/prisma in 135ms

Run

(venv) $ DATABASE_URL=postgresql://postgres:password@localhost:5432 APP_CONFIG_FILE=local uvicorn app.main:app --reload-dir app

You can now access localhost:8000/docs to see the API documentation.

GraphQL

This application has additional endpoint /graphql. If installed graphene, you can also access localhost:8000/graphql.

(venv) $ pip install graphene
(venv) $ DATABASE_URL=postgresql://postgres:password@localhost:5432 APP_CONFIG_FILE=local uvicorn app.main:app --reload-dir app
$ curl -X POST localhost:8000/graphql -H 'content-type=application/json' --data '{"query": "query { notebook(id:1) { id title notes { title notebookId }}}"}'
{
  "notebook": {
    "id": "1",
    "title": "string",
    "notes": [
      {
        "title": "string",
        "notebookId": 1
      }
    ]
  }
}

Test

(venv) $ pip install -r requirements_test.txt
(venv) $ black app
(venv) $ isort app
(venv) $ pytest app
(venv) $ mypy app
(venv) $ pyright

Prisma Commands

See https://www.prisma.io/docs/reference/api-reference/command-reference

TODOs

  • Add Unit tests
  • Setup a temporary db for unit test