Skip to main content

Python client for CloudOS Cohort Browser API

Project description

cloudos-cb-py

Python client for the CloudOS Cohort Browser API. Provides functions for schema discovery, table exploration, and SQL query execution with team-based access control.

Requirements

  • Python >= 3.9
  • requests >= 2.28.0
  • pandas >= 1.5.0

Prerequisites

IMPORTANT: Before using this package, ensure the following requirements are met:

  • Bastion must be enabled for your workspace
  • You are running the package from within an interactive session
  • The interactive session and the cohort queried must be in the same workspace

Without these prerequisites, API calls will fail even with valid credentials.

Installation

From PyPI (recommended)

pip install cloudos-cb-py

From source

git clone https://github.com/lifebit-ai/cloudos-cb-py
cd cloudos-cb-py
pip install .

Development install (includes test dependencies)

pip install -e ".[dev]"

Quick Start

1. Configure a profile

import cloudos_cb

cloudos_cb.configure(
    profilename="production",
    apikey="your-api-key-here",
    workspace_id="953h453uhr73894hhr9348h9",
    set_default=True,
)

Credentials are stored in ~/.cloudos-cb/config.json with 0600 permissions. Set CLOUDOS_CONFIG_DIR to store the file elsewhere.

2. List configured profiles

profiles = cloudos_cb.profile_list()
print(profiles)
# Returns a pandas DataFrame with columns:
# profile_name, workspace_id, base_url, default, created_at, updated_at

3. Discover cohort tables

tables = cloudos_cb.cohort_tables(cohort_id="1a2b3c4d5e6f7g8h9i10j11k")
print(tables)
# Cohort 1a2b3c4d5e6f7g8h9i10j11k:
#   - omop_data.person
#       - person_id (integer)
#       - year_of_birth (integer)
#       - gender_concept_id (integer)
#       ...
#   - omop_data.observation
#       ...
#
# Total: 1 database(s), 5 table(s)

# Access raw data
schema_list = tables.schemas

4. Validate SQL (optional but recommended)

result = cloudos_cb.sql_validate(
    sql="SELECT person_id FROM omop_data.person WHERE year_of_birth >= 1960"
)

if result["isValid"]:
    print("SQL is valid")
else:
    print("SQL invalid:", result["error"]["message"])

5. Execute a query (high-level)

df = cloudos_cb.query(
    cohort_id="1a2b3c4d5e6f7g8h9i10j11k",
    sql="SELECT person_id, gender_concept_id FROM omop_data.person LIMIT 100",
)
print(df.head())
print(f"Total rows: {df.attrs['total_rows']}")

By default query() fetches all pages automatically. To return only the first page:

df = cloudos_cb.query(
    cohort_id="1a2b3c4d5e6f7g8h9i10j11k",
    sql="SELECT person_id FROM omop_data.person",
    all_pages=False,
    page_size=500,
)

6. Manual workflow

For fine-grained control over the submit / poll / fetch cycle:

# Step 1: Submit
task = cloudos_cb.query_submit_async(
    cohort_id="1a2b3c4d5e6f7g8h9i10j11k",
    sql="SELECT person_id FROM omop_data.person",
    pagination={"pageNumber": 0, "pageSize": 100},
)
print("Task ID:", task["task_id"])

# Step 2: Poll
status = cloudos_cb.query_status(task_id=task["task_id"])
print("Status:", status["status"])
# status["status"] is one of: "pending", "running", "completed", "failed"

# Step 3: Fetch results when completed
df = cloudos_cb.query_results(task_id=task["task_id"])
print(df)

API Reference

configure(profilename, apikey, workspace_id, base_url=..., set_default=False)

Create or update a named credential profile.

