[project] name = "posthog" version = "0.0.0" requires-python = "==3.12.11" # Leave patch version so that we don't accidentally upgrade minor versions dependencies = [ "aioboto3==15.4.0", "aiohttp==3.11.10", "aiokafka>=0.8", "anthropic==0.69.0", "antlr4-python3-runtime==4.13.1", "asyncstdlib==3.13.1", "beautifulsoup4==4.12.3", "boto3==1.40.49", "brotli==1.1.0", "celery==5.3.6", "celery-redbeat==2.1.1", "certifi==2025.8.3", "clickhouse-connect==0.8.17", "clickhouse-driver==0.2.9", "clickhouse-pool==0.5.3", "conditional-cache==1.2", "cryptography==39.0.2", "dagster==1.10.18", "dagster-cloud==1.10.18", "dagster-aws==0.26.18", "dagster-celery==0.26.18", "dagster-docker==0.26.18", "dagster-k8s==0.26.18", "dagster-pipes==1.10.18", "dagster-postgres==0.26.18", "dagster-slack==0.26.18", "dagster-webserver==1.10.18", "deltalake==0.25.2", "dj-database-url==0.5.0", "django~=4.2.26", "django-axes[ipware]==8.0.0", "django-cors-headers~=4.8.0", "django-deprecate-fields==0.1.1", "django-extensions~=4.1.0", "django-filter~=25.1", "django-loginas==0.3.11", "django-picklefield==3.0.1", "django-prometheus==2.2.0", "django-redis==6.0.0", "django-statsd==2.5.2", "django-structlog[celery]~=9.1.0", "django-two-factor-auth~=1.18.0", "djangorestframework~=3.16.1", "djangorestframework-csv~=3.0.2", "djangorestframework-dataclasses~=1.4.0", "dlt==1.3.0", "dnspython==2.2.1", "drf-exceptions-hog==0.4.0", "drf-extensions~=0.8.0", "drf-spectacular~=0.28.0", "emoji==2.14.1", "geoip2==4.6.0", "google-ads==26.1.0", "google-cloud-bigquery==3.26", "google-genai==1.46.0", "granian[uvloop,reload,pname]==2.5.5", "gspread==6.2.1", "hogql-parser==1.2.11", "infi-clickhouse-orm", "jsonref==1.1.0", "kafka-python==2.0.6", "kombu==5.3.7", "langchain==0.3.26", "langchain-community==0.3.27", "langchain-openai==0.3.33", "langchain-anthropic==0.3.22", "langgraph==0.4.10", "lxml==5.2.1", "lzstring==1.0.4", "markdown-it-py~=3.0.0", "mimesis==5.2.1", "mistralai==1.6.0", "more-itertools==9.0.0", "nanoid==2.0.0", "natsort==8.4.0", "nh3==0.2.14", "numpy~=2.1.0", "openai==1.109.1", "openpyxl==3.1.2", "orjson==3.10.15", "pandas~=2.2.2", "paramiko==3.4.0", "phonenumberslite==8.13.6", "pillow==10.2.0", "posthoganalytics==6.9.3", "psutil==6.0.0", "psycopg2-binary==2.9.10", "psycopg[binary]==3.2.4", "pyarrow==18.1.0", "pydantic==2.10.3", "pyjwt~=2.10.0", "pympler==1.1", "pymssql==2.3.5", "pymysql==1.1.1", "pymongo==4.13.2", "pyodbc==5.1.0", "python-dateutil>=2.8.2", "python-snappy~=0.7.3", "python3-saml==1.16.0", "pytz==2023.3", "redis==5.3.1", "requests~=2.32.3", "retry==0.9.2", "s3fs==2025.9.0", "scikit-learn~=1.5.0", "selenium==4.28.1", "semantic-version==2.8.5", "simple-salesforce>=1.12.6", "slack-sdk==3.17.1", "snowflake-connector-python==3.15.0", "snowflake-sqlalchemy==1.7.3", "social-auth-app-django~=5.4.0", "social-auth-core~=4.7.0", "django-scim2==0.19.0", "sqlalchemy==2.0.38", "sqlalchemy-bigquery[bqstorage]==1.12.1", "sqlparse==0.4.4", "sshtunnel==0.4.0", "statshog==1.0.6", "stripe==12.2.0", "structlog==25.4.0", "temporalio==1.14.1", "tenacity==9.1.2", "tiktoken==0.9.*", "token-bucket==0.3.0", "toronado==0.1.0", "tree-sitter==0.24.0", "click~=8.0", "tree-sitter-bash==0.23.3", "tree-sitter-go==0.23.4", "tree-sitter-javascript==0.23.1", "tree-sitter-python==0.23.6", "tree-sitter-rust==0.23.2", "tree-sitter-typescript==0.23.2", "types-cachetools==5.5.0.20240820", "tzlocal~=5.1", "webdriver-manager==4.0.2", "whitenoise~=6.10.0", "xmlsec==1.3.14", "zstd==1.5.7.2", "zxcvbn==4.4.28", "pyyaml==6.0.1", "chdb==3.3.0", "elevenlabs>=1.58.1", "django-oauth-toolkit>=3.0.1", "langchain-perplexity>=0.1.1", "azure-ai-projects>=1.0.0b11", "azure-ai-inference>=1.0.0b9", "opentelemetry-sdk==1.33.1", "opentelemetry-instrumentation-django==0.54b1", "opentelemetry-instrumentation-asgi==0.54b1", "opentelemetry-instrumentation-redis==0.54b1", "opentelemetry-instrumentation-psycopg==0.54b1", "opentelemetry-instrumentation-aiokafka==0.54b1", "opentelemetry-instrumentation-kafka-python==0.54b1", "opentelemetry-exporter-otlp-proto-grpc==1.33.1", "asgiref==3.8.1", "claude-code-sdk>=0.0.14", "user-agents>=2.2.0", "django-admin-inline-paginator===0.4.0", "fastavro>=1.12.0", "pydantic-avro>=0.9.0", "playwright>=1.54.0", "linkedin-api-client>=0.3.0", "glom>=24.11.0", "aiobotocore>=2.7.0", "modal>=1.2.1", "databricks-sql-connector~=4.1.3", "databricks-sdk~=0.67.0", "litellm>=1.77.7", "free-email-domains>=1.0.1", "disposable-email-domains>=0.0.140", "pymediainfo>=7.0.1", "cachetools>=5.5.2", "textcase>=0.4.5", "gitpython>=3.1.44", ] [dependency-groups] dev = [ "aioresponses==0.7.6", "autoevals==0.0.129", "black~=23.9.1", "boto3-stubs[s3]>=1.34.84", "braintrust==0.2.4", "braintrust-langchain==0.0.4", "dagster-dg-cli>=1.10.18", "datamodel-code-generator==0.28.5", "debugpy>=1.8.0", "deepdiff>=8.5.0", "django-linear-migrations~=2.17.0", "django-stubs~=5.2.0", "djangorestframework-stubs~=3.16.0", "faker==17.5.0", "fakeredis[lua]==2.23.3", "flaky==3.7.0", "freezegun==1.2.2", "inline-snapshot==0.19.*", "ipython>=9.3.0", "mypy~=1.18.2", "mypy-baseline~=0.7.3", "mypy-extensions~=1.1.0", "ty==0.0.1a22", # openapi-spec-validator needed for prance as a validation backend "openapi-spec-validator==0.7.1", "orjson==3.10.15", "packaging==24.1", "parameterized==0.9.0", "prance==23.6.21.0", "pyarrow==18.1.0", "pyarrow-stubs==17.16", "pytest==8.0.2", "pytest-asyncio==0.21.1", "pytest-cov==4.1.0", "pytest-django~=4.11.1", "pytest-env==0.8.2", "pytest-icdiff==0.6", "pytest-mock==3.15.0", "pytest-split==0.9.0", "pytest-watch==4.2.0", "pytest-xdist==3.6.1", "python-dateutil>=2.8.2", "requests-mock>=1.12.1", "responses==0.23.1", "ruff~=0.8.1", "sqlalchemy==2.0.38", "stpyv8==13.1.201.22; sys_platform != 'linux' or (platform_machine != 'aarch64' and platform_machine != 'arm64')", "syrupy~=4.9.1", "tach~=0.20.0", "types-aioboto3[s3]>=14.3.0", "types-aiobotocore>=2.22.0", "types-boto3[essential]==1.37.6", "types-freezegun==1.1.10", "types-markdown==3.3.9", "types-paramiko==3.4.0.20240423", "types-pymysql==1.1.0.20240524", "types-python-dateutil>=2.8.3", "types-pytz==2023.3", "types-pyyaml==6.0.1", "types-redis==4.6.0.20241004", # >= 2.31.0.7 versions of types-requests require urllib>=2, which is incompatible with our dependencies "types-requests==2.31.0.6", "types-retry==0.9.9.4", "types-tzlocal~=5.1.0.1", "watchdog==5.0.3", ] [tool.uv] required-version = ">=0.7.0" [tool.uv.sources] infi-clickhouse-orm = { git = "https://github.com/PostHog/infi.clickhouse_orm", rev = "9578c79f29635ee2c1d01b7979e89adab8383de2" } [tool.black] line-length = 120 target-version = ['py312'] [tool.isort] profile = "black" [tool.ruff] line-length = 120 exclude = [ ".git", "./plugin-server/node_modules/", "./plugins/node_modules/", "./env", "./posthog/hogql/grammar", ] [tool.ruff.lint] ignore = [ "B017", "B019", "B904", "B905", "C901", "E501", "E722", "E731", "F403", "F541", "F601", "UP007", "UP032", ] select = [ "B", "C4", "C9", "DJ012", "E", "F", "I", "RUF005", "RUF013", "RUF015", "RUF019", "T100", "T2", "TRY201", "TRY400", "UP", "W", ] [tool.ruff.lint.mccabe] max-complexity = 10 [tool.ruff.lint.isort] combine-as-imports = true force-wrap-aliases = true length-sort-straight = true split-on-trailing-comma = false section-order = [ "future", "standard-library", "testing", "django", "third-party", "posthog.schema", "posthog.hogql", "posthog", "products", "first-party", "local-folder", ] [tool.ruff.lint.isort.sections] "django" = ["django"] # Group all Django imports into a separate section. "testing" = [ # Group all testing imports into a separate section. "freezegun", "pytest", "unittest", "posthog.test.base", ] # Separate groups for our own stuff "posthog.schema" = ["posthog.schema"] "posthog.hogql" = ["posthog.hogql"] "posthog" = ["posthog"] "products" = ["products"] [tool.dagster] python_version = "3.12" [tool.mypy-baseline] sort_baseline = true ignore_categories = ["note"] [tool.ty.environment] python-version = "3.12" [tool.ty.src] exclude = [ "bin/**", "manage.py", "posthog/hogql/grammar/**", ] [tool.ty.rules] # Import resolution - ty can't always find all modules/stubs unresolved-import = "ignore" # Django-related rules - ty doesn't support Django's metaprogramming yet # See: https://github.com/astral-sh/ty/issues/291 unresolved-attribute = "ignore" # Django model fields, relationships, auto-generated attributes invalid-argument-type = "ignore" # Django querysets, managers, form fields invalid-base = "ignore" # Django model metaclasses (e.g., models.Model)