# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. [build-system] requires = ["setuptools>=40.9.0", "wheel"] build-backend = "setuptools.build_meta" [project] name = "apache_superset" description = "A modern, enterprise-ready business intelligence web application" readme = "README.md" dynamic = ["version", "scripts", "entry-points"] requires-python = ">=3.11" license = { file="LICENSE.txt" } authors = [ { name = "Apache Software Foundation", email = "dev@superset.apache.org" }, ] classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", ] dependencies = [ # no bounds for apache-superset-core until we have a stable version "apache-superset-core", "backoff>=1.8.0", # cachetools is used directly by ``superset.db_engine_specs.aws_iam`` (TTLCache). # It used to be installed transitively via ``google-auth`` (<2.53), but # ``google-auth`` 2.53+ dropped it, so Superset must declare it # explicitly to keep fresh ``pip install apache-superset`` working # without the ``base.txt`` lock file (#40962). "cachetools>=7.1.7, <8", "celery>=5.6.3, <6.0.0", "click>=8.4.2", "click-option-group", "colorama", "flask-cors>=6.0.5, <7.0", "croniter>=6.2.4", "cron-descriptor", "cryptography>=50.0.0, <51.0.0", "deprecation>=2.1.0, <2.2.0", "flask>=2.2.5, <4.0.0", "flask-appbuilder>=5.2.2, <6.0.0", "flask-caching>=2.4.1, <3", "flask-compress>=1.13, <2.0", "flask-talisman>=1.0.0, <2.0", "flask-login>=0.6.0, < 1.0", "flask-migrate>=4.1.0, <5.0", "flask-session>=0.4.0, <1.0", # Bumped to 3.1.1 alongside the SQLAlchemy 2.0 core bump (discussion # #40273, step 6), which resolves the session/app-context handling # across Celery task boundaries that previously blocked this (see # PR #42542). "flask-sqlalchemy>=3.1.1, <4.0", "flask-wtf>=1.3.0, <2.0", "geopy", "greenlet<=3.5.4, >=3.5.4", "gunicorn>=26.0.0, <27; sys_platform != 'win32'", "hashids>=1.3.1, <2", # holidays>=0.45 required for security fix "holidays>=0.101, <1", "humanize", "isodate", "jsonpath-ng>=1.8.0, <2", "Mako>=1.4.1", "markdown>=3.10.3", # marshmallow 4 compatibility: see superset/marshmallow_compatibility.py for a # Flask-AppBuilder workaround. Tracking issue: # https://github.com/apache/superset/issues/33162 "marshmallow>=3.0, <5", "marshmallow-union>=0.1.15.post1", "msgpack>=1.2.0, <1.3", "nh3>=0.3.5, <0.4", "numpy>=1.23.5, <2.5", "packaging", # -------------------------- # pandas and related (wanting pandas[performance] without numba as it's 100+MB and not needed) "pandas[excel]>=2.3.3, <2.4", "bottleneck", # recommended performance dependency for pandas, see https://pandas.pydata.org/docs/getting_started/install.html#performance-dependencies-recommended # -------------------------- "parsedatetime", "paramiko>=3.4.0, <4.0", # 4.0 removed DSSKey, still referenced by sshtunnel "pgsanity", "Pillow>=12.3.0, <13", # raise floor to match resolved pin; closes SCA false-positive on 11.x-range CVEs already fixed in 12.3.0 "polyline>=2.0.4, <3.0", "pydantic>=2.8.0", "pyparsing>=3.3.2, <4", "python-dateutil", "python-dotenv", # optional dependencies for Flask but required for Superset, see https://flask.palletsprojects.com/en/stable/installation/#optional-dependencies "pygeohash", "pyarrow>=25.0.1, <26", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693 "pyyaml>=6.0.3, <7.0.0", "PyJWT>=2.13.0, <3.0", # raise floor to match resolved pin; closes SCA false-positive on 2.4.x-range CVEs already fixed in 2.13.0 "redis>=5.0.0, <9.0", "rison>=2.0.1, <3.0", "shillelagh[gsheetsapi]>=1.4.5, <2.0", "sshtunnel>=0.4.0, <0.5", "simplejson>=4.1.1", "slack_sdk>=3.43.0, <4", "sqlalchemy>=2.0.52, <2.1", "sqlalchemy-continuum>=1.6.0, <2.0.0", "sqlalchemy-utils>=0.42.1, <0.43", # expanding lowerbound to work with pydoris "sqlglot>=30.17.0, <31", # 30.16.0 adds Trino inline UDF IF/CASE routine statement parsing # newer pandas needs 0.9+ "tabulate>=0.10.0, <1.0", "typing-extensions>=4.16.0, <5", "waitress; sys_platform == 'win32'", "watchdog>=6.0.0", "wtforms>=3.2.2, <4", "wtforms-json", "xlsxwriter>=3.2.9, <3.3", ] [project.optional-dependencies] athena = ["pyathena[pandas]>=3.35.4, <4"] # No SQLAlchemy 2.0 support anywhere in this dialect's ecosystem today: our # own preset-io/sqlalchemy-aurora-data-api fork is dead since 2021, and the # more active community fork (cloud-utils/sqlalchemy-aurora-data-api) has an # unresolved SQLAlchemy 2.0 break (upstream issue #43). See # superset/db_engine_specs/aurora.py's known_incompatibilities metadata. aurora-data-api = ["preset-sqlalchemy-aurora-data-api>=0.2.8,<0.3"] bigquery = [ "pandas-gbq>=0.35.1", # 1.17.1 is likely the final release: googleapis/python-bigquery-sqlalchemy # was archived 2026-05-16. Both 1.17.0 and 1.17.1 support SQLAlchemy 1.4/2.0. "sqlalchemy-bigquery>=1.17.2", "google-cloud-bigquery>=3.42.3", ] clickhouse = ["clickhouse-connect>=1.7.2, <2.0"] # The `cockroachdb` PyPI package (last released 2021) is abandoned and its # SQLAlchemy dialect cannot even import under SQLAlchemy 2.0 (it references # sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2, removed in # 2.0). sqlalchemy-cockroachdb is the actively maintained replacement, # already linked from CockroachDbEngineSpec.metadata's docs_url, and # registers the same `cockroachdb` SQLAlchemy dialect entry point. # sqlalchemy-cockroachdb depends only on SQLAlchemy itself, not on a DBAPI # driver, so psycopg2-binary is pinned alongside it (matching the `postgres` # extra) to keep this extra self-contained -- CockroachDB speaks the # PostgreSQL wire protocol, so psycopg2 is what actually opens connections. cockroachdb = ["sqlalchemy-cockroachdb>=2.0.0, <3", "psycopg2-binary==2.9.12"] crate = ["sqlalchemy-cratedb>=0.43.1, <1"] # sqlalchemy-d1's only release (0.1.0, Nov 2025) pins sqlalchemy<2,>=1.4, # explicitly excluding SQLAlchemy 2.0. See superset/db_engine_specs/d1.py's # known_incompatibilities metadata. d1 = [ "superset-engine-d1>=0.1.0", "sqlalchemy-d1>=0.1.0", "dbapi-d1>=0.1.0", ] databend = ["databend-sqlalchemy>=0.5.5, <1.0"] databricks = [ "databricks-sql-connector>=4.4.0, <4.5.0", "databricks-sqlalchemy==1.0.5", ] datafusion = ["flightsql-dbapi>=0.2.2, <0.3"] db2 = ["ibm-db-sa<=0.4.4, >=0.4.4"] denodo = ["denodo-sqlalchemy>=2.0.5,<2.1.0"] # sqlalchemy-dremio 3.0.5+ hard-pins sqlalchemy~=2.0.41, dropping 1.4. # Widened now that Superset's own SQLAlchemy 2.0 core bump has landed # (discussion #40273). dremio = ["sqlalchemy-dremio>=3.0.5, <4"] # <2 was an artificial ceiling; upstream has no SQLAlchemy version cap and # 1.1.10 already supports SQLAlchemy 2.0 (added `import_dbapi` in 1.1.7). drill = ["sqlalchemy-drill>=1.1.10, <3"] druid = ["pydruid>=0.6.5,<0.7"] duckdb = ["duckdb>=1.5.5,<2", "duckdb-engine>=0.17.0"] dynamodb = ["pydynamodb>=0.8.2"] # Effectively unmaintained (only dependabot bumps since 2024); hard-pinned to # SQLAlchemy ~1.4.7 upstream, no SQLAlchemy 2.0 work. See # superset/db_engine_specs/solr.py's known_incompatibilities metadata. solr = ["sqlalchemy-solr>=0.2.4.3"] elasticsearch = ["elasticsearch-dbapi>=0.2.13, <0.3.0"] # sqlalchemy-exasol cuts hard from SQLAlchemy 1.4-only (<6.0.0) to 2.0-only # (>=6.0.0) with no dual-compat release. Bumped now that Superset's own # SQLAlchemy 2.0 core bump has landed (discussion #40273). exasol = ["sqlalchemy-exasol>=6.0.0, <8.0"] excel = ["xlrd>=2.0.2, <2.1"] # Async dashboard "Export Data/Images to Excel": uploads the workbook to S3 and # emails a pre-signed link. boto3 is imported lazily by superset.utils.s3, so # installing this extra is only required to actually run exports. excel-export = ["boto3"] fastmcp = [ "fastmcp>=3.4.7,<4.0", "mcp>=1.29.1,<3.0", # tiktoken backs the response-size-guard token estimator. Without # it, the middleware falls back to a coarser character-based # heuristic that under-counts JSON-heavy MCP responses. "tiktoken>=0.14.0,<1.0", ] # sqlalchemy-firebird >=2.0.0 unconditionally requires SQLAlchemy 2.0 on # Python >=3.8 (which covers Superset's >=3.11 floor), with no dual-compat # release. Bumped now that Superset's own SQLAlchemy 2.0 core bump has # landed (discussion #40273). firebird = ["sqlalchemy-firebird>=2.2.0"] firebolt = ["firebolt-sqlalchemy>=1.1.2, <2"] gevent = ["gevent>=26.8.0"] gsheets = ["shillelagh[gsheetsapi]>=1.4.5, <2"] hana = ["hdbcli==2.29.25", "sqlalchemy_hana==3.0.3"] hive = [ "pyhive[hive_pure_sasl]>=0.7.0", "tableschema", "thrift>=0.24.0, <1.0.0", "thrift_sasl>=0.4.3, < 1.0.0", ] impala = ["impyla>=0.24.0, <0.25"] # Actively maintained upstream, but setup.py on main hard-pins # sqlalchemy==1.4.*, no SQLAlchemy 2.0 work yet. See # superset/db_engine_specs/kusto.py's known_incompatibilities metadata. kusto = ["sqlalchemy-kusto>=3.1.2, <4"] kylin = ["kylinpy>=2.8.4, <2.9"] mssql = ["pymssql>=2.3.13, <3"] # motherduck is an alias for duckdb - MotherDuck works via the duckdb driver motherduck = ["apache-superset[duckdb]"] mysql = ["mysqlclient>=2.2.8, <3"] ocient = [ # Closed-source vendor package with no public changelog; permissive # unpinned sqlalchemy>=1.4 declared. Verified compatible with SQLAlchemy # 2.0 against pyocient>=3.9.0 (discussion #40273): dialect construction, # error extraction, and GIS-type sanitization all pass under 2.0.52. Note # pyocient 3.9.0 relocated its geo-type classes from private top-level # names (pyocient._STPoint) to public ones under pyocient.api # (pyocient.api.STPoint), which is unrelated to the SQLAlchemy bump. "sqlalchemy-ocient>=3.0.0, <4", "pyocient>=3.9.0, <4", "shapely", "geojson", ] oracle = ["oracledb>=4.0.2, <5"] parseable = ["sqlalchemy-parseable>=0.1.6,<0.2.0"] pinot = ["pinotdb>=5.0.0, <10.0.0"] playwright = ["playwright>=1.62.0, <2"] postgres = ["psycopg2-binary==2.9.12"] presto = ["pyhive[presto]>=0.6.5"] trino = ["trino>=0.339.0"] prophet = ["prophet>=1.4.0, <2"] # sqlalchemy-redshift cuts hard from SQLAlchemy 1.4-only (0.8.x) to 2.0-only # (>=1.0.0) with no dual-compat release. Bumped now that Superset's own # SQLAlchemy 2.0 core bump has landed (discussion #40273). redshift = ["sqlalchemy-redshift>=1.0.0"] # No release of sqlalchemy-risingwave has ever supported both SQLAlchemy 1.4 # and 2.0 (version numbers don't track SQLAlchemy compat monotonically). # Bumped to the 2.0-only line now that Superset's own SQLAlchemy 2.0 core # bump has landed (discussion #40273). risingwave = ["sqlalchemy-risingwave>=2.0.0"] shillelagh = ["shillelagh[all]>=1.4.5, <2"] singlestore = ["sqlalchemy-singlestoredb>=1.2.1, <2"] snowflake = ["snowflake-sqlalchemy>=1.11.0, <2"] sqlite = ["syntaqlite>=0.9.0,<0.10.0"] spark = [ "pyhive[hive_pure_sasl]>=0.7", "tableschema", "thrift>=0.24.0, <1", ] tdengine = [ "taospy>=2.8.10", "taos-ws-py>=0.7.0" ] teradata = ["teradatasql>=20.0.0.66"] thumbnails = [] # deprecated, will be removed in 7.0 vertica = ["sqlalchemy-vertica-python>= 0.6.3, < 0.7"] netezza = ["nzalchemy>= 11.1.2, < 11.2"] starrocks = ["starrocks>=1.3.4, <2"] doris = ["pydoris>=1.2.0, <2.0.0"] oceanbase = ["oceanbase_py>=0.0.1.2"] ydb = ["ydb-sqlalchemy>=0.1.22", "ydb-sqlglot-plugin>=0.2.8"] development = [ # no bounds for apache-superset-extensions-cli until a stable version "apache-superset-extensions-cli", "boto3", "docker", "flask-testing", "freezegun", "grpcio>=1.82.1", "openapi-spec-validator", "parameterized", "pip", "polib", # used by scripts/translations/ and their unit tests "pre-commit", "progress>=1.6.1,<2", "psutil", "pyfakefs", "pyinstrument>=5.1.3,<6", "pylint", "pytest<10.0.0", # cap below the next major until validated; the earlier <8 pin (current_app proxy timing) no longer reproduces "pytest-asyncio", "pytest-cov", "pytest-mock", "python-ldap>=3.4.7", "ruff", "sqloxide", "statsd", "syntaqlite>=0.9.0,<0.10.0", ] [project.urls] homepage = "https://superset.apache.org/" documentation = "https://superset.apache.org/docs/intro" [tool.isort] combine_as_imports = true include_trailing_comma = true line_length = 88 known_first_party = "superset, apache-superset-core, apache-superset-extensions-cli" known_third_party = "alembic, apispec, backoff, celery, click, colorama, cron_descriptor, croniter, cryptography, dateutil, deprecation, flask, flask_appbuilder, flask_babel, flask_caching, flask_compress, flask_jwt_extended, flask_login, flask_migrate, flask_sqlalchemy, flask_talisman, flask_testing, flask_wtf, freezegun, geohash, geopy, holidays, humanize, isodate, jinja2, jwt, markdown, markupsafe, marshmallow, marshmallow-union, msgpack, nh3, numpy, pandas, parameterized, parsedatetime, pgsanity, polyline, rison, progress, pyarrow, sqlalchemy_bigquery, pyhive, pyparsing, pytest, pytest_mock, pytz, redis, requests, setuptools, shillelagh, simplejson, slack, sqlalchemy, sqlalchemy_utils, syntaqlite, typing_extensions, urllib3, werkzeug, wtforms, wtforms_json, yaml" multi_line_output = 3 order_by_type = false [tool.mypy] check_untyped_defs = true disallow_any_generics = true disallow_untyped_calls = true disallow_untyped_defs = true ignore_missing_imports = true no_implicit_optional = true warn_unused_ignores = true [[tool.mypy.overrides]] module = "superset.migrations.versions.*" ignore_errors = true [[tool.mypy.overrides]] module = "tests.*" check_untyped_defs = false disallow_untyped_calls = false disallow_untyped_defs = false disable_error_code = "annotation-unchecked" # TODO: remove this once cryptography is fixed, introduced in cryptography 44.0.3 [[tool.mypy.overrides]] module = "cryptography.*" ignore_errors = true follow_imports = "skip" # superset-core is installed as editable locally but CI may not expose types # This ensures consistent behavior between local dev and CI [[tool.mypy.overrides]] module = "superset_core.*" follow_imports = "skip" # Disable warn_unused_ignores for modules with dynamic type assignments # These type: ignore comments are needed in CI where superset-core types aren't visible [[tool.mypy.overrides]] module = [ "superset.core.api.core_api_injection", "superset.security.manager", "superset.daos.base", "superset.connectors.sqla.models", "superset.tags.filters", "superset.commands.security.update", "superset.commands.security.create", "superset.semantic_layers.api", ] warn_unused_ignores = false [tool.ruff] # Exclude a variety of commonly ignored directories. exclude = [ "**/*.ipynb", ".bzr", ".direnv", ".eggs", ".git", ".git-rewrite", ".hg", ".ipynb_checkpoints", ".mypy_cache", ".nox", ".pants.d", ".pyenv", ".pytest_cache", ".pytype", ".ruff_cache", ".svn", ".tox", ".venv", ".vscode", "__pypackages__", "_build", "buck-out", "build", "dist", "node_modules", "site-packages", "venv", ] # Same as Black. line-length = 88 indent-width = 4 # Assume Python 3.11 target-version = "py311" [tool.ruff.lint] # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. select = [ "B904", "E4", "E7", "E9", "PT009", "TRY201", "B", "C", "E", "F", "F", "G", "I", "N", "PT", "Q", "S", "T", "TID", "W", ] ignore = [ "S101", "PT001", # pytest-fixture-incorrect-parentheses-style: different ruff versions disagree "PT006", "T201", "N999", "G201", ] extend-select = ["I"] # Allow fix for all enabled rules (when `--fix`) is provided. fixable = ["ALL"] unfixable = [] # Allow unused variables when underscore-prefixed. dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" [tool.ruff.lint.per-file-ignores] "superset/mcp_service/app.py" = ["S608", "E501"] # LLM instruction text: SQL examples (S608) and long lines in multiline string (E501) "superset/mcp_service/*/tool/list_*.py" = ["E501"] # LLM docstring examples show full request shapes which exceed line length "scripts/*" = ["TID251"] "setup.py" = ["TID251"] "superset/config.py" = ["TID251"] "superset/cli/update.py" = ["TID251"] "superset/key_value/types.py" = ["TID251"] "superset/translations/utils.py" = ["TID251"] "superset/extensions/__init__.py" = ["TID251"] "superset/utils/json.py" = ["TID251"] "docker/*" = ["I"] # Docker config files have non-standard imports that vary by environment "superset/db_engine_specs/lib.py" = ["E501"] # Database config file with long description strings [tool.ruff.lint.isort] case-sensitive = false combine-as-imports = true force-sort-within-sections = false known-first-party = [] known-third-party = [] lines-after-imports = -1 order-by-type = false section-order = [ "future", "standard-library", "third-party", "first-party", "local-folder" ] [tool.ruff.lint.flake8-tidy-imports] banned-api = { json = { msg = "Use superset.utils.json instead" }, simplejson = { msg = "Use superset.utils.json instead" } } [tool.ruff.format] # Like Black, use double quotes for strings. quote-style = "double" # Like Black, indent with spaces, rather than tabs. indent-style = "space" # Like Black, respect magic trailing commas. skip-magic-trailing-comma = false # Like Black, automatically detect the appropriate line ending. line-ending = "auto" # Enable auto-formatting of code examples in docstrings. Markdown, # reStructuredText code/literal blocks and doctests are all supported. # # This is currently disabled by default, but it is planned for this # to be opt-out in the future. docstring-code-format = false # Set the line length limit used when formatting code snippets in # docstrings. # # This only has an effect when the `docstring-code-format` setting is # enabled. docstring-code-line-length = "dynamic" [tool.liccheck] requirement_txt_file = "requirements/base.txt" authorized_licenses = [ "academic free license (afl)", "any-osi", "apache-2.0", "apache license 2.0", "apache software", "apache software, bsd", "bsd", "bsd-2-clause", "bsd-3-clause", "isc license (iscl)", "isc license", "mit", "mit and psf-2.0", "mit-cmu", "mozilla public license 2.0 (mpl 2.0)", "osi approved", "osi approved", "psf-2.0", "python software foundation", "simplified bsd", "the unlicense (unlicense)", "the unlicense", ] [tool.liccheck.authorized_packages] # -------------------------------------------------------------- # These are ok, checked manually # Seems ok, might need legal review # https://github.com/urschrei/pypolyline/blob/master/LICENSE.md polyline = "2" # NumPy 2.x reports a combined SPDX license expression covering vendored # code (BSD-3-Clause AND 0BSD AND MIT AND Zlib AND CC0-1.0), all of which # are permissive OSI-approved licenses; the package itself remains # BSD-3-Clause. https://github.com/numpy/numpy/blob/main/LICENSE.txt numpy = "2" # -------------------------------------------------------------- # TODO REMOVE THESE DEPS FROM CODEBASE paramiko = "3" # GPL pyxlsb = "1" # GPL [tool.uv.sources] apache-superset-core = { path = "./superset-core", editable = true } apache-superset-extensions-cli = { path = "./superset-extensions-cli", editable = true }