Skip to main content

Mascope SDK

Python SDK for the Mascope mass spectrometry data analysis platform. Designed for researchers who want to load and analyze data from a Mascope server in Jupyter notebooks or Python scripts, or export it to use in other environments.

New to Python? The user docs include a step-by-step getting started guide that walks you from installing an editor to running your first tutorial notebook. It is also available on any Mascope instance under /docs/sdk/getting-started/.

Contents

Installation

Prerequisites

Set up a virtual environment

python -m venv .venv

Activate it (Windows):

.venv\Scripts\activate

Or on macOS/Linux:

source .venv/bin/activate

Install the SDK

pip install mascope_sdk

Or with uv:

uv add mascope_sdk

To run the bundled tutorial notebooks, install with the examples extra instead - it adds the plotting and analysis libraries the notebooks use (plotly + nbformat, matplotlib, numpy, scipy, ipykernel):

pip install "mascope_sdk[examples]"   # or: uv add "mascope_sdk[examples]"

Tutorial Notebooks

The best way to learn the SDK is to walk through the bundled example notebooks. They cover everything from basic setup to advanced analysis workflows.

The notebooks need the examples extra (see Installation): pip install "mascope_sdk[examples]".

Copy them to your project directory:

import mascope_sdk

mascope_sdk.copy_examples("./tutorials")

This creates a tutorials/ folder with the following notebooks:

# Notebook Topic
1 01_getting_started.ipynb Connect, list datasets/batches/samples, view a spectrum
2 02_batch_timeseries.ipynb Load peaks across batches, filter, and plot
3 03_intra_sample_timeseries.ipynb Per-scan intensity timeseries for specific compounds
4 04_mass_defect_plot.ipynb Mass defect visualization
5 05_peaks_by_stage.ipynb Compare measurement stages within a single sample
6 06_normalization.ipynb Normalize intensities by TIC or reagent-ion signal
7 07_background_subtraction.ipynb Subtract a background sample (matched ions or m/z bins)
8 08_correlation_analysis.ipynb Find co-varying peaks via correlation and clustering
9 09_batch_stages.ipynb Split a batch into stages and compare per-stage averages
10 10_peak_assignment.ipynb Read a server-side peak-assignment run: tiers, sources, Van Krevelen

Open them in VS Code (or any Jupyter-compatible IDE) and run the cells. Each notebook is self-contained, just make sure your .env credentials are set up first (see Configuration).

Existing files are never overwritten, so you can safely re-run copy_examples after an SDK update to get new notebooks.

Quick Start

1. Configure credentials

Create a .env file in your working directory (or any parent directory):

MASCOPE_URL=https://example.mascope.app
MASCOPE_ACCESS_TOKEN=your-api-token

Tip: Generate the API token in your Mascope instance's user settings.

2. Use the SDK

from mascope_sdk import MascopeClient

# Auto-loads credentials from .env
mascope = MascopeClient(workspace="My Workspace")

# List datasets (returns a DataFrame)
datasets = mascope.datasets.list()

# List batches by dataset name
batches = mascope.batches.list("My Dataset")

# List samples from a single batch (raises if ambiguous)
samples = mascope.samples.list(batch="My Batch")

# List samples from all matching batches (containing the given keyword)
samples = mascope.samples.list(batches="Uronium")

# Load peaks across all samples in matching batches
peaks = mascope.load_peaks(dataset="My Dataset", batches="Uronium")

# Load peaks across a subset of samples, within matching batches
peaks = mascope.load_peaks(dataset="My Dataset", batches="Uronium", samples="12:")

# Plot a sample spectrum (based on sample id)
spectrum = mascope.samples.get_spectrum(sample_id=samples.iloc[0]["sample_item_id"])

import matplotlib.pyplot as plt

plt.scatter(spectrum["mz"], spectrum["intensity"])
plt.xlabel("m/z")
plt.ylabel("Intensity")
plt.show()

See more examples below.

Configuration

