# ----------------------------------------------------------------
# 💡 Build system (PEP 517)
#     - setuptools ≥ 77 gives SPDX licence support (PEP 639)
#     - wheel is needed by most build front-ends
# ----------------------------------------------------------------
[build-system]
requires = ["setuptools>=77", "wheel"]
build-backend = "setuptools.build_meta"

# ----------------------------------------------------------------
# 📦 Core project metadata (PEP 621)
# ----------------------------------------------------------------
[project]
name = "mcp-contextforge-gateway"
version = "0.3.1"
description = "A production-grade MCP Gateway & Proxy built with FastAPI. Supports multi-server registration, virtual server composition, authentication, retry logic, observability, protocol translation, and a unified federated tool catalog."
keywords = ["MCP","API","gateway","proxy","tools",
  "agents","agentic ai","model context protocol","multi-agent","fastapi",
  "json-rpc","sse","websocket","federation","security","authentication"
]
classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Developers",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Framework :: FastAPI",
    "Framework :: AsyncIO",
    "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
    "Topic :: Software Development :: Libraries :: Application Frameworks"
]
readme = "README.md"
requires-python = ">=3.11,<3.14"

# SPDX licence expression + explicit licence file (PEP 639)
license = "Apache-2.0"
license-files = ["LICENSE"]

# Maintainers
maintainers = [
    {name = "Mihai Criveti", email = "redacted@ibm.com"}
]

# ----------------------------------------------------------------
# Runtime dependencies
# ----------------------------------------------------------------
dependencies = [
    "alembic>=1.16.4",
    "cryptography>=45.0.5",
    "fastapi>=0.116.0",
    "filelock>=3.18.0",
    "gunicorn>=23.0.0",
    "httpx>=0.28.1",
    "jinja2>=3.1.6",
    "jq>=1.9.1",
    "jsonpath-ng>=1.7.0",
    "jsonschema>=4.24.0",
    "mcp>=1.11.0",
    "parse>=1.20.2",
    "psutil>=7.0.0",
    "pydantic>=2.11.7",
    "pydantic-settings>=2.10.1",
    "pyjwt>=2.10.1",
    "sqlalchemy>=2.0.41",
    "sse-starlette>=2.4.1",
    "starlette>=0.46.2",
    "uvicorn>=0.35.0",
    "zeroconf>=0.147.0",
]

# ----------------------------------------------------------------
# Optional dependency groups (extras)
# ----------------------------------------------------------------
[project.optional-dependencies]

# Optional dependency groups (runtime)
redis = [
    "redis>=6.2.0",
]

postgres = [
    "psycopg2-binary>=2.9.10",
]

alembic = [
    "alembic>=1.16.4",
]

# Async SQLite Driver (optional)
aiosqlite = [
    "aiosqlite>=0.21.0",
]

# Async PostgreSQL driver (optional)
asyncpg = [
    "asyncpg>=0.30.0",
]

# Optional dependency groups (development)
dev = [
    "argparse-manpage>=4.6",
    "autoflake>=2.3.1",
    "bandit>=1.8.6",
    "black>=25.1.0",
    "bump2version>=1.0.1",
    "check-manifest>=0.50",
    "code2flow>=2.5.1",
    "cookiecutter>=2.6.0",
    "coverage>=7.9.2",
    "coverage-badge>=1.1.2",
    "darglint>=1.8.1",
    "fawltydeps>=0.20.0",
    "flake8>=7.3.0",
    "gprof2dot>=2025.4.14",
    "importchecker>=3.0",
    "isort>=6.0.1",
    "mypy>=1.16.1",
    "pexpect>=4.9.0",
    "pip-licenses>=5.0.0",
    "pip_audit>=2.9.0",
    "pre-commit>=4.2.0",
    "pydocstyle>=6.3.0",
    "pylint>=3.3.7",
    "pylint-pydantic>=0.3.5",
    "pyre-check>=0.9.25",
    "pyrefly>=0.23.1",
    "pyright>=1.1.403",
    "pyroma>=4.3.3",
    "pyspelling>=2.10",
    "pytest>=8.4.1",
    "pytest-asyncio>=1.0.0",
    "pytest-cov>=6.2.1",
    "pytest-examples>=0.0.18",
    "pytest-md-report>=0.7.0",
    "pytest-rerunfailures>=15.1",
    "pytest-xdist>=3.8.0",
    "pytype>=2024.10.11",
    "radon>=6.0.1",
    "redis>=6.2.0",
    "ruff>=0.12.2",
    "settings-doc>=4.3.2",
    "snakeviz>=2.2.2",
    "tomlcheck>=0.2.3",
    "tox>=4.27.0",
    "tox-uv>=1.26.1",
    "twine>=6.1.0",
    "ty>=0.0.1a14",
    "types-tabulate>=0.9.0.20241207",
    "uv>=0.7.20",
    "yamllint>=1.37.1",
]

