Skip to main content

xoople-sdk

Official Python SDK for the Xoople Products API.

from xoople.sdk import Config, XoopleClient, StaticToken, models

client = XoopleClient.from_credentials(
    "https://api.xoople.com", StaticToken("...")
)
# Or pass the complete transport configuration directly:
# client = XoopleClient(Config.from_env())

estimate = client.analyses.estimate(request)
analysis = client.analyses.create(request)

# `list` returns a paginator: iterate it for items across every page.
for run in client.analyses.runs.list(analysis.uid):
    print(run.state)

# Sub-resources take the parent analysis uid:
output = client.analyses.outputs.get(analysis.uid, output_uid)
access = client.analyses.outputs.generate_access_url(analysis.uid, output_uid, ttl_seconds=900)

# A table output resolves to a handle that reads itself:
table = client.table(analysis.uid)          # or client.table(uid, output=output_uid)
print(table.shared)                         # measures, grid, size, created time
df = table.to_pandas()                      # pip install "xoople-sdk[sharing]"
sdf = table.to_spark(spark)                 # your session, your connector

# Select an inclusive Delta Change Data Feed range. Start at 0 on the first sync.
changes = table.changes(starting_version=0)
change_df = changes.to_pandas()
change_sdf = changes.to_spark(spark)
latest = table.latest_changes()
latest_df = latest.to_pandas()
latest_sdf = latest.to_spark(spark)

# Custom verbs are plain methods:
client.analyses.cancel(analysis.uid)
client.analyses.schedules.pause(analysis.uid, schedule_uid)

# Cross-analysis reads and catalogs are top-level:
client.schedules.list(state=models.ScheduleStatus.ACTIVE)
client.usage.limits()
client.catalog.measures(product="tabular_time_series")

Config.from_env() reads XOOPLE_API_URL and XOOPLE_TOKEN.

API keys

An API key lets a script or a scheduled job call the API without a browser sign-in. Create one on the API keys section of your Xoople profile page (/profile). The key starts with sk_ and is shown once, so store it in a secret manager.

A key belongs to one organization membership. It acts as you, in the organization that was active when you created it, with that membership's roles. To work in a different organization, create a key there.

The SDK sends the key as the bearer token. Set XOOPLE_TOKEN to the key and use Config.from_env(), or pass it explicitly:

import os

from xoople.sdk import StaticToken, XoopleClient

client = XoopleClient.from_credentials(
    "https://api.xoople.com", StaticToken(os.environ["XOOPLE_TOKEN"])
)

The API accepts at most 300 API key requests a minute from one IP address. The SDK retries rate-limited GETs and replay-safe writes with backoff. Any rate-limited request that is not retried, or still fails after the retries, raises xoople.sdk.errors.RateLimitError. Revoke a key on the same profile page when you no longer need it.

Connection profiles

Config.from_profile(path) reads the URL and the credential from one file, for tools that take a file and not an environment:

{
  "version": 1,
  "api_url": "https://gateway.xoople.com",
  "auth": { "type": "bearer", "token": "<token>" },
  "expires_at": "2026-09-30T00:00:00Z"
}

To use the sign-in from xoople auth login instead of a token, set "auth": { "type": "xoople-cli" }. The profile then names only the API, and the session is read from $XDG_CONFIG_HOME/xoople/session.json (else ~/.config/xoople/session.json) and refreshed in place. xoople.sdk.session reads and writes that file. The profile must name the API the session signed in for, so sign in with xoople auth login --api-url <url>; another API raises CredentialError.

expires_at is optional and is what the issuer stamped. It carries a UTC offset. A profile past it raises ProfileExpiredError on load, not at the first request.

The file is a credential. Keep it out of projects and repositories. Restrict who can read it.

client.table() is the authenticated half of xoople.sdk.sharing, which reads a .share profile with no API credential at all. It downloads one profile for the client's lifetime and removes it on close(), so keep the client open through every read — Spark reads lazily. client.table(uid, profile_path=...) uses a profile you own instead; the SDK never writes or removes that one.

Change Data Feed reads accept either starting_version with an optional ending_version, or starting_timestamp with an optional ending_timestamp. Ranges are inclusive and return the standard _change_type, _commit_version, and _commit_timestamp columns. Persist the highest commit version you apply, then begin the next read at that value plus one. For inspection rather than cursor-based synchronization, latest_changes().to_pandas() and latest_changes().to_spark(spark) read only the newest available table commit.

Every failure raises a subclass of xoople.sdk.errors.XoopleError.

Metadata

Release files for xoople-sdk 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for xoople-sdk 0.6.0
File Size Uploaded Provenance
xoople_sdk-0.6.0.tar.gz 68.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for xoople-sdk 0.6.0
File Interpreter ABI Platform
xoople_sdk-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 144.4 kB

Release files / xoople_sdk-0.6.0.tar.gz

Download URL xoople_sdk-0.6.0.tar.gz
Size 68.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0f6be4b9631e989c75698f23bb77b5a579b8f668c5a04b882508e8c3c3e6a8e2
BLAKE2b-256 checksum
How to use checksums
03450e9c7e15be2d33f5353d2f6663612319e3247020c5d920260be1e2dc63c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.11 {"installer":{"name":"uv","version":"0.12.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / xoople_sdk-0.6.0-py3-none-any.whl

Download URL xoople_sdk-0.6.0-py3-none-any.whl
Size 76.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
97a93eb915fe85434656485dc8b46de148ee671e639b09e9d6ee154f21a2cb0f
BLAKE2b-256 checksum
How to use checksums
1f78b99c4ba2dd65df72e16d0238c3c94c58e0382754cb579f598c6ae790dfd1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.11 {"installer":{"name":"uv","version":"0.12.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for xoople-sdk 0.6.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page