Skip to content

Configuration

If you ran qirabot login, you're already configured — the SDK reads the same saved key:

python
from qirabot import Qirabot

bot = Qirabot()  # api_key param > QIRA_API_KEY env var > `qirabot login` config

An environment variable always wins over the login config (so CI and one-off overrides behave as expected). Settings can also live in a project .env: scripts opt in explicitly — from qirabot import load_dotenv; load_dotenv() — which reads $QIRA_DOTENV or ./.env and never overrides exported variables. The CLI loads .env automatically; the SDK never reads it on its own.

Constructor options

ParameterEnv VariableDefaultDescription
api_keyQIRA_API_KEYqirabot login configAPI key
base_urlQIRA_BASE_URLhttps://app.qirabot.comAPI server URL
timeout120.0HTTP request timeout (seconds)
verify_sslTrueTLS verification (set False for self-hosted / self-signed)
model_alias""Model alias for all operations; empty = the server picks its default
languageserver defaultResponse language, e.g. "zh" / "en"
task_name""Task name (visible in dashboard)
task_id""Attach to an existing server task instead of creating one
source"sdk"Task source tag shown in the dashboard
reportTrueWrite an HTML run report on close
report_dirQIRA_REPORT_DIR./qira_runs/...Report output root
recordQIRA_RECORDFalseRecord the screen (ffmpeg)
record_fps12Recording frame rate
record_windowQIRA_RECORD_WINDOWFalseWindows: record just the window under test
record_audioQIRA_RECORD_AUDIOFalseWindows: capture system audio
record_audio_offsetQIRA_AUDIO_OFFSETNoneA/V sync offset in seconds
record_deviceQIRA_RECORD_DEVICEFalseRecord the device screen (adb / Appium)
record_mjpeg_urlQIRA_RECORD_MJPEG_URLNoneRecord an MJPEG stream (iOS WDA)
screenshot_annotateTrueRed crosshair at click/type coordinates
screenshot_format"jpeg""jpeg" or "png"
screenshot_quality80JPEG quality, 1–100
retry1Retries per action on transient failures (also a per-call kwarg: bot.click(..., retry=3))
retry_delay1.0Seconds between retries
settle_secondsQIRA_SETTLE_SECONDSper-platformPause after each action before the next screenshot
heartbeatQIRA_HEARTBEATTrueBackground liveness ping so long-sleeping scripts aren't reclaimed as orphans; QIRA_HEARTBEAT=0 is the kill switch
sync_local_stepsTrueUpload locally-executed steps to the server task timeline

What the record* knobs actually produce (formats, per-platform mechanics, where the file lands) is covered in Reports & Recording.

A few env-only overrides with no constructor equivalent: QIRA_ADB_PATH (explicit adb binary for the Android backend), QIRA_SCREEN_INDEX (which monitor to record on multi-display machines), QIRA_AUDIO_DEVICE (recording audio device), QIRA_DOTENV (path load_dotenv() reads instead of ./.env).

Model & language

model_alias selects which model backs every operation:

AliasTrade-off
fastCheapest, lowest latency
balancedGood cost/quality balance
balanced_proStronger than balanced
high_qualityBest quality, highest cost
python
bot = Qirabot(model_alias="high_quality")        # applies to all actions
bot.click(page, "Login", model_alias="fast")     # or override per call

The models are hosted server-side — there is no API key or endpoint to configure, and the concrete model behind each alias is managed (and upgraded) by the platform. qirabot models lists the aliases your account can use; leave the alias empty for the server default.

Which alias when? Rules of thumb:

  • Leave it unset until you have a reason not to — the server default is tuned for general use.
  • fast — clean, high-contrast UIs with unambiguous targets: form filling, standard web flows, big buttons. Cheapest and lowest latency.
  • high_quality — dense or low-contrast screens: small text, crowded dashboards, game UIs, subtle visual assertions ("the icon is greyed out").
  • Mix per call — the pattern that keeps cost down without giving up accuracy: default the bot to a cheap alias and raise only the hard calls:
python
bot = Qirabot(model_alias="fast")
bot.click(page, "the Search button")                        # easy → fast
data = bot.extract(page, "all prices in the results table",
                   model_alias="high_quality")              # hard → upgrade

Watching cost: extract() / verify() results and each StepResult from ai() carry input_tokens / output_tokens fields — a call's spend is their sum. See the Method Reference.

language sets the language of AI responses (extracted text, reasoning) — a short tag like "zh" or "en":

python
bot = Qirabot(language="zh")
text = bot.extract(page, "Get the main heading", language="zh")

Settle delay

After every screen-changing action each adapter pauses briefly so the UI repaints before the next screenshot — without it the model can capture a mid-animation frame and wrongly conclude the action did nothing. Defaults are tuned per platform (desktop/Android 1.0s, Selenium/Appium/WDA 0.6s; Playwright relies on its own auto-waiting and adds none).

python
bot = Qirabot(settle_seconds=1.5)   # laggy remote device: wait longer
bot = Qirabot(settle_seconds=0.3)   # fast local app: go quicker
bot = Qirabot(settle_seconds=0)     # disable; lean on wait_for() instead

This is a blunt fixed delay. For "wait until X appears" prefer the auto-wait timeout= / wait_for() polling — it returns as soon as the condition holds.

Task lifecycle

Each Qirabot instance manages a server-side task: created on construction (pass an existing task_id to attach instead), every call recorded as a step, marked complete on close() / context-manager exit. If close() is never called, atexit cleans up; a background heartbeat keeps the task alive while your process runs, and a silently-dead process is reclaimed by the server's orphan cleaner after ~5 minutes. To end a task as failed or cancelled instead of completed, see fail() / cancel() in the API reference.

Released under the MIT License.