From 27b696119400c999c90920803af6e5608fa81a08 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 29 Dec 2025 15:06:42 -0800 Subject: [PATCH 1/5] Update Python and PostgreSQL versions run in matrix tests https://www.postgresql.org/support/versioning/ says that 12 and 13 are no longer supported, 17 and 18 are out. --- .github/workflows/publish.yml | 16 ++++++++-------- .github/workflows/test.yml | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5f57bfb..b6aa985 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,15 +9,15 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] - postgresql-version: [12, 13, 14, 15, 16] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + postgresql-version: [14, 15, 16, 17, 18] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v6 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - - uses: actions/cache@v2 + - uses: actions/cache@v5 name: Configure pip caching with: path: ~/.cache/pip @@ -47,12 +47,12 @@ jobs: runs-on: ubuntu-latest needs: [test] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v6 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v6 with: python-version: "3.12" - - uses: actions/cache@v2 + - uses: actions/cache@v5 name: Configure pip caching with: path: ~/.cache/pip diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c86b176..7cb367b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,15 +7,15 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] - postgresql-version: [12, 13, 14, 15, 16] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + postgresql-version: [14, 15, 16, 17, 18] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v6 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - - uses: actions/cache@v2 + - uses: actions/cache@v5 name: Configure pip caching with: path: ~/.cache/pip From 4489e70fd356b26bfa589749f39d16c0a3cd8a44 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 29 Dec 2025 15:41:35 -0800 Subject: [PATCH 2/5] Bump pytest-django --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index bd606d5..702a199 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ def get_long_description(): "black>=22.3.0", "psycopg2", "pytest", - "pytest-django==4.2.0", + "pytest-django>=4.11.1", "pytest-pythonpath", "dj-database-url", "testing.postgresql", @@ -52,5 +52,5 @@ def get_long_description(): ], }, tests_require=["django-sql-dashboard[test]"], - python_requires=">=3.6", + python_requires=">=3.10", ) From 7bc6d0bc34c0476362e85b779bb164e43d2f02ec Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 29 Dec 2025 15:43:29 -0800 Subject: [PATCH 3/5] Use python_paths not site_dirs --- pytest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index db54719..0e22809 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,4 +1,4 @@ [pytest] addopts = -p pytest_use_postgresql DJANGO_SETTINGS_MODULE = config.settings -site_dirs = test_project/ +python_paths = test_project/ \ No newline at end of file From e0ec8f0946ca03c221801eea6fbb1f8860be4cf4 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 29 Dec 2025 16:05:21 -0800 Subject: [PATCH 4/5] Port setup.py to pyproject.toml, switch to uv https://gistpreview.github.io/?354b66dab89c47d7e190b424665ca944/index.html --- .github/workflows/publish.yml | 2 +- .github/workflows/test.yml | 2 +- conftest.py | 11 ++++++- docs/contributing.md | 28 +++++------------- pyproject.toml | 48 ++++++++++++++++++++++++++++++ pytest.ini | 4 --- setup.py | 56 ----------------------------------- 7 files changed, 67 insertions(+), 84 deletions(-) delete mode 100644 pytest.ini delete mode 100644 setup.py diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b6aa985..1229521 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: sudo apt-get -y install "postgresql-$POSTGRESQL_VERSION" - name: Install dependencies run: | - pip install -e '.[test]' + pip install -e . --group dev - name: Run tests env: POSTGRESQL_VERSION: ${{ matrix.postgresql-version }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7cb367b..c8be5c5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,7 +32,7 @@ jobs: sudo apt-get -y install "postgresql-$POSTGRESQL_VERSION" - name: Install dependencies run: | - pip install -e '.[test]' + pip install -e . --group dev - name: Run tests env: POSTGRESQL_VERSION: ${{ matrix.postgresql-version }} diff --git a/conftest.py b/conftest.py index f4b886f..bc0cd63 100644 --- a/conftest.py +++ b/conftest.py @@ -4,8 +4,17 @@ from django_sql_dashboard.models import Dashboard +def pytest_collection_modifyitems(items): + """Add django_db marker with databases to tests that need database access.""" + for item in items: + fixturenames = getattr(item, "fixturenames", ()) + # Tests using client fixtures or dashboard_db need both databases + if any(f in fixturenames for f in ("admin_client", "client", "dashboard_db")): + item.add_marker(pytest.mark.django_db(databases=["default", "dashboard"])) + + @pytest.fixture -def dashboard_db(settings, db): +def dashboard_db(settings): settings.DATABASES["dashboard"]["OPTIONS"] = { "options": "-c default_transaction_read_only=on -c statement_timeout=100" } diff --git a/docs/contributing.md b/docs/contributing.md index 371fb62..3675435 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,35 +1,22 @@ # Contributing -To contribute to this library, first checkout the code. Then create a new virtual environment: +To contribute to this library, first checkout the code. Use [uv](https://github.com/astral-sh/uv) to run the tests: cd django-sql-dashboard - python -m venv venv - source venv/bin/activate - -Or if you are using `pipenv`: - - pipenv shell - -Now install the dependencies and tests: - - pip install -e '.[test]' - -## Running the tests - -To run the tests: - - pytest + uv run pytest ## Generating new migrations To generate migrations for model changes: cd test_project - ./manage.py makemigrations + uv run ./manage.py makemigrations ## Code style -This library uses [Black](https://github.com/psf/black) for code formatting. The correct version of Black will be installed by `pip install -e '.[test]'` - you can run `black .` in the root directory to apply those formatting rules. +This library uses [Black](https://github.com/psf/black) for code formatting. You can run it like this: + + uv run black . ## Documentation @@ -38,8 +25,7 @@ Documentation for this project uses [MyST](https://myst-parser.readthedocs.io/) To build the documentation locally, run the following: cd docs - pip install -r requirements.txt - make livehtml + uv run --with-requirements requirements.txt make livehtml This will start a live preview server, using [sphinx-autobuild](https://pypi.org/project/sphinx-autobuild/). diff --git a/pyproject.toml b/pyproject.toml index aa7e766..154521d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,51 @@ +[project] +name = "django-sql-dashboard" +version = "1.2" +description = "Django app for building dashboards using raw SQL queries" +readme = "README.md" +license = "Apache-2.0" +authors = [ + { name = "Simon Willison" } +] +requires-python = ">=3.10" +dependencies = [ + "Django>=4.2", + "markdown", + "bleach", +] + +[project.urls] +Documentation = "https://django-sql-dashboard.datasette.io/" +Issues = "https://github.com/simonw/django-sql-dashboard/issues" +CI = "https://github.com/simonw/django-sql-dashboard/actions" +Changelog = "https://github.com/simonw/django-sql-dashboard/releases" +Homepage = "https://github.com/simonw/django-sql-dashboard" + +[dependency-groups] +dev = [ + "black>=22.3.0", + "psycopg2", + "pytest", + "pytest-django>=4.11.1", + "pytest-pythonpath", + "dj-database-url", + "testing.postgresql", + "beautifulsoup4", + "html5lib", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["django_sql_dashboard"] + [tool.isort] profile = "black" multi_line_output = 3 + +[tool.pytest.ini_options] +DJANGO_SETTINGS_MODULE = "config.settings" +pythonpath = ["test_project", "pytest_plugins"] +addopts = "-p pytest_use_postgresql" diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 0e22809..0000000 --- a/pytest.ini +++ /dev/null @@ -1,4 +0,0 @@ -[pytest] -addopts = -p pytest_use_postgresql -DJANGO_SETTINGS_MODULE = config.settings -python_paths = test_project/ \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 702a199..0000000 --- a/setup.py +++ /dev/null @@ -1,56 +0,0 @@ -import os - -from setuptools import setup - -VERSION = "1.2" - - -def get_long_description(): - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), "README.md"), - encoding="utf8", - ) as fp: - return fp.read() - - -setup( - name="django-sql-dashboard", - description="Django app for building dashboards using raw SQL queries", - long_description=get_long_description(), - long_description_content_type="text/markdown", - author="Simon Willison", - url="https://github.com/simonw/django-sql-dashboard", - project_urls={ - "Documentation": "https://django-sql-dashboard.datasette.io/", - "Issues": "https://github.com/simonw/django-sql-dashboard/issues", - "CI": "https://github.com/simonw/django-sql-dashboard/actions", - "Changelog": "https://github.com/simonw/django-sql-dashboard/releases", - }, - license="Apache License, Version 2.0", - version=VERSION, - packages=["django_sql_dashboard"], - package_data={ - "django_sql_dashboard": [ - "templates/django_sql_dashboard/*.html", - "templates/django_sql_dashboard/widgets/*.html", - "migrations/*.py", - "templatetags/*.py", - ] - }, - install_requires=["Django>=3.0", "markdown", "bleach"], - extras_require={ - "test": [ - "black>=22.3.0", - "psycopg2", - "pytest", - "pytest-django>=4.11.1", - "pytest-pythonpath", - "dj-database-url", - "testing.postgresql", - "beautifulsoup4", - "html5lib", - ], - }, - tests_require=["django-sql-dashboard[test]"], - python_requires=">=3.10", -) From d3188a6498d15db5a6247fd91d170be4a261aea7 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 29 Dec 2025 16:07:12 -0800 Subject: [PATCH 5/5] Ran black --- django_sql_dashboard/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/django_sql_dashboard/views.py b/django_sql_dashboard/views.py index f56bd6b..d9ae2e0 100644 --- a/django_sql_dashboard/views.py +++ b/django_sql_dashboard/views.py @@ -341,9 +341,9 @@ def _dashboard_index( }, json_dumps_params={ "indent": 2, - "default": lambda o: o.isoformat() - if hasattr(o, "isoformat") - else str(o), + "default": lambda o: ( + o.isoformat() if hasattr(o, "isoformat") else str(o) + ), }, )