Files
python-sdk/pyproject.toml
T
248e5e0ea9 fix(browser-mcp): migrate CDP bridge → zapd consumer; disk authoritative (#35)
* fix(browser-mcp): migrate CDP bridge -> zapd consumer; make disk authoritative

The MCP runtime kept pulling the buggy published wheel (hanzo-tools-browser
0.5.7) from PyPI instead of the migrated on-disk source, so every restart
re-broke the `cdp` tool. Reinstate `cdp` as a zapd-native tool, finish the
bridge->zapd migration (delete dead bridge/server modules + their tests), bump
to 0.5.8 and pin hanzo-mcp >=0.5.8, add the package to the uv workspace/sources
so disk is authoritative. 9/9 browser tests pass.

Pairs with the hanzoai/extension bridge->zapd migration (separate, still
uncommitted). The ~/.claude.json MCP invocation was also pointed at the local
editable source (machine config, not in this repo).

(cherry picked from commit 11b4d4ea8a5570d6fb0e51079fa445dba3713f71)

* fix(browser): drop dead lifecycle.py (in-process zap_server/cdp_bridge are gone)

lifecycle.py only wrapped the removed in-process ZAP server + CDP bridge; nothing
imports it under the zapd-consumer model. One way: transport is zapd_consumer,
tools are browser/cdp/playwright.

---------

Co-authored-by: hanzo-dev <[email protected]>

Co-authored-by: Antje Worring <[email protected]>

Co-authored-by: Hanzo Dev <[email protected]>
2026-06-16 22:12:07 -07:00

519 lines
12 KiB
TOML

[project]
name = "hanzoai"
version = "2.2.1"
description = "The official Python library for the Hanzo API"
dynamic = ["readme"]
license = "BSD-3-Clause"
authors = [
{ name = "Hanzo", email = "[email protected]" },
]
dependencies = [
# All runtime deps below are pure-Python — fully compatible with free-threaded 3.13t.
"httpx>=0.23.0, <1",
# Bump pydantic floor so we land on a pydantic-core (≥2.27) that ships cp313t wheels.
"pydantic>=2.10, <3",
"typing-extensions>=4.10, <5",
"anyio>=3.5.0, <5",
"distro>=1.7.0, <2",
"sniffio",
# Security: pin minimum versions to address vulnerabilities
"h11>=0.16.0",
"urllib3>=2.6.0",
]
requires-python = ">=3.12"
classifiers = [
"Typing :: Typed",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Operating System :: OS Independent",
"Operating System :: POSIX",
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
"Operating System :: Microsoft :: Windows",
"Topic :: Software Development :: Libraries :: Python Modules",
"License :: OSI Approved :: BSD License"
]
[project.optional-dependencies]
llm = ["hanzo-llm>=1.0.0"]
[project.urls]
Homepage = "https://github.com/hanzoai/python-sdk"
Repository = "https://github.com/hanzoai/python-sdk"
[tool.rye]
managed = true
# version pins are in requirements-dev.lock
dev-dependencies = [
"pyright>=1.1.359",
"mypy",
"respx",
"pytest",
"pytest-asyncio>=0.26.0,<1.0.0",
"ruff",
"time-machine",
"nox",
"dirty-equals>=0.6.0",
"importlib-metadata>=6.7.0",
"rich>=13.7.1",
"nest_asyncio==1.6.0",
# hanzo-memory test dependencies
"polars>=1.0.0",
"httpx>=0.27.0",
"fastapi>=0.115.0",
"fastembed>=0.4.0",
]
[tool.rye.workspace]
members = [
"pkg/hanzo",
"pkg/hanzo-aci",
"pkg/hanzo-mcp",
"pkg/hanzo-memory",
"pkg/hanzo-network",
"pkg/hanzo-dev-py",
"pkg/hanzo-s3",
"pkg/hanzo-tools-ui",
"pkg/hanzo-zap",
"pkg/hanzoai",
]
[tool.rye.scripts]
format = { chain = [
"format:ruff",
"format:docs",
"fix:ruff",
# run formatting again to fix any inconsistencies when imports are stripped
"format:ruff",
]}
"format:docs" = "python scripts/utils/ruffen-docs.py README.md api.md"
"format:ruff" = "ruff format"
"lint" = { chain = [
"check:ruff",
"typecheck",
"check:importable",
]}
"check:ruff" = "ruff check ."
"fix:ruff" = "ruff check --fix ."
"check:importable" = "python -c 'import hanzoai'"
typecheck = { chain = [
"typecheck:pyright",
"typecheck:mypy"
]}
"typecheck:pyright" = "pyright"
"typecheck:verify-types" = "pyright --verifytypes hanzoai --ignoreexternal"
"typecheck:mypy" = "mypy pkg/hanzoai"
[build-system]
requires = ["hatchling==1.26.3", "hatch-fancy-pypi-readme"]
build-backend = "hatchling.build"
[dependency-groups]
dev = [
"build>=1.2.2.post1",
"dirty-equals>=0.6.0",
"fastapi>=0.128.0",
"fastembed>=0.7.4",
"hanzo-memory",
"httpx>=0.28.1",
"importlib-metadata>=6.7.0",
"mypy",
"nest-asyncio==1.6.0",
"nox",
"polars>=1.36.1",
"pyright>=1.1.359",
"pytest>=8.4.2",
"pytest-asyncio>=0.26.0,<1.0.0",
"respx",
"rich>=13.7.1",
"ruff",
"time-machine",
]
[tool.hatch.build]
include = [
"pkg/hanzoai"
]
[tool.hatch.build.targets.wheel]
packages = ["pkg/hanzoai"]
[tool.hatch.build.targets.sdist]
# Basically everything except hidden files/directories (such as .github, .devcontainers, .python-version, etc)
include = [
"/*.toml",
"/*.json",
"/*.lock",
"/*.md",
"/mypy.ini",
"/noxfile.py",
"bin/*",
"examples/*",
"pkg/hanzoai/*",
"tests/*",
]
[tool.hatch.metadata.hooks.fancy-pypi-readme]
content-type = "text/markdown"
[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]
path = "README.md"
[[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
# replace relative links with absolute links
pattern = '\[(.+?)\]\(((?!https?://)\S+?)\)'
replacement = '[\1](https://github.com/hanzoai/python-sdk/tree/main/\g<2>)'
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--tb=short"
xfail_strict = true
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
markers = [
"integration: marks tests as integration tests (deselect with '-m \"not integration\"')"
]
filterwarnings = [
"error",
"ignore:OpenTelemetry configuration.*is not supported by Datadog:UserWarning",
"ignore::DeprecationWarning:ddtrace.*",
"ignore:Support for class-based `config` is deprecated:pydantic.warnings.PydanticDeprecatedSince20",
"ignore:hanzo-tools-core is deprecated:DeprecationWarning"
]
[tool.pyright]
# Use basic mode — strict mode with 22+ disabled checks is contradictory.
# SDK has many optional dependencies and generated code that cannot be
# fully type-checked in strict mode.
typeCheckingMode = "basic"
pythonVersion = "3.12"
exclude = [
"_dev",
".venv",
".nox",
# All subpackages have their own linting/type checking
"pkg/hanzo",
"pkg/hanzo-aci",
"pkg/hanzo-agent",
"pkg/hanzo-agents",
"pkg/hanzo-async",
"pkg/hanzo-cli",
"pkg/hanzo-consensus",
"pkg/hanzo-iam",
"pkg/hanzo-kms",
"pkg/hanzo-mcp",
"pkg/hanzo-memory",
"pkg/hanzo-network",
"pkg/hanzo-node",
"pkg/hanzo-dev-py",
"pkg/hanzo-tools",
"pkg/hanzo-tools-agent",
"pkg/hanzo-tools-api",
"pkg/hanzo-tools-browser",
"pkg/hanzo-tools-code",
"pkg/hanzo-tools-computer",
"pkg/hanzo-tools-config",
"pkg/hanzo-tools-core",
"pkg/hanzo-tools-database",
"pkg/hanzo-tools-editor",
"pkg/hanzo-tools-fs",
"pkg/hanzo-tools-ide",
"pkg/hanzo-tools-jupyter",
"pkg/hanzo-tools-llm",
"pkg/hanzo-tools-lsp",
"pkg/hanzo-tools-mcp",
"pkg/hanzo-tools-memory",
"pkg/hanzo-tools-net",
"pkg/hanzo-tools-plan",
"pkg/hanzo-tools-reasoning",
"pkg/hanzo-tools-refactor",
"pkg/hanzo-tools-repl",
"pkg/hanzo-tools-shell",
"pkg/hanzo-tools-test",
"pkg/hanzo-tools-todo",
"pkg/hanzo-tools-ui",
"pkg/hanzo-tools-vcs",
"pkg/hanzo-tools-vector",
"pkg/hanzo-web3",
# Non-production code
"bin",
"examples",
"tests",
"scripts",
]
reportImportCycles = false
reportPrivateUsage = false
# Relax strict checks for this SDK with many optional dependencies
reportMissingTypeStubs = false
reportUnknownVariableType = false
reportUnknownMemberType = false
reportUnknownParameterType = false
reportUnknownArgumentType = false
reportMissingParameterType = false
reportUnusedImport = "warning"
reportIncompatibleMethodOverride = false
reportMissingImports = false
reportConstantRedefinition = false
reportMissingTypeArgument = false
reportArgumentType = false
reportReturnType = false
reportIndexIssue = false
reportUnnecessaryContains = false
reportAttributeAccessIssue = false
reportCallIssue = false
reportOptionalMemberAccess = false
reportGeneralTypeIssues = false
reportImplicitOverride = false
reportAssignmentType = false
reportOptionalIterable = false
[tool.ruff]
line-length = 120
output-format = "grouped"
target-version = "py312"
exclude = [
"pkg/hanzo-agent", # submodule - linted separately
"pkg/hanzo-memory", # needs careful review - has complex redefinitions
]
[tool.ruff.format]
docstring-code-format = true
[tool.ruff.lint]
select = [
# isort
"I",
# bugbear rules
"B",
# remove unused imports
"F401",
# bare except statements
"E722",
# unused arguments
"ARG",
# misuse of typing.TYPE_CHECKING
# import rules
"TID251",
# docstring issues
"D",
# logging format
"G",
# security
"S",
# module imports
"E402",
# star imports
"F403",
# undefined names
"F821",
]
ignore = [
# mutable defaults
"B006",
# Unused function/method arguments - OK for protocol methods
"ARG001",
"ARG002",
"ARG003",
"ARG004",
"ARG005",
# Docstring formatting
"D205",
"D415",
# Line too long - handled by formatter
"E501",
# Ambiguous variable name
"E741",
# subprocess call - OK for CLI tools
"S603",
# Empty method in abstract base class
"B027",
# print statements - OK in examples and CLI tools
"T201",
"T203",
# Unused imports - we'll fix these manually
"F401",
# Undefined name - we'll fix these manually
"F821",
# raise without from inside except
"B904",
# logging format issues - OK for now
"G001",
"G002",
"G003",
# Unused loop control variable
"B007",
# subprocess without shell validation - OK for our use
"S605",
# try-except-pass - OK for optional imports
"S110",
# Missing docstrings - too many to fix now
"D100",
"D101",
"D102",
"D103",
"D104",
"D105",
"D106",
"D107",
# Other docstring issues
"D200",
"D201",
"D202",
"D203",
"D204",
"D206",
"D207",
"D208",
"D209",
"D210",
"D211",
"D212",
"D213",
"D214",
"D215",
"D300",
"D301",
"D400",
"D401",
"D402",
"D403",
"D404",
"D405",
"D406",
"D407",
"D408",
"D409",
"D410",
"D411",
"D412",
"D413",
"D414",
"D416",
"D417",
# Module level import not at top
"E402",
# Star imports
"F403",
# Loop variable binding
"B023",
# Use single if instead of nested - sometimes nested is clearer
"SIM102",
# Use of assert - OK in tests
"S101",
# Logging with f-string - performance is not critical
"G004",
# Starting process with partial path - OK for our use
"S607",
# Hardcoded temp directory - OK for tests
"S108",
# Popen without shell - OK
"S602",
# Starting process with shell - already handled
"S608",
# Use of random - OK for non-crypto use
"S311",
# Try-except-continue - OK
"S112",
# Insecure hash function - OK for non-crypto use
"S324",
# Request without timeout - OK for some cases
"S113",
# Hardcoded password - only in tests
"S106",
# os.system - OK for some CLI tools
"S606",
# eval - used safely in specific contexts
"S307",
# Hardcoded bind address - OK for examples
"S105",
# Use of exec - OK for specific use cases
"S102",
# Exception info in logging - OK
"G201",
]
unfixable = [
# disable auto fix for print statements
"T201",
"T203",
]
[tool.ruff.lint.flake8-tidy-imports.banned-api]
"functools.lru_cache".msg = "This function does not retain type information for the wrapped function's arguments; The `lru_cache` function from `_utils` should be used instead"
[tool.ruff.lint.isort]
length-sort = true
length-sort-straight = true
combine-as-imports = true
extra-standard-library = ["typing_extensions"]
known-first-party = ["hanzoai", "tests"]
[tool.mypy]
python_version = "3.12"
ignore_missing_imports = true
# Relax type checking - SDK has many optional dependencies and dynamic imports
check_untyped_defs = false
disallow_untyped_defs = false
disallow_untyped_calls = false
disallow_incomplete_defs = false
warn_return_any = false
warn_unused_ignores = false
exclude = [
# Subpackages - have their own linting/type checking
"pkg/hanzo-agent/",
"pkg/hanzo-aci/",
"pkg/hanzo-mcp/",
"pkg/hanzo-memory/",
"pkg/hanzo-network/",
"pkg/hanzo-dev-py/",
"pkg/hanzo/",
# Non-production code
"bin/",
"examples/",
"scripts/",
"tests/",
]
[tool.uv.workspace]
members = [
"pkg/hanzo-memory",
"pkg/hanzo-s3",
"pkg/hanzo-tools-ui",
"pkg/hanzo-tools-browser",
]
[tool.uv.sources]
hanzo-memory = { workspace = true }
hanzo-tools-ui = { workspace = true }
# Browser tool routes through the local zapd router; the on-disk source is the
# single truth (not a published wheel) so the MCP and the repo never diverge.
hanzo-tools-browser = { workspace = true }
[tool.ruff.lint.extend-per-file-ignores]
# Allow print statements in scripts and examples
"bin/**.py" = ["T201", "T203"]
"scripts/**.py" = ["T201", "T203", "E722"]
"tests/**.py" = ["T201", "T203", "F401", "F841"]
"examples/**.py" = ["T201", "T203", "F841"]
"**/examples/**.py" = ["T201", "T203", "F841"]
"pkg/**/examples/**.py" = ["T201", "T203", "F841"]
# CLI tools can use print
"**/cli*.py" = ["T201", "T203"]
"**/__main__.py" = ["T201", "T203"]
# Specific file ignores
"pkg/hanzo-memory/src/hanzo_memory/db/base.py" = ["B027"]
"pkg/hanzo-dev-py/src/hanzo_dev/backends.py" = ["S603"]
"pkg/hanzo-dev-py/src/hanzo_dev/repl.py" = ["S605"]
"pkg/hanzo-dev-py/src/hanzo_dev/tests.py" = ["ARG001"]
"pkg/hanzo-dev-py/src/hanzo_dev/ipython_repl.py" = ["ARG002"]
"**/cli.py" = ["T201", "T203"]
# Test files
"**/test_*.py" = ["F401", "F841"]
"**/tests/**.py" = ["F401", "F841"]