[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "langgraph-sdk"
dynamic = ["version"]
description = "SDK for interacting with LangGraph API"
authors = []
requires-python = ">=3.10"
readme = "README.md"
license = "MIT"
license-files = ['LICENSE']
dependencies = [
    "httpx>=0.25.2",
    "orjson>=3.11.5",
    "langchain-protocol>=0.0.15",
    "langchain-core>=1.4.0,<2",
    "websockets>=14,<17",
]

[tool.hatch.version]
path = "langgraph_sdk/__init__.py"

[project.urls]
Source = "https://github.com/langchain-ai/langgraph/tree/main/libs/sdk-py"
Twitter = "https://x.com/langchain_oss"
Slack = "https://www.langchain.com/join-community"
Reddit = "https://www.reddit.com/r/LangChain/"

[dependency-groups]
test = [
    "pytest",
    "pytest-asyncio",
    "pytest-mock",
    "pytest-watch",
]
lint = [
    "ruff==0.15.20",
    "codespell",
    "ty",
    "starlette",
]
dev = [
  { include-group = "test" },
  { include-group = "lint" },
  "langgraph",
  "pydantic>=2.12.4",
]

[tool.hatch.build.targets.wheel]
include = ["langgraph_sdk"]

[tool.pytest.ini_options]
addopts = "--strict-markers --strict-config --durations=5 -vv -m 'not integration'"
asyncio_mode = "auto"
markers = [
    "integration: end-to-end tests that require a running langgraph-api stack at http://localhost:2024. Excluded from `make test` by default; opt in with `pytest -m integration` (and the autouse fixture skips if the API is unreachable).",
]

[tool.uv]
default-groups = ['dev']

[tool.uv.sources]
langgraph = { path = "../langgraph", editable = true }

[tool.ruff]
exclude = ["venv", ".venv", "build", "dist"]
[tool.ruff.lint]
select = [
  "E",      # pycodestyle errors
  "F",      # pyflakes
  "I",      # isort (import sorting)
  "ARG",    # unused arguments
  "TID251", # banned imports
  "TID252", # banned relative imports
  "T20",    # print statements
  "UP",     # pyupgrade (Python version-specific fixes)
  "B",      # flake8-bugbear (common bugs)
  "SIM",    # flake8-simplify (code simplification)
  "RUF",    # ruff-specific rules
  "S101",   # flake8-bandit: use of assert
]
ignore = [
  "E501",   # line too long (handled by formatter)
  "B006",   # mutable default arguments (sometimes intentional)
  "B904",   # raise without from inside except (sometimes intentional)
  "SIM102", # nested if statements (sometimes clearer)
]
per-file-ignores = { "tests/**" = ["S101", "B017"], "integration/**" = ["S101", "T20", "B017", "ARG001", "ARG002"] }

[tool.ty.src]
# The `integration/` graphs run inside the docker image (with `deepagents`
# and other graph-only deps installed there) and are not part of the SDK
# package surface, so we don't typecheck them in the sdk-py venv.
exclude = ["integration"]

[tool.ty.rules]
no-matching-overload = "ignore"
