# Copyright 2025 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" }]
dependencies = [
"dotpromptz==0.1.5",
"genkit",
"genkit-plugin-anthropic",
"genkit-plugin-checks",
"genkit-plugin-cloudflare-workers-ai",
"genkit-plugin-compat-oai",
"genkit-plugin-deepseek",
"genkit-plugin-dev-local-vectorstore",
"genkit-plugin-evaluators",
"genkit-plugin-firebase",
"genkit-plugin-flask",
"genkit-plugin-google-cloud",
"genkit-plugin-google-genai",
"genkit-plugin-ollama",
"genkit-plugin-vertex-ai",
"genkit-plugin-xai",
"genkit-plugin-mcp",
"genkit-plugin-microsoft-foundry",
"genkit-plugin-amazon-bedrock",
"genkit-plugin-cohere",
"genkit-plugin-mistral",
"genkit-plugin-huggingface",
"genkit-plugin-observability",
"liccheck>=0.9.2",
"setuptools>=75.0.0,<82", # Required by liccheck (provides pkg_resources, removed in setuptools 82+)
"mcp>=1.25.0",
"python-multipart>=0.0.22",
"strenum>=0.4.15; python_version < '3.11'",
]
description = "Workspace for Genkit packages"
license = "Apache-2.0"
name = "genkit-workspace"
readme = "README.md"
requires-python = ">=3.10"
version = "0.1.0"
[dependency-groups]
dev = [
"bpython>=0.25",
"ipython~=8.22; python_version <= '3.10'",
"ipython~=9.0.2; python_version >= '3.11'",
"jupyter>=1.1.1",
"pytest-asyncio>=0.25.3",
"pytest>=8.3.4",
"pytest-cov>=6.0.0",
"datamodel-code-generator>=0.27.3",
"pytest-watcher>=0.4.3",
"pytest-mock>=3.14.0",
"twine>=6.1.0",
"poethepoet>=0.33.1",
"pip>=25.0.1",
"tox>=4.25.0",
"tox-uv>=1.25.0",
"nox>=2025.2.9",
"nox-uv>=0.2.2",
]
lint = [
"bandit>=1.7.0",
"deptry>=0.22.0",
"granian>=1.0.0", # For web-endpoints-hello type resolution
"litestar>=2.20.0", # For web/typing.py type resolution
"mypy>=1.14.0",
"pip-audit>=2.7.0",
"pydantic-settings>=2.0.0", # For web-endpoints-hello type resolution
"pypdf>=6.6.2",
"pyrefly>=0.15.0",
"pyright>=1.1.392",
"pysentry-rs>=0.3.14",
"ruff>=0.9",
"strenum>=0.4.15",
"streamlit>=1.41.0",
"ty>=0.0.1",
"typos>=1.42.0",
# ── web-endpoints-hello type resolution ──
# These are needed so workspace-level type checkers can resolve all
# imports in the sample. The sample is checked in both the workspace
# pipeline AND its own `just lint` pipeline with identical settings.
"fastapi>=0.115.0",
"grpcio>=1.68.0",
"grpcio-reflection>=1.68.0",
"gunicorn>=22.0.0",
"hypercorn>=0.17.0",
"opentelemetry-exporter-otlp-proto-grpc>=1.20.0",
"opentelemetry-instrumentation-asgi>=0.41b0",
"opentelemetry-instrumentation-fastapi>=0.41b0",
"opentelemetry-instrumentation-grpc>=0.41b0",
"quart>=0.19.0",
"secure>=1.0.0",
"sentry-sdk>=2.0.0",
"structlog>=24.0.0",
# ── releasekit type resolution ──
# These are needed so workspace-level type checkers can resolve all
# imports in tools/releasekit/. The tool has its own venv but the
# type checkers run at workspace scope.
"diagnostic>=3.0.0",
"packaging>=24.0",
"tomlkit>=0.13.0",
]
[tool.hatch.build.targets.wheel]
[tool.setuptools]
py-modules = []
# Pytest for unit testing and coverage.
[tool.pytest]
[tool.pytest.ini_options]
addopts = [
"--cov",
#"--cov-report=", # Disable terminal report generation by pytest-cov
"-ra",
"-vv",
"--ignore=testapps",
# web-endpoints-hello has its own deps (fastapi, litestar, httpx, grpcio) not
# installed by workspace 'uv sync'. Run its tests locally from the sample dir.
"--ignore=samples/web-endpoints-hello/tests",
# releasekit is a standalone tool with its own venv. Run its tests from
# tools/releasekit/ (e.g. 'cd tools/releasekit && uv run pytest tests/').
"--ignore=tools/releasekit/tests",
]
asyncio_default_fixture_loop_scope = "session"
norecursedirs = ["testapps", ".git", ".tox", ".nox", ".venv", "build", "dist"]
python_files = ["*_test.py"]
testpaths = ["packages", "plugins", "samples", "tests"]
#asyncio_mode = "auto"
asyncio_mode = "strict"
[tool.coverage.report]
fail_under = 78
[tool.coverage.run]
omit = [
"**/__init__.py", # Often contains just imports
"**/testing.py", # Test utilities
"**/constants.py", # Typically just constants
"**/typing.py", # Often auto-generated or complex types
"**/types.py", # Often auto-generated or complex types
]
source = ["packages", "plugins"]
# uv based package management.
[tool.uv]
default-groups = ["dev", "lint"]
[tool.uv.sources]
# Samples (alphabetical by package name from pyproject.toml)
dev-local-vectorstore-hello = { workspace = true }
framework-context-demo = { workspace = true }
framework-dynamic-tools-demo = { workspace = true }
framework-evaluator-demo = { workspace = true }
framework-format-demo = { workspace = true }
framework-middleware-demo = { workspace = true }
framework-prompt-demo = { workspace = true }
framework-realtime-tracing-demo = { workspace = true }
framework-restaurant-demo = { workspace = true }
framework-tool-interrupts = { workspace = true }
provider-amazon-bedrock-hello = { workspace = true }
provider-anthropic-hello = { workspace = true }
provider-checks-hello = { workspace = true }
provider-cloudflare-workers-ai-hello = { workspace = true }
provider-cohere-hello = { workspace = true }
provider-compat-oai-hello = { workspace = true }
provider-deepseek-hello = { workspace = true }
provider-firestore-retriever = { workspace = true }
provider-google-genai-code-execution = { workspace = true }
provider-google-genai-context-caching = { workspace = true }
provider-google-genai-hello = { workspace = true }
provider-google-genai-media-models-demo = { workspace = true }
provider-google-genai-vertexai-hello = { workspace = true }
provider-google-genai-vertexai-image = { workspace = true }
provider-huggingface-hello = { workspace = true }
provider-microsoft-foundry-hello = { workspace = true }
provider-mistral-hello = { workspace = true }
provider-observability-hello = { workspace = true }
provider-ollama-hello = { workspace = true }
provider-vertex-ai-model-garden = { workspace = true }
provider-vertex-ai-rerank-eval = { workspace = true }
provider-vertex-ai-vector-search-bigquery = { workspace = true }
provider-vertex-ai-vector-search-firestore = { workspace = true }
provider-xai-hello = { workspace = true }
web-endpoints-hello = { workspace = true }
web-flask-hello = { workspace = true }
web-multi-server = { workspace = true }
web-short-n-long = { workspace = true }
# Core packages
genkit = { workspace = true }
# Plugins (alphabetical)
genkit-plugin-amazon-bedrock = { workspace = true }
genkit-plugin-anthropic = { workspace = true }
genkit-plugin-checks = { workspace = true }
genkit-plugin-cloudflare-workers-ai = { workspace = true }
genkit-plugin-cohere = { workspace = true }
genkit-plugin-compat-oai = { workspace = true }
genkit-plugin-deepseek = { workspace = true }
genkit-plugin-dev-local-vectorstore = { workspace = true }
genkit-plugin-evaluators = { workspace = true }
genkit-plugin-firebase = { workspace = true }
genkit-plugin-flask = { workspace = true }
genkit-plugin-google-cloud = { workspace = true }
genkit-plugin-google-genai = { workspace = true }
genkit-plugin-huggingface = { workspace = true }
genkit-plugin-mcp = { workspace = true }
genkit-plugin-microsoft-foundry = { workspace = true }
genkit-plugin-mistral = { workspace = true }
genkit-plugin-observability = { workspace = true }
genkit-plugin-ollama = { workspace = true }
genkit-plugin-vertex-ai = { workspace = true }
genkit-plugin-xai = { workspace = true }
[tool.uv.workspace]
exclude = ["*/shared", "samples/sample-test", "testapps/*"]
members = ["packages/*", "plugins/*", "samples/*"]
# Ruff checks and formatting.
[tool.ruff]
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".ipynb_checkpoints",
".mypy_cache",
".nox",
".pants.d",
".pyenv",
".pytest_cache",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
".vscode",
"__pypackages__",
"_build",
"bazel-*",
"buck-out",
"build",
"dist",
"node_modules",
"site-packages",
"venv",
]
indent-width = 4
line-length = 120
preview = true
target-version = "py310"
unsafe-fixes = true
[tool.ruff.lint]
fixable = ["ALL"]
ignore = [
"S101", # assert used - we use assert for type narrowing and tests
"S105", # hardcoded password string - false positives in tests
"S106", # hardcoded password func arg - false positives in tests
"S311", # random not for security - we don't use random for crypto
]
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)
# TODO(https://github.com/firebase/genkit/issues/4398): Enable PLC0415 after
# completing cleanup of remaining in-function imports in core framework.
# "PLC0415",
]
[tool.ruff.lint.per-file-ignores]
# Typing tests use reveal_type(), intentional unused vars, and don't need docstrings
"packages/genkit/tests/typing/*.py" = ["D", "F821", "F841", "B018", "ANN"]
# Samples have install_rich_traceback() call after imports, before other code
# Samples are demo code and can use blocking I/O for simplicity
"samples/*/*.py" = ["E402", "ASYNC"]
"samples/*/**/*.py" = ["E402", "ASYNC"]
"samples/*/src/*.py" = ["E402", "ASYNC"]
[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"
quote-style = "single"
skip-magic-trailing-comma = false
[tool.datamodel-codegen]
#collapse-root-models = true # Don't use; produces Any as types.
#strict-types = ["str", "int", "float", "bool", "bytes"] # Don't use; produces StrictStr, StrictInt, etc.
#use-subclass-enum = true
capitalize-enum-members = true
disable-timestamp = true
enable-version-header = true
field-constraints = true
input = "../genkit-tools/genkit-schema.json"
input-file-type = "jsonschema"
output = "packages/genkit/src/genkit/core/typing.py"
output-model-type = "pydantic_v2.BaseModel"
snake-case-field = true
strict-nullable = true
target-python-version = "3.11"
use-default = false
use-schema-description = true
use-standard-collections = true
use-subclass-enum = true
use-union-operator = true
use-unique-items-as-set = true
[tool.liccheck]
authorized_licenses = [
"3-clause bsd",
"apache 2.0",
"apache software license",
"apache software",
"apache",
"apache-2.0",
"bsd license",
"bsd-3-clause",
"bsd",
"cmu license (mit-cmu)",
"isc license (iscl)",
"isc license",
"mit license",
"mit",
"mit-cmu",
"new bsd license",
"new bsd",
"psf-2.0",
"python software foundation license",
"simplified bsd",
"the unlicense (unlicense)", # TODO: verify.
"bsd-2-clause",
"apache license 2.0",
"apache-2.0 and mit",
"mpl-2.0 and mit", # tqdm uses this dual license
]
dependencies = true
unauthorized_licenses = [
"gnu lgpl",
"gpl v3",
"lgpl with exceptions or zpl",
"zpl 2.1",
"mpl",
]
[tool.liccheck.authorized_packages]
aiohappyeyeballs = "2.6.1" # Python Software Foundation (transitive dep of xai-sdk)
aiohttp = "3.13.3" # Apache-2.0 AND MIT (transitive dep of xai-sdk)
certifi = "2026.1.4" # TODO: Verify.
dependencies = true
dotpromptz-handlebars = "0.1.8" # Apache-2.0 "https://github.com/google/dotprompt/blob/main/LICENSE"
google-crc32c = "1.8.0" # Apache-2.0
mistralai = ">=1.9.11" # Apache-2.0 "https://github.com/mistralai/client-python/blob/main/LICENSE"
multidict = "6.7.0" # Apache-2.0
ollama = "0.5.1" # MIT "https://github.com/ollama/ollama-python/blob/main/LICENSE"
pyasn1 = "0.6.2" # BSD-2-Clause
# Ty (Astral/Ruff) type checking configuration.
# See: https://docs.astral.sh/ty/modules/#first-party-modules
[tool.ty.src]
# Auto-generated protobuf stubs use grpc.experimental implicit submodule
# access that ty warns about. We can't modify generated code.
exclude = ["**/generated"]
[tool.ty.environment]
root = [
# Core package
"packages/genkit/src",
# Plugins
"plugins/anthropic/src",
"plugins/amazon-bedrock/src",
"plugins/checks/src",
"plugins/cloudflare-workers-ai/src",
"plugins/cohere/src",
"plugins/compat-oai/src",
"plugins/deepseek/src",
"plugins/dev-local-vectorstore/src",
"plugins/evaluators/src",
"plugins/firebase/src",
"plugins/flask/src",
"plugins/google-cloud/src",
"plugins/google-genai/src",
"plugins/huggingface/src",
"plugins/mcp/src",
"plugins/microsoft-foundry/src",
"plugins/mistral/src",
"plugins/observability/src",
"plugins/ollama/src",
"plugins/vertex-ai/src",
"plugins/xai/src",
# Samples
".", # For samples.shared imports
"samples/framework-evaluator-demo", # For evaluator_demo package imports
"samples/framework-restaurant-demo/src", # For restaurant demo sample imports
"samples/web-endpoints-hello", # For src imports in tests
"plugins/mcp/tests", # For fakes module imports in tests
# Tools
"tools/releasekit/src", # For releasekit package imports
"tools/releasekit", # For test imports (pythonpath = ["."])
]
# Pyright type checking configuration.
[tool.pyright]
exclude = [
"**/__pycache__",
".git",
".mypy_cache",
".nox",
".pytest_cache",
".ruff_cache",
".tox",
"build",
"dist",
]
# Use the venv where packages are installed as editable installs.
# extraPaths lists all source roots so pyright can resolve PEP 420
# namespace packages (genkit.plugins.*) across the workspace without
# relying solely on the venv's editable install paths.
extraPaths = [
"packages/genkit/src",
"plugins/amazon-bedrock/src",
"plugins/anthropic/src",
"plugins/checks/src",
"plugins/cloudflare-workers-ai/src",
"plugins/cohere/src",
"plugins/compat-oai/src",
"plugins/deepseek/src",
"plugins/dev-local-vectorstore/src",
"plugins/evaluators/src",
"plugins/firebase/src",
"plugins/flask/src",
"plugins/google-cloud/src",
"plugins/google-genai/src",
"plugins/huggingface/src",
"plugins/mcp/src",
"plugins/microsoft-foundry/src",
"plugins/mistral/src",
"plugins/observability/src",
"plugins/ollama/src",
"plugins/vertex-ai/src",
"plugins/xai/src",
# Tools
"tools/releasekit/src",
]
pythonVersion = "3.10"
reportMissingImports = true
reportMissingTypeStubs = false
typeCheckingMode = "basic"
venv = ".venv"
venvPath = "."
# Pyrefly type checking configuration (Meta's new type checker).
#
# Import Resolution Note:
# Pyrefly doesn't fully support PEP 420 namespace packages. The genkit plugins use
# namespace packages (genkit.plugins.*) where intermediate directories (genkit/ and
# genkit/plugins/) don't have __init__.py files. This is intentional for allowing
# multiple packages to contribute to the same namespace, but pyrefly can't resolve
# these imports statically. We use ignore-missing-imports for "genkit.plugins.*" to
# suppress false positive import errors while still catching real type errors.
# At runtime, these imports work correctly because Python's import system handles
# PEP 420 namespace packages natively.
[tool.pyrefly]
project_excludes = [
"**/__pycache__",
".git",
".mypy_cache",
".nox",
".pytest_cache",
".ruff_cache",
".tox",
".venv",
"build",
"dist",
"testapps",
"samples/sample-test/**/*.py",
]
project_includes = [
# Core package (source and tests)
"packages/genkit/src/**/*.py",
"packages/genkit/tests/**/*.py",
# Plugins (source and tests)
"plugins/*/src/**/*.py",
"plugins/*/tests/**/*.py",
# Samples
"samples/*/src/**/*.py",
"samples/*/tests/**/*.py",
"samples/framework-evaluator-demo/evaluator_demo/**/*.py",
# Tools
"tools/releasekit/src/**/*.py",
"tools/releasekit/tests/**/*.py",
]
# Search path for first-party code import resolution.
# The project root "." covers all packages. Additional paths are needed for:
# - plugins/mcp/tests: has a local `fakes` module for test mocks
# - samples/framework-evaluator-demo: has `evaluator_demo` package with internal imports
# - samples/framework-restaurant-demo/src: has internal imports (menu_ai, menu_schemas)
search-path = [
".",
"plugins/mcp/tests",
"samples/framework-evaluator-demo",
"samples/framework-restaurant-demo/src",
"samples/web-endpoints-hello",
# Tools
"tools/releasekit/src",
"tools/releasekit",
]
# Ignore missing imports for namespace packages - pyrefly can't resolve PEP 420
# namespace packages but these imports work at runtime.
# model_performance_test is local to sample-test (excluded from workspace).
ignore-missing-imports = ["genkit.plugins.*", "model_performance_test"]
python_version = "3.10"
# Treat warnings as errors.
[tool.pyrefly.errors]
deprecated = "error"
redundant-cast = "error"