[project]
name = "strawberry-graphql"
version = "0.314.2"
description = "A library for creating GraphQL APIs"
authors = [{ name = "Patrick Arminio", email = "patrick.arminio@gmail.com" }]
license = "MIT"
license-files = ["LICENSE"]
readme = "README.md"
keywords = ["graphql", "api", "rest", "starlette", "async"]
classifiers = [
  "Development Status :: 5 - Production/Stable",
  "Intended Audience :: Developers",
  "Topic :: Software Development :: Libraries",
  "Topic :: Software Development :: Libraries :: Python Modules",
]
requires-python = ">=3.10,<4.0"
dependencies = [
  "graphql-core>=3.2.0,<3.4.0",
  "typing-extensions>=4.5.0",
  "python-dateutil>=2.7",
  "packaging>=23",
  "cross-web>=0.4.0",
]

[project.urls]
homepage = "https://strawberry.rocks/"
repository = "https://github.com/strawberry-graphql/strawberry"
documentation = "https://strawberry.rocks/"
"Changelog" = "https://strawberry.rocks/changelog"
"Discord" = "https://discord.com/invite/3uQ2PaY"
"Twitter" = "https://twitter.com/strawberry_gql"
"Mastodon" = "https://farbun.social/@strawberry"
"Sponsor on GitHub" = "https://github.com/sponsors/strawberry-graphql"
"Sponsor on Open Collective" = "https://opencollective.com/strawberry-graphql"

[project.scripts]
strawberry = "strawberry.cli:run"

[project.optional-dependencies]
aiohttp = ["aiohttp>=3.7.4.post0,<4"]
asgi = ["starlette>=0.18.0", "python-multipart>=0.0.7"]
debug = ["rich>=12.0.0", "libcst"]
django = ["Django>=3.2", "asgiref>=3.2"]
channels = ["channels>=3.0.5", "asgiref>=3.2"]
flask = ["flask>=1.1"]
quart = ["quart>=0.19.3"]
apollo-federation = ["protobuf>=3.20"]
opentelemetry = ["opentelemetry-api<2", "opentelemetry-sdk<2"]
pydantic = ["pydantic>1.6.1"]
sanic = ["sanic>=20.12.2"]
fastapi = ["fastapi>=0.65.2", "python-multipart>=0.0.7"]
chalice = ["chalice>=1.22"]
cli = [
  "typer>=0.12.4",
  "pygments>=2.3",
  "rich>=12.0.0",
  "libcst",
  "starlette>=0.18.0",
  "uvicorn>=0.11.6",
  "websockets>=15.0.1,<17",
  "python-multipart>=0.0.7",
]
litestar = ["litestar>=2; python_version~='3.10'"]
pyinstrument = ["pyinstrument>=4.0.0"]

