A code-first, decorator-driven GraphQL framework for Python with a hand-built engine and a web-framework-agnostic core.
Project description
FastQL
A code-first, decorator-driven GraphQL framework for Python with a hand-built engine (lexer → parser → validator → executor), a built-in dependency-injection / context layer, and a web-framework-agnostic core — zero runtime dependencies, Python 3.11+.
Status: early development. The core engine (parse → build → validate → execute, with dependency injection and introspection) is in place.
Documentation: Start with the FastQL documentation, then use the capability catalog to trace documented behavior to its canonical OpenSpec requirements.
Quickstart
Define types and operations with decorators — field and argument types come from your
Python type hints. Resolvers are plain functions; the executor injects arguments, the
parent object, resolve info, and the Context based on each resolver's signature.
import asyncio
from typing import Annotated
from fastql import Argument, Context, Field, Query, Schema, Type, execute
@Type
class User: # just fields — constructor/repr/eq are auto-generated
id: int
full_name: str
@Field
def loud_name(self) -> str: # exposed as loudName by default
return self.full_name.upper()
class AppContext(Context):
def __init__(self, users):
self.users = users
@Query # group related queries on a class…
class Queries:
@Field
async def user(
self,
user_id: Annotated[int, Argument(name="id")],
ctx: Context,
) -> "User | None":
return ctx.users.get(user_id)
@Field
def ping(self) -> str: # sync resolvers work alongside async ones
return "pong"
schema = Schema(query=Queries)
async def main():
ctx = AppContext(users={1: User(1, "Ada Lovelace")})
result = await execute(schema, "{ user(id: 1) { id fullName loudName } ping }", context=ctx)
print(result.data) # {'user': {'id': 1, 'fullName': 'Ada Lovelace', 'loudName': 'ADA LOVELACE'}, 'ping': 'pong'}
asyncio.run(main())
@Type and @Input classes get generated constructors, repr, and equality unless they define
their own methods. Python snake_case fields and arguments become GraphQL camelCase by default;
pass SchemaConfig(auto_camel_case=False) to Schema to preserve Python names. Explicit name=
metadata always wins. build_schema() remains available for applications that intentionally merge
multiple globally decorated root classes.
execute returns an ExecutionResult with data, errors, and extensions, and a
.formatted() helper that produces the GraphQL-over-HTTP response shape. Introspection
(__schema, __type, __typename) is built in.
A fuller, runnable version — covering every type kind, mutations, subscriptions,
DataLoaders, permissions, and extensions — lives in examples/app, the
showcase schema that the per-framework projects under examples/projects
all reuse.
The documentation quickstart and first-schema examples are also executed by the test
suite from docs/snippets.
Dev server & playground
Try a schema in the browser with the built-in, zero-dependency dev server:
python -m fastql serve examples.app:schema # http://127.0.0.1:7691
It serves, on the default port 7691:
| Route | Description |
|---|---|
GET / |
GraphiQL IDE (loaded from CDN) |
POST/GET /graphql |
the GraphQL endpoint ({data, errors} JSON) |
GET /schema.graphql |
the schema as SDL |
GET /schema.json |
the schema as an introspection result |
Override the binding with --host / --port. If your resolvers need a Context,
point --context at a value or zero-arg factory:
python -m fastql serve examples.app:schema --context examples.app:make_context
Or call it programmatically:
import fastql
from examples.app import schema, make_context
fastql.serve(schema, port=7691, context_factory=make_context) # blocking; Ctrl-C to stop
The dev server lives outside the agnostic core (in fastql.server) and only
consumes build_schema / execute — it is a developer convenience, not a
production transport (no TLS, auth, or subscriptions).
Design at a glance
@Type / @Input / root class decorators ← unified type-hint-driven authoring
▼
Schema(query=...) / build_schema() ← compiles decorators into the type-system IR
▼
Type-system IR (Schema, ObjectType, Field, scalars, wrappers)
▼
execute() ── validation ── coercion ── async resolution + DI/context
▲
language: Source → Lexer → Parser → AST ← hand-built front-end
The core never imports an HTTP framework. Transports (an optional built-in dev server,
plus FastAPI/Django/Flask/ASGI adapters) plug in on top and consume build_schema / execute.
Web framework integrations
Install only the framework adapter an application uses:
pip install mygenx-fastql[fastapi] # or starlette, flask, django
from fastapi import FastAPI
from fastql.integrations.fastapi import create_fastapi_router
app = FastAPI()
app.include_router(create_fastapi_router(schema, graphiql=True))
The base installation includes the dependency-free GraphQLASGI adapter. See
the integration documentation for mounting,
request context, endpoint configuration, and supported versions.
Runnable per-framework projects — FastAPI, Starlette, Flask, Django, and raw ASGI, each
mounting the same examples/app schema — live under
examples/projects. Reusing one schema across every adapter is the
proof that the core is framework-agnostic; each project differs only in a few lines of glue.
Development
pip install -e ".[dev]"
pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mygenx_fastql-0.0.1.tar.gz.
File metadata
- Download URL: mygenx_fastql-0.0.1.tar.gz
- Upload date:
- Size: 62.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0717bc7dd6e0a2f1cc3a82b26285a4c50e35cff03afd8ed823391ab988760cd5
|
|
| MD5 |
8183e22f25f3d835263d0af3f413e3fd
|
|
| BLAKE2b-256 |
afa474b7bc891262fd44033e1477cce1b50eaf1ed5f6a5672b6daa8379890e75
|
Provenance
The following attestation bundles were made for mygenx_fastql-0.0.1.tar.gz:
Publisher:
publish.yml on MyGenX/FastQL
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mygenx_fastql-0.0.1.tar.gz -
Subject digest:
0717bc7dd6e0a2f1cc3a82b26285a4c50e35cff03afd8ed823391ab988760cd5 - Sigstore transparency entry: 1755592497
- Sigstore integration time:
-
Permalink:
MyGenX/FastQL@9453737e0bbfc9f5064ac66a5a5860106a4b6ce6 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/MyGenX
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9453737e0bbfc9f5064ac66a5a5860106a4b6ce6 -
Trigger Event:
release
-
Statement type:
File details
Details for the file mygenx_fastql-0.0.1-py3-none-any.whl.
File metadata
- Download URL: mygenx_fastql-0.0.1-py3-none-any.whl
- Upload date:
- Size: 82.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e89a67984b5dc4bf71e1b58726f393c00e4e11ad6427d00f3c5a68b8a24c0534
|
|
| MD5 |
03622c238f1dd132f7289112475ec1d5
|
|
| BLAKE2b-256 |
40fb7c8cb0d97678617e199cc26bcc421ec9664262775476b197ee1ac40c306d
|
Provenance
The following attestation bundles were made for mygenx_fastql-0.0.1-py3-none-any.whl:
Publisher:
publish.yml on MyGenX/FastQL
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mygenx_fastql-0.0.1-py3-none-any.whl -
Subject digest:
e89a67984b5dc4bf71e1b58726f393c00e4e11ad6427d00f3c5a68b8a24c0534 - Sigstore transparency entry: 1755592968
- Sigstore integration time:
-
Permalink:
MyGenX/FastQL@9453737e0bbfc9f5064ac66a5a5860106a4b6ce6 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/MyGenX
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9453737e0bbfc9f5064ac66a5a5860106a4b6ce6 -
Trigger Event:
release
-
Statement type: