[project]
name = "arize-phoenix"
description = "AI Observability and Evaluation"
readme = "README.md"
requires-python = ">=3.10, <3.14"
license = {text="Elastic-2.0"}
license-files = { paths = ["LICENSE", "IP_NOTICE"] }
keywords = [
"Observability",
"Monitoring",
"Explainability",
]
authors = [
{ name = "Arize AI", email = "phoenix-devs@arize.com" },
]
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
dependencies = [
"scikit-learn",
"numpy!=2.0.0", # https://github.com/lmcinnes/umap/issues/1138
"pandas>=1.0",
"jinja2",
"starlette",
"uvicorn",
"psutil",
"strawberry-graphql==0.287.3",
"pyarrow",
"typing-extensions>=4.6",
"scipy",
"wrapt>=1.17.2,<2",
"protobuf>=4.25.8",
"grpcio",
"grpc-interceptor",
"tqdm",
"httpx",
"opentelemetry-sdk",
"opentelemetry-proto>=1.12.0", # needed to avoid this issue: https://github.com/Arize-ai/phoenix/issues/2695
"opentelemetry-exporter-otlp",
"opentelemetry-semantic-conventions",
"openinference-semantic-conventions>=0.1.20",
"openinference-instrumentation>=0.1.32",
"sqlalchemy[asyncio]>=2.0.4, <3",
"alembic>=1.3.0, <2",
"aiosqlite",
"aioitertools",
"sqlean.py>=3.45.1; platform_system != 'Windows'",
"sqlean.py>=3.45.1,<3.50; platform_system == 'Windows'", # https://github.com/nalgeon/sqlean.py/commit/2714a4789998811b7dd9f102f5b45ea071ed879e
"cachetools",
"python-multipart", # see https://www.starlette.io/#dependencies
"arize-phoenix-evals>=2.8.0",
"arize-phoenix-otel>=0.14.0",
"fastapi",
"pydantic>=2.1.0", # exclude 2.0.* since it does not support the `json_encoders` configuration setting
"authlib",
"arize-phoenix-client>=1.28.0",
"email-validator",
"python-dateutil",
"prometheus_client",
"orjson",
"jmespath",
"ldap3",
]
dynamic = ["version"]
[project.scripts]
arize-phoenix = "phoenix.server.main:main"
phoenix = "phoenix.server.main:main"
[dependency-groups]
dev = [
"aiosqlite<0.22.0", # new version is causing tests to hang
"anthropic",
"arize",
"asgi-lifespan",
"asyncpg",
"azure-identity",
"beautifulsoup4",
"boto3",
"debugpy",
"deepdiff==8.6.1",
"Faker>=30.1.0",
"fast-hdbscan",
"freezegun",
"google-genai>=1.0.0",
"grpc-interceptor[testing]",
"grpcio",
"httpx",
"httpx-ws",
"jsonpath-ng",
"ldap3",
"litellm>1.61.15",
"mypy==1.15.0",
"mypy-boto3-bedrock-runtime",
"nest-asyncio", # for executor testing
"numpy",
"openai",
"openinference-semantic-conventions",
"opentelemetry-exporter-otlp",
"opentelemetry-instrumentation-fastapi",
"opentelemetry-instrumentation-grpc",
"opentelemetry-instrumentation-sqlalchemy",
"opentelemetry-proto>=1.12.0",
"opentelemetry-sdk>=1.35.0",
"opentelemetry-semantic-conventions",
"pandas>=1.0",
"pandas-stubs==2.0.3.230814",
"portpicker",
"prometheus_client",
"protobuf",
"psutil",
"psycopg[binary,pool]",
"py-grpc-prometheus",
"pyarrow-stubs",
"pydantic>=1.0,!=2.0.*,<3",
"pyjwt",
"pypistats", # this is needed to type-check third-party packages
"pyright[nodejs]==1.1.394",
"pytest",
"pytest-asyncio",
"pytest-postgresql",
"pytest-randomly",
"pytest-rerunfailures",
"pytest-smtpd",
"pytest-xdist",
"requests", # this is needed to type-check third-party packages
"responses",
"respx>=0.22.0",
"strawberry-graphql[opentelemetry]==0.287.3",
"syrupy",
"tenacity",
"tiktoken",
"ty",
"types-beautifulsoup4",
"types-cachetools",
"types-jmespath",
"types-jsonschema",
"types-ldap3",
"types-protobuf",
"types-psutil",
"types-python-dateutil",
"types-requests",
"types-setuptools",
"types-tabulate",
"types-tqdm",
"typing-extensions",
"umap-learn",
"uvloop; platform_system != 'Windows'",
"vcrpy",
]
[project.optional-dependencies]
embeddings = [
"fast-hdbscan>=0.2.0",
"numba>=0.60.0", # https://github.com/astral-sh/uv/issues/6281
"umap-learn",
]
evals = []
experimental = []
pg = [
"asyncpg",
"psycopg[binary,pool]",
]
aws = [
"boto3",
]
container = [
"anthropic>=0.49.0",
"google-genai>=1.50.0 ; python_version >= '3.10'",
"google-genai ; python_version < '3.10'",
"prometheus-client",
"openai>=1.0.0",
"azure-identity",
"aiohttp", # used by azure-identity via azure.core.pipeline.transport
# Note: when updating opentelemetry dependencies, all packages must use versions
# released on the same date (e.g., 1.39.1/0.60b1) to ensure compatibility.
"opentelemetry-sdk==1.39.1",
"opentelemetry-proto==1.39.1",
"opentelemetry-exporter-otlp==1.39.1",
"opentelemetry-semantic-conventions==0.60b1",
"opentelemetry-instrumentation-fastapi==0.60b1", # https://github.com/open-telemetry/opentelemetry-python-contrib/issues/3637
"opentelemetry-instrumentation-sqlalchemy==0.60b1",
"opentelemetry-instrumentation-grpc==0.60b1",
"py-grpc-prometheus",
"strawberry-graphql[opentelemetry]==0.287.3",
"uvloop; platform_system != 'Windows'",
"fast-hdbscan>=0.2.0",
"numba>=0.60.0", # https://github.com/astral-sh/uv/issues/6281
"umap-learn",
"boto3",
]
test = [
]
[project.urls]
Documentation = "https://arize.com/docs/phoenix/"
Issues = "https://github.com/Arize-ai/phoenix/issues"
Source = "https://github.com/Arize-ai/phoenix"
[tool.hatch.version]
path = "src/phoenix/version.py"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/phoenix"]
exclude = [
"src/phoenix/client/",
"src/phoenix/evals/",
"src/phoenix/otel/",
]
artifacts = [
"src/phoenix/server/static",
"src/phoenix/db/migrations",
"src/phoenix/server/cost_tracking/model_cost_manifest.json",
]
[tool.hatch.build]
only-packages = true
[tool.hatch.build.targets.sdist]
exclude = [
"packages/",
"src/phoenix/client/",
"src/phoenix/evals/",
"src/phoenix/otel/",
"tests/",
"scripts/",
"examples/",
"js/",
]
artifacts = [
"src/phoenix/server/static",
"src/phoenix/db/migrations",
"src/phoenix/server/cost_tracking/model_cost_manifest.json",
]
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope="function"
addopts = [
"-rA",
"--import-mode=importlib",
"--doctest-modules",
"--new-first",
"--showlocals",
]
testpaths = [
"tests",
]
[tool.hatch.envs.publish]
dependencies = [
"check-wheel-contents",
"twine",
]
[tool.hatch.envs.publish.scripts]
testpypi = [
"check-wheel-contents dist/",
"twine upload --verbose --repository testpypi dist/*",
]
pypi = [
"check-wheel-contents dist/",
"twine upload --verbose dist/*",
]
[tool.mypy]
plugins = ["strawberry.ext.mypy_plugin", "pydantic.mypy"]
strict = true
exclude = [
"api_reference",
"dist/",
"examples/",
"packages/",
"scripts/",
"sdist/",
"src/phoenix/client/",
"src/phoenix/evals/",
"src/phoenix/otel/",
"tutorials/",
"js/",
]
[[tool.mypy.overrides]]
module = [
"fast_hdbscan",
"umap",
"numba.*",
"scipy.*",
"sklearn.*",
"arize.*",
"wrapt",
"langchain.*",
"litellm",
"litellm.*",
"nest_asyncio",
"opentelemetry.*",
"pyarrow",
"sqlean",
"grpc.*",
"py_grpc_prometheus.*",
"orjson", # suppress fastapi internal type errors
"pypistats",
"authlib.*",
"google.*",
"mistralai.*",
]
ignore_missing_imports = true
[tool.ruff]
exclude = [
"api_reference",
"dist/",
".git",
"__pycache__",
"*_pb2.py*",
"*.pyi",
"docs/",
]
line-length = 100
target-version = "py310"
[tool.ruff.lint.per-file-ignores]
"*.ipynb" = ["E402", "E501"]
"examples/**/*.py" = ["E501"]
"tests/**/*.py" = ["E501"]
[tool.ruff.lint]
select = ["E", "F", "W", "I", "NPY201"]
[tool.ruff.lint.isort]
force-single-line = false
[tool.ruff.format]
line-ending = "native"
[tool.uv.workspace]
members = ["packages/*"]
[tool.uv.sources]
arize-phoenix-client = { workspace = true }
arize-phoenix-evals = { workspace = true }
arize-phoenix-otel = { workspace = true }