# Convenience meta-extras
all = [
    "mcp-contextforge-gateway[redis]>=0.3.1",
]
dev-all = [
    "mcp-contextforge-gateway[redis,dev]>=0.3.1",
]

# --------------------------------------------------------------------
#  Authors and URLs
# --------------------------------------------------------------------
[[project.authors]]
name = "Mihai Criveti"
email = "redacted@ibm.com"

[project.urls]
Homepage = "https://ibm.github.io/mcp-context-forge/"
Documentation = "https://ibm.github.io/mcp-context-forge/"
Repository = "https://github.com/IBM/mcp-context-forge"
"Bug Tracker" = "https://github.com/IBM/mcp-context-forge/issues"
Changelog = "https://github.com/IBM/mcp-context-forge/blob/main/CHANGELOG.md"

# --------------------------------------------------------------------
#  💻 Project scripts (cli entrypoint)
# --------------------------------------------------------------------
[project.scripts]
mcpgateway = "mcpgateway.cli:main"

# --------------------------------------------------------------------
#  🔧 setuptools-specific configuration
# --------------------------------------------------------------------
[tool.setuptools]
include-package-data = true          # ensure wheels include the data files

# Automatic discovery: keep every package that starts with "mcpgateway"
[tool.setuptools.packages.find]
include = ["mcpgateway*"]
exclude = ["tests*"]

##  Runtime data files  ------------------------------------------------
#  - py.typed  -> advertises inline type hints (PEP 561)
#  - static/*  -> CSS/JS for the admin UI
#  - templates -> Jinja2 templates shipped at runtime
[tool.setuptools.package-data]
mcpgateway = [
  "py.typed",
  "static/*.css",
  "static/*.js",
  "templates/*.html",
  "alembic.ini",
  "alembic/*.py",
  "alembic/*.mako",
  "alembic/*.md",
  "alembic/versions/*.py",
]

# --------------------------------------------------------------------
#  🛠  Tool configurations (black, mypy, etc.)
# --------------------------------------------------------------------
[tool.pytype]
# Directory-specific options:
inputs = ["mcpgateway"]
python_version = "3.11"          # match default runtime

[tool.check-manifest]
ignore = [
    "docs/**",
    "tests/**",
    ".github/**",
    "Makefile",
]

[tool.black]
line-length = 200
target-version = ["py310", "py311", "py312"]
include = "\\.pyi?$"

# isort configuration
[tool.isort]
###############################################################################
# Core behaviour
###############################################################################
profile                    = "black"      # inherit Black's own import-sorting profile
line_length                = 200          # match Black's custom line length
multi_line_output          = 3            # vertical-hanging-indent style
include_trailing_comma     = true         # keep trailing commas for Black
from_first                 = true         # place all "from ... import ..." before plain "import ..."

###############################################################################
# Section ordering & headings
###############################################################################
sections                   = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
import_heading_future      = "Future"       # header above FUTURE imports (if headings enabled)
import_heading_stdlib      = "Standard"     # header for built-in Stdlib imports
import_heading_thirdparty  = "Third-Party"  # header for pip-installed packages
import_heading_firstparty  = "First-Party"  # header for internal 'mcpgateway' code
import_heading_localfolder = "Local"        # header for ad-hoc scripts / tests

###############################################################################
# What belongs where
###############################################################################
known_first_party          = ["mcpgateway"]    # treat "mcpgateway.*" as FIRSTPARTY
known_local_folder         = ["tests", "scripts"]  # treat these folders as LOCALFOLDER
# src_paths                = ["src/mcpgateway"]    # uncomment only if package moves under src/