The MascopeClient can be configured in three ways (in override priority order):

  1. Constructor parameters (highest priority):

    Initialize client with parameters:

    mascope = MascopeClient(
        url="https://example.mascope.app",
        access_token="your-token",
        workspace="My Workspace",
    )
    
  2. Environment variables:

    Set environment variables:

    export MASCOPE_URL=https://example.mascope.app
    export MASCOPE_ACCESS_TOKEN=your-token
    

    Initialize client (parameters are read from the environment unless overridden):

    mascope = MascopeClient()
    
  3. .env file (recommended for notebooks):

    Create .env file in the project directory:

    MASCOPE_URL=https://example.mascope.app
    MASCOPE_ACCESS_TOKEN=your-token
    

    Initialize client (parameters are read from the .env file unless overridden):

    mascope = MascopeClient()
    

Workspace Selection

The workspace parameter selects which workspace to operate on. It accepts a name, substring, or ID:

# Explicit workspace selection
mascope = MascopeClient(workspace="My Workspace")

If omitted and your account belongs to exactly one workspace, it is auto-selected. If you belong to multiple workspaces, a ConfigurationError is raised listing the available options.

High-Level Loaders

The SDK provides four convenience loaders that handle dataset/batch/sample resolution, concurrent requests, and progress bars automatically. These are the recommended way to load data for analysis.


load_peaks: Peaks across batches

Load averaged peaks ("sum spectrum") for all samples across one or more batches, returned as a single DataFrame enriched with batch and sample metadata.

The batches / samples filters are case-insensitive literal substrings, so one filter can select several batches at once. Pass exact=True to match a single batch by its full name, or a compiled re.Pattern for a regex.

import re

# All peaks from every batch whose name contains "Uronium"
peaks = mascope.load_peaks(dataset="My Dataset", batches="Uronium")

# Exactly one batch, by full name
peaks = mascope.load_peaks(dataset="My Dataset", batches="Uronium 2026-01", exact=True)

# Regex: batches from 2025 or 2026
peaks = mascope.load_peaks(
    dataset="My Dataset", batches=re.compile("2025|2026", re.IGNORECASE)
)

# Filter by sample name
peaks = mascope.load_peaks(dataset="My Dataset", samples="blank")

# All peaks from every batch (skip confirmation prompt)
peaks = mascope.load_peaks(dataset="My Dataset", confirm_above=None)

# Without match data, areas only
peaks = mascope.load_peaks(dataset="My Dataset", matches=False, heights=False)

load_peak_timeseries: Intra-sample timeseries

Load per-scan intensity timeseries for peaks matching a compound, ion, or isotope across batches. Provide exactly one of compound, ion, or isotope — the value can be a formula or compound name. Pass a list to load multiple targets in a single call (peaks are discovered once per sample).

# Timeseries for all peaks matched to Urea (by name or formula)
ts = mascope.load_peak_timeseries(
    dataset="My Dataset",
    batches="Uronium",
    compound="Urea",  # or compound="CH4N2O"
)

# Multiple compounds in one call
ts = mascope.load_peak_timeseries(
    dataset="My Dataset",
    compound=["Urea", "Lactic acid"],
)

# Plot per-sample timeseries
import matplotlib.pyplot as plt

for name, group in ts.groupby("sample_item_name"):
    plt.plot(group["time"], group["height"], label=name)
plt.legend()
plt.show()

load_peaks_by_stage: Stage-based peak loading

Load averaged peaks for distinct time-range stages of a single sample. Useful when a measurement has phases (e.g. blank, sample introduction, wash).

stages = [
    (0, 30, "blank"),
    (30, 120, "sample"),
    (120, 180, "wash"),
]

peaks = mascope.load_peaks_by_stage(sample="My Sample", stages=stages)

# Compare areas between stages
peaks.groupby("stage_name")["area"].sum()

The sample parameter accepts a sample name or ID. Stage tuples can be (t_min, t_max) or (t_min, t_max, name).

Key columns: stage, stage_name, t_min, t_max, plus all columns from get_peaks.


load_batch_ledger: The batch ledger

Load a batch's batch ledger — the batch-primary record of peak assignment: one batch peak per species across the batch's samples, with the consensus formula and tier the samples' assignments vote for, and one member per sample the species was seen in, carrying that sample's own reading of the peak. Every processed sample folds in as it arrives, so the ledger is complete without a per-sample run in sight.

# One row per member: the whole ledger of every matching batch, flat
ledger = mascope.load_batch_ledger(dataset="My Dataset", batches="Uronium")
ledger.to_csv("ledger.csv", index=False)  # a short way to any format

