Integrate CAPTCHAs powered by Cloudflare Turnstile
Project description
datasette-turnstile
Protect Datasette paths with Cloudflare Turnstile challenges.
Installation
Install this plugin in the same environment as Datasette.
datasette install datasette-turnstile
Configuration
Configure the plugin in your datasette.yaml:
plugins:
datasette-turnstile:
site_key: "0x4AAAAAAxxxxxxxxxxxxxxx"
secret_key:
$env: TURNSTILE_SECRET_KEY
protected_paths:
- "/admin/*"
- "/-/import-*"
exclude_patterns:
- "*.json"
cookie_max_age: 86400
Configuration options
site_key(required): Your Turnstile site key from the Cloudflare dashboardsecret_key(required): Your Turnstile secret key (supports$envsyntax)protected_paths(required): List of URL patterns to protectexclude_patterns(optional): Patterns to exclude from protection (e.g.,*.json)cookie_max_age(optional): Cookie lifetime in seconds (default: 86400 = 24 hours)cookie_name(optional): Name of the verification cookie (default:ds_turnstile)
URL Pattern Matching
Patterns use simple wildcard matching where * matches any characters:
/admin/*- Protects all paths under/admin//-/import-*- Protects/-/import-csv,/-/import-json, etc./data?*&*&*- Protects/datawith 2+ query string parameters
Use ? in patterns to match against the full URL including query string. Without ?, patterns only match the path.
How It Works
- When a user visits a protected path, they're redirected to
/-/turnstile - The challenge page displays a Cloudflare Turnstile widget
- Upon completing the challenge, the token is verified server-side
- On success, a signed cookie is set and the user is redirected to their original destination
- The cookie remains valid for 24 hours (configurable)
API Requests
For requests with Accept: application/json header, the plugin returns a 403 JSON response instead of redirecting:
{"error": "turnstile_required"}
Use exclude_patterns: ["*.json"] to exclude JSON endpoints from protection entirely.
Development
To set up this plugin locally, first checkout the code:
cd datasette-turnstile
To run the tests:
uv run pytest
Create a config file using Turnstile test keys:
cat > datasette.yaml << 'EOF'
plugins:
datasette-turnstile:
site_key: "1x00000000000000000000AA"
secret_key:
$env: TURNSTILE_SECRET_KEY
protected_paths:
- "/demo/example*
EOF
Create an example database:
sqlite3 demo.db "CREATE TABLE example (id INTEGER PRIMARY KEY, name TEXT);"
Put the secret in an environment variable and run Datasette with the plugin:
TURNSTILE_SECRET_KEY='1x0000000000000000000000000000000AA' uv run datasette -c datasette.yaml demo.db
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file datasette_turnstile-0.1a1.tar.gz.
File metadata
- Download URL: datasette_turnstile-0.1a1.tar.gz
- Upload date:
- Size: 15.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6664543e306f909488eacc2dc9c317a2fb3637751a1d8b573b37e50aa4041fb0
|
|
| MD5 |
dbe95057f2907b1fc505d1e49b57b0e6
|
|
| BLAKE2b-256 |
4bf39574e1688764c3c624492372357052897fa111e2f1ac647232dc034cdf77
|
Provenance
The following attestation bundles were made for datasette_turnstile-0.1a1.tar.gz:
Publisher:
publish.yml on simonw/datasette-turnstile
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
datasette_turnstile-0.1a1.tar.gz -
Subject digest:
6664543e306f909488eacc2dc9c317a2fb3637751a1d8b573b37e50aa4041fb0 - Sigstore transparency entry: 1255533357
- Sigstore integration time:
-
Permalink:
simonw/datasette-turnstile@50c36ab7a516e30dd3371188967d4e3622083ae9 -
Branch / Tag:
refs/tags/0.1a1 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@50c36ab7a516e30dd3371188967d4e3622083ae9 -
Trigger Event:
release
-
Statement type:
File details
Details for the file datasette_turnstile-0.1a1-py3-none-any.whl.
File metadata
- Download URL: datasette_turnstile-0.1a1-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5fb0bc4c67d77c67ce6d78e26e0905678d3966ad937e75b2eb5a3231ec530073
|
|
| MD5 |
4f6a6c06341ac127c764d3fec746d7dd
|
|
| BLAKE2b-256 |
dba303f3ad28d8e6ca09db4c72fb63b5304f678ece0c901e6d211447157c6b17
|
Provenance
The following attestation bundles were made for datasette_turnstile-0.1a1-py3-none-any.whl:
Publisher:
publish.yml on simonw/datasette-turnstile
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
datasette_turnstile-0.1a1-py3-none-any.whl -
Subject digest:
5fb0bc4c67d77c67ce6d78e26e0905678d3966ad937e75b2eb5a3231ec530073 - Sigstore transparency entry: 1255533515
- Sigstore integration time:
-
Permalink:
simonw/datasette-turnstile@50c36ab7a516e30dd3371188967d4e3622083ae9 -
Branch / Tag:
refs/tags/0.1a1 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@50c36ab7a516e30dd3371188967d4e3622083ae9 -
Trigger Event:
release
-
Statement type: