Gwenlake Python Library
The Gwenlake Python library provides convenient access to the Gwenlake API
from applications written in Python. A single Gwenlake client gives you access
to your catalog — projects, datasets, files and SQL.
Installation
pip install -U gwenlake
Or install the latest development version straight from GitHub:
pip install -U git+https://github.com/gwenlake/gwenlake-python
The Transforms layer needs pandas (and pyarrow for parquet);
install it with the optional transforms extra:
pip install -U "gwenlake[transforms]"
Authentication
The client authenticates with a Bearer token, resolved in this order:
- an explicit
api_key/credentialspassed to the client, - a named
profile, - the
GWENLAKE_API_KEYenvironment variable, - the
defaultprofile in~/.gwenlake/credentials.
export GWENLAKE_API_KEY='sk-...'
import gwenlake
# uses GWENLAKE_API_KEY, or the default ~/.gwenlake/credentials profile
client = gwenlake.Gwenlake()
# or pass the key explicitly
client = gwenlake.Gwenlake(api_key="sk-...")
# or pick a profile from ~/.gwenlake/credentials
client = gwenlake.Gwenlake(profile="myteam")
The ~/.gwenlake/credentials file is an INI file with one section per profile,
holding either a static token (API key) or OAuth2 client_id / client_secret.
Projects
projects = client.projects.list()
for p in projects:
print(p["alias"], p["id"])
project = client.projects.get("res.project.…")
Datasets
datasets = client.datasets.list()
for d in datasets:
print(d["alias"], d["id"])
dataset = client.datasets.get("res.dataset.…")
Files
Files live inside a dataset.
dataset_id = "res.dataset.…"
# list files
for f in client.files.list(dataset_id):
print(f["filename"], f["file_size"])
# upload a local file (optionally into a subdirectory with path=...)
client.files.upload(dataset_id, "report.pdf")
client.files.upload(dataset_id, "report.pdf", path="docs")
# download a file
content = client.files.download(dataset_id, "report.pdf")
# presigned URL / delete
url = client.files.presigned_url(dataset_id, "report.pdf")
client.files.delete(dataset_id, "report.pdf")
SQL
Run SQL against a dataset (DuckDB), referencing it as
'<project_alias>.<dataset_alias>'. With format="json" the rows are returned
under data:
result = client.statements.create(
statement="SELECT * FROM 'flights.flight-data' LIMIT 10",
format="json",
)
for row in result["data"]:
print(row)
Pass a connection_id to run the statement against a connection's native engine
(PostgreSQL, S3, …) instead of a dataset.
Transforms
A Palantir Foundry-style transforms layer (gwenlake.transforms) lets you write
dataset-to-dataset transformations as decorated functions. Datasets are
addressed as "<project_alias>.<dataset_alias>" — the same handle used in SQL.
Requires the transforms extra (see Installation).
transform_df — the function receives each Input as a pandas.DataFrame and
returns the DataFrame to write to the (single) Output. The result is
written automatically (snapshot/replace by default):
from gwenlake.transforms import transform_df, Input, Output
@transform_df(
donnees_brutes=Input("Projet_A.utilisateurs"),
donnees_nettoyees=Output("Projet_A.utilisateurs_filtres"),
)
def ma_transformation(donnees_brutes):
df = donnees_brutes[donnees_brutes["age"] >= 18].copy()
df["nom_majuscule"] = df["nom"].str.upper()
return df
ma_transformation(client) # reads, computes, writes
transform — the lower-level form: the function receives TransformInput /
TransformOutput objects and reads/writes explicitly. Use it for non-tabular
data (images, PDFs, …) via .filesystem():
from gwenlake.transforms import transform, Input, Output
@transform(
mon_entree=Input("Projet_A.utilisateurs"),
mon_sortie=Output("Projet_A.utilisateurs_distinct"),
)
def transformation_avancee(mon_entree, mon_sortie):
df = mon_entree.dataframe()
# mode="replace" (default) clears the dataset first; "append" keeps existing files
mon_sortie.write_dataframe(df.drop_duplicates(), mode="replace")
@transform(
images=Input("Projet_A.scans"),
vignettes=Output("Projet_A.scans_traites"),
)
def traiter_fichiers(images, vignettes):
src, dst = images.filesystem(), vignettes.filesystem()
for entry in src.ls():
data = src.read(entry["filename"]) # raw bytes (PDF, image, …)
with dst.open(f"copie/{entry['filename']}", "wb") as f:
f.write(data)
Large datasets — page through with LIMIT/OFFSET instead of loading
everything at once. iter_dataframes() yields pandas.DataFrame chunks and
write_dataframes() streams them back out as part-00000.parquet, …:
@transform(
gros_dataset=Input("Projet_A.evenements"),
resultat=Output("Projet_A.evenements_propres"),
)
def transformation_par_chunks(gros_dataset, resultat):
chunks = (
chunk[chunk["valide"]]
for chunk in gros_dataset.iter_dataframes(chunk_size=50_000, order_by="id")
)
resultat.write_dataframes(chunks, mode="replace")
Pass order_by= for a deterministic page split. The transforms layer is
synchronous.
Async
Every resource is also available on AsyncGwenlake:
import asyncio
import gwenlake
async def main():
client = gwenlake.AsyncGwenlake()
print(await client.projects.list())
asyncio.run(main())
See examples/ for runnable scripts.
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 gwenlake-0.7.0.tar.gz.
File metadata
- Download URL: gwenlake-0.7.0.tar.gz
- Upload date:
- Size: 16.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b000aaf0d1aefe2ae284a42d97fa7994d3b15e5972242b2bf497ebfb1c467c86
|
|
| MD5 |
d6cd88072f3099344d08050ee4257683
|
|
| BLAKE2b-256 |
71338347c084c5fb6e834edcc76a9201f8517041f098b45fd54a007726e05841
|
Provenance
The following attestation bundles were made for gwenlake-0.7.0.tar.gz:
Publisher:
python-publish.yml on gwenlake/gwenlake-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gwenlake-0.7.0.tar.gz -
Subject digest:
b000aaf0d1aefe2ae284a42d97fa7994d3b15e5972242b2bf497ebfb1c467c86 - Sigstore transparency entry: 1826558178
- Sigstore integration time:
-
Permalink:
gwenlake/gwenlake-python@ffea41146d843dd57938c33ea282641bfe3fdbbc -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/gwenlake
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@ffea41146d843dd57938c33ea282641bfe3fdbbc -
Trigger Event:
release
-
Statement type:
File details
Details for the file gwenlake-0.7.0-py3-none-any.whl.
File metadata
- Download URL: gwenlake-0.7.0-py3-none-any.whl
- Upload date:
- Size: 23.2 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 |
705c9e305b8621e8242389abd50f5822146d8cc95bab975c1a47b6a10c84d8cd
|
|
| MD5 |
335552e32741a418229369e8a01f55e2
|
|
| BLAKE2b-256 |
b2ee4e529534bd00b73236fe3a11d8e64b2489156a366ec4dc91080076aedd5f
|
Provenance
The following attestation bundles were made for gwenlake-0.7.0-py3-none-any.whl:
Publisher:
python-publish.yml on gwenlake/gwenlake-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gwenlake-0.7.0-py3-none-any.whl -
Subject digest:
705c9e305b8621e8242389abd50f5822146d8cc95bab975c1a47b6a10c84d8cd - Sigstore transparency entry: 1826558817
- Sigstore integration time:
-
Permalink:
gwenlake/gwenlake-python@ffea41146d843dd57938c33ea282641bfe3fdbbc -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/gwenlake
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@ffea41146d843dd57938c33ea282641bfe3fdbbc -
Trigger Event:
release
-
Statement type: