Files
superset2/pyproject.toml
T

560 lines
20 KiB
TOML

# 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,<2.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 }