[dependency-groups]
dev = [
  "ruff>=0.14.1,<0.16.0",
  "asgiref>=3.2,<4.0",
  "email-validator>=1.1.3,<3.0.0",
  "freezegun>=1.2.1,<2.0.0",
  "libcst>=1.8.2,<2.0.0",
  "markupsafe~=3.0.3",
  "nox>=2025.11.12,<2026.3.0",
  "opentelemetry-api<2",
  "opentelemetry-sdk<2",
  "pygments>=2.3,<3.0",
  "pyinstrument>=4.0.0",
  "pytest~=9.0.2",
  "pytest-asyncio~=1.3.0",
  "pytest-codspeed>=4.2.0",
  "pytest-cov>=7.0,<7.2",
  "pytest-emoji>=0.2.0,<0.3.0",
  "pytest-mock>=3.10,<4.0",
  "pytest-snapshot>=0.9.0,<0.10.0",
  "pytest-xdist[psutil]>=3.1.0,<4.0.0",
  "python-multipart>=0.0.7",
  "rich>=12.5.1",
  "sanic-testing~=24.6.0",
  "typer>=0.12.4",
  "types-aiofiles~=25.1.0.20251011",
  "types-certifi>=2021.10.8,<2022.0.0",
  "types-chardet>=5.0.4,<6.0.0",
  "types-freezegun>=1.1.9,<2.0.0",
  "types-python-dateutil>=2.8.19,<3.0.0",
  "types-toml>=0.10.8,<0.11.0",
  "types-typed-ast>=1.5.8,<2.0.0",
  "types-ujson>=5.10.0.20250326,<6.0.0.0",
  "types-protobuf~=6.32.1.20251210",
  "inline-snapshot>=0.31.1,<0.33.0",
  "types-deprecated>=1.2.15.20241117,<2.0.0.0",
  "types-six>=1.17.0.20250403,<2.0.0.0",
  "types-pyyaml>=6.0.12.20240917,<7.0.0.0",
  "mypy>=1.15.0,<2.0.0",
  "pyright~=1.1.408",
  "codeflash>=0.19.1",
  "pre-commit",
  "protobuf (>=7.34.1,<8.0.0)",
]
integrations = [
  "aiohttp>=3.7.4.post0,<4.0.0",
  "chalice>=1.22,<2.0",
  "channels>=3.0.5,<5.0.0",
  "django>=3.2",
  "fastapi>=0.65.0",
  "flask>=1.1",
  "quart>=0.19.3",
  "pydantic>=2.0",
  "pytest-aiohttp>=1.0.3,<2.0.0",
  "pytest-django>=4.5,<5.0",
  "sanic>=20.12.2",
  "starlette>=0.13.6",
  "litestar>=2; python_version >= '3.10'",
  "uvicorn>=0.11.6",
  "daphne>=4.0.0,<5.0.0",
]

[tool.uv]
default-groups = ["dev", "integrations"]

[tool.uv.build-backend]
module-name = "strawberry"
module-root = ""

[tool.pytest.ini_options]
addopts = "--emoji"
DJANGO_SETTINGS_MODULE = "tests.django.django_settings"
testpaths = ["tests/"]
markers = [
  "aiohttp",
  "asgi",
  "chalice",
  "channels",
  "django_db",
  "django",
  "fastapi",
  "flaky",
  "flask",
  "litestar",
  "pydantic",
  "quart",
  "relay",
  "sanic",
  "starlette",
]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
filterwarnings = [
  "ignore::DeprecationWarning:strawberry.*.resolver",
  "ignore:LazyType is deprecated:DeprecationWarning",
  "ignore:Passing a class to strawberry.scalar:DeprecationWarning",
  "ignore::DeprecationWarning:ddtrace.internal",
  "ignore::DeprecationWarning:django.utils.encoding",
  # ignoring the text instead of the whole warning because we'd
  # get an error when django is not installed
  "ignore:The default value of USE_TZ",
  "ignore::DeprecationWarning:pydantic_openapi_schema.*",
  "ignore::DeprecationWarning:graphql.*",
  "ignore::DeprecationWarning:websockets.*",
  "ignore::DeprecationWarning:pydantic.*",
  "ignore::UserWarning:pydantic.*",
  "ignore::DeprecationWarning:pkg_resources.*",
]


[tool.autopub]
git-username = "Botberry"
git-email = "bot@strawberry.rocks"
project-name = "🍓"
append-github-contributor = true
plugins = [
  "autopub.plugins.github",
  "autopub.plugins.uv",
  "strawberry_autopub_plugins.typefully:TypefullyPlugin",
]

[tool.autopub.plugin_config.typefully]
project-name = "Strawberry GraphQL"
platforms = ["x", "linkedin", "bluesky", "mastodon"]
publish-mode = "next-free-slot"

[tool.pyright]
# include = ["strawberry"]
exclude = ["**/__pycache__", "**/.venv", "**/.pytest_cache", "**/.nox"]
reportMissingImports = true
reportMissingTypeStubs = false
pythonVersion = "3.10"
stubPath = ""

[tool.ruff]
line-length = 88
target-version = "py310"
fix = true
exclude = [
  ".bzr",
  ".direnv",
  ".eggs",
  ".git",
  ".hg",
  ".mypy_cache",
  ".nox",
  ".pants.d",
  ".ruff_cache",
  ".svn",
  ".tox",
  ".venv",
  "__pypackages__",
  "_build",
  "buck-out",
  "build",
  "dist",
  "node_modules",
  "venv",
  "tests/*/snapshots",
]
src = ["strawberry", "tests"]