Parameter Type Description
profilename str Profile name (required)
apikey str API key (required)
workspace_id str Workspace/team ID (required)
base_url str CloudOS base URL (default: https://cloudos.lifebit.ai)
set_default bool Mark this profile as the default

profile_list()

Return a pandas.DataFrame of all configured profiles.


cohort_tables(cohort_id, profilename="")

Retrieve schemas, tables, and columns for a cohort.

Returns a CohortTables object. Print it for a human-readable tree, or access .schemas for the raw list.


sql_validate(sql, profilename="")

Validate SQL syntax and references before execution.

Returns a dict with isValid (bool), tableReferences, columnReferences, and on failure an error dict with a message key.


query_submit_async(cohort_id, sql, pagination=None, profilename="")

Submit an async SQL task. Returns a dict with:

Key Description
task_id Use this to poll status and fetch results
status Initial status (typically "pending")
query Echo of the submitted SQL
type Task type string
sync_execution_timeout Server-side timeout hint in ms
full_response Raw API response

pagination is an optional dict with pageNumber (int >= 0) and pageSize (int >= 1).


query_status(task_id, profilename="")

Check task status. Returns a dict with task_id, status, type, count_of_results, query, created_at, started_at, ended_at, user, full_response.


query_results(task_id, profilename="")

Fetch results for a completed task. Returns a pandas.DataFrame with metadata in .attrs:

Attribute Description
total_rows Total rows across all pages
page Page index returned
page_size Rows in this page
total_pages Total number of pages available

query(cohort_id, sql, poll_interval=2, max_wait=600, page_size=1000, all_pages=True, profilename="")

High-level orchestrator. Submits, polls, and fetches results automatically. When all_pages=True, submits one async task per page and concatenates them.

Parameter Default Description
poll_interval 2 Seconds between status checks (minimum 1)
max_wait 600 Maximum seconds to wait per task
page_size 1000 Rows per page
all_pages True Fetch all pages and combine them

Using multiple profiles

# Configure multiple profiles
cloudos_cb.configure(
    profilename="production",
    apikey="prod-key",
    workspace_id="prod-workspace",
    set_default=True,
)
cloudos_cb.configure(
    profilename="staging",
    apikey="stage-key",
    workspace_id="stage-workspace",
)

# Use default profile (production)
df = cloudos_cb.query(cohort_id="cohort-prod", sql="SELECT 1")

# Explicitly use staging profile
df = cloudos_cb.query(
    cohort_id="cohort-stage",
    sql="SELECT 1",
    profilename="staging",
)

Configuration storage

The config file is located at:

  • $CLOUDOS_CONFIG_DIR/config.json when the env var is set
  • ~/.cloudos/config.json otherwise (home directory)

File permissions are set to 0600 (user read/write only). The default location (~/.cloudos/) is outside any repository. If you override CLOUDOS_CONFIG_DIR to a path inside a project, add that directory to your .gitignore.

Error handling

from cloudos_cb import (
    CloudOSAuthError,
    CloudOSAccessError,
    CloudOSServerError,
    CloudOSConfigError,
    CloudOSValidationError,
)

try:
    df = cloudos_cb.query(cohort_id="...", sql="SELECT 1")
except CloudOSAuthError:
    print("Authentication failed - check your API key.")
except CloudOSAccessError:
    print("Access denied or resource not found.")
except CloudOSServerError:
    print("Server error - try again later.")
except CloudOSConfigError:
    print("Profile not configured - run configure() first.")
except CloudOSValidationError as e:
    print(f"Invalid input: {e}")

Logging

The package uses Python's standard logging module under the cloudos_cb namespace. To see informational messages:

import logging
logging.basicConfig(level=logging.INFO)

Running tests

pip install -e ".[dev]"
pytest

To check code style:

flake8 cloudos_cb tests

Package structure

cloudos-cb-py/
├── pyproject.toml        # Package metadata and build config
├── CHANGELOG.md
├── README.md
├── LICENSE
├── cloudos_cb/           # Package source
│   ├── __init__.py       # Public API
│   ├── exceptions.py     # Custom exception classes
│   ├── config.py         # Profile management
│   ├── http.py           # Authenticated HTTP helpers
│   ├── utils.py          # Shared utilities
│   └── queries.py        # Cohort Browser query functions
└── tests/
    ├── test_config.py
    ├── test_http.py
    ├── test_utils.py
    └── test_query.py

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

cloudos_cb_py-1.2.2.tar.gz (22.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cloudos_cb_py-1.2.2-py3-none-any.whl (16.3 kB view details)

Uploaded Python 3

File details

Details for the file cloudos_cb_py-1.2.2.tar.gz.

File metadata

  • Download URL: cloudos_cb_py-1.2.2.tar.gz
  • Upload date:
  • Size: 22.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for cloudos_cb_py-1.2.2.tar.gz
Algorithm Hash digest
SHA256 a37534d3e593ef4178d25499f3920e12cb4002fbcb5cccc769b4dd8e440bc8a8
MD5 38096358924f77dc0dccfae66d05bc24
BLAKE2b-256 05edbf428732d3f740eb3928db7cd0a27f833e447fdb7182df75e7ee6da43a63

See more details on using hashes here.

File details

Details for the file cloudos_cb_py-1.2.2-py3-none-any.whl.

File metadata

  • Download URL: cloudos_cb_py-1.2.2-py3-none-any.whl
  • Upload date:
  • Size: 16.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for cloudos_cb_py-1.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 718a145ec1441731062786c2c14fc30312bf6c73dcc5ed769fda971fc57130a7
MD5 ed5cfda21ef627db7a85d23d2a221891
BLAKE2b-256 e224e9db13b5f8e8e296417030102dae60f79f48f15393bb5d5000956e3be157

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page