# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
[project]
authors = [
{ name = "Google" },
{ name = "Yesudeep Mangalapilly", email = "yesudeep@google.com" },
{ name = "Elisa Shen", email = "mengqin@google.com" },
{ name = "Niraj Nepal", email = "nnepal@google.com" },
]
classifiers = [
"Development Status :: 3 - Alpha",
"Environment :: Console",
"Environment :: Web Environment",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Topic :: Software Development :: Libraries",
]
dependencies = [
"rich>=13.0.0",
"fastapi>=0.115.0",
"granian>=1.0.0",
"hypercorn>=0.17.0",
"litestar>=2.0.0",
"quart>=0.19.0",
"pydantic-settings>=2.0.0",
"structlog>=24.0.0",
"gunicorn>=22.0.0",
"uvicorn[standard]>=0.34.0",
"genkit",
"genkit-plugin-google-genai",
"uvloop>=0.21.0",
# gRPC — server, codegen, and reflection (for grpcui / grpcurl).
"grpcio>=1.68.0",
"grpcio-tools>=1.68.0",
"grpcio-reflection>=1.68.0",
# OpenTelemetry — included in main deps so tracing works out of the box.
"opentelemetry-api>=1.20.0",
"opentelemetry-sdk>=1.20.0",
"opentelemetry-exporter-otlp-proto-http>=1.20.0",
"opentelemetry-exporter-otlp-proto-grpc>=1.20.0",
"opentelemetry-instrumentation-fastapi>=0.41b0",
"opentelemetry-instrumentation-asgi>=0.41b0",
"opentelemetry-instrumentation-grpc>=0.41b0",
# OSS security headers — tracks OWASP recommendations automatically.
"secure>=1.0.0",
]
description = "Genkit endpoints sample — REST (FastAPI, Litestar, Quart) + gRPC"
license = "Apache-2.0"
name = "web-endpoints-hello"
readme = "README.md"
requires-python = ">=3.10"
version = "0.1.0"
[project.optional-dependencies]
aws = ["genkit-plugin-amazon-bedrock"]
azure = ["genkit-plugin-microsoft-foundry"]
dev = [
"liccheck>=0.9.2",
"pip-audit>=2.7.0",
"pip-licenses>=5.0.0",
"pyrefly>=0.15.0",
"pyright>=1.1.392",
"pysentry-rs>=0.3.14",
"ruff>=0.11.0",
"sentry-sdk[fastapi,litestar,quart,grpc]>=2.0.0",
"ty>=0.0.1",
"watchdog>=6.0.0",
]
docs = [
"mkdocs-material>=9.6.0",
"mkdocs-awesome-pages-plugin>=2.9.0",
"mkdocs-mermaid2-plugin>=1.1.0",
"mkdocstrings[python]>=0.27.0",
]
gcp = ["genkit-plugin-google-cloud"]
observability = ["genkit-plugin-observability"]
sentry = ["sentry-sdk[fastapi,litestar,quart,grpc]>=2.0.0"]
test = [
"httpx>=0.27.0",
"pytest>=8.0.0",
"pytest-asyncio>=0.24.0",
"opentelemetry-api>=1.20.0",
"opentelemetry-sdk>=1.20.0",
"opentelemetry-instrumentation-fastapi>=0.41b0",
]
[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]
[tool.hatch.build.targets.wheel]
packages = ["src"]
[tool.coverage.run]
omit = ["src/generated/*", "src/__main__.py"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"if __name__ == .__main__.",
"if TYPE_CHECKING:",
]
[tool.pytest.ini_options]
asyncio_mode = "strict"
python_files = ["*_test.py"]
pythonpath = ["."]
[tool.ruff]
exclude = ["src/generated"]
indent-width = 4
line-length = 120
preview = true
target-version = "py310"
unsafe-fixes = true
[tool.ruff.lint]
fixable = ["ALL"]
select = [
"E", # pycodestyle (errors)
"W", # pycodestyle (warnings)
"F", # pyflakes
"I", # isort (import sorting)
"UP", # pyupgrade (Python version upgrades)
"B", # flake8-bugbear (common bugs)
"N", # pep8-naming (naming conventions)
"D", # pydocstyle
"ANN", # flake8-annotations (type hints)
"F401", # unused imports
"F403", # wildcard imports
"F841", # unused variables
"S", # flake8-bandit (security)
"ASYNC", # flake8-async (async best practices)
"T20", # flake8-print (no print statements)
"PLC", # pylint convention (e.g. PLC0415 lazy imports)
"RUF100", # unused noqa directives
]
[tool.ruff.lint.per-file-ignores]
# ``assert`` is idiomatic pytest — no alternative exists.
"tests/**/*.py" = ["S101"]
[tool.ruff.lint.isort]
combine-as-imports = true
force-single-line = false
known-first-party = ["genkit"]
section-order = [
"future",
"standard-library",
"third-party",
"first-party",
"local-folder",
]
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.ruff.format]
docstring-code-format = true
docstring-code-line-length = 120
indent-style = "space"
line-ending = "lf"
[tool.ty.src]
# Exclude auto-generated protobuf/gRPC stubs from type checking.
exclude = ["src/generated"]
[tool.ty.rules]
# type: ignore comments are required for pyright compatibility; ty uses its
# own ty: ignore syntax. Suppressing this single cross-tool compatibility
# warning avoids a circular-suppression loop (ty flags type: ignore as unused,
# then flags its own ty: ignore[unused-type-ignore-comment] as unused too).
unused-type-ignore-comment = "ignore"
[tool.ty.environment]
root = ["."]
[tool.pyright]
exclude = [
"**/__pycache__",
".git",
".pytest_cache",
".ruff_cache",
"build",
"dist",
"src/generated",
]
pythonVersion = "3.10"
reportMissingImports = "warning"
reportMissingTypeStubs = false
typeCheckingMode = "standard"
# Inside the monorepo, the workspace venv is at py/.venv (two levels up).
# When ejected as a standalone project, override venvPath to ".".
venv = ".venv"
venvPath = "../.."
[tool.pyrefly]
project_excludes = [
"**/__pycache__",
".venv",
"build",
"dist",
"src/generated",
"src/generated/**",
"**/generated/**",
]
project_includes = ["src/**/*.py", "tests/**/*.py"]
# Include tests/ in search path so pyrefly resolves conftest.py and
# cross-test imports the same way pytest does.
search-path = [".", "tests"]
# Ignore missing imports for PEP 420 namespace packages — pyrefly can't
# resolve these statically but they work at runtime.
ignore-missing-imports = ["genkit.plugins.*"]
python_version = "3.10"
[tool.pyrefly.errors]
deprecated = "error"
redundant-cast = "error"
# grpc.experimental implicit submodule imports — only in auto-generated
# protobuf stubs (src/generated/), which we cannot modify.
implicit-import = "ignore"
# ---------------------------------------------------------------------------
# liccheck — dependency license compliance (mirrors workspace py/pyproject.toml)
# ---------------------------------------------------------------------------
[tool.liccheck]
authorized_licenses = [
"3-clause bsd",
"apache 2.0",
"apache license 2.0",
"apache software license",
"apache software",
"apache",
"apache-2.0",
"apache-2.0 and mit",
"bsd license",
"bsd-2-clause",
"bsd-3-clause",
"bsd",
"cmu license (mit-cmu)",
"isc license (iscl)",
"isc license",
"mit license",
"mit",
"mit-cmu",
"mpl-2.0 and mit",
"new bsd license",
"new bsd",
"psf-2.0",
"python software foundation license",
"simplified bsd",
"the unlicense (unlicense)",
]
dependencies = true
unauthorized_licenses = [
"gnu lgpl",
"gpl v3",
"lgpl with exceptions or zpl",
"zpl 2.1",
"mpl",
]
[tool.liccheck.authorized_packages]
certifi = ">=2024.0.0" # MPL-2.0 — Mozilla Public License, redistributable
dotpromptz-handlebars = ">=0.1.8" # Apache-2.0 (https://github.com/google/dotprompt/blob/main/LICENSE)
google-crc32c = ">=1.8.0" # Apache-2.0