[tool.ruff.lint]
select = ["ALL"]
ignore = [
  # × this should be fine to use :)
  "RUF002",
  # we use asserts in tests and to hint mypy
  "S101",

  # Allow "Any" for annotations. We have too many Any annotations and some
  # are legit. Maybe reconsider in the future, except for tests?
  "ANN401",

  # Allow our exceptions to have names that don't end in "Error". Maybe refactor
  # in the future? But that would be a breaking change.
  "N818",

  # Allow "type: ignore" without rule code. Because we support both mypy and
  # pyright, and they have different codes for the same error, we can't properly
  # fix those issues.
  "PGH003",

  # Variable `T` in function should be lowercase
  # this seems a potential bug or opportunity for improvement in ruff
  "N806",

  # shadowing builtins
  "A001",
  "A002",
  "A003",
  "A005",

  # Unused arguments
  "ARG001",
  "ARG002",
  "ARG003",
  "ARG004",
  "ARG005",

  # Boolean positional arguments
  "FBT001",
  "FBT002",
  "FBT003",

  # Too many arguments/branches/return statements
  "PLR0913",
  "PLR0912",
  "PLR0911",

  # Do not force adding _co to covariant typevars
  "PLC0105",

  # Allow private access to attributes
  "SLF001",

  # code complexity
  "C901",

  # Allow todo/fixme/etc comments
  "TD002",
  "TD003",
  "FIX001",
  "FIX002",

  # We don't want to add "from __future__ mport annotations" everywhere
  "FA100",

  # Docstrings, maybe to enable later
  "D100",
  "D101",
  "D102",
  "D103",
  "D104",
  "D105",
  "D106",
  "D107",
  "D412",

  # Allow to define exceptions text in the exception body
  "TRY003",
  "EM101",
  "EM102",
  "EM103",

  # Allow comparisons with magic numbers
  "PLR2004",

  # Allow methods to use lru_cache
  "B019",

  # Don't force if branches to be converted to "or"
  "SIM114",

  # Allow imports inside functions
  "PLC0415",

  # ruff formatter recommends to disable those, as they conflict with it
  # we don't need to ever enable those.
  "COM812",
  "COM819",
  "D206",
  "E111",
  "E114",
  "E117",
  "E501",
  "ISC001",
  "Q000",
  "Q001",
  "Q002",
  "Q003",
  "W191",
  "PLR0915",
]

[tool.ruff.lint.per-file-ignores]
".github/*" = ["INP001"]
"federation-compatibility/*" = ["INP001"]
"strawberry/cli/*" = ["B008"]
"strawberry/extensions/tracing/__init__.py" = ["TCH004"]
"strawberry/fastapi/*" = ["B008"]
"strawberry/annotation.py" = ["RET505"]
"tests/*" = [
  "ANN001",
  "ANN201",
  "ANN202",
  "ANN204",
  "B008",
  "B018",
  "D",
  "DTZ001",
  "DTZ005",
  "FA102",
  "N805",
  "PLC1901",
  "PLR2004",
  "PLW0603",
  "PT011",
  "RUF012",
  "S105",
  "S106",
  "S603",
  "S607",
  "TCH001",
  "TCH002",
  "TCH003",
  "TRY002",
  "UP007",
  "UP045",
]

[tool.ruff.lint.isort]
known-first-party = ["strawberry"]
known-third-party = [
  "django",
  "graphql",
  "fastapi",
  "pydantic",
  "litestar",
  "aiohttp",
  "channels",
  "sanic",
  "chalice",
  "quart",
]
extra-standard-library = ["typing_extensions"]

[tool.ruff.format]
exclude = ['tests/codegen/snapshots/', 'tests/cli/snapshots/']

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.inline-snapshot]
format-command = ["ruff", "format"]

[tool.codeflash]
# All paths are relative to this pyproject.toml's directory.
module-root = "strawberry"
tests-root = "tests"
test-framework = "pytest"
ignore-paths = []
formatter-cmds = ["ruff check --exit-zero --fix $file", "ruff format $file"]

[build-system]
requires = ["uv_build>=0.11,<0.12"]
build-backend = "uv_build"