# The species table rides along: one row per batch peak
species = ledger.attrs["batch_peaks"]
species.groupby("sample_batch_name")["consensus_tier"].value_counts()

# Or the species table alone
species = mascope.load_batch_ledger(dataset="My Dataset", members=False)

Key columns of a member row: the anchor's batch_peak_id, batch_mz, consensus_formula, consensus_tier, support_fraction, n_present, curated (pinned by hand for the whole batch), beside the member's sample_item_name, sample_peak_id, mz, intensity, assigned_formula, source, tier, role, fit_score — so a sample that dissents from the batch reads as one row saying both. Per batch, the same reads are mascope.batch_peaks.list(batch_id), .members(batch_id, sample_id=...) and .verdicts(batch_id) (the batch-level verdicts recorded on its species). The app's Batch peaks pane exports the same rows as a CSV from its view menu.

load_assignments: Peak assignments across batches

Load the persisted peak-assignment results (see Peak assignments) of every sample across one or more batches, concatenated into a single DataFrame enriched with batch and sample metadata — the peak-assignment counterpart of load_peaks.

Read-only: each sample contributes its latest completed assignment run; samples without one are skipped (and logged), not assigned on the fly.

# Assignments of every sample in matching batches
assignments = mascope.load_assignments(dataset="My Dataset", batches="Uronium")

# Confidently assigned peaks that came from the untargeted stage
assignments = mascope.load_assignments(
    dataset="My Dataset", tier="assigned", source="untargeted"
)

# Tier breakdown per sample
assignments.groupby(["sample_item_name", "tier"]).size()

Key columns: sample_batch_name, sample_item_name, datetime_utc, plus all columns from peak_assignments.get (one row per observed peak; core rows only — fetch alternatives/provenance per assignment with peak_assignments.detail).


Confirmation prompt

load_peaks, load_peak_timeseries, and load_assignments show an interactive confirmation prompt when the number of samples exceeds confirm_above. Defaults are 100 for load_peaks and load_assignments, and 20 for load_peak_timeseries. This prevents accidentally launching hundreds of concurrent requests from a notebook cell. Set confirm_above=None to disable.

Peak Assignments

Mascope's peak-centric assignment engine assigns a composition to every observed peak of a sample — database-known targets first (Stage A), then untargeted composition search (Stage B) — arbitrates a single owner per peak, and files each assignment into a confidence tier (assigned | candidate | below_assignability | unassigned). The tier is read off the row's evidence — its fit_score weighted by the chemical plausibility of the assigned formula — under the run's tier_bands. fit_score is served alongside it, unchanged, as the pure fit measurement. Runs are launched from the Mascope app and persisted; the SDK reads the results (it does not trigger runs).

The top tier used to be called identified. The API still accepts that spelling wherever a tier is sent and normalises it to assigned, so scripts written against the old vocabulary keep working.

This coexists with targeted matching (mascope.matching, get_peaks match columns): a database-sourced assignment is the targeted result, anchored on the peak.

# Run history of a sample, newest first
runs = mascope.peak_assignments.list_runs(sample_id)

# The whole ledger of the latest completed run: one row per observed peak.
# Pages through the API internally; run metadata rides on df.attrs["run"].
assignments = mascope.peak_assignments.get(sample_id)
assignments.attrs["run"]["engine_version"]
assignments["tier"].value_counts()

# Server-side filters (a bad value raises ValidationError naming the accepted set)
assigned = mascope.peak_assignments.get(sample_id, tier="assigned")
stage_b = mascope.peak_assignments.get(sample_id, source="untargeted")
curated = mascope.peak_assignments.get(sample_id, source="manual")

# A specific (e.g. older) run
old = mascope.peak_assignments.get(
    sample_id, run_id=runs.iloc[-1]["peak_assignment_run_id"]
)

# Full detail of one assignment: alternatives considered + scoring provenance
full = mascope.peak_assignments.detail(
    sample_id, assignments.iloc[0]["peak_assignment_id"]
)

Key get() columns: sample_peak_mz, sample_peak_intensity, role (M0 | iso_child | reagent | artifact | unassigned), assigned_formula, ion_formula, isotope_formula, source (database | untargeted | manual), fit_score, evidence, mz_error_ppm, tier, p_correct, and target_compound_id/target_ion_id for database-sourced assignments.