###############################################################################
# Style niceties
###############################################################################
force_sort_within_sections = true         # always alphabetise names inside each block
order_by_type              = false        # don't group imports by "type vs. straight name"
balanced_wrapping          = true         # spread wrapped imports evenly between lines
lines_between_sections     = 1            # exactly one blank line between the five groups
lines_between_types        = 1            # one blank line between 'import X' and 'from X import ...'
no_lines_before            = ["LOCALFOLDER"]  # suppress blank line *before* the LOCALFOLDER block
ensure_newline_before_comments = true     # newline before any inline # comment after an import

###############################################################################
# Ignore junk we never want to touch
###############################################################################
extend_skip                = [
  ".md", ".json", ".yaml", ".yml",
  "dist", "build", ".venv", ".tox",
  "*.tmp", "*.bak",
]
skip_glob                  = ["**/__init__.py"]  # leave namespace init files alone

# ---- Optional CI toggles ----------------------------------------------------
# check_only             = true    # dry-run mode: non-zero exit if files would change
# verbose                = true    # print every file name processed
# case_sensitive         = true    # treat upper/lowercase differences as significant

[tool.mypy]
# Target Python version
python_version = "3.11"

# Full strictness and individual checks
strict = true                           # Enable all strict checks

check_untyped_defs = true              # Type-check the bodies of untyped functions
no_implicit_optional = true            # Require explicit Optional for None default
disallow_untyped_defs = true           # Require type annotations for all functions
disallow_untyped_calls = true          # Disallow calling functions without type info
disallow_any_unimported = true         # Disallow Any from missing imports
warn_return_any = true                 # Warn if a function returns Any
warn_unreachable = true                # Warn about unreachable code
warn_unused_ignores = true             # Warn if a "# type: ignore" is unnecessary
warn_unused_configs = true             # Warn about unused config options
warn_redundant_casts = true            # Warn if a cast does nothing
strict_equality = true                 # Disallow ==/!= between incompatible types

# Output formatting
show_error_codes = true                # Show error codes in output
pretty = true                          # Format output nicely

# Exclude these paths from analysis
exclude = [
  '^build/',
  '^\\.venv/',
  '^\\.mypy_cache/',
]

[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra -q --cov=mcpgateway"
testpaths = [ "tests",]
asyncio_mode = "auto"
filterwarnings = [
  "ignore:Passing 'msg' argument to .*\\.cancel\\(\\) is deprecated:DeprecationWarning", # From 3rd party libraries
]

# ── fawltydeps ─────────────────────────────────────────────────────
[tool.fawltydeps]
# only parse main pyproject.toml
deps = ["pyproject.toml"]

# ignore 'dev' extras so they won't show up in fawltydeps
ignore_unused = [
  "autoflake",
  "argparse-manpage",
  "bandit",
  "black",
  "bump2version",
  "check-manifest",
  "code2flow",
  "cookiecutter",
  "coverage",
  "coverage-badge",
  "darglint",
  "flake8",
  "fawltydeps",
  "gprof2dot",
  "gunicorn",
  "importchecker",
  "isort",
  "ty",
  "tomlcheck",
  "mypy",
  "pexpect",
  "pip-licenses",
  "pip_audit",
  "pre-commit",
  "pydocstyle",
  "pylint",
  "pylint-pydantic",
  "pyre-check",
  "pyright",
  "pyroma",
  "pyspelling",
  "pytest",
  "pytest-asyncio",
  "pytest-cov",
  "pytest-examples",
  "pytest-md-report",
  "pytest-rerunfailures",
  "pytest-xdist",
  "pytype",
  "radon",
  "ruff",
  "settings-doc",
  "snakeviz",
  "types-tabulate",
  "twine",
  "uvicorn"
]

# --------------------------------------------------------------------
#  🛠  https://github.com/facebook/pyrefly (replaces pyre)
# --------------------------------------------------------------------
[tool.pyrefly]
project-excludes = [
    "**/build/",
    '**/\.venv/',
    '**/\.mypy_cache/',
]
python-version = "3.11.0"
