tox.ini•14.1 kB
[tox]
isolated_build = True
skipsdist = True
[testenv]
package = wheel
wheel_build_env = .pkg
[testenv:phoenix_client]
description = Run tests for the arize-phoenix-client package
changedir = packages/phoenix-client/
deps =
-r requirements/packages/phoenix-client.txt
commands_pre = uv pip install --strict --reinstall-package arize-phoenix-client .
commands =
uv pip list -v
{envbindir}/pyright .
{envbindir}/mypy --strict .
{envbindir}/pytest {posargs} tests/client
[testenv:phoenix_client_canary_tests_sdk_openai]
description = Run phoenix-client canary tests for third-party SDK: anthropic
changedir = packages/phoenix-client/
setenv =
SDK = openai
MOD = chat
TESTS = tests/canary/sdk
HELPERS = src/phoenix/client/helpers/sdk
SDK_TESTS = {env:TESTS}/{env:SDK}
SDK_HELPERS = {env:HELPERS}/{env:SDK}
REQ = {toxinidir}/requirements
SDK_REQ = {env:REQ}/canary/sdk/{env:SDK}.txt
commands_pre =
uv pip install --strict -U --reinstall-package arize-phoenix-client .
uv pip uninstall -r {toxinidir}/requirements/canary/sdk/{env:SDK}.txt
uv pip list -v
commands =
python -c "import phoenix.client.helpers.sdk.{env:SDK}.{env:MOD}"
uv pip install --strict -U -r {env:REQ}/ci.txt
uv pip install --strict -U -r {env:SDK_REQ}
uv pip list -v
pyright -p {env:HELPERS}/pyrightconfig.json {env:SDK_HELPERS}
pyright -p {env:TESTS}/pyrightconfig.json {env:SDK_TESTS}
mypy --strict --follow-untyped-imports {env:SDK_HELPERS}/{env:MOD}.py
mypy --strict --follow-untyped-imports {env:SDK_TESTS}/test_{env:MOD}.py
pytest --disable-socket {posargs} {env:SDK_TESTS}
[testenv:phoenix_client_canary_tests_sdk_anthropic]
description = Run phoenix-client canary tests for third-party SDK: anthropic
changedir = packages/phoenix-client/
setenv =
SDK = anthropic
MOD = messages
TESTS = tests/canary/sdk
HELPERS = src/phoenix/client/helpers/sdk
SDK_TESTS = {env:TESTS}/{env:SDK}
SDK_HELPERS = {env:HELPERS}/{env:SDK}
REQ = {toxinidir}/requirements
SDK_REQ = {env:REQ}/canary/sdk/{env:SDK}.txt
commands_pre =
uv pip install --strict -U --reinstall-package arize-phoenix-client .
uv pip uninstall -r {toxinidir}/requirements/canary/sdk/{env:SDK}.txt
uv pip list -v
commands =
python -c "import phoenix.client.helpers.sdk.{env:SDK}.{env:MOD}"
uv pip install --strict -U -r {env:REQ}/ci.txt
uv pip install --strict -U -r {env:SDK_REQ}
uv pip list -v
pyright -p {env:HELPERS}/pyrightconfig.json {env:SDK_HELPERS}
pyright -p {env:TESTS}/pyrightconfig.json {env:SDK_TESTS}
mypy --strict --follow-untyped-imports {env:SDK_HELPERS}/{env:MOD}.py
mypy --strict --follow-untyped-imports {env:SDK_TESTS}/test_{env:MOD}.py
pytest --disable-socket {posargs} {env:SDK_TESTS}
[testenv:phoenix_client_canary_tests_sdk_google_generativeai]
description = Run phoenix-client canary tests for third-party SDK: google_generativeai
changedir = packages/phoenix-client/
setenv =
SDK = google_generativeai
MOD = generate_content
TESTS = tests/canary/sdk
HELPERS = src/phoenix/client/helpers/sdk
SDK_TESTS = {env:TESTS}/{env:SDK}
SDK_HELPERS = {env:HELPERS}/{env:SDK}
REQ = {toxinidir}/requirements
SDK_REQ = {env:REQ}/canary/sdk/{env:SDK}.txt
commands_pre =
uv pip install --strict -U --reinstall-package arize-phoenix-client .
uv pip uninstall -r {toxinidir}/requirements/canary/sdk/{env:SDK}.txt
uv pip list -v
commands =
python -c "import phoenix.client.helpers.sdk.{env:SDK}.{env:MOD}"
uv pip install --strict -U -r {env:REQ}/ci.txt
uv pip install --strict -U -r {env:SDK_REQ}
uv pip list -v
pyright -p {env:HELPERS}/pyrightconfig.json {env:SDK_HELPERS}
pyright -p {env:TESTS}/pyrightconfig.json {env:SDK_TESTS}
mypy --strict --follow-untyped-imports {env:SDK_HELPERS}/{env:MOD}.py
mypy --strict --follow-untyped-imports {env:SDK_TESTS}/test_{env:MOD}.py
pytest --disable-socket {posargs} {env:SDK_TESTS}
[testenv:phoenix_evals]
description = Run tests for the arize-phoenix-evals package
changedir = packages/phoenix-evals/
deps =
-r requirements/packages/phoenix-evals.txt
commands_pre = uv pip install --strict --reinstall-package arize-phoenix-evals .[test]
commands =
uv pip list -v
mypy .
pytest {posargs} .
[testenv:phoenix_otel]
description = Run tests for the arize-phoenix-otel package
changedir = packages/phoenix-otel/
deps =
-r requirements/ci.txt
commands_pre = uv pip install --strict --reinstall-package arize-phoenix-otel .[test]
commands =
uv pip list -v
mypy .
pytest -ra {posargs:.}
[testenv:type_check_integration_tests]
description = Run type checking with mypy on integration tests
changedir = tests/integration
deps =
-r requirements/integration-tests.txt
commands_pre =
uv pip install --strict --reinstall-package arize-phoenix {toxinidir}
uv pip install --strict --reinstall-package arize-phoenix-client {toxinidir}/packages/phoenix-client
commands =
uv pip list -v
pyright -p pyrightconfig.json client/
mypy --strict .
[testenv:integration_tests]
description = Run integration tests
pass_env =
CI_TEST_DB_BACKEND
changedir = tests/integration
deps =
-r requirements/integration-tests.txt
setenv =
PHOENIX_MASK_INTERNAL_SERVER_ERRORS = false
commands_pre =
uv pip install --strict --reinstall-package arize-phoenix {toxinidir}
uv pip install --strict --reinstall-package arize-phoenix-client {toxinidir}/packages/phoenix-client
commands =
uv pip list -v
pytest {posargs} .
[testenv:type_check_unit_tests]
description = Run type checking with mypy on unit tests
changedir = tests/
deps =
-r requirements/unit-tests.txt
commands_pre =
uv pip install --strict --reinstall-package arize-phoenix {toxinidir}
commands =
uv pip list -v
mypy --strict unit/
[testenv:unit_tests]
description = Run unit tests
changedir = tests
deps =
-r requirements/unit-tests.txt
setenv =
PHOENIX_MASK_INTERNAL_SERVER_ERRORS = false
commands_pre =
uv pip install --strict --reinstall-package arize-phoenix {toxinidir}
commands =
uv pip list -v
pytest {posargs} unit/
[testenv:unit_tests_local_evals]
description = Run unit tests with phoenix-evals installed from local source
changedir = tests
deps =
-r requirements/unit-tests.txt
commands_pre =
uv pip install --strict --reinstall-package arize-phoenix --reinstall-package arize-phoenix-evals ../. arize-phoenix-evals@../packages/phoenix-evals
commands =
uv pip list -v
pytest {posargs} unit/
[testenv:type_check]
description = Run type checking with mypy on src/phoenix
deps =
-r requirements/type-check.txt
commands_pre =
uv pip install --strict --reinstall-package arize-phoenix .
uv pip install --strict --reinstall-package arize-phoenix-client {toxinidir}/packages/phoenix-client
commands =
uv pip list -v
mypy --strict src/phoenix/
[testenv:ensure_graphql_mutations_have_permission_classes]
description = Ensure each GraphQL mutation and subscription is decorated with permission classes
changedir = src/phoenix/server/api
commands =
python {toxinidir}/scripts/ci/ensure_graphql_mutations_have_permission_classes.py
[testenv:clean_jupyter_notebooks]
description = Clear output and metadata from Jupyter notebooks
deps =
-r requirements/clean-jupyter-notebooks.txt
commands =
uv pip list -v
find . -type f -name "*.ipynb" -not -path "*/tutorials/evals/*" -not -path "*/tutorials/ai_evals_course/*" -exec jupyter nbconvert --ClearOutputPreprocessor.enabled=True --ClearMetadataPreprocessor.enabled=True --inplace {} \;
allowlist_externals =
find
[testenv:build_graphql_schema]
description = Export GraphQL schema to a file (Python 3.9)
recreate = true
basepython = python3.9
changedir = app
deps =
-r requirements/build-graphql-schema.txt
commands_pre =
uv pip install --strict --reinstall-package arize-phoenix {toxinidir}
uv pip install 'libcst<1.8' # https://github.com/strawberry-graphql/strawberry/issues/3874
commands =
uv pip list -v
strawberry export-schema phoenix.server.api.schema:_EXPORTED_GRAPHQL_SCHEMA -o schema.graphql
[testenv:build_openapi_schema]
description = Export OpenAPI schema to a file (Python 3.9)
recreate = true
basepython = python3.9
changedir = schemas
commands_pre =
uv pip install --strict --reinstall-package arize-phoenix {toxinidir}
commands =
uv pip list -v
python -m phoenix.server.api.openapi.main -o openapi.json
[testenv:compile_protobuf]
description = Compile protobuf files (Python 3.9)
basepython = python3.9
deps =
-r requirements/compile-protobuf.txt
commands =
uv pip list -v
python -m grpc_tools.protoc -I src/phoenix/proto --python_out=src/phoenix --mypy_out=src/phoenix src/phoenix/proto/trace/v1/evaluation.proto
[testenv:add_symlinks]
description = Add symlinks to packages (for editable install)
changedir = src/phoenix
allowlist_externals =
sh
commands =
sh -c '[ -e client ] || ln -s ../../packages/phoenix-client/src/phoenix/client client'
sh -c '[ -e evals ] || ln -s ../../packages/phoenix-evals/src/phoenix/evals evals'
sh -c '[ -e otel ] || ln -s ../../packages/phoenix-otel/src/phoenix/otel otel'
[testenv:remove_symlinks]
description = Remove symlinks to packages
changedir = src/phoenix
allowlist_externals = find
commands =
find . -maxdepth 1 -type l -exec unlink {} \;
[testenv:phoenix_main]
description = Run Phoenix server
pass_env =
PHOENIX_PORT
PHOENIX_GRPC_PORT
PHOENIX_HOST_ROOT_PATH
PHOENIX_SQL_DATABASE_URL
PHOENIX_SQL_DATABASE_SCHEMA
PHOENIX_ENABLE_AUTH
PHOENIX_SECRET
PHOENIX_DISABLE_BASIC_AUTH
PHOENIX_ADMINS
PHOENIX_COOKIES_PATH
PHOENIX_DISABLE_LOGIN_FORM
PHOENIX_OAUTH2_ARIZE_CLIENT_SECRET
PHOENIX_OAUTH2_ARIZE_CLIENT_ID
PHOENIX_OAUTH2_ARIZE_OIDC_CONFIG_URL
PHOENIX_OAUTH2_ARIZE_ALLOW_SIGN_UP
PHOENIX_OAUTH2_ARIZE_AUTO_LOGIN
PHOENIX_OAUTH2_GOOGLE_CLIENT_ID
PHOENIX_OAUTH2_GOOGLE_CLIENT_SECRET
PHOENIX_OAUTH2_GOOGLE_OIDC_CONFIG_URL
PHOENIX_OAUTH2_GOOGLE_ALLOW_SIGN_UP
PHOENIX_OAUTH2_GOOGLE_AUTO_LOGIN
PHOENIX_OAUTH_GITHUB_CLIENT_ID
PHOENIX_OAUTH_GITHUB_CLIENT_SECRET
PHOENIX_OAUTH2_AUTH0_CLIENT_ID
PHOENIX_OAUTH2_AUTH0_CLIENT_SECRET
PHOENIX_OAUTH2_AUTH0_OIDC_CONFIG_URL
PHOENIX_OAUTH2_AUTH0_ALLOW_SIGN_UP
PHOENIX_OAUTH2_AUTH0_AUTO_LOGIN
PHOENIX_OAUTH2_AZURE_AD_OIDC_CONFIG_URL
PHOENIX_OAUTH2_AZURE_AD_CLIENT_ID
PHOENIX_OAUTH2_AZURE_AD_CLIENT_SECRET
PHOENIX_OAUTH2_AZURE_AD_ALLOW_SIGN_UP
PHOENIX_OAUTH2_AZURE_AD_AUTO_LOGIN
PHOENIX_OAUTH2_AWS_COGNITO_CLIENT_ID
PHOENIX_OAUTH2_AWS_COGNITO_CLIENT_SECRET
PHOENIX_OAUTH2_AWS_COGNITO_OIDC_CONFIG_URL
PHOENIX_OAUTH2_AWS_COGNITO_ALLOW_SIGN_UP
PHOENIX_OAUTH2_AWS_COGNITO_AUTO_LOGIN
PHOENIX_SMTP_HOSTNAME
PHOENIX_SMTP_PORT
PHOENIX_SMTP_USERNAME
PHOENIX_SMTP_PASSWORD
PHOENIX_ACCESS_TOKEN_EXPIRY_MINUTES
PHOENIX_DATABASE_ALLOCATED_STORAGE_CAPACITY_GIBIBYTES
PHOENIX_DANGEROUSLY_DISABLE_MIGRATIONS
PHOENIX_DISABLE_BASIC_AUTH
PHOENIX_ALLOWED_ORIGINS
PHOENIX_LOGGING_LEVEL
PHOENIX_FULLSTORY_ORG
commands_pre =
uv tool install -U --force arize-phoenix@. \
--reinstall-package arize-phoenix \
--with-requirements requirements/dev.txt \
--compile-bytecode
commands =
uv tool run arize-phoenix {posargs:serve}
[testenv:ruff]
description = Run ruff for formatting and linting
commands_pre =
uv tool install ruff@0.12.5
commands =
uv tool run ruff format
uv tool run ruff check --fix
[testenv:openapi_codegen_for_python_client]
description = Generate data models from OpenAPI schema for Python client
recreate = true
changedir = packages/phoenix-client/src/phoenix/client/__generated__/
commands_pre =
uv tool install --force ruff@0.12.5
commands =
uv pip list -v
uv pip install datamodel-code-generator==0.32.0 pydantic==2.11.0
python -c "import pathlib; pathlib.Path('v1/__init__.py').unlink(missing_ok=True)"
datamodel-codegen \
--input {toxinidir}/schemas/openapi.json \
--input-file-type openapi \
--output v1/.dataclass.py \
--output-model-type dataclasses.dataclass \
--collapse-root-models \
--enum-field-as-literal all \
--target-python-version 3.9 \
--use-default-kwarg \
--use-double-quotes \
--use-generic-container-types \
--wrap-string-literal \
--disable-timestamp
python -c "import re; file = 'v1/.dataclass.py'; lines = [re.sub(r'\\bSequence]', 'Sequence[Any]]', line) for line in open(file).readlines()]; open(file, 'w').writelines(lines)"
python {toxinidir}/packages/phoenix-client/scripts/codegen/transform.py v1
uv pip install --strict --reinstall-package arize-phoenix-client {toxinidir}/packages/phoenix-client
uv pip list -v
python -c "import phoenix.client.__generated__.v1"
uv tool run ruff format v1
uv tool run ruff check --fix v1
[testenv:graphql_codegen_for_python_tests]
description = Generate data models from GraphQL schema for Python tests
recreate = true
changedir = tests/__generated__/graphql/
commands =
uv pip list -v
python -c "import pathlib; pathlib.Path('__init__.py').unlink(missing_ok=True)"
uv tool run --from 'datamodel-code-generator[graphql]' datamodel-codegen \
--input {toxinidir}/app/schema.graphql \
--input-file-type graphql \
--output __init__.py \
--output-model-type pydantic_v2.BaseModel \
--collapse-root-models \
--enable-faux-immutability \
--enum-field-as-literal all \
--target-python-version 3.9 \
--use-default-kwarg \
--use-double-quotes \
--use-generic-container-types \
--use-standard-collections \
--wrap-string-literal \
--disable-timestamp
python __main__.py
[testenv:sync_models]
description = Sync model cost manifest from remote sources
recreate = true
commands_pre =
uv pip install pydantic
commands =
python {toxinidir}/.github/.scripts/sync_models.py
[testenv:ddl_extract]
description = Extract DDL schema from PostgreSQL database
basepython = python3.13
changedir = scripts/ddl
pass_env =
PGHOST
PGPORT
PGDATABASE
PGUSER
PGPASSWORD
commands_pre =
uv pip install --strict psycopg[binary] testing.postgresql pglast ty
uv pip install --strict --reinstall-package arize-phoenix {toxinidir}
commands =
uv pip list -v
ty check generate_ddl_postgresql.py
python generate_ddl_postgresql.py {posargs}