Skip to content

qirabot/python-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Qirabot Python SDK

Official Python SDK for Qirabot - AI-powered device automation platform.

Automate mobile and web devices with natural language or structured actions. Let AI see the screen, click, type, extract data, and verify results.

Installation

pip install qirabot

Requires Python 3.10+.

Quick Start

Interactive Mode

Step-by-step control with real-time feedback via WebSocket:

from qirabot import Qirabot

bot = Qirabot("qk_your_api_key", base_url="https://app.qirabot.com")

with bot.task("device-id", name="wiki-extract") as t:
    t.navigate("https://en.wikipedia.org")
    t.type("Search Wikipedia input", "Artificial intelligence")
    t.click("Search button")
    t.wait_for("Wikipedia article page is visible", timeout_ms=10000)

    summary = t.extract("Get the first paragraph of the article")
    print(f"Summary: {summary}")

    t.verify("The article title contains 'Artificial intelligence'")

Submit Mode

Fire-and-forget execution with polling:

from qirabot import Qirabot, Action

bot = Qirabot("qk_your_api_key")

# Single AI instruction — let AI handle the entire workflow
task_id = bot.submit(
    "device-id",
    name="hn-top-stories",
    instruction="Go to news.ycombinator.com, extract the top 3 story titles and their scores",
)
result = bot.wait(task_id, timeout=120)
print(f"Status: {result.status}, Steps: {len(result.steps)}")

# Composed actions — precise control over each step
task_id = bot.submit("device-id", name="github-trending", actions=[
    Action.navigate("https://github.com/trending"),
    Action.wait_for("Trending repositories page is loaded"),
    Action.extract("Get the names and descriptions of the top 5 trending repositories", variable="repos"),
    Action.take_screenshot(),
])
result = bot.wait(task_id)
for step in result.steps:
    if step.output:
        print(step.output)

Download Images

Download screenshots from completed tasks:

# Download a single step screenshot
bot.download_screenshot(task_id, step=1, path="step_1.png")

# Get screenshot bytes without saving to file
img_bytes = bot.download_screenshot(task_id, step=1)

# Download all screenshots as a ZIP archive
bot.download_images(task_id, path="task_images.zip")

Actions

Action Android iOS Chrome Desktop Sandbox
click
double_click
type_text
type_direct
clear_text
press_key
scroll
scroll_at
wait
wait_for
take_screenshot
ai
extract
verify
search
hover
right_click
drag
navigate
go_back
swipe
start_app
stop_app

Events

Listen for real-time step and screenshot events in interactive mode:

from qirabot import StepEvent, ScreenshotEvent

with bot.task("device-id") as t:
    t.on("step", lambda s: print(f"Step {s.number}: {s.action} -> {s.status}"))
    t.on("screenshot", lambda s: s.save(f"screenshots/step_{s.number}.png"))

    t.click("Login button")

Workflow Integration

Interactive mode keeps the device connection alive across steps. You can run your own Python code between any two device actions — read files, validate data, branch on results, write reports:

import json
import os
from qirabot import Qirabot

bot = Qirabot(os.environ["QIRA_API_KEY"])

# Test data — ready to run, no extra files needed
test_cases = [
    {"url": "https://github.com",       "expect_keyword": "GitHub"},
    {"url": "https://www.wikipedia.org", "expect_keyword": "Wikipedia"},
    {"url": "https://news.ycombinator.com", "expect_keyword": "Hacker News"},
]

results = []

with bot.task("device-id", name="heading-check") as t:
    for case in test_cases:
        # Device: navigate to the page
        t.navigate(case["url"])
        t.wait_for("Page has finished loading", timeout_ms=15000)

        # Device: extract the page heading
        heading = t.extract("Get the main heading or site title text")

        # Your code: validate between steps
        passed = case["expect_keyword"].lower() in heading.lower()
        results.append({"url": case["url"], "heading": heading, "passed": passed})
        print(f"{'PASS' if passed else 'FAIL'} {case['url']} -> {heading}")

        # Conditional: screenshot only on failure
        if not passed:
            t.screenshot(path=f"{case['expect_keyword']}_fail.png")

print(json.dumps(results, indent=2, ensure_ascii=False))

Submit mode returns structured step results for post-processing:

import csv

task_id = bot.submit(
    "device-id",
    name="product-hunt-scrape",
    instruction="Go to producthunt.com, extract the top 5 products with their names and taglines",
)
result = bot.wait(task_id)

with open("steps.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["step", "action", "status", "duration_ms"])
    writer.writeheader()
    for step in result.steps:
        writer.writerow({
            "step": step.number,
            "action": step.action,
            "status": step.status,
            "duration_ms": step.step_duration_ms,
        })

Error Handling

from qirabot import ActionError, QirabotTimeoutError, DeviceOfflineError

try:
    with bot.task("device-id", name="error-demo") as t:
        t.navigate("https://httpstat.us/500")
        t.verify("Page shows a success message")
except ActionError as e:
    print(f"Action failed: {e}")
except DeviceOfflineError:
    print("Device is offline")
except QirabotTimeoutError:
    print("Operation timed out")

License

MIT

About

Official Python SDK for Qirabot - AI-powered device automation

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages