Python client library

The official qube-survey Python client provides programmatic access to the hosted QUBE Survey REST API. It is a lightweight, zero-dependency library built entirely on the Python standard library, compatible with Python 3.9 and later.

Use the library to automate questionnaire version uploads, inspect review tickets, manage question reviews, and integrate survey authoring pipelines into continuous integration or automated testing workflows.

Download and installation

You can install the published wheel distribution or download the single-file module directly:

DistributionDownloadChecksum
Python Wheel (.whl)qube_survey-1.0.0-py3-none-any.whlSHA-256
Standalone module (.py)qube_survey_client.pySHA-256

Install via pip

pip install https://qubesurvey.com/downloads/qube_survey-1.0.0-py3-none-any.whl

Or download standalone script

curl -O https://qubesurvey.com/downloads/qube_survey_client.py

Because the client uses only Python standard library modules (urllib.request, json, pathlib, uuid), no external dependencies or virtual environment setups are required.

Authentication

The client supports both RFC 8628 OAuth device authorization and direct bearer token initialization.

Interactive device authorization

For command-line tools or interactive scripts, use the browser-based device flow:

from qube_survey import authorize, QubeSurveyClient
 
# Initiates device code flow; prints verification URL and user code
token = authorize("https://app.qubesurvey.com")
 
# Initialize client with the resulting token
client = QubeSurveyClient(token, "https://app.qubesurvey.com")

Cached credentials

Use load_client to persist credentials to disk and automatically refresh them when expired:

from pathlib import Path
from qube_survey import load_client
 
token_file = Path.home() / ".config" / "qube" / "credentials.json"
client = load_client(token_file, "https://app.qubesurvey.com")

Automated environments and CI/CD

In automated pipelines, supply an existing access token or service credential via environment variables:

import os
from qube_survey import QubeSurveyClient
 
token = os.environ["QUBE_API_TOKEN"]
client = QubeSurveyClient(token, "https://app.qubesurvey.com")

Managing Scripts and Versions

Uploaded script versions are immutable snapshots. Uploading a revised .qube or .odin file creates a new version record without modifying earlier snapshots.

from pathlib import Path
 
# List available scripts/projects
projects = client.list_projects()
for project in projects:
    print(f"{project['id']}: {project['name']}")
 
# Upload an immutable version
source_path = Path("feedback.qube")
source_content = source_path.read_text(encoding="utf-8")
 
version = client.create_version(
    project_id="proj_market_research_2026",
    instrument_id="feedback",
    source_name="feedback.qube",
    source=source_content,
    language="qube",  # "qube" or "odin"
)
 
print(f"Uploaded version ID: {version['id']}")

Inspecting question reviews

When reviewing an uploaded version, you can retrieve the declared questions, source line numbers, and review identity:

reviews = client.list_question_reviews(
    project_id="proj_market_research_2026",
    version_id=version["id"],
)
 
for review in reviews:
    print(f"Line {review['line']}: Question {review['question']}")

Managing tickets and proposed fixes

The issue tracker lets team members and AI assistants file tickets linked to specific interview paths and candidate source fixes:

# List open tickets
tickets = client.list_tickets("proj_market_research_2026", status="open")
for ticket in tickets:
    print(f"[{ticket['id']}] {ticket['title']}")
 
# File a project ticket
new_ticket = client.create_project_ticket(
    project_id="proj_market_research_2026",
    title="Routing error on Q2 branch",
    description="Selecting 'No' should route directly to Q5 instead of Q3.",
)
 
# Retrieve ticket details and reproduction answer log
details = client.get_ticket("proj_market_research_2026", new_ticket["id"])
answer_log = details.get("reproduction", {}).get("answerLog", [])
 
# Add an audit comment
client.add_ticket_comment(
    project_id="proj_market_research_2026",
    ticket_id=new_ticket["id"],
    body="Fixed in candidate version 0.8.6. Verified test journey passes.",
)
 
# Resolve the ticket
client.update_ticket(
    project_id="proj_market_research_2026",
    ticket_id=new_ticket["id"],
    status="resolved",
)

Command-line ticket tool

The repository includes a ready-to-run CLI built on this client:

# List open tickets for the current project
python3 tools/hosted_tickets.py list
 
# Inspect a ticket and reproduction replay
python3 tools/hosted_tickets.py show <ticket-id>
 
# Propose or apply a candidate fix
python3 tools/hosted_tickets.py fix <ticket-id> "Resolved routing on branch"
 
# Resolve ticket
python3 tools/hosted_tickets.py resolve <ticket-id> "Confirmed in debugger"

API reference summary

MethodDescription
list_projects()Returns all accessible scripts/projects.
create_project(name)Creates a new hosted script record.
list_versions(project_id)Enumerate immutable versions uploaded for a script.
get_version(project_id, version_id)Retrieve version details and source metadata.
create_version(...)Upload a new immutable questionnaire source version (.qube or .odin).
list_question_reviews(...)Inspect parsed questions, line coordinates, and review states.
list_tickets(project_id, ...)Query tickets filtered by status or version.
get_ticket(project_id, ticket_id)Fetch ticket reproduction answer logs and comments.
create_project_ticket(...)Create a new review ticket for a script.
update_ticket(project_id, ticket_id, ...)Update status, assignment, or metadata on a ticket.
add_ticket_comment(project_id, ticket_id, body)Append an audit comment to a ticket.