Skip to main content

A batteries-included framework to build high performance, async GraphQL APIs

Project description

Turbulette

test Codacy Badge Codacy Badge PyPI PyPI - Python Version PyPI - License Checked with mypy Generic badge security: bandit Generic badge

Turbulette packages all you need to build great GraphQL APIs :

ASGI framework, GraphQL library, ORM and data validation


Documentation : https://python-turbulette.github.io/turbulette/


Features :

  • Split your API in small, independent applications
  • Generate Pydantic models from GraphQL types
  • JWT authentication with refresh and fresh tokens
  • Declarative, powerful and extendable policy-based access control (PBAC)
  • Extendable auth user model with role management
  • Async caching (provided by async-caches)
  • Built-in CLI to manage project, apps, and DB migrations
  • Built-in pytest plugin to quickly test your resolvers
  • Settings management at project and app-level (thanks to simple-settings)
  • CSRF middleware
  • 100% test coverage
  • 100% typed, your IDE will thank you ;)
  • Handcrafted with โค๏ธ, from ๐Ÿ‡ซ๐Ÿ‡ท

Requirements

Python 3.6+

๐Ÿ‘ Turbulette makes use of great tools/frameworks and wouldn't exist without them :

  • Ariadne - Schema-first GraphQL library
  • Starlette - The little ASGI framework that shines
  • GINO - Lightweight, async ORM
  • Pydantic - Powerful data validation with type annotations
  • Alembic - Lightweight database migration tool
  • simple-settings - A generic settings system inspired by Django's one
  • async-caches - Async caching library
  • Click - A "Command Line Interface Creation Kit"

Installation

pip install turbulette

You will also need an ASGI server, such as uvicorn :

pip install uvicorn

๐Ÿš€ 5 min Quick Start

Here is a short example that demonstrates a minimal project setup.

We will see how to scaffold a simple Turbulette project, create a Turbulette application, and write some GraphQL schema/resolver. It's advisable to start the project in a virtualenv to isolate your dependencies. Here we will be using poetry :

poetry init

Then, install Turbulette from PyPI :

poetry add turbulette

1: Create a project

First, create a hello_world/ directory that will contain the whole project.

Now, inside this folder, create your Turbulette project using the turb CLI :

turb project my-project

You should get with something like this :

.
โ””โ”€โ”€ ๐Ÿ“ my-project
    โ”œโ”€โ”€ ๐Ÿ“ alembic
    โ”‚   โ”œโ”€โ”€ ๐Ÿ“„ env.py
    โ”‚   โ””โ”€โ”€ ๐Ÿ“„ script.py.mako
    โ”œโ”€โ”€ ๐Ÿ“„ .env
    โ”œโ”€โ”€ ๐Ÿ“„ alembic.ini
    โ”œโ”€โ”€ ๐Ÿ“„ app.py
    โ””โ”€โ”€ ๐Ÿ“„ settings.py

Let's break down the structure :

  • ๐Ÿ“ my-project : Here is the so-called Turbulette project folder, it will contain applications and project-level configuration files
  • ๐Ÿ“ alembic : Contains the Alembic scripts used when generating/applying DB migrations
    • ๐Ÿ“„ env.py
    • ๐Ÿ“„ script.py.mako
  • ๐Ÿ“„ .env : The actual project settings live here
  • ๐Ÿ“„ app.py : Your API entrypoint, it contains the ASGI app
  • ๐Ÿ“„ settings.py : Will load settings from .env file

Why have both .env and settings.py?

You don't have to. You can also put all your settings in settings.py. But Turbulette encourage you to follow the twelve-factor methodology, that recommend to separate settings from code because config varies substantially across deploys, code does not. This way, you can untrack .env from version control and only keep tracking settings.py, which will load settings from .env using Starlette's Config object.

2: Create the first app

Now it's time to create a Turbulette application!

Run this command under the project directory (my-project) :

turb app --name hello-world

