[build-system]
requires = ["setuptools>=61.0", "wheel", "setuptools-scm>=8.0"]
build-backend = "setuptools.build_meta"
# Note: setup.py provides custom build commands to build UI before packaging

[project]
name = "pycharter"
dynamic = ["version"]
description = "A Python package for data contract management with five core services: contract parsing, metadata storage, Pydantic generation, JSON Schema conversion, and runtime validation"
readme = "README.md"
requires-python = ">=3.11"
license = "MIT"
dependencies = [
    "pydantic>=2.0.0",
    "jsonschema>=4.0.0",
    "pandas>=2.0.0",
    "numpy>=1.24.0",
    "pyyaml>=6.0.0",
    "sqlalchemy>=2.0.0",
    "alembic>=1.13.0",
    "jsonata-python>=0.6.0",  # JSONata transformation engine
    "httpx>=0.24.0",  # HTTP extractor (core ETL)
]
authors = [
    {name = "semantic developers", email = "na@example.com"},
]
keywords = ["semantic", "python", "pydantic", "contract", "validation", "schema"]
classifiers = [
    "Development Status :: 3 - Alpha",
    "Intended Audience :: Developers",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
]

[project.urls]
Homepage = "https://github.com/optophi/pycharter"
Documentation = "https://optophi.github.io/pycharter/"
Repository = "https://github.com/optophi/pycharter"
Issues = "https://github.com/optophi/pycharter/issues"

[tool.setuptools_scm]
# Version from Git tags (e.g. v1.2.3 -> 1.2.3). Untagged commits get a dev version.

[project.optional-dependencies]
# ---------------------------------------------------------------------------
# Install extras:
#   pip install pycharter              → core library only
#   pip install pycharter[api]         → + REST API server
#   pip install pycharter[worker]      → + background worker
#   pip install pycharter[ui]          → + UI server
#   pip install pycharter[all]         → api + worker + ui + etl + postgres + docs
#   pip install pycharter[dev]         → all + testing & dev tools
#   pycharter docs serve / docs build  → requires [docs] extra
# ---------------------------------------------------------------------------

# --- Service extras (identical interface across pycharter/pystator/pyoptima) ---
api = [
    "fastapi>=0.104.0",
    "uvicorn[standard]>=0.24.0",
    "pydantic-settings>=2.0.0",
    "python-multipart>=0.0.6",
    "PyJWT>=2.8.0",
    "httpx>=0.24.0",
]
worker = [
    # Worker uses only SQLAlchemy (core dep) -- no extra install needed.
    # This extra is kept for interface consistency with pystator/pyoptima.
]
ui = [
    "fastapi>=0.104.0",
    "uvicorn[standard]>=0.24.0",
    "httpx>=0.24.0",
    "aiofiles>=23.0.0",
]

# --- Package-specific extras ---
postgres = [
    "psycopg2-binary>=2.9.0",
]
etl = [
    "sshtunnel>=0.4.0",
    "boto3>=1.26.0",
    "google-cloud-storage>=2.0.0",
    "azure-storage-blob>=12.0.0",
    "openpyxl>=3.0.0",
    "lxml>=4.9.0",
    "pyarrow>=14.0.0",
    "pymongo>=4.0.0",
]
docs = [
    "mkdocs>=1.5.3,<2",
    "mkdocs-material>=9.5.0",
    "mkdocstrings[python]>=0.24.0",
    "pymdown-extensions>=10.0.0",
    "mike>=2.0.0",
]
ontology = [
    "rdflib>=7.0.0",
    "pyshacl>=0.26.0",
]
lineage = [
    "openlineage-python>=1.0.0",
]
streaming = [
    "websockets>=12.0",
    "watchfiles>=0.21.0",
]
kafka = [
    "aiokafka>=0.9.0",
]
rabbitmq = [
    "aio-pika>=9.0.0",
]
messaging = [
    "pycharter[kafka,rabbitmq]",
]

# --- Aggregate extras ---
all = [
    "pycharter[api,worker,ui,etl,postgres,docs,ontology,lineage,streaming,messaging]",
]
dev = [
    "pycharter[all]",
    "PyJWT>=2.8.0",  # required by api auth; tests import api routes
    "pytest>=7.0.0",
    "pytest-asyncio>=0.21.0",
    "pytest-cov>=4.0.0",
    "black==26.1.0",
    "isort==5.13.2",
    "mypy>=1.0.0",
    "pre-commit>=3.0.0",
    "build>=0.10.0",
    "twine>=4.0.0",
    "jupyterlab>=4.0.0",
    "ipykernel>=6.0.0",
    "pymongo>=4.0.0",
    "boto3>=1.26.0",
]

[tool.setuptools.packages.find]
where = ["src"]
include = ["pycharter*"]
# Exclude UI static/out so they are never treated as packages (only package-data)
exclude = ["pycharter.ui.static*", "pycharter.ui.out*"]

[tool.setuptools.package-data]
pycharter = [
    "py.typed",
    # Migration files and templates
    "db/migrations/versions/*.py",
    "db/migrations/env.py",
    "db/migrations/script.py.mako",
    "db/migrations/README",
    # Template files (contract artifacts; ETL configs)
    "data/templates/contract/*.yaml",
    "data/templates/etl/*.yaml",
    "data/templates/etl/README.md",
    # Default seed data for pycharter db seed
    "data/seed/*.yaml",
    # Ontology context and SHACL shapes
    "data/ontology/context/*.jsonld",
    "data/ontology/shapes/*.ttl",
    # UI static files (build with: pycharter ui build)
    "ui/static/*",
    "ui/static/**/*",
]

[project.scripts]
pycharter = "pycharter.cli:main"

[tool.black]
line-length = 88
target-version = ['py310']

[tool.isort]
profile = "black"

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
addopts = [
    "-v",
    "--strict-markers",
    "--tb=short",
]
markers = [
    "slow: marks tests as slow (deselect with '-m \"not slow\"')",
    "integration: marks tests as integration tests",
    "unit: marks tests as unit tests",
]
filterwarnings = [
    "error",
    "ignore::UserWarning",
]

