FluxFiles for Python (server-side token SDK)
Mint FluxFiles JWTs from any Python backend (Django, FastAPI, Flask, …). Tokens are byte-compatible with the PHP core, so non-PHP apps can issue access tokens — including encrypted BYOB (Bring Your Own Bucket) credentials — without running PHP.
This package only issues tokens — it is not a backend. You still run a FluxFiles core service (the file-manager backend that talks to storage; a PHP app, e.g. the Docker image) for the token to authenticate against.
fluxfiles-tokensimply removes the need for your app to be PHP in order to mint those tokens.
Requirements
- Python 3.10+
- A running FluxFiles core service the issued tokens authenticate against
(the SDK/iframe
endpointpoints at it). - The same
FLUXFILES_SECRETyour FluxFiles core server uses to verify tokens (HS256, must be ≥ 32 bytes). Keep it server-side only.
Installation
pip install fluxfiles-token
Usage
Mint a token
from fluxfiles_token import create_token
token = create_token(
user_id="user-42",
perms=["read", "write"],
disks=["local", "s3"],
prefix="users/42", # scope the user to their own directory
max_upload_mb=25,
allowed_ext=["png", "jpg", "pdf"],
ttl=3600, # seconds
# secret=..., # or omit to read FLUXFILES_SECRET from the environment
)
Role & edition presets
Mint-time-only DX sugar — they expand into ordinary claims and are never themselves a JWT claim. Explicit kwargs always win over a preset default.
from fluxfiles_token import create_token
# perms=["read", "write"], owner_only=True, allow_extract=True,
# allow_chmod=False (the "editor" bundle).
token = create_token(user_id="user-42", role="editor")
# Every module claim the "enterprise" edition grants — license/module
# install are still the real gate; a preset just defaults the per-tenant claim.
token = create_token(user_id="tenant-9", edition="enterprise")
Enable Import from URL
Import-from-URL is off by default. Turn it on for a token by setting the import options — no server-side per-tenant config is needed:
token = create_token(
user_id="user-42",
perms=["read", "write"],
allow_url_import=True, # required — enables the feature
max_import_mb=20, # optional — cap per import (MB)
import_url_allowlist=["*.unsplash.com"], # optional — restrict source hosts
# import_path, import_rate_limit, import_concurrency also supported
)
The core then accepts POST /api/fm/import-url for that token (SSRF-guarded,
sharing the quota/dedup/variants pipeline). Server-wide defaults come from
FLUXFILES_IMPORT_* env vars on the core service.
SFTP disk: chmod & SSH terminal
When the token targets a FluxFiles server that has an SFTP disk configured
(SFTP_* env on that server — see the
core README),
you can hand a token the SFTP file-manager tools. chmod is on by default for
SFTP; the SSH terminal is opt-in (it grants shell access as the SSH user):
token = create_token(
user_id="admin-7",
perms=["read", "write"],
disks=["sftp"], # an SFTP disk configured on the FluxFiles server
allow_chmod=True, # cPanel-style permissions (default on for SFTP)
allow_terminal=True, # SSH terminal — opt-in, off by default
)
These are standalone-core features: fluxfiles-token mints for a real
FluxFiles server (Docker / standalone), which serves them — they aren't
available behind the WordPress / Laravel-proxy adapters.
BYOB — encrypt a user's own bucket credentials
import os
from fluxfiles_token import create_byob_token
token = create_byob_token(
user_id="user-42",
byob_disks={
"my-s3": {
"driver": "s3",
"key": os.environ["USER_AWS_KEY"],
"secret": os.environ["USER_AWS_SECRET"],
"bucket": "user-personal-bucket",
"region": "us-east-1",
# "endpoint": "https://<acct>.r2.cloudflarestorage.com", # R2/MinIO/Spaces
},
},
)
Credentials are AES-256-GCM encrypted into the token and decrypted only at
runtime by the FluxFiles server (which also re-validates the endpoint for
SSRF). role/edition presets are supported on BYOB tokens too.
Verify / decode (optional)
from fluxfiles_token import verify_token, decode_token
claims = verify_token(token) # checks HS256 signature + expiry, raises on failure
peek = decode_token(token) # decode only, NO verification — never trust for auth
Django view
from django.http import JsonResponse
from fluxfiles_token import create_token
def fluxfiles_token_view(request):
token = create_token(
user_id=str(request.user.id),
perms=["read", "write"],
prefix=f"users/{request.user.id}",
)
return JsonResponse({"token": token})
FastAPI route
from fastapi import APIRouter, Depends
from fluxfiles_token import create_token
router = APIRouter()
@router.get("/fluxfiles/token")
def fluxfiles_token(user=Depends(get_current_user)):
return {"token": create_token(user_id=user.id, perms=["read", "write"])}
API
| Function | Description |
|---|---|
create_token(**opts) |
Standard token. Mirrors PHP fluxfiles_token(). |
create_byob_token(**opts) |
Token with encrypted BYOB disk credentials. Mirrors fluxfiles_byob_token(). |
verify_token(token, secret=None) |
Verify HS256 signature + expiry; returns decoded claims or raises. |
decode_token(token) |
Decode without verifying (inspection/logging only). |
create_token keyword arguments: secret=None, user_id, perms=None,
disks=None, prefix=None, max_upload_mb=None, allowed_ext=None,
ttl=None, owner_only=None, max_storage_mb=None, max_files=None,
edition=None, role=None. Per-tenant overrides (omit to inherit the server
default): ai_auto_tag=None (bool), rate_read=None / rate_write=None
(req/min), variants=None ({"thumb": .., "medium": .., "large": ..} px),
and every other allow_*/module claim documented in
docs/CONFIG.md —
plus a claims: dict escape hatch for any claim by its raw snake_case name.
create_byob_token replaces disks with byob_disks (a map of name →
S3-compatible/SFTP config) and does not take max_storage_mb/max_files
(matching the core), but accepts the same role/edition/per-tenant kwargs.
Compatibility
Tokens and BYOB blobs are validated against the PHP core in CI: a
Python-minted token decodes in JwtCompat::decode, and BYOB credentials
round-trip both ways through CredentialEncryptor (HS256 + HKDF-SHA256 +
AES-256-GCM). Always mint tokens on the server — never ship
FLUXFILES_SECRET to the browser.
License
MIT — see LICENSE for details.
Links
- Main repository:
https://github.com/thai-pc/fluxfiles - Documentation:
https://github.com/thai-pc/fluxfiles#python-server-side-token-sdk - Issues:
https://github.com/thai-pc/fluxfiles/issues
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 fluxfiles_token-0.1.0.tar.gz.
File metadata
- Download URL: fluxfiles_token-0.1.0.tar.gz
- Upload date:
- Size: 21.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08978d2d51e499b9d45522c022f3deef8f5c9302ec4ee29a1060cfe29b859065
|
|
| MD5 |
ea7b71a7240ca15b115b04db14466739
|
|
| BLAKE2b-256 |
bcc05741b22293d3b941af77bedb0649d4ad35bdb8f7cedb16c7a16593a323e0
|
Provenance
The following attestation bundles were made for fluxfiles_token-0.1.0.tar.gz:
Publisher:
pypi-publish.yml on thai-pc/fluxfiles
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fluxfiles_token-0.1.0.tar.gz -
Subject digest:
08978d2d51e499b9d45522c022f3deef8f5c9302ec4ee29a1060cfe29b859065 - Sigstore transparency entry: 2758608341
- Sigstore integration time:
-
Permalink:
thai-pc/fluxfiles@a3989b8bbf28147f266cf04c26bb721e01bcbd94 -
Branch / Tag:
refs/tags/python-v0.1.0 - Owner: https://github.com/thai-pc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@a3989b8bbf28147f266cf04c26bb721e01bcbd94 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fluxfiles_token-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fluxfiles_token-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25090bbd47494956fbb172f4d9cffb875a3b7b3061e6ae40f7816e649166d50b
|
|
| MD5 |
e93ced3887b8ff7ddb2b86e26989f62b
|
|
| BLAKE2b-256 |
f8b1d1292fe129a20d5088d869d6e4f917e64134f3f573ae02fc6a80a617733c
|
Provenance
The following attestation bundles were made for fluxfiles_token-0.1.0-py3-none-any.whl:
Publisher:
pypi-publish.yml on thai-pc/fluxfiles
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fluxfiles_token-0.1.0-py3-none-any.whl -
Subject digest:
25090bbd47494956fbb172f4d9cffb875a3b7b3061e6ae40f7816e649166d50b - Sigstore transparency entry: 2758608400
- Sigstore integration time:
-
Permalink:
thai-pc/fluxfiles@a3989b8bbf28147f266cf04c26bb721e01bcbd94 -
Branch / Tag:
refs/tags/python-v0.1.0 - Owner: https://github.com/thai-pc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@a3989b8bbf28147f266cf04c26bb721e01bcbd94 -
Trigger Event:
push
-
Statement type: