Skip to main content

strawberry-alchemy

Batteries-included toolkit for building Strawberry GraphQL APIs backed by SQLAlchemy

CI PyPI version Python versions License: MIT

Ask DeepWiki


Source Code: https://github.com/Alteian/strawberry-alchemy

Documentation: docs/index.md · API reference


What is it?

strawberry-alchemy turns Strawberry GraphQL selection sets into a single optimized SQLAlchemy query — automatic selectinload for relationships, column deferral, and SQL EXISTS/COUNT annotations — and ships the supporting cast: filter inputs, Relay pagination, CRUD repositories, row-level security, permissions, and mapping helpers.

  • No N+1 queries: nested selections become eager loads automatically
  • Unrequested columns are deferred — you only fetch what the client asked for
  • Declarative computed fields (hasComments, coverThumbUrl, counts) resolved by SQL subqueries
  • AND/OR filters, relationship joins, and custom per-model filters from Strawberry inputs
  • Relay Connection pagination with totalCount
  • Async repositories with lifecycle hooks and cascade deletes
  • Row-level access filters applied to every query — and to totalCount

Installation

pip install strawberry-alchemy
# or
uv add strawberry-alchemy

Requires Python >= 3.13, Strawberry GraphQL >= 0.220, SQLAlchemy, Pydantic v2.

Quick example

# models.py
import uuid

from sqlalchemy import ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column

from strawberry_alchemy.models import Base


class Post(Base):
    user_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("user.id"))
    title: Mapped[str]
    body: Mapped[str]
# access_filters.py
from typing import Any
from models import Post
from strawberry_alchemy.filtering import AccessControlFilter


class PostAccessFilter(AccessControlFilter):
    model_class = Post

    @staticmethod
    async def apply_filter(query: Any, model: type[Any], context_user: Any) -> Any:
        return query.where(model.user_id == context_user.id)
# types.py
import strawberry
from typing import ClassVar
from strawberry_alchemy import BaseNodeType


@strawberry.type
class PostType(BaseNodeType):
    access_filter: ClassVar = PostAccessFilter()

    title: str | None = strawberry.UNSET
    body: str | None = strawberry.UNSET
# queries.py
import strawberry
from strawberry.types import Info
from strawberry_alchemy import ListResult


@strawberry.type
class Query:
    @strawberry.field
    async def posts(self, info: Info, limit: int | None = None) -> ListResult[PostType]:
        return await PostType.resolve_list(info=info, limit=limit)
# schema.py
import strawberry
from strawberry.schema.config import StrawberryConfig

schema = strawberry.Schema(
    query=Query,
    config=StrawberryConfig(auto_camel_case=True, relay_max_results=100),
)
query {
  posts(limit: 10) {
    items { id title body }
    totalCount
  }
}

Your request context needs three things: get_session(), an identity/user attribute, and a db_execution_lock (see docs/getting-started.md#context-contract).

Documentation

Page Topic
docs/index.md Overview, features, architecture
docs/getting-started.md Full walkthrough: models, types, filters, queries, mutations
docs/types-and-models.md Base, BaseNodeType, ListResult, connections, ordering
docs/queries.md resolve_node / resolve_list / resolve_connection, pagination
docs/query-optimizer.md Load strategies, @optimize_field hints, QueryAnalyzer
docs/filtering.md Filter inputs, operators, AND/OR, custom & access-control filters
docs/repository.md CRUD, relations, deletion handlers
docs/mapping-and-schema.md BaseSchema, SQLAlchemy → Strawberry mapping
docs/permissions.md Permission classes, resource checks
docs/api-reference.md Every public export with signatures

Development

git clone https://github.com/Alteian/strawberry-alchemy.git
cd strawberry-alchemy
uv sync

# Lint & test
uv run ruff check .
uv run pytest -v

# Build
uv build

Contributing

See CONTRIBUTING.md for guidelines.

License

MIT

Release files for strawberry-alchemy 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for strawberry-alchemy 0.1.5
File Size Uploaded
strawberry_alchemy-0.1.5.tar.gz 28.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for strawberry-alchemy 0.1.5
File Interpreter ABI Platform
strawberry_alchemy-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 70.0 kB

Release files / strawberry_alchemy-0.1.5.tar.gz

Download URL strawberry_alchemy-0.1.5.tar.gz
Size 28.9 kB
Tags Source
SHA-256 checksum
How to use checksums
0259c2ab73c6ed094303e71a05a678ef9327e8de77a5fc592dfab4cb2d6d631f
BLAKE2b-256 checksum
How to use checksums
86ac7ea649deaf13e8865f212ab1e5eed13e632dc0afcce7901afc1dc30df41f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release files / strawberry_alchemy-0.1.5-py3-none-any.whl

Download URL strawberry_alchemy-0.1.5-py3-none-any.whl
Size 41.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2fe84528fda248466843c30b665ab5a62f3d1ecf8985d793e0a3a9792787fae9
BLAKE2b-256 checksum
How to use checksums
6c0e56e6b8c144c9b2ef71e2608764fe69142349d2b1045a3eafeba48a61fc22
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page