Hand-curated rows (source: manual)

A person can overrule the engine on a single row from the app's peak inspector — promote a close alternative, or commit a re-search hit. That row is persisted with source manual, so it leaves database/untargeted rather than joining them:

# Wrong: these two no longer sum to the run
stage_a = mascope.peak_assignments.get(sample_id, source="database")
stage_b = mascope.peak_assignments.get(sample_id, source="untargeted")

# Right: read the run once and split it locally, so nothing can fall out
assignments = mascope.peak_assignments.get(sample_id)
assignments.groupby("source", dropna=False).size()

Peaks nothing explained carry no source at all (None), which is why the groupby above passes dropna=False. A manual row is not necessarily an assigned one either: when an override displaces a compound, the isotopologue satellites of that compound are stripped and end up source: manual, tier: unassigned, with no formula.

peak_assignments.detail() on a curated row returns a provenance.manual block — action, user_id, at, and previous (the displaced winner, kept verbatim), plus manual.demoted, the archive of the satellites the override stripped so committing that compound back restores them.

Which engine produced a run

A run's ledger does not say who computed it — the run does. list_runs (and df.attrs["run"]) carries:

Column Meaning
engine mascope for a run this deployment computed, otherwise the external engine that published its ledger here. Never null, and mascope is reserved server-side so an import cannot claim it.
engine_version That engine's version string.
tier_bands The assigned / candidate evidence thresholds the run tiered with.
calibration What an external engine disclosed about its calibration at import. Null for mascope runs, whose calibration state is the sample's own.

This matters because reads default to the latest completed run whatever its engine, so a published run is what you get unless you ask for another. It is also what makes two engines comparable on one sample — read each run by id and join on sample_peak_id:

runs = mascope.peak_assignments.list_runs(sample_id)
runs[["engine", "engine_version", "tier_bands", "status"]]

mine = mascope.peak_assignments.get(sample_id, run_id=<a mascope run id>)
theirs = mascope.peak_assignments.get(sample_id, run_id=<an imported run id>)
side_by_side = mine.merge(theirs, on="sample_peak_id", suffixes=("_mascope", "_ext"))

Compare tiers only against each run's own tier_bands: the same word means different confidence under different thresholds. An imported run's p_correct is always empty — that column is Mascope's own calibrated judgement and an import may not write it.

For cross-sample analysis use the load_assignments loader; for a guided walk-through see tutorial notebook 10_peak_assignment.ipynb.

Caching

Dataset, batch, sample, and ionization mechanism listings are cached (in volatile memory) automatically after the first call. This speeds up repeated name resolution and avoids redundant API calls. When data on the server changes (e.g. new batch created), the cache needs to be cleared to reload the data on the next call. The cache is not persisted on disk, so restarting the kernel always clears the cache.

# Clear the cache when server data changes
mascope.clear_cache()

API Reference

MascopeClient

from mascope_sdk import MascopeClient

mascope = MascopeClient(workspace="My Workspace")

Resources

All list() methods accept names (or substrings) instead of IDs and return pd.DataFrame | None. A plain string filters case-insensitively as a literal substring — regex metacharacters carry no special meaning, so a name like "Sample (A)" matches as-is. To filter with a regular expression, pass a compiled pattern; case comes from its flags. For example, batches=re.compile("2025|2026") matches batch names containing "2025" or "2026".

mascope.datasets

Method Description Returns
list() List all accessible datasets pd.DataFrame│None

mascope.batches

Method Description Returns
list(dataset) List batches in a dataset (by name) pd.DataFrame│None

mascope.samples

Method Description Returns
list(batch=, batches=, dataset=, samples=) List samples from one or more batches pd.DataFrame│None
get(sample_id) Get sample details dict│None
get_peaks(sample_id, ...) Get peak data with optional match/filter/time params pd.DataFrame│None
get_peak_timeseries(sample_id, mz=, peak_id=) Get intensity over time for a peak pd.DataFrame│None
get_spectrum(sample_id, ...) Get averaged spectrum pd.DataFrame│None
get_spectra(sample_ids, ...) Get spectra for multiple samples pd.DataFrame│None
get_centroids(sample_ids) Get centroid data dict│None

