Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-python@v5
with:
python-version: '3.13'
- run: python -m pip install black==23.1.0 ruff==0.0.287
python-version: '3.14'
- run: python -m pip install black==25.11.0 ruff==0.0.287
- run: ruff check .
- run: black --check .

Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/psf/black
rev: 23.1.0
rev: 25.11.0
hooks:
- id: black
language_version: python3
Expand Down
2 changes: 1 addition & 1 deletion .restyled.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ labels:
# Restylers to run, and how
restylers:
- name: black
image: restyled/restyler-black:v24.4.2
image: public.ecr.aws/restyled-io/restyler-black:v26.3.1
include:
- redash
- tests
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ RUN --mount=type=cache,id=pnpm-store,target=/frontend/.cache/pnpm,uid=1001,gid=1
fi
EOF

FROM python:3.13-slim-bookworm
FROM python:3.14-slim-trixie

EXPOSE 5000

Expand Down
593 changes: 291 additions & 302 deletions poetry.lock

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[project]
name = "redash"
version = "26.06.0-dev"
requires-python = ">=3.13"
requires-python = ">=3.13,<3.15"
description = "Make Your Company Data Driven. Connect to any data source, easily visualize, dashboard and share your data."
authors = [
{ name = "Arik Fraimovich", email = "<arik@redash.io>" }
Expand All @@ -14,7 +14,7 @@ readme = "README.md"
dependencies = []

[tool.black]
target-version = ['py38']
target-version = ['py314']
line-length = 119
force-exclude = '''
/(
Expand All @@ -23,7 +23,7 @@ force-exclude = '''
'''

[tool.poetry.dependencies]
python = ">=3.13,<3.14"
python = ">=3.13,<3.15"
advocate = "1.0.0"
aniso8601 = "8.0.0"
authlib = "0.15.5"
Expand Down Expand Up @@ -99,15 +99,17 @@ optional = true
[tool.poetry.group.all_ds.dependencies]
atsd-client = "3.0.5"
azure-kusto-data = "5.0.1"
boto3 = "1.28.8"
botocore = "1.31.8"
cassandra-driver = "3.29.3"
boto3 = "1.43.7"
botocore = "1.43.7"
cassandra-driver = "3.30.0"
certifi = ">=2019.9.11"
cmem-cmempy = "21.2.3"
databend-py = "0.4.6"
databend-sqlalchemy = "0.2.4"
duckdb = "1.3.2"
duckdb = "1.5.3"
google-api-python-client = "2.190.0"
# Avoid yanked grpcio 1.78.1 (fork/Gunicorn hang: https://github.com/grpc/grpc/issues/41725).
grpcio = ">=1.80.0,<2"
gspread = "5.11.2"
impyla = "0.22.0"
influxdb = "5.2.3"
Expand Down
1 change: 1 addition & 0 deletions redash/authentication/saml_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

logger = logging.getLogger("saml_auth")
blueprint = Blueprint("saml_auth", __name__)

inline_metadata_template = """<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor entityID="{{entity_id}}" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"><md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>{{x509_cert}}</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="{{sso_url}}"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="{{sso_url}}"/></md:IDPSSODescriptor></md:EntityDescriptor>"""


Expand Down
2 changes: 1 addition & 1 deletion redash/query_runner/duckdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def run_query(self, query, user) -> tuple:
cursor = self.con.cursor()
cursor.execute(query)
columns = self.fetch_columns(
[(d[0], TYPES_MAP.get(d[1].upper(), TYPE_STRING)) for d in cursor.description]
[(d[0], TYPES_MAP.get(str(d[1]).upper(), TYPE_STRING)) for d in cursor.description]
)
rows = [dict(zip((col["name"] for col in columns), row)) for row in cursor.fetchall()]
data = {"columns": columns, "rows": rows}
Expand Down
9 changes: 4 additions & 5 deletions tests/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,11 +403,10 @@ def test_disabled_user_should_not_receive_password_reset_link(self):
self.db.session.add(user)
self.db.session.commit()

with patch(
"redash.handlers.authentication.send_password_reset_email"
) as send_password_reset_email_mock, patch(
"redash.handlers.authentication.send_user_disabled_email"
) as send_user_disabled_email_mock:
with (
patch("redash.handlers.authentication.send_password_reset_email") as send_password_reset_email_mock,
patch("redash.handlers.authentication.send_user_disabled_email") as send_user_disabled_email_mock,
):
response = self.post_request("/forgot", org=user.org, data={"email": user.email})
self.assertEqual(response.status_code, 200)
send_password_reset_email_mock.assert_not_called()
Expand Down
7 changes: 4 additions & 3 deletions tests/test_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ def test_rq_job_ids_uses_rq_redis_connection():
mock_registry = MagicMock()
mock_registry.get_job_ids.return_value = []

with patch("redash.monitor.Queue") as mock_Queue, patch(
"redash.monitor.StartedJobRegistry"
) as mock_StartedJobRegistry:
with (
patch("redash.monitor.Queue") as mock_Queue,
patch("redash.monitor.StartedJobRegistry") as mock_StartedJobRegistry,
):
mock_Queue.all.return_value = [mock_queue]
mock_StartedJobRegistry.return_value = mock_registry

Expand Down