Polnor Python SDK — query Iceberg lakehouses, manage notebooks/jobs/models, MLflow-compatible tracking.
Project description
Polnor Python SDK
The official Python client for the Polnor lakehouse — query Iceberg tables with SQL, manage notebooks / jobs / models / endpoints, read & write pandas DataFrames, and use the PEP 249 driver for dbt, pandas, sqlalchemy, and any tool that speaks standard Python DB API.
Install
pip install polnor
Quick start
import polnor
# `polnor.sql()` runs against your default warehouse. Inside a Polnor
# notebook or job, credentials are injected automatically. On a laptop,
# set env vars first (see "Auth" below).
result = polnor.sql("SELECT * FROM demo.orders LIMIT 5")
print(result.rows) # list of lists
print(result.to_pandas()) # pandas DataFrame
Auth
The SDK resolves credentials in this order (first match wins):
polnor.set_token("...", api_url="...", warehouse_id="...")— explicit call- Environment variables:
POLNOR_API_URL,POLNOR_TOKEN,POLNOR_WAREHOUSE_ID ~/.polnor/config.toml— TOML config file written by thepolnorCLI
Inside a Polnor notebook or job, all three POLNOR_ env vars are injected
by the runtime* — your cell-1 polnor.sql(...) works with no setup.
Local example (TOML config):
# ~/.polnor/config.toml
host = "https://api.polnor.net"
token = "<personal access token>"
workspace_id = "<your workspace>"
warehouse_id = "<your default warehouse>"
What's in the box
| Module | What it does |
|---|---|
polnor.sql(query) |
Run SQL on a SQL warehouse, return rows / pandas / dicts. |
polnor.warehouses |
List / get / start / stop / default SQL warehouses. |
polnor.compute |
Manage compute VMs (start, stop, install_library, logs). |
polnor.notebooks |
Create / start / stop Jupyter notebooks on a compute. |
polnor.jobs |
Create + run DAG jobs, fetch logs, cancel, wait. |
polnor.models |
Model registry: versions, artifact URIs, framework tags. |
polnor.endpoints |
Serve a model image: deploy, predict, scale, stop. |
polnor.tables |
Browse databases (Iceberg namespaces) and tables. |
polnor.read_pandas |
Read a table (with where=, limit=) into a DataFrame. |
polnor.write_pandas |
Bulk-insert a DataFrame (append / overwrite / create). |
polnor.dbapi |
PEP 249 driver: connect() / cursor() for dbt / pandas. |
polnor.mlflow |
MLflow-compatible tracking: log_param, log_metric, etc. |
Examples
SQL → pandas DataFrame
df = polnor.sql("SELECT region, COUNT(*) c FROM demo.orders GROUP BY region").to_pandas()
df.plot(kind="bar")
Push a DataFrame to a table
import pandas as pd
df = pd.DataFrame({"id": [1, 2, 3], "name": ["alice", "bob", "carol"]})
polnor.write_pandas(df, "polnor.demo.default.users", mode="create")
PEP 249 (works with dbt, pandas.read_sql, sqlalchemy)
import pandas as pd
import polnor.dbapi as dbapi
conn = dbapi.connect()
df = pd.read_sql("SELECT * FROM demo.orders", conn)
Notebooks, jobs, models, endpoints
# Start a notebook on a CPU compute
polnor.compute.start("my-cpu", wait=True)
nb = polnor.notebooks.create(name="explore", compute_id="my-cpu")
polnor.notebooks.start("explore", wait=True)
# Run a DAG job
job = polnor.jobs.create(name="etl", tasks=[
{"key": "extract", "command": "python extract.py", "image": "python:3.11"},
{"key": "transform", "command": "python transform.py", "image": "python:3.11",
"depends_on": ["extract"]},
])
run_id = polnor.jobs.run("etl")
polnor.jobs.wait(run_id)
print(polnor.jobs.logs(run_id))
# Serve a model
polnor.endpoints.create(name="fraud-v1", image="my-registry/fraud:1.0",
environment={"CONTAINER_PORT": "8080"})
polnor.endpoints.deploy("fraud-v1", wait=True)
pred = polnor.endpoints.predict("fraud-v1", inputs=[[0.1, 0.2, 0.3]])
MLflow-compatible tracking
from polnor import mlflow
with mlflow.start_run() as run:
mlflow.log_param("lr", 0.01)
mlflow.log_metric("accuracy", 0.93)
mlflow.log_artifact("./model.pkl")
Errors
The SDK raises these typed exceptions:
polnor.PolnorAPIError— non-2xx HTTP from the control plane.polnor.SQLError— statement failed, cancelled, or timed out.polnor.PolnorConfigError— no credentials could be resolved.polnor.dbapi.ProgrammingError/OperationalError/ etc. — PEP 249 hierarchy.
Compatibility
- Python ≥ 3.9 (
tomlifalls in for 3.9 / 3.10; 3.11+ hastomllibbuilt in) - pandas integration: optional, lazily imported
- dbt: works via
polnor.dbapi(a dedicateddbt-polnoradapter is in V2)
Development
pip install -e ".[test]"
pytest
Tests use responses to mock HTTP —
no live API needed. The tests/test_e2e_prod.py suite (opt-in via env)
hits api.polnor.net and requires a running warehouse + valid PAT.
Links
- Homepage: https://polnor.net
- API docs: https://docs.polnor.net
- Source / issues: https://github.com/polnor/polnor
License
Apache-2.0.
Project details
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 polnor-1.1.0.tar.gz.
File metadata
- Download URL: polnor-1.1.0.tar.gz
- Upload date:
- Size: 37.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b11190196daf8b0ac10d65c394f3a1bd2051ab3ba1691e51e539b2e4e922606
|
|
| MD5 |
cd8c43c3792e64e83dabc58ed2bcdd6a
|
|
| BLAKE2b-256 |
28431cf0de714d0eabb1054ffea7be66b335a7588f37ca9501dcc77ff7d27891
|
File details
Details for the file polnor-1.1.0-py3-none-any.whl.
File metadata
- Download URL: polnor-1.1.0-py3-none-any.whl
- Upload date:
- Size: 38.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5efbf19a977a8c5ce2b527d1084f70e0cb52bf2395d6d9c2b17e06c7bb80b08f
|
|
| MD5 |
0616932970b8e7209082095c0c1fb84a
|
|
| BLAKE2b-256 |
f7c6011413bb834d24f540d51f8cd780b6028cf8441511eba326a4bb1b3b461f
|