Feed CanvasXpress from authenticated data sources (databases, Google Sheets) — reshape rows into CanvasXpress data objects behind your own origin.
Project description
canvasxpress-connectors
Feed CanvasXpress from authenticated data sources — databases and Google Sheets — by reshaping query results into CanvasXpress data objects served from your own origin. The browser never holds a credential.
Browser (CanvasXpress) ──► your app (this package) ──► authenticated source
no secrets auth + encrypted creds DB / Google Sheets
Install
pip install canvasxpress-connectors # core only (needs just cryptography)
pip install "canvasxpress-connectors[sql]" # + SQLAlchemy databases
pip install "canvasxpress-connectors[sheets]" # + Google Sheets
pip install "canvasxpress-connectors[all]" # everything incl. the web app
The 3-second version
Any source returns (header, rows); rows_to_cx turns that into a CanvasXpress object:
from cx_connectors.sources import SqlSource
from cx_connectors.sources.base import to_cx
data = to_cx(SqlSource(
"sqlite:///demo.db",
'SELECT sample, GeneA, GeneB, category AS "Category" FROM expression',
))
# {"y": {"vars": ["GeneA","GeneB"], "smps": [...], "data": [...]}, "x": {"Category": [...]}}
Return data as JSON from an endpoint; the page does new CanvasXpress("cx", data, {...}).
Architecture
| Layer | Module | Job |
|---|---|---|
| Reshape | cx_connectors.reshape |
rows → CanvasXpress {y, x} (core, no heavy deps) |
| Sources | cx_connectors.sources |
DataSource protocol + SqlSource, GoogleSheetsSource |
| Store | cx_connectors.store |
users (PBKDF2) + per-user encrypted connection strings |
| Web | cx_connectors.web |
create_byo_app() — a mountable FastAPI app |
Adding a backend (BigQuery, a REST API, CSV) = one class with a read() returning
(header, rows). Nothing else changes.
Runnable demo — bring-your-own-database, with login
Each user logs in, registers their own database (connection string stored encrypted), and charts their own data. Users are isolated by session.
pip install -e ".[all]"
export ENCRYPTION_KEY=$(python -c "from cx_connectors.store import generate_key;print(generate_key())")
export SESSION_SECRET=$(python -c "import secrets;print(secrets.token_urlsafe(32))")
python examples/seed_demo.py # users alice & bob, each with their own SQLite DB
python examples/run_byo.py # http://localhost:8100
Log in as alice/alicepw and bob/bobpw (incognito) — each sees only their own rows.
Runnable demo — Google Sheets, per-user OAuth
Each user connects their own Google account; the app reads their private sheet. The browser never sees a Google token or URL.
Prereqs: a Google OAuth Web application client (Cloud Console → Credentials) with
redirect URI http://localhost:8080/oauth/callback, and the Google Sheets API enabled.
pip install -e ".[all]"
export GOOGLE_CLIENT_ID=... GOOGLE_CLIENT_SECRET=...
export OAUTH_REDIRECT_URI=http://localhost:8080/oauth/callback
export SESSION_SECRET=$(python -c "import secrets;print(secrets.token_urlsafe(32))")
export TOKEN_ENCRYPTION_KEY=$(python -c "from cx_connectors.store import generate_key;print(generate_key())")
export OAUTHLIB_INSECURE_TRANSPORT=1 # localhost http only; remove in production
python examples/run_sheets.py # http://localhost:8080 → Connect Google Sheets
Use it inside your own FastAPI
from cx_connectors.web import create_byo_app, create_sheets_app
app = create_byo_app(https_only=True) # database app: login + per-user DBs
# or
app = create_sheets_app(https_only=True) # Google Sheets app: per-user OAuth
Or just the pieces — call SqlSource / GoogleSheetsSource + rows_to_cx from your
own handlers, and bring your own auth.
Databases beyond SQLite
Connection strings are SQLAlchemy URLs; add the driver and go:
- Postgres:
pip install "psycopg[binary]"→postgresql+psycopg://user:pw@host/db - MySQL:
pip install PyMySQL→mysql+pymysql://user:pw@host/db
Security notes
- Connection strings / tokens are Fernet-encrypted at rest; passwords are PBKDF2-hashed.
SqlSourceenforces a single read-onlySELECT; still give the DB user least-privilege read access.- For production: HTTPS +
https_only=Truecookies, rate-limit/auth/login, secrets from a manager (not.env), and pool engines per source.
License
MIT
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 canvasxpress_connectors-0.1.0.tar.gz.
File metadata
- Download URL: canvasxpress_connectors-0.1.0.tar.gz
- Upload date:
- Size: 17.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5bc0cc421b498028ebbef72cf3bf22db80acd0852d6eb50de509799854a26b6
|
|
| MD5 |
4b4e81c4f271e0ccbacafaf9504ccba2
|
|
| BLAKE2b-256 |
9138e1b02d4b818c1dc619f1f7a227de07720bb027430a7674fca1b2044446ac
|
Provenance
The following attestation bundles were made for canvasxpress_connectors-0.1.0.tar.gz:
Publisher:
release.yml on neuhausi/canvasxpress-connectors
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
canvasxpress_connectors-0.1.0.tar.gz -
Subject digest:
d5bc0cc421b498028ebbef72cf3bf22db80acd0852d6eb50de509799854a26b6 - Sigstore transparency entry: 2215732146
- Sigstore integration time:
-
Permalink:
neuhausi/canvasxpress-connectors@96bf76915da9dd0b32eb70e9a36b06e32b5f53c2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/neuhausi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@96bf76915da9dd0b32eb70e9a36b06e32b5f53c2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file canvasxpress_connectors-0.1.0-py3-none-any.whl.
File metadata
- Download URL: canvasxpress_connectors-0.1.0-py3-none-any.whl
- Upload date:
- Size: 19.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a454d7f5c42e890d0e69fca4cdd47fa008ac10d2cc5a14d901611f72b31b293b
|
|
| MD5 |
1d66fa6ca7fccd482d6a10a4c54a9555
|
|
| BLAKE2b-256 |
3b46b2848909febd59e85400e6ee05aadc7266c6f8b496c23b37c44873af502e
|
Provenance
The following attestation bundles were made for canvasxpress_connectors-0.1.0-py3-none-any.whl:
Publisher:
release.yml on neuhausi/canvasxpress-connectors
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
canvasxpress_connectors-0.1.0-py3-none-any.whl -
Subject digest:
a454d7f5c42e890d0e69fca4cdd47fa008ac10d2cc5a14d901611f72b31b293b - Sigstore transparency entry: 2215732156
- Sigstore integration time:
-
Permalink:
neuhausi/canvasxpress-connectors@96bf76915da9dd0b32eb70e9a36b06e32b5f53c2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/neuhausi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@96bf76915da9dd0b32eb70e9a36b06e32b5f53c2 -
Trigger Event:
push
-
Statement type: