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.4

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.4
File Size Uploaded
strawberry_alchemy-0.1.4.tar.gz 28.7 kB Details

Built distribution (wheel)

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

Total release size: 69.6 kB

Release files / strawberry_alchemy-0.1.4.tar.gz

Download URL strawberry_alchemy-0.1.4.tar.gz
Size 28.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d132fa50489b223848b70de52761faf821136adae122cd5699e1e4c23a9cc5ca
BLAKE2b-256 checksum
How to use checksums
e2681b7538e1f22e4b44314611c8ea2fc76b81b40822bb5c124a5488043f6a54
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 16, 2026.

Transparency log

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

Download URL strawberry_alchemy-0.1.4-py3-none-any.whl
Size 40.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8c87a3c0db783f0023e90dd65993c989b9cae933730f6222530cf72fbc8ed262
BLAKE2b-256 checksum
How to use checksums
cf901c69b5e8fe49c0d02d4bae65072529dce2f3504a07b13dfde26240caef31
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 16, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.5

2 release files

This release

0.1.4 This release

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