You need to run turb app under the project dir because the CLI needs to access the almebic.ini file to create the initial database migration.

You should see your new app under the project folder :

.
โ””โ”€โ”€ ๐Ÿ“ my-project
    ...
    |
    โ””โ”€โ”€ ๐Ÿ“ hello-world
        โ”œโ”€โ”€ ๐Ÿ“ graphql
        โ”œโ”€โ”€ ๐Ÿ“ migrations
        โ”‚   โ””โ”€โ”€ ๐Ÿ“„ 20200926_1508_auto_ef7704f9741f_initial.py
        โ”œโ”€โ”€ ๐Ÿ“ resolvers
        โ””โ”€โ”€ ๐Ÿ“„ models.py

Details :

  • ๐Ÿ“ graphql : All the GraphQL schema will live here
  • ๐Ÿ“ migrations : Will contain database migrations generated by Alembic
  • ๐Ÿ“ resolvers : Python package where you will write resolvers binded to the schema
  • ๐Ÿ“„ models.py : Will hold GINO models for this app

3: GraphQL schema

Now that we have our project scaffold, we can start writing actual schema/code.

Create a schema.gql file in the ๐Ÿ“ graphql folder and add this base schema :

extend type Query {
    user: [User]
}

type User {
    id: ID!
    username: String!
    gender: String!
    isStaff: Boolean!
}

Note that we extend the type Query because Turbulette already defines it. The same goes for Mutation type

4: Add a resolver

The last missing piece is the resolver for our user query, to make the API returning something when querying for it.

As you may have guessed, we will create a new Python module in our ๐Ÿ“ resolvers package. Let's call it user.py :

from turbulette import query


@query.field("user")
async def user(obj, info, **kwargs):
    return [
        {"id": 1, "username": "Gustave Eiffel", "gender": "male", "is_staff": False},
        {"id": 2, "username": "Marie Curie", "gender": "female", "is_staff": True},
    ]

5: Run it

Our user query is now binded to the schema, so let's test it.

Start the server :

poetry run uvicorn app:app --port 8000

Now, go to http://localhost:8000/graphql, you will see the GraphQL Playground IDE. Finally, run the user query, for example :

query {
  user {
    id
    username
    gender
    isStaff
  }
}

Should give you the following expected result :

{
  "data": {
    "user": [
      {
        "id": "1",
        "username": "Gustave Eiffel",
        "gender": "male",
        "isStaff": false
      },
      {
        "id": "2",
        "username": "Marie Curie",
        "gender": "female",
        "isStaff": true
      }
    ]
  }
}

Good job! That was a straightforward example, showing off the bare minimum needed to set up a Turbulette API. To get the most of it, follow the User Guide.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

turbulette-0.3.0.tar.gz (45.0 kB view details)

Uploaded Source

Built Distribution

turbulette-0.3.0-py3-none-any.whl (56.9 kB view details)

Uploaded Python 3

File details

Details for the file turbulette-0.3.0.tar.gz.

File metadata

  • Download URL: turbulette-0.3.0.tar.gz
  • Upload date:
  • Size: 45.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.0 CPython/3.8.5 Linux/5.4.0-1025-azure

File hashes

Hashes for turbulette-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e615de082ed6e3c864d57541b674c8c12747ac946c42c8bb5329e4b28455102b
MD5 40fa71ed11eda88098e13d2e8f93b386
BLAKE2b-256 7b13c2c439a9d67d6af46604e234272ef6af5943e432ebff555db2a3a679db9a

See more details on using hashes here.

File details

Details for the file turbulette-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: turbulette-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 56.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.0 CPython/3.8.5 Linux/5.4.0-1025-azure

File hashes

Hashes for turbulette-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d606c73f9cd6aaf429b995b2780270003555d06df8de250781849af3b468a2ff
MD5 34dd2abc3d38af2e0ba36b96812f7d0e
BLAKE2b-256 e61ea062bbd0355f49cb809a61e7d24b4e7199bc96d13caccafc548bcefbf6d1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page