list accepts exactly one of batch (must match a single batch; raises if ambiguous) or batches (returns samples from all matching batches, with an added sample_batch_name column).

mascope.matching

Method Description Returns
match_compound(sample_id, formula) Match a compound in a sample dict│None
match_compounds(sample_id, formulas) Match multiple compounds list[dict]│None

mascope.peak_assignments

Method Description Returns
list_runs(sample_id) List a sample's assignment runs, newest first pd.DataFrame│None
get(sample_id, run_id=, tier=, role=, source=) Full run ledger, one row per peak; run metadata on df.attrs["run"] pd.DataFrame│None
detail(sample_id, peak_assignment_id) One assignment in full (alternatives, provenance) dict│None

get reads the latest completed run unless run_id is given, and pages through the API internally — the whole run comes back as one DataFrame. See Peak Assignments.

mascope.ionization

Method Description Returns
list() List available ionization mechanisms pd.DataFrame│None

Columns: ionization_mechanism_id, ionization_mechanism (human-readable name), ionization_mechanism_polarity.

mascope.cheminfo

Method Description Returns
query_by_mz(mz, mechanism_ids, ...) Query potential formulas for an m/z value list[dict]

Examples

Load peaks and plot by compound

from mascope_sdk import MascopeClient

mascope = MascopeClient(workspace="My Workspace")

peaks = mascope.load_peaks(dataset="My Dataset", batches="Uronium")

# Filter to matched peaks and summarise by compound
matched = peaks[peaks["target_compound_formula"].notna()]
summary = matched.groupby("target_compound_formula")["area"].mean()
summary.sort_values(ascending=False).head(10).plot.barh()

Intra-sample timeseries

import matplotlib.pyplot as plt
from mascope_sdk import MascopeClient

mascope = MascopeClient(workspace="My Workspace")

ts = mascope.load_peak_timeseries(
    dataset="My Dataset",
    compound="Urea",
)

# Plot per-isotope timeseries for one sample
sample = ts[ts["sample_item_name"] == ts["sample_item_name"].iloc[0]]
for isotope, group in sample.groupby("target_isotope_formula"):
    plt.plot(group["time"], group["height"], label=isotope)
plt.xlabel("Time (s)")
plt.ylabel("Intensity")
plt.legend()
plt.show()

Compare stages within a sample

from mascope_sdk import MascopeClient

mascope = MascopeClient(workspace="My Workspace")

# First load samples so the name is cached for resolution
mascope.samples.list(batch="My Batch")

stages = [
    (0, 30, "blank"),
    (30, 120, "sample"),
    (120, 180, "wash"),
]

peaks = mascope.load_peaks_by_stage(sample="My Sample", stages=stages)
peaks.groupby("stage_name")[["area", "height"]].mean()

Low-level peak timeseries

import matplotlib.pyplot as plt
from mascope_sdk import MascopeClient

mascope = MascopeClient(workspace="My Workspace")

ts = mascope.samples.get_peak_timeseries(
    sample_id="sample-123",
    mz=180.063,
    mz_tolerance_ppm=5.0,
)

if ts is not None:
    plt.plot(ts["time"], ts["height"])
    plt.xlabel("Time (s)")
    plt.ylabel("Intensity")
    plt.title(f"Peak at m/z {ts['mz'].iloc[0]:.3f}")
    plt.show()

For Developers

Logging

The SDK logs operational info (batch resolution, request counts, etc.) via loguru. The default level is INFO.

Set the MASCOPE_SDK_LOG_LEVEL environment variable to change it:

MASCOPE_SDK_LOG_LEVEL=DEBUG    # verbose (HTTP requests, cache hits, etc.)
MASCOPE_SDK_LOG_LEVEL=WARNING  # quiet (only warnings and errors)

Or in Python before importing the SDK:

import os

os.environ["MASCOPE_SDK_LOG_LEVEL"] = "DEBUG"

from mascope_sdk import MascopeClient

SSL Verification

By default the SDK verifies SSL certificates. To disable verification (e.g. for local development with a self-signed certificate), set:

MASCOPE_SDK_VERIFY_SSL=false

Or pass it to the constructor:

mascope = MascopeClient(verify_ssl=False)

Error Handling

from mascope_sdk import MascopeClient
from mascope_sdk.exceptions import (
    AuthenticationError,
    NotFoundError,
    ConfigurationError,
)

try:
    mascope = MascopeClient()
    sample = mascope.samples.get("invalid-id")
except ConfigurationError:
    print("Missing MASCOPE_URL or MASCOPE_ACCESS_TOKEN")
except AuthenticationError:
    print("Invalid API token")
except NotFoundError:
    print("Sample not found")

Exception Hierarchy

  • MascopeError — Base exception
    • ConfigurationError — Missing/invalid configuration
    • MascopeConnectionError — Network/connection issues
      • MascopeTimeoutError — Request timeout
    • MascopeAPIError — API errors (includes status_code, message, url)
      • AuthenticationError — 401/403 responses
      • NotFoundError — 404 responses
      • ValidationError — 422 responses
      • ServerError — 5xx responses

Project Structure

mascope_sdk/
├── __init__.py          # Public exports (MascopeClient, exceptions)
├── client.py            # MascopeClient: main entry point and high-level loader methods
├── exceptions.py        # Exception hierarchy
├── _http.py             # Low-level HTTP session (requests wrapper)
├── _resolve.py          # Name-to-ID resolution helpers
├── _loaders.py          # High-level loaders (load_peaks, load_peak_timeseries, load_peaks_by_stage, load_assignments)
├── _concurrent.py       # ThreadPoolExecutor wrapper with progress bars and cancellation
├── _agents.py           # Internal HTTP helpers for Mascope agents (file-agent)
├── resources/
│   ├── _base.py         # BaseResource: shared HTTP helpers and datetime coercion
│   ├── batches.py       # BatchesResource
│   ├── cheminfo.py      # CheminfoResource (m/z queries)
│   ├── datasets.py      # DatasetsResource
│   ├── ionization.py    # IonizationResource
│   ├── matching.py      # MatchingResource (compound matching)
│   ├── peak_assignments.py  # PeakAssignmentsResource (read persisted assignment runs)
│   ├── samples.py       # SamplesResource (peaks, spectra, timeseries)
│   └── workspaces.py    # WorkspacesResource
└── examples/            # Jupyter notebook examples

Key patterns:

  • client.py owns the public API. High-level loaders (load_peaks, etc.) are thin wrappers that delegate to _loaders.py.
  • resources/ contains one class per API domain. Each resource inherits BaseResource which provides _get() / _post() helpers and automatic datetime column coercion.
  • _concurrent.py centralises ThreadPoolExecutor usage with run_concurrent(), which handles progress bars (tqdm), None-filtering, future cancellation on error, and the max_workers <= 8 guard.
  • _resolve.py handles name matching (literal substring for strings, regex for compiled patterns) and name -> ID resolution (used by resources and loaders).
  • Underscore-prefixed modules (_http, _loaders, _concurrent, _resolve, _agents) are internal — not part of the public API.

Metadata

Release files for mascope_sdk 2026.9.15

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

Source distribution (sdist)

Source distribution for mascope_sdk 2026.9.15
File Size Uploaded
mascope_sdk-2026.9.15.tar.gz 93.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mascope_sdk 2026.9.15
File Interpreter ABI Platform
mascope_sdk-2026.9.15-py3-none-any.whl Python 3 none any Details

Total release size: 200.4 kB

Release files / mascope_sdk-2026.9.15.tar.gz

Download URL mascope_sdk-2026.9.15.tar.gz
Size 93.7 kB
Tags Source
SHA-256 checksum
How to use checksums
a054801c72e3a50036454a20c8cf8850760c30e3755b3bf48ffe2b23fc221de1
BLAKE2b-256 checksum
How to use checksums
0166f279f1070649de2de2d9a6ae73e4a8e7d9b39ef6fb053b585bf201eed96c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","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 / mascope_sdk-2026.9.15-py3-none-any.whl

Download URL mascope_sdk-2026.9.15-py3-none-any.whl
Size 106.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
77b20137532547ba3272359a9d21131a104a1435c901fc9875ed04bb785243d8
BLAKE2b-256 checksum
How to use checksums
779e0cc76c5adcaecabffbac86ae1317ab7a6f1ce3da29106bbf7a4fe33bdc15
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","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}
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