{
  "canonical_name": "oxylabs/oxylabs-ai-studio-py",
  "compilation_id": "pack_7d2958d93b914bdaba92a1d7df49ad55",
  "created_at": "2026-05-24T07:47:47.606818+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=prompt, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=prompt, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `pip install oxylabs-ai-studio` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "pip install oxylabs-ai-studio",
      "sandbox_container_image": "python:3.12-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "llm_execute_isolated_install",
      "sandbox_validation_id": "sbx_21956381ba104e288864ad19883fa56a"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_2b69f1c1199039ddb0cc114e699c36ef",
    "canonical_name": "oxylabs/oxylabs-ai-studio-py",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/oxylabs/oxylabs-ai-studio-py",
    "slug": "oxylabs-ai-studio-py",
    "source_packet_id": "phit_cdb549ccb0e24dfdaf14da83f707fe2e",
    "source_validation_id": "dval_79126fc4f2384013954c78fe80c83a06"
  },
  "merchandising": {
    "best_for": "需要流程自动化能力，并使用 local_cli的用户",
    "github_forks": 25,
    "github_stars": 2898,
    "one_liner_en": "Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.",
    "one_liner_zh": "Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.",
    "primary_category": {
      "category_id": "workflow-automation",
      "confidence": "high",
      "name_en": "Workflow Automation",
      "name_zh": "流程自动化",
      "reason": "strong category phrase match from project identity and outcome"
    },
    "target_user": "使用 local_cli 等宿主 AI 的用户",
    "title_en": "oxylabs-ai-studio-py",
    "title_zh": "oxylabs-ai-studio-py 能力包",
    "visible_tags": [
      {
        "label_en": "Browser Agents",
        "label_zh": "浏览器 Agent",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-browser-agents",
        "type": "product_domain"
      },
      {
        "label_en": "Web Task Automation",
        "label_zh": "网页任务自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-web-task-automation",
        "type": "user_job"
      },
      {
        "label_en": "Natural-language Web Actions",
        "label_zh": "自然语言网页操作",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-natural-language-web-actions",
        "type": "core_capability"
      },
      {
        "label_en": "Automated Workflow",
        "label_zh": "自动化工作流",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-automated-workflow",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Structured Data Extraction",
        "label_zh": "结构化数据提取",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-structured-data-extraction",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_cdb549ccb0e24dfdaf14da83f707fe2e",
  "page_model": {
    "artifacts": {
      "artifact_slug": "oxylabs-ai-studio-py",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "pip install oxylabs-ai-studio",
          "label": "Python / pip · 官方安装入口",
          "source": "https://github.com/oxylabs/oxylabs-ai-studio-py#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "自然语言网页操作",
        "自动化工作流",
        "结构化数据提取"
      ],
      "eyebrow": "流程自动化",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要流程自动化能力，并使用 local_cli的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering."
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "local_cli",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "prompt, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "仓库名 `oxylabs-ai-studio-py` 与安装入口 `oxylabs-ai-studio` 不完全一致。",
            "category": "身份坑",
            "evidence": [
              "identity.distribution | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | repo=oxylabs-ai-studio-py; install=oxylabs-ai-studio"
            ],
            "severity": "medium",
            "suggested_check": "在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。",
            "title": "仓库名和安装名不一致",
            "user_impact": "用户照着仓库名搜索包或照着包名找仓库时容易走错入口。"
          },
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：v.0.2.19",
            "category": "维护坑",
            "evidence": [
              "community_evidence:github | cevd_96a2e22cbea94aac8c2788f763ce7c04 | https://github.com/oxylabs/oxylabs-ai-studio-py/releases/tag/v0.2.19 | 来源类型 github_release 暴露的待验证使用条件。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：v.0.2.19",
            "user_impact": "可能影响升级、迁移或版本选择。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：身份坑 - 仓库名和安装名不一致。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": 4,
        "forks": 25,
        "license": "unknown",
        "note": "站点快照，非实时质量证明；用于开工前背景判断。",
        "stars": 2898
      },
      "source_url": "https://github.com/oxylabs/oxylabs-ai-studio-py",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.",
      "title": "oxylabs-ai-studio-py 能力包",
      "trial_prompt": "# oxylabs-ai-studio-py - Prompt Preview\n\n> Copy the prompt below into your AI host before installing anything.\n> Its purpose is to let you safely feel the project's workflow, not to claim the project has already run.\n\n## Copy this prompt\n\n```text\nYou are using an independent Doramagic capability pack for oxylabs/oxylabs-ai-studio-py.\n\nProject:\n- Name: oxylabs-ai-studio-py\n- Repository: https://github.com/oxylabs/oxylabs-ai-studio-py\n- Summary: Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.\n- Host target: local_cli\n\nGoal:\nHelp me evaluate this project for the following task without installing it yet: Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.\n\nBefore taking action:\n1. Restate my task, success standard, and boundary.\n2. Identify whether the next step requires tools, browser access, network access, filesystem access, credentials, package installation, or host configuration.\n3. Use only the Doramagic Project Pack, the upstream repository, and the source-linked evidence listed below.\n4. If a real command, install step, API call, file write, or host integration is required, mark it as \"requires post-install verification\" and ask for approval first.\n5. If evidence is missing, say \"evidence is missing\" instead of filling the gap.\n\nPreviewable capabilities:\n- Capability 1: Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.\n\nCapabilities that require post-install verification:\n- Capability 1: Use the source-backed project context to guide one small, checkable workflow step.\n\nCore service flow:\n1. quickstart: Quick Start Guide. Produce one small intermediate artifact and wait for confirmation.\n2. ai-scraper: AI-Scraper Feature. Produce one small intermediate artifact and wait for confirmation.\n3. ai-crawler: AI-Crawler Feature. Produce one small intermediate artifact and wait for confirmation.\n4. ai-search: AI-Search Feature. Produce one small intermediate artifact and wait for confirmation.\n5. browser-agent: Browser Agent Feature. Produce one small intermediate artifact and wait for confirmation.\n\nSource-backed evidence to keep in mind:\n- https://github.com/oxylabs/oxylabs-ai-studio-py\n- https://github.com/oxylabs/oxylabs-ai-studio-py#readme\n- src/oxylabs_ai_studio/client.py\n- src/oxylabs_ai_studio/__init__.py\n- src/oxylabs_ai_studio/apps/ai_scraper.py\n- examples/scrape_markdown.py\n- examples/scrape_pydantic_schema.py\n- examples/scrape_generated_schema.py\n- src/oxylabs_ai_studio/apps/ai_crawler.py\n- examples/crawl_markdown.py\n\nFirst response rules:\n1. Start Step 1 only.\n2. Explain the one service action you will perform first.\n3. Ask exactly three questions about my target workflow, success standard, and sandbox boundary.\n4. Stop and wait for my answers.\n\nStep 1 follow-up protocol:\n- After I answer the first three questions, stay in Step 1.\n- Produce six parts only: clarified task, success standard, boundary conditions, two or three options, tradeoffs for each option, and one recommendation.\n- End by asking whether I confirm the recommendation.\n- Do not move to Step 2 until I explicitly confirm.\n\nConversation rules:\n- Advance one step at a time and wait for confirmation after each small artifact.\n- Write outputs as recommendations or planned checks, not as completed execution.\n- Do not claim tests passed, files changed, commands ran, APIs were called, or the project was installed.\n- If the user asks for execution, first provide the sandbox setup, expected output, rollback, and approval checkpoint.\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_release: v.0.2.19（https://github.com/oxylabs/oxylabs-ai-studio-py/releases/tag/v0.2.19）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_release",
              "source": "github",
              "title": "v.0.2.19",
              "url": "https://github.com/oxylabs/oxylabs-ai-studio-py/releases/tag/v0.2.19"
            }
          ],
          "status": "已收录 1 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "流程自动化",
      "desc": "Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.",
      "effort": "安装已验证",
      "forks": 25,
      "icon": "bolt",
      "name": "oxylabs-ai-studio-py 能力包",
      "risk": "需复核",
      "slug": "oxylabs-ai-studio-py",
      "stars": 2898,
      "tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "自然语言网页操作",
        "自动化工作流",
        "结构化数据提取"
      ],
      "thumb": "gray",
      "type": "Prompt Preview"
    },
    "manual": {
      "markdown": "# https://github.com/oxylabs/oxylabs-ai-studio-py 项目说明书\n\n生成时间：2026-05-18 03:01:39 UTC\n\n## 目录\n\n- [Installation Guide](#installation)\n- [Quick Start Guide](#quickstart)\n- [AI-Scraper Feature](#ai-scraper)\n- [AI-Crawler Feature](#ai-crawler)\n- [AI-Search Feature](#ai-search)\n- [AI-Map Feature](#ai-map)\n- [Browser Agent Feature](#browser-agent)\n- [Client Architecture](#client-architecture)\n- [Data Models](#data-models)\n- [Configuration and Settings](#configuration-settings)\n- [Error Handling and Logging](#error-handling-logging)\n\n<a id='installation'></a>\n\n## Installation Guide\n\n### 相关页面\n\n相关主题：[Quick Start Guide](#quickstart)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [pyproject.toml](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/pyproject.toml)\n- [readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n</details>\n\n# Installation Guide\n\n## Overview\n\nThis guide covers the installation process for the **Oxylabs AI Studio Python SDK** (`oxylabs-ai-studio`). The SDK provides a Python interface for interacting with Oxylabs AI Studio API services, including AI-Scraper, AI-Crawler, AI-Browser-Agent, and other data extraction tools.\n\n资料来源：[readme.md:1-10]()\n\n## System Requirements\n\n| Requirement | Minimum Version | Notes |\n|-------------|-----------------|-------|\n| Python | 3.10+ | Earlier versions are not supported |\n| Package Manager | pip | Standard Python package installer |\n| API Key | Required | Must be obtained from Oxylabs AI Studio |\n\n资料来源：[readme.md:10-11]()\n\n## Prerequisites\n\nBefore installing the SDK, ensure your environment meets the following requirements:\n\n### Python Version Check\n\n```bash\npython --version\n# or\npython3 --version\n```\n\nThe output should show Python 3.10 or higher.\n\n### pip Availability\n\n```bash\npip --version\n# or\npip3 --version\n```\n\n## Installation Methods\n\n### Standard Installation (Recommended)\n\nThe official release version can be installed directly from PyPI using pip:\n\n```bash\npip install oxylabs-ai-studio\n```\n\n资料来源：[readme.md:14]()\n\n### Installation from Source\n\nFor development or testing purposes, you can install from the source repository:\n\n```bash\ngit clone https://github.com/oxylabs/oxylabs-ai-studio-py.git\ncd oxylabs-ai-studio-py\npip install -e .\n```\n\n## Post-Installation Verification\n\nAfter installation, verify the SDK is properly installed:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\nfrom oxylabs_ai_studio.apps.browser_agent import BrowserAgent\nfrom oxylabs_ai_studio.apps.ai_map import AiMap\n\nprint(\"Oxylabs AI Studio SDK imported successfully\")\n```\n\nIf no import errors occur, the installation was successful.\n\n## SDK Components\n\nThe SDK includes the following main components:\n\n| Component | Module Path | Purpose |\n|-----------|-------------|---------|\n| AI Scraper | `oxylabs_ai_studio.apps.ai_scraper` | Scrape website content with AI |\n| AI Crawler | `oxylabs_ai_studio.apps.ai_crawler` | Crawl and extract data from sites |\n| AI Search | `oxylabs_ai_studio.apps.ai_search` | Perform AI-powered SERP searches |\n| Browser Agent | `oxylabs_ai_studio.apps.browser_agent` | Automate browser-based tasks |\n| AI Map | `oxylabs_ai_studio.apps.ai_map` | Map website structures |\n\n资料来源：[readme.md:6-7]()\n\n## Quick Start Configuration\n\nAfter installation, you need to configure your API key to use the SDK:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\n# Initialize with your API key\nscraper = AiScraper(api_key=\"<YOUR_API_KEY>\")\n\n# Example usage\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"markdown\"\n)\n```\n\nReplace `<YOUR_API_KEY>` with your actual Oxylabs AI Studio API key.\n\n## Environment Setup Recommendations\n\n### Virtual Environment (Recommended)\n\nFor isolated development, use a virtual environment:\n\n```bash\n# Create virtual environment\npython -m venv ai-studio-env\n\n# Activate on Linux/macOS\nsource ai-studio-env/bin/activate\n\n# Activate on Windows\nai-studio-env\\Scripts\\activate\n\n# Install SDK\npip install oxylabs-ai-studio\n```\n\n### Using pyproject.toml\n\nIf you're managing a project with `pyproject.toml`:\n\n```toml\n[project]\nname = \"oxylabs-ai-studio\"\nversion = \"latest\"\nrequires-python = \">=3.10\"\ndependencies = [\n    \"oxylabs-ai-studio\",\n]\n```\n\n## Dependencies\n\nThe SDK relies on the following core dependencies (automatically installed):\n\n- `httpx` - HTTP client for API requests\n- `pydantic` - Data validation using Python type hints\n- Standard library modules: `time`, `asyncio`, `logging`\n\n资料来源：[pyproject.toml](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/pyproject.toml)\n\n## Troubleshooting\n\n### Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| ImportError | Ensure Python 3.10+ is installed |\n| AuthenticationError | Verify API key is correct and active |\n| TimeoutError | Check network connectivity |\n| pip install fails | Try upgrading pip: `pip install --upgrade pip` |\n\n### Upgrade Instructions\n\nTo upgrade to the latest version:\n\n```bash\npip install --upgrade oxylabs-ai-studio\n```\n\n## Related Documentation\n\n- [Oxylabs AI Studio](https://aistudio.oxylabs.io/) - Official product page\n- [API Documentation](https://developers.oxylabs.io/) - Detailed API reference\n- [Discord Community](https://discord.gg/Pds3gBmKMH) - Get help from the community\n\n---\n\n<a id='quickstart'></a>\n\n## Quick Start Guide\n\n### 相关页面\n\n相关主题：[Installation Guide](#installation), [AI-Scraper Feature](#ai-scraper), [AI-Crawler Feature](#ai-crawler)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n- [agentic_code_guide.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/agentic_code_guide.md)\n- [examples/scrape_markdown.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_markdown.py)\n- [examples/crawl_markdown.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/crawl_markdown.py)\n- [examples/search_instant.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/search_instant.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n</details>\n\n# Quick Start Guide\n\n## Overview\n\nThe **Oxylabs AI Studio Python SDK** (`oxylabs-ai-studio`) provides a simple Python interface for interacting with [Oxylabs AI Studio API](https://aistudio.oxylabs.io/) services. This SDK enables developers to integrate AI-powered web scraping, crawling, search, and browser automation capabilities into their Python applications with minimal configuration.\n\n**Key Features:**\n\n- AI-Scraper: Extract structured data from web pages using natural language prompts\n- AI-Crawler: Automatically discover and crawl related pages starting from a URL\n- AI-Search: Perform SERP (Search Engine Results Page) searches with content extraction\n- Browser-Agent: Automate browser actions (clicks, scrolls, navigation) via prompts\n- AI-Map: Discover website structure and find pages matching specific keywords\n\n**Requirements:**\n\n| Requirement | Version |\n|-------------|---------|\n| Python | 3.10+ |\n| API Key | Valid Oxylabs AI Studio API key |\n\n资料来源：[readme.md:1-15]()\n\n---\n\n## Installation\n\nInstall the SDK using pip:\n\n```bash\npip install oxylabs-ai-studio\n```\n\n资料来源：[readme.md:16-19]()\n\n---\n\n## Core Concepts\n\n### Authentication\n\nAll applications in the SDK require an API key for authentication. You can obtain an API key from the [Oxylabs AI Studio dashboard](https://aistudio.oxylabs.io/).\n\n### Application Classes\n\nThe SDK provides five main application classes, each located in `oxylabs_ai_studio.apps`:\n\n| Application | Class | Purpose |\n|-------------|-------|---------|\n| AI-Scraper | `AiScraper` | Single-page content extraction |\n| AI-Crawler | `AiCrawler` | Multi-page website crawling |\n| AI-Search | `AiSearch` | Search engine results extraction |\n| Browser-Agent | `BrowserAgent` | Browser automation |\n| AI-Map | `AiMap` | Website structure discovery |\n\n### Output Formats\n\nEach application supports multiple output formats:\n\n| Format | Description | Applicable Apps |\n|--------|-------------|-----------------|\n| `json` | Structured JSON data (requires schema) | All apps |\n| `markdown` | Markdown formatted text | All apps |\n| `html` | Raw HTML content | Scraper, Browser-Agent |\n| `screenshot` | Base64-encoded screenshot | Scraper, Browser-Agent |\n| `csv` | Comma-separated values | Scraper, Crawler |\n| `toon` | AI-defined format | Scraper, Crawler |\n\n---\n\n## Quick Start Workflows\n\n### Mermaid: SDK Initialization Flow\n\n```mermaid\ngraph TD\n    A[Install SDK] --> B[Import Application Class]\n    B --> C[Initialize with API Key]\n    C --> D[Call Method<br/>scrape/crawl/search/run]\n    D --> E[Receive AiXxxJob Response]\n    E --> F[Access result.data]\n    \n    style A fill:#e1f5fe\n    style E fill:#fff3e0\n    style F fill:#e8f5e8\n```\n\n---\n\n## Usage Examples\n\n### AI-Scraper: Basic Scraping\n\nScrape a single URL and extract content in Markdown format:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nurl = \"https://sandbox.oxylabs.io/products/1\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"markdown\",\n    render_javascript=False,\n    geo_location=\"Germany\",\n)\nprint(result)\n```\n\n资料来源：[examples/scrape_markdown.py:1-14]()\n\n### AI-Scraper: Structured JSON Extraction\n\nExtract structured data using a JSON schema:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nschema = scraper.generate_schema(\n    prompt=\"want to parse developer, platform, type, price game title, genre (array) and description\"\n)\nprint(f\"Generated schema: {schema}\")\n\nurl = \"https://sandbox.oxylabs.io/products/3\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"json\",\n    schema=schema,\n    render_javascript=False,\n)\nprint(result)\n```\n\n资料来源：[examples/scrape_generated_schema.py:1-19]()\n\n**Parameters for `AiScraper.scrape`:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `url` | `str` | Yes | - | Target URL to scrape |\n| `output_format` | `Literal[\"json\", \"markdown\", \"csv\", \"screenshot\", \"toon\"]` | No | `\"markdown\"` | Output format |\n| `schema` | `dict \\| None` | Conditional | `None` | JSON schema (required for `json`, `csv`, `toon`) |\n| `render_javascript` | `bool` | No | `False` | Enable JavaScript rendering |\n| `geo_location` | `str` | No | `None` | Proxy location (ISO2 or country name) |\n\n资料来源：[readme.md:55-68]()\n\n---\n\n### AI-Crawler: Website Crawling\n\nCrawl a website starting from a specific URL:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nurl = \"https://oxylabs.io\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"markdown\",\n    render_javascript=False,\n    return_sources_limit=3,\n    geo_location=\"France\",\n)\nprint(\"Results:\")\nfor item in result.data:\n    print(item, \"\\n\")\n```\n\n资料来源：[examples/crawl_markdown.py:1-18]()\n\n### AI-Crawler: Structured Extraction with Pydantic Schema\n\nUse Pydantic models for type-safe schema definition:\n\n```python\nfrom pydantic import BaseModel, Field\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nclass ProxyPlan(BaseModel):\n    name: str = Field(description=\"The name of the proxy plan\")\n    price: str = Field(description=\"The price of the proxy plan\")\n    features: list[str] = Field(description=\"The features of the proxy plan\")\n\nclass ProxyPlans(BaseModel):\n    proxy_plans: list[ProxyPlan] = Field(description=\"The proxy plans\")\n\nurl = \"https://oxylabs.io/\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"json\",\n    schema=ProxyPlans.model_json_schema(),\n    render_javascript=False,\n)\nprint(\"Results:\\n\")\nfor item in result.data:\n    print(item, \"\\n\")\n```\n\n资料来源：[examples/crawl_pydantic_schema.py:1-30]()\n\n**Parameters for `AiCrawler.crawl`:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `url` | `str` | Yes | - | Starting URL to crawl |\n| `user_prompt` | `str` | Yes | - | Natural language prompt to guide extraction |\n| `output_format` | `Literal[\"json\", \"markdown\", \"csv\", \"toon\"]` | No | `\"markdown\"` | Output format |\n| `schema` | `dict \\| None` | Conditional | `None` | JSON schema (required for `json`, `csv`, `toon`) |\n| `render_javascript` | `bool` | No | `False` | Enable JavaScript rendering |\n| `return_sources_limit` | `int` | No | `25` | Max number of sources to return |\n| `geo_location` | `str` | No | `None` | Proxy location (ISO2 or country name) |\n| `max_credits` | `int \\| None` | No | `None` | Maximum credits to use |\n\n资料来源：[readme.md:33-52]()\n\n---\n\n### AI-Search: Search Engine Results\n\nPerform a search with full content extraction:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna recipe\"\nresult = search.search(\n    query=query,\n    limit=5,\n    render_javascript=False,\n    return_content=True,\n)\nprint(result.data)\n```\n\n资料来源：[readme.md:54-67]()\n\n### AI-Search: Instant Search\n\nFor fast results without content (up to 10 results):\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna recipes\"\nresult = search.instant_search(\n    query=query,\n    limit=5,\n    geo_location=\"United States\",\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_instant.py:1-13]()\n\n### AI-Search: Results Without Content\n\nOptimize for speed by disabling content extraction:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna\"\nresult = search.search(\n    query=query,\n    limit=5,\n    render_javascript=False,\n    return_content=False,\n    geo_location=\"Italy\",\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_no_content.py:1-14]()\n\n**Parameters for `AiSearch.search`:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | `str` | Yes | - | What to search for |\n| `limit` | `int` | No | `10` | Max results (max: 50) |\n| `render_javascript` | `bool` | No | `False` | Enable JavaScript rendering |\n| `return_content` | `bool` | No | `True` | Include markdown content in results |\n| `geo_location` | `str` | No | `None` | ISO 2-letter format or country name |\n\n**Instant Search Parameters:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | `str` | Yes | - | The search query |\n| `limit` | `int` | No | `10` | Max results (max: 10) |\n| `geo_location` | `str` | No | `None` | Google's canonical location name |\n\n> **Note:** When `limit <= 10` and `return_content=False`, the search automatically uses the instant endpoint (`/search/instant`) which returns results immediately without polling.\n\n资料来源：[readme.md:68-95]()\n\n---\n\n## Response Data Models\n\n### Mermaid: Response Flow\n\n```mermaid\ngraph LR\n    A[API Request] --> B{AI Studio API}\n    B --> C{Status Check}\n    C -->|Processing| D[Poll for completion]\n    C -->|Completed| E[Return AiXxxJob]\n    C -->|Failed| F[Return with error]\n    D --> C\n    \n    style E fill:#e8f5e8\n    style F fill:#ffebee\n```\n\n### AiScraperJob\n\n```python\nclass AiScraperJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: str | dict | None\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the job |\n| `message` | `str \\| None` | Error code or status message |\n| `data` | `str \\| dict \\| None` | Result data (type depends on `output_format`) |\n\n资料来源：[agentic_code_guide.md:95-104]()\n\n### BrowserAgentJob\n\n```python\nclass DataModel(BaseModel):\n    type: Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\"]\n    content: dict[str, Any] | str | None\n\nclass BrowserAgentJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: DataModel | None = None\n```\n\n资料来源：[agentic_code_guide.md:27-35]()\n\n---\n\n## Best Practices\n\n### Rate Limiting\n\nImplement rate limiting in your application to respect the limits associated with your purchased plan. This prevents service disruptions or overuse.\n\n### Retry Mechanism\n\nImplement retry logic for handling failed requests, but include a limit on the number of retries to avoid:\n\n- Infinite loops\n- Excessive API calls\n- Unnecessary costs\n\n```python\nimport time\n\nMAX_RETRIES = 3\nRETRY_DELAY = 5  # seconds\n\nfor attempt in range(MAX_RETRIES):\n    try:\n        result = scraper.scrape(url=url, output_format=\"markdown\")\n        break\n    except TimeoutError:\n        if attempt < MAX_RETRIES - 1:\n            time.sleep(RETRY_DELAY)\n        else:\n            raise\n```\n\n### Schema Generation\n\nUse the built-in `generate_schema()` method to automatically create JSON schemas from natural language prompts:\n\n```python\nschema = scraper.generate_schema(\n    prompt=\"want to parse developer, platform, type, price game title, genre (array) and description\"\n)\n```\n\nThis approach is recommended over manually writing JSON schemas.\n\n资料来源：[agentic_code_guide.md:7-18]()\n\n### JavaScript Rendering\n\n- Set `render_javascript=False` for static pages to improve performance\n- Use `render_javascript=True` for Single Page Applications (SPAs) or pages with dynamic content\n- The `AiScraper` also supports `render_javascript=\"auto\"` for automatic detection\n\n---\n\n## Next Steps\n\nAfter completing this quick start guide, explore these topics:\n\n1. **Advanced Configuration**: Configure timeouts, custom headers, and proxy settings\n2. **Error Handling**: Implement robust error handling for production applications\n3. **Async Usage**: Use async/await patterns for concurrent operations\n4. **Use Cases**: Review [use case examples](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/agentic_code_guide.md#use-cases-examples) for common workflows\n\n---\n\n## Summary\n\nThe Oxylabs AI Studio Python SDK provides a streamlined interface for AI-powered web data extraction. With just an API key and a few lines of code, you can:\n\n| Capability | SDK Component | Primary Method |\n|------------|---------------|----------------|\n| Extract data from single pages | `AiScraper` | `scrape()` |\n| Crawl entire websites | `AiCrawler` | `crawl()` |\n| Search search engines | `AiSearch` | `search()` / `instant_search()` |\n| Automate browser actions | `BrowserAgent` | `run()` / `run_async()` |\n| Discover site structure | `AiMap` | `map()` |\n\n---\n\n<a id='ai-scraper'></a>\n\n## AI-Scraper Feature\n\n### 相关页面\n\n相关主题：[AI-Crawler Feature](#ai-crawler), [Data Models](#data-models)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [examples/scrape_markdown.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_markdown.py)\n- [examples/scrape_pydantic_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_pydantic_schema.py)\n- [examples/scrape_generated_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_generated_schema.py)\n</details>\n\n# AI-Scraper Feature\n\n## Overview\n\nThe **AI-Scraper** is a core feature of the Oxylabs AI Studio Python SDK designed to scrape website content and return extracted data in multiple formats. It leverages AI capabilities to intelligently extract structured or unstructured data from web pages based on natural language prompts or JSON schemas.\n\n### Purpose and Scope\n\nThe AI-Scraper provides the following capabilities:\n\n- **Flexible Output Formats**: Supports Markdown, JSON, CSV, and screenshot output\n- **Schema-Based Extraction**: Enables structured data extraction using JSON schemas or Pydantic models\n- **AI-Powered Parsing**: Uses natural language prompts to guide data extraction\n- **JavaScript Rendering**: Supports pages requiring client-side rendering\n- **Geo-Location Targeting**: Allows scraping from specific geographic locations\n\n## Architecture\n\n```mermaid\ngraph TD\n    A[User Request] --> B[AiScraper Class]\n    B --> C{Output Format}\n    C -->|markdown| D[Markdown Parser]\n    C -->|json| E[Schema Validator]\n    C -->|csv| F[CSV Formatter]\n    C -->|screenshot| G[Screenshot Capture]\n    D --> H[API Endpoint]\n    E --> H\n    F --> H\n    G --> H\n    H --> I[Oxylabs API]\n    I --> J[Response Handler]\n    J --> K[Structured Data]\n```\n\n## Core Components\n\n### AiScraper Class\n\nThe main interface for web scraping operations. The class provides both synchronous and asynchronous methods for scraping web content.\n\n**Import Statement:**\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n```\n\n**Initialization:**\n```python\nscraper = AiScraper(api_key=\"<API_KEY>\")\n```\n\n### Key Methods\n\n| Method | Description | Type |\n|--------|-------------|------|\n| `scrape()` | Synchronous scraping operation | Sync |\n| `scrape_async()` | Asynchronous scraping operation | Async |\n| `generate_schema()` | Auto-generate JSON schema from prompt | Helper |\n\n## API Parameters\n\n### Required Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `url` | `str` | Target URL to scrape |\n| `output_format` | `Literal[\"json\", \"markdown\", \"csv\", \"screenshot\"]` | Desired output format |\n\n### Optional Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `schema` | `dict \\| None` | `None` | JSON schema for structured extraction (required for \"json\" and \"csv\" formats) |\n| `render_javascript` | `bool` | `False` | Enable JavaScript rendering |\n| `geo_location` | `str` | `None` | Proxy location in ISO2 format or country name |\n\n## Usage Patterns\n\n### Basic Markdown Scraping\n\nThe simplest use case extracts page content as Markdown without requiring a schema.\n\n**Example** ([examples/scrape_markdown.py](examples/scrape_markdown.py)):\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nurl = \"https://sandbox.oxylabs.io/products/1\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"markdown\",\n    render_javascript=False,\n    geo_location=\"Germany\",\n)\nprint(result)\n```\n\n### Schema-Based JSON Extraction\n\nFor structured data extraction, provide a JSON schema defining the expected output structure.\n\n**Example** ([examples/scrape_generated_schema.py](examples/scrape_generated_schema.py)):\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nschema = scraper.generate_schema(\n    prompt=\"want to parse developer, platform, type, price game title, genre (array) and description\"\n)\nprint(f\"Generated schema: {schema}\")\n\nurl = \"https://sandbox.oxylabs.io/products/3\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"json\",\n    schema=schema,\n    render_javascript=False,\n)\nprint(result)\n```\n\n### Pydantic Model Integration\n\nFor type-safe extraction, use Pydantic models which are automatically converted to JSON schemas.\n\n**Example** ([examples/scrape_pydantic_schema.py](examples/scrape_pydantic_schema.py)):\n```python\nfrom pydantic import BaseModel\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nclass Game(BaseModel):\n    title: str\n    genre: list[str]\n    developer: str\n    platform: str\n    game_type: str\n    description: str\n    price: str\n    availability: str\n\nurl = \"https://sandbox.oxylabs.io/products/1\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"json\",\n    schema=Game.model_json_schema(),\n    render_javascript=False,\n)\nprint(result)\n```\n\n## Async Usage\n\n### Async Interface\n\nFor high-performance applications, use the async interface:\n\n```python\nimport asyncio\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nasync def main():\n    url = \"https://sandbox.oxylabs.io/products/3\"\n    result = await scraper.scrape_async(\n        url=url,\n        output_format=\"json\",\n        schema={\"type\": \"object\", \"properties\": {\"price\": {\"type\": \"string\"}}, \"required\": []},\n        render_javascript=False,\n    )\n    print(result)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n## Response Data Model\n\n### AiScraperJob Structure\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the scraping job |\n| `message` | `str \\| None` | Status message or error description |\n| `data` | `dict \\| str \\| None` | Extracted data based on output format |\n\n### Data Type by Output Format\n\n| Output Format | Data Type | Description |\n|---------------|-----------|-------------|\n| `json` | `dict` | Parsed JSON object |\n| `markdown` | `str` | HTML content converted to Markdown |\n| `csv` | `str` | Comma-separated values string |\n| `screenshot` | `str` | Base64-encoded image data |\n\n## Schema Generation\n\nThe AI-Scraper provides a `generate_schema()` helper method that uses AI to create appropriate JSON schemas from natural language prompts.\n\n```python\nschema = scraper.generate_schema(\n    prompt=\"proxy plans which have name, price, and features\"\n)\n```\n\n**Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `prompt` | `str` | Natural language description of desired data structure |\n\n**Returns:** `dict` - A valid JSON schema object\n\n## Workflow Diagram\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant AiScraper\n    participant API\n    participant Response\n\n    User->>AiScraper: scrape(url, output_format, schema)\n    AiScraper->>AiScraper: Validate parameters\n    AiScraper->>API: POST request with payload\n    API->>API: Process scraping request\n    API->>Response: Return extracted data\n    Response->>AiScraper: AiScraperJob response\n    AiScraper->>User: Return result object\n```\n\n## Configuration Options\n\n### JavaScript Rendering\n\nThe `render_javascript` parameter controls browser rendering behavior:\n\n| Value | Behavior |\n|-------|----------|\n| `False` | No JavaScript rendering (default) |\n| `True` | Always render JavaScript |\n| `\"auto\"` | Service automatically detects if rendering is needed |\n\n### Geo-Location\n\nSpecify geographic location for proxy-based scraping:\n\n```python\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    geo_location=\"Germany\",  # Country name\n    # or \"DE\" for ISO2 format\n)\n```\n\n## Error Handling\n\nWhen a scraping operation fails, the response will include:\n\n1. `run_id` - The job identifier for troubleshooting\n2. `message` - Error description\n3. `data` - `None` when an error occurs\n\nAlways check the `message` field before accessing `data`:\n\n```python\nresult = scraper.scrape(url=url, output_format=\"json\", schema=schema)\nif result.message:\n    print(f\"Error: {result.message}\")\nelse:\n    print(result.data)\n```\n\n## Best Practices\n\n1. **Use Appropriate Schemas**: Always provide a valid JSON schema when using `output_format=\"json\"` or `output_format=\"csv\"`\n2. **Enable JS Rendering When Needed**: Set `render_javascript=True` for SPAs and dynamic content\n3. **Specify Geo-Location**: Use `geo_location` parameter when location-specific content is required\n4. **Handle Errors Gracefully**: Always check the `message` field in the response\n\n## Summary\n\nThe AI-Scraper feature provides a powerful, flexible interface for web content extraction within the Oxylabs AI Studio ecosystem. With support for multiple output formats, schema-based extraction, and both synchronous and asynchronous operation modes, it serves as a versatile tool for various web scraping use cases.\n\n---\n\n<a id='ai-crawler'></a>\n\n## AI-Crawler Feature\n\n### 相关页面\n\n相关主题：[AI-Scraper Feature](#ai-scraper), [AI-Map Feature](#ai-map)\n\n<details>\n<summary>Related Source Files</summary>\n\nThe following source files were used to generate this documentation:\n\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [examples/crawl_markdown.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/crawl_markdown.py)\n- [examples/crawl_pydantic_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/crawl_pydantic_schema.py)\n- [examples/crawl_generated_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/crawl_generated_schema.py)\n- [readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n</details>\n\n# AI-Crawler Feature\n\n## Overview\n\nThe AI-Crawler is a web crawling and content extraction module within the Oxylabs AI Studio Python SDK. It enables intelligent, AI-powered website crawling with natural language prompts to guide content extraction. The crawler navigates starting URLs, discovers relevant pages based on user-defined prompts, and returns structured or unstructured data in multiple formats.\n\n**Key Characteristics:**\n- Natural language-based extraction guidance via `user_prompt`\n- Multi-format output support (JSON, Markdown, CSV, Toon)\n- JavaScript rendering capability for dynamic web pages\n- Geographic localization through proxy positioning\n- Schema-driven structured extraction with optional automatic schema generation\n- Polling-based async job completion handling with configurable timeout\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:1-31]()\n\n## Architecture\n\n### Class Hierarchy\n\n```mermaid\ngraph TD\n    A[OxyStudioAIClient] --> B[AiCrawler]\n    B --> C[AiCrawlerJob]\n    \n    B1[BaseModel] --> C\n```\n\nThe `AiCrawler` class inherits from `OxyStudioAIClient`, which provides the underlying API client functionality including authentication, request handling, and response parsing.\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:23-31]()\n\n### Data Models\n\n```python\nclass AiCrawlerJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: list[dict[str, Any]] | list[str] | None = None\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the crawl job |\n| `message` | `str \\| None` | Error code or status message if job failed |\n| `data` | `list[dict[str, Any]] \\| list[str] \\| None` | Extracted content based on output format |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:27-30]()\n\n## Configuration Constants\n\n| Constant | Value | Purpose |\n|----------|-------|---------|\n| `CRAWLER_TIMEOUT_SECONDS` | `600` (10 minutes) | Maximum time to wait for job completion |\n| `POLL_INTERVAL_SECONDS` | `5` | Interval between status checks |\n| `POLL_MAX_ATTEMPTS` | `120` | Maximum polling attempts before timeout |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:12-14]()\n\n## Core Methods\n\n### `crawl()`\n\nThe primary method for initiating a crawl operation.\n\n```python\ndef crawl(\n    self,\n    url: str,\n    user_prompt: str,\n    output_format: Literal[\"json\", \"markdown\", \"csv\", \"toon\"] = \"markdown\",\n    schema: dict[str, Any] | None = None,\n    render_javascript: bool = False,\n    return_sources_limit: int = 25,\n    geo_location: str | None = None,\n    max_credits: int | None = None,\n) -> AiCrawlerJob\n```\n\n#### Parameters\n\n| Parameter | Type | Default | Required | Description |\n|-----------|------|---------|----------|-------------|\n| `url` | `str` | - | Yes | Starting URL to crawl |\n| `user_prompt` | `str` | - | Yes | Natural language prompt to guide extraction |\n| `output_format` | `Literal[\"json\", \"markdown\", \"csv\", \"toon\"]` | `\"markdown\"` | No | Desired output format |\n| `schema` | `dict[str, Any] \\| None` | `None` | Conditional | JSON schema for structured extraction (required for `json`, `csv`, `toon` formats) |\n| `render_javascript` | `bool` | `False` | No | Enable JavaScript rendering |\n| `return_sources_limit` | `int` | `25` | No | Maximum number of sources to return |\n| `geo_location` | `str \\| None` | `None` | No | Proxy location in ISO2 format or country name |\n| `max_credits` | `int \\| None` | `None` | No | Maximum credits to consume |\n\n#### Validation Rules\n\n```python\nif output_format in [\"json\", \"csv\", \"toon\"] and schema is None:\n    raise ValueError(\n        \"openapi_schema is required when output_format is json, csv or toon.\",\n    )\n```\n\nWhen using `json`, `csv`, or `toon` output formats, a valid JSON schema must be provided. Markdown format does not require a schema.\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:47-52]()\n\n### `generate_schema()`\n\nAutomatically generates a JSON schema based on a natural language prompt.\n\n```python\ndef generate_schema(self, prompt: str) -> dict[str, Any] | None\n```\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `prompt` | `str` | Yes | Natural language description of desired data structure |\n\n**Returns:** A dictionary containing the generated JSON schema.\n\n**Process Flow:**\n1. Sends prompt to `/crawl/generate-params` endpoint\n2. Validates response status code (must be 200)\n3. Parses and returns schema response\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:89-103]()\n\n## Workflow\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant AiCrawler\n    participant API\n    participant PollService\n    \n    User->>AiCrawler: crawl(url, user_prompt, output_format, schema)\n    AiCrawler->>API: POST /crawl/run\n    API-->>AiCrawler: run_id\n    AiCrawler->>PollService: Start polling\n    PollService->>API: GET /crawl/run/data?run_id=xxx\n    alt Status: processing\n        API-->>PollService: 202 Accepted\n        PollService->>PollService: wait(POLL_INTERVAL_SECONDS)\n        PollService->>API: GET /crawl/run/data\n    end\n    alt Status: completed\n        API-->>PollService: 200 + data\n        PollService-->>User: AiCrawlerJob(data)\n    else Status: failed\n        API-->>PollService: 200 + failed status\n        PollService-->>User: AiCrawlerJob(message=error)\n    else Timeout\n        PollService-->>User: TimeoutError\n    end\n```\n\n### Job Completion States\n\n| Status | Response | Action |\n|--------|----------|--------|\n| `processing` | `202` | Continue polling at `POLL_INTERVAL_SECONDS` |\n| `completed` | `200` with `data` | Return `AiCrawlerJob` with extracted data |\n| `failed` | `200` with `failed` | Return `AiCrawlerJob` with error message |\n| Timeout | After 10 minutes | Raise `TimeoutError` |\n| KeyboardInterrupt | User cancels | Log and re-raise `KeyboardInterrupt` |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:54-85]()\n\n## Usage Examples\n\n### Basic Markdown Crawl\n\n```python\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nurl = \"https://oxylabs.io\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"markdown\",\n    render_javascript=False,\n    return_sources_limit=3,\n    geo_location=\"France\",\n)\nprint(\"Results:\")\nfor item in result.data:\n    print(item, \"\\n\")\n```\n\n资料来源：[examples/crawl_markdown.py:1-18]()\n\n### JSON Extraction with Generated Schema\n\n```python\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nschema = crawler.generate_schema(\n    prompt=\"proxy plans which have name, price, and features\",\n)\nprint(\"schema: \", schema)\n\nurl = \"https://oxylabs.io\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"json\",\n    schema=schema,\n    render_javascript=False,\n)\nprint(\"Results:\")\nfor item in result.data:\n    print(item, \"\\n\")\n```\n\n资料来源：[examples/crawl_generated_schema.py:1-24]()\n\n### Structured Extraction with Pydantic Schema\n\n```python\nfrom pydantic import BaseModel, Field\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nclass ProxyPlan(BaseModel):\n    name: str = Field(description=\"The name of the proxy plan\")\n    price: str = Field(description=\"The price of the proxy plan\")\n    features: list[str] = Field(description=\"The features of the proxy plan\")\n\nclass ProxyPlans(BaseModel):\n    proxy_plans: list[ProxyPlan] = Field(description=\"The proxy plans\")\n\nurl = \"https://oxylabs.io/\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"json\",\n    schema=ProxyPlans.model_json_schema(),\n    render_javascript=False,\n)\n```\n\n资料来源：[examples/crawl_pydantic_schema.py:1-28]()\n\n## Output Formats\n\n| Format | Schema Required | Data Type in `AiCrawlerJob.data` | Use Case |\n|--------|-----------------|----------------------------------|----------|\n| `markdown` | No | `list[str]` | Content summarization, human-readable output |\n| `json` | Yes | `list[dict[str, Any]]` | Structured data processing, API integration |\n| `csv` | Yes | `list[dict[str, Any]]` | Spreadsheet imports, tabular analysis |\n| `toon` | Yes | `list[dict[str, Any]]` | Specialized structured format |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:41-46]()\n\n## Geographic Localization\n\nThe `geo_location` parameter supports multiple formats:\n\n| Format | Example | Description |\n|--------|---------|-------------|\n| ISO 2-letter code | `\"US\"` | US, GB, DE, FR, etc. |\n| Country canonical name | `\"United States\"` | Capitalized full name |\n| Coordinate formats | See SERP Localization docs | Advanced localization |\n\n资料来源：[readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n\n## Error Handling\n\n### Schema Validation Error\n\n```python\n# This raises ValueError\nresult = crawler.crawl(\n    url=\"https://example.com\",\n    user_prompt=\"Extract prices\",\n    output_format=\"json\",\n    schema=None,  # Missing schema\n)\n# ValueError: openapi_schema is required when output_format is json, csv or toon.\n```\n\n### Timeout Handling\n\n```python\ntry:\n    result = crawler.crawl(\n        url=\"https://example.com\",\n        user_prompt=\"Extract all products\",\n        output_format=\"markdown\",\n    )\nexcept TimeoutError as e:\n    print(f\"Crawl failed: {e}\")\n    # Handle timeout - consider retrying with reduced scope\n```\n\n### Keyboard Interrupt\n\nWhen a user cancels the operation mid-polling, the crawler logs the cancellation and re-raises the `KeyboardInterrupt`:\n\n```python\nexcept KeyboardInterrupt:\n    logger.info(\"[Cancelled] Crawling was cancelled by user.\")\n    raise KeyboardInterrupt from None\n```\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:80-82]()\n\n## Best Practices\n\n### 1. Set Appropriate Source Limits\n\n```python\n# Limit to most relevant sources\nresult = crawler.crawl(\n    url=\"https://ecommerce.example.com\",\n    user_prompt=\"Product pages with pricing\",\n    return_sources_limit=10,  # Balance between coverage and performance\n)\n```\n\n### 2. Use Specific Prompts\n\n```python\n# Good: Specific and actionable\nresult = crawler.crawl(\n    url=\"https://example.com\",\n    user_prompt=\"Find all blog posts published in 2024 with author names and publication dates\",\n)\n\n# Less effective: Too vague\nresult = crawler.crawl(\n    url=\"https://example.com\",\n    user_prompt=\"Find stuff\",\n)\n```\n\n### 3. Handle JavaScript Rendering Selectively\n\n```python\n# Only enable if necessary - adds latency\nresult = crawler.crawl(\n    url=\"https://spa.example.com\",\n    user_prompt=\"Extract dashboard metrics\",\n    render_javascript=True,  # Required for SPAs\n)\n```\n\n### 4. Credit Management\n\n```python\n# Set maximum credits for cost control\nresult = crawler.crawl(\n    url=\"https://example.com\",\n    user_prompt=\"Extract product data\",\n    max_credits=100,  # Prevents runaway costs\n)\n```\n\n## Related Features\n\n| Feature | Module | Purpose |\n|---------|--------|---------|\n| AI-Scraper | `AiScraper` | Single-page extraction without crawling |\n| AI-Search | `AiSearch` | Search engine result extraction |\n| AI-Map | `AiMap` | URL discovery and site mapping |\n| Browser-Agent | `BrowserAgent` | Interactive browser automation |\n\n资料来源：[readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n\n---\n\n<a id='ai-search'></a>\n\n## AI-Search Feature\n\n### 相关页面\n\n相关主题：[AI-Scraper Feature](#ai-scraper), [Client Architecture](#client-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [examples/search_with_content.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/search_with_content.py)\n- [examples/search_no_content.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/search_no_content.py)\n- [examples/search_instant.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/search_instant.py)\n</details>\n\n# AI-Search Feature\n\n## Overview\n\nThe AI-Search feature provides a programmatic interface for performing AI-powered search engine results page (SERP) queries. It enables users to search for information and retrieve results with optional full content extraction, JavaScript rendering support, and geographic localization.\n\nThe feature offers two search modes:\n- **Standard Search**: A polling-based approach for retrieving comprehensive search results with content\n- **Instant Search**: A lightweight endpoint optimized for quick results (up to 10 results) without content\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:1-50]()\n\n## Architecture\n\n### Class Hierarchy\n\nThe AI-Search feature is built on the `OxyStudioAIClient` base class, which provides HTTP client functionality and API communication capabilities.\n\n```python\nclass AiSearch(OxyStudioAIClient):\n    \"\"\"AI Search app.\"\"\"\n```\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:37-38]()\n\n### Module Structure\n\n| Component | File | Responsibility |\n|-----------|------|----------------|\n| AiSearch | ai_search.py | Main synchronous interface |\n| AiSearchJob | ai_search.py | Response data model |\n| SearchResult | ai_search.py | Individual result data model |\n\n## Data Models\n\n### SearchResult\n\nRepresents a single search result entry.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| url | str | The URL of the search result |\n| title | str | The title of the search result |\n| description | str | The description/snippet of the search result |\n| content | str \\| None | Full content of the page (when return_content=True) |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:22-27]()\n\n### AiSearchJob\n\nRepresents the complete search job response.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| run_id | str | Unique identifier for the search job |\n| message | str \\| None | Status message or error code |\n| data | list[SearchResult] \\| None | List of search results |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:29-31]()\n\n## API Methods\n\n### Synchronous Interface\n\n#### search()\n\nPerforms a standard search with polling until results are available.\n\n```python\ndef search(\n    self,\n    query: str,\n    limit: int = 10,\n    render_javascript: bool = False,\n    return_content: bool = True,\n    geo_location: str | None = None,\n) -> AiSearchJob\n```\n\n**Parameters:**\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| query | str | required | The search query string |\n| limit | int | 10 | Maximum number of results (max: 50) |\n| render_javascript | bool | False | Enable JavaScript rendering |\n| return_content | bool | True | Include full content in results |\n| geo_location | str \\| None | None | Geographic location for localized results |\n\n**Return Type:** `AiSearchJob`\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:43-55]()\n\n#### instant_search()\n\nPerforms a fast search using the instant endpoint without polling.\n\n```python\ndef instant_search(\n    self,\n    query: str,\n    limit: int = 10,\n    geo_location: str | None = None,\n) -> AiSearchJob\n```\n\n**Parameters:**\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| query | str | required | The search query string |\n| limit | int | 10 | Maximum number of results (max: 10) |\n| geo_location | str \\| None | None | Geographic location for localized results |\n\n**Note:** Instant search automatically bypasses the polling mechanism when `limit <= 10` and `return_content=False`.\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:95-106]()\n\n### Asynchronous Interface\n\n#### search_async()\n\nAsync version of the standard search method.\n\n```python\nasync def search_async(\n    self,\n    query: str,\n    limit: int = 10,\n    render_javascript: bool = False,\n    return_content: bool = True,\n    geo_location: str | None = None,\n) -> AiSearchJob\n```\n\n#### instant_search_async()\n\nAsync version of the instant search method.\n\n```python\nasync def instant_search_async(\n    self,\n    query: str,\n    limit: int = 10,\n    geo_location: str | None = None,\n) -> AiSearchJob\n```\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:108-148]()\n\n## Workflow and State Management\n\n### Standard Search Polling Flow\n\n```mermaid\ngraph TD\n    A[Start search] --> B[Call /search/run API]\n    B --> C[Extract run_id]\n    C --> D[Call /search/run/data API]\n    D --> E{Status Check}\n    E -->|202 Pending| F[Wait POLL_INTERVAL_SECONDS]\n    E -->|200 Completed| G[Return AiSearchJob with data]\n    E -->|200 Failed| H[Return AiSearchJob with error]\n    F --> D\n    H --> I[End with error]\n    G --> J[End success]\n    \n    style A fill:#e1f5ff\n    style G fill:#c8e6c9\n    style H fill:#ffcdd2\n```\n\n### Instant Search Flow\n\n```mermaid\ngraph TD\n    A[Start instant_search] --> B[Call /search/instant API]\n    B --> C{Status 200?}\n    C -->|Yes| D[Parse response JSON]\n    C -->|No| E[Raise Exception]\n    D --> F[Return AiSearchJob]\n    F --> G[End success]\n    E --> H[End with error]\n    \n    style A fill:#e1f5ff\n    style F fill:#c8e6c9\n    style E fill:#ffcdd2\n```\n\n### Endpoint Selection Logic\n\n```mermaid\ngraph TD\n    A[search called] --> B{limit <= 10?}\n    B -->|Yes| C{return_content == False?}\n    B -->|No| D[Use standard /search/run]\n    C -->|Yes| E[Use instant /search/instant]\n    C -->|No| D\n    E --> F[Return immediately]\n    D --> G[Start polling]\n    G --> H{Status completed?}\n    H -->|Yes| I[Return results]\n    H -->|No| J{Status failed?}\n    J -->|Yes| K[Return with error]\n    J -->|No| L[Continue polling]\n    L --> G\n    \n    style A fill:#e1f5ff\n    style E fill:#c8e6c9\n    style K fill:#ffcdd2\n```\n\n## Configuration Constants\n\n| Constant | Value | Description |\n|----------|-------|-------------|\n| SEARCH_TIMEOUT_SECONDS | 180 (60 * 3) | Maximum time to wait for search completion |\n| POLL_INTERVAL_SECONDS | 5 | Time between polling attempts |\n| POLL_MAX_ATTEMPTS | 36 | Maximum number of polling attempts |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:11-13]()\n\n## Usage Examples\n\n### Search with Content\n\nRetrieves search results including full page content:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna recipe\"\nresult = search.search(\n    query=query,\n    limit=5,\n    render_javascript=False,\n    return_content=True,\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_with_content.py:1-15]()\n\n### Search Without Content\n\nPerforms a lightweight search returning only URL, title, and description:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna\"\nresult = search.search(\n    query=query,\n    limit=5,\n    render_javascript=False,\n    return_content=False,\n    geo_location=\"Italy\",\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_no_content.py:1-17]()\n\n### Instant Search\n\nFast search for up to 10 results with geographic localization:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna recipes\"\nresult = search.instant_search(\n    query=query,\n    limit=5,\n    geo_location=\"United States\",\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_instant.py:1-14]()\n\n## Geographic Localization\n\nThe `geo_location` parameter supports multiple formats:\n\n| Format | Example |\n|--------|---------|\n| ISO 2-letter code | \"US\", \"DE\", \"FR\" |\n| Country canonical name | \"United States\", \"Germany\", \"France\" |\n| Coordinate formats | Supported per SERP Localization docs |\n\nSupported locations are documented at: [SERP Localization](https://developers.oxylabs.io/scraping-solutions/web-scraper-api/features/localization/serp-localization)\n\n## Error Handling\n\n| Scenario | Behavior |\n|----------|----------|\n| Empty query | Raises `ValueError(\"query is required\")` |\n| API returns non-200 status | Raises `Exception` with response text |\n| Search timeout | Raises `TimeoutError` |\n| Keyboard interrupt | Logs cancellation and re-raises |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:77-82]()\n\n## Key Implementation Details\n\n### Request Body Construction\n\nBoth search methods construct a standardized request body:\n\n```python\nbody = {\n    \"query\": query,\n    \"limit\": limit,\n    \"render_javascript\": render_javascript,\n    \"return_content\": return_content,\n    \"geo_location\": geo_location,\n}\n```\n\n### API Endpoints\n\n| Endpoint | Method | Purpose |\n|----------|--------|---------|\n| /search/run | POST | Create a new search job |\n| /search/run/data | GET | Poll for search results |\n| /search/instant | POST | Execute instant search |\n\n### Timeout Calculation\n\n```python\nPOLL_MAX_ATTEMPTS = SEARCH_TIMEOUT_SECONDS // POLL_INTERVAL_SECONDS\n# 180 // 5 = 36 attempts\n\n---\n\n<a id='ai-map'></a>\n\n## AI-Map Feature\n\n### 相关页面\n\n相关主题：[AI-Crawler Feature](#ai-crawler), [Client Architecture](#client-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/apps/ai_map.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_map.py)\n- [examples/ai_map.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/ai_map.py)\n</details>\n\n# AI-Map Feature\n\n## Overview\n\nThe AI-Map feature is a URL discovery and site mapping tool within the Oxylabs AI Studio Python SDK. It enables users to explore website structures by mapping URLs based on specified keywords, crawl depth, and filtering criteria. The feature automatically discovers URLs from sitemaps and linked pages, returning a structured list of discovered endpoints that match user-defined search parameters.\n\nAI-Map serves as the first step in many web scraping workflows, helping users understand the structure of a target website before proceeding with detailed content extraction using tools like AiCrawler or AiScraper. 资料来源：[readme.md](readme.md)\n\n## Core Functionality\n\nThe `AiMap` class provides a single primary method: `map()`. This method accepts a comprehensive configuration payload that controls URL discovery behavior. The feature supports:\n\n- **Keyword-based filtering**: Filter discovered URLs by search keywords or natural language prompts\n- **Crawl depth control**: Limit how deep the mapping exploration goes (1-5 levels)\n- **Result limiting**: Cap the total number of URLs returned\n- **Geographic targeting**: Discover URLs with specific geo-location configurations\n- **JavaScript rendering**: Enable JS rendering for dynamically loaded links\n- **Sitemap integration**: Include or exclude sitemap-based URL discovery\n- **Domain scope control**: Allow or restrict subdomains and external domains\n\n资料来源：[examples/ai_map.py](examples/ai_map.py)\n\n## Architecture\n\n```mermaid\ngraph TD\n    A[User calls ai_map.map payload] --> B[AiMap.map method]\n    B --> C[Build request payload]\n    C --> D[POST to /map endpoint]\n    D --> E{Response status?}\n    E -->|pending| F[Poll for completion]\n    E -->|completed| G[Return AiMapJob]\n    E -->|failed| H[Return error]\n    F --> E\n    G --> I[Extract result.data]\n    H --> J[Raise exception]\n    \n    style A fill:#e1f5ff\n    style G fill:#c8e6c9\n    style J fill:#ffcdd2\n```\n\n## Class Reference\n\n### AiMap\n\n**Module**: `oxylabs_ai_studio.apps.ai_map`\n\n**Constructor**:\n\n```python\nAiMap(api_key: str)\n```\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| api_key | str | Oxylabs API key for authentication (required) |\n\n资料来源：[examples/ai_map.py](examples/ai_map.py)\n\n### map() Method\n\n**Signature**:\n\n```python\ndef map(self, **payload) -> AiMapJob\n```\n\n**Parameters Table**:\n\n| Parameter | Type | Default | Required | Description |\n|-----------|------|---------|----------|-------------|\n| url | str | - | Yes | Starting URL or domain to map |\n| search_keywords | list[str] | None | No | Keywords for URL path filtering |\n| user_prompt | str \\| None | None | No | Natural language prompt for keyword search. Can be used together with 'search_keywords' or standalone |\n| max_crawl_depth | int | 1 | No | Maximum crawl depth (range: 1-5) |\n| limit | int | 25 | No | Maximum number of URLs to return |\n| geo_location | str | None | No | Proxy location in ISO2 format or country canonical name |\n| render_javascript | bool | False | No | Enable JavaScript rendering for dynamic content |\n| include_sitemap | bool | True | No | Include sitemap as a seed source for URL discovery |\n| max_credits | int \\| None | None | No | Maximum credits to use for this operation |\n| allow_subdomains | bool | False | No | Allow mapping of subdomain URLs |\n| allow_external_domains | bool | False | No | Allow mapping of external domain URLs |\n\n资料来源：[readme.md](readme.md)\n\n## Usage Examples\n\n### Basic URL Mapping\n\n```python\nfrom oxylabs_ai_studio.apps.ai_map import AiMap\n\nai_map = AiMap(api_key=\"<API_KEY>\")\npayload = {\n    \"url\": \"https://oxylabs.io\",\n    \"search_keywords\": [\"blog\"],\n    \"max_crawl_depth\": 3,\n    \"limit\": 50,\n    \"render_javascript\": False,\n    \"include_sitemap\": True,\n    \"max_credits\": None,\n    \"allow_subdomains\": False,\n    \"allow_external_domains\": False,\n}\nresult = ai_map.map(**payload)\nprint(result.data)\n```\n\n资料来源：[examples/ai_map.py](examples/ai_map.py)\n\n### Mapping Career Pages\n\n```python\nfrom oxylabs_ai_studio.apps.ai_map import AiMap\n\nai_map = AiMap(api_key=\"<API_KEY>\")\npayload = {\n    \"url\": \"https://career.oxylabs.io\",\n    \"search_keywords\": [\"career\", \"jobs\", \"vacancy\"],\n    \"user_prompt\": \"job ad pages\",\n    \"max_crawl_depth\": 2,\n    \"limit\": 10,\n    \"geo_location\": \"Germany\",\n    \"render_javascript\": False,\n    \"include_sitemap\": True,\n    \"max_credits\": None,\n    \"allow_subdomains\": False,\n    \"allow_external_domains\": False,\n}\nresult = ai_map.map(**payload)\nprint(result.data)\n```\n\n资料来源：[readme.md](readme.md)\n\n## Response Model\n\n### AiMapJob\n\n| Field | Type | Description |\n|-------|------|-------------|\n| run_id | str | Unique identifier for this mapping job |\n| message | str \\| None | Status message or error code |\n| data | list \\| None | Discovered URLs matching the search criteria |\n\n## Workflow Diagram: Complete Scraping Pipeline\n\n```mermaid\ngraph LR\n    A[Define target domain] --> B[Use AiMap to discover URLs]\n    B --> C{URLs discovered?}\n    C -->|Yes| D[Filter and select URLs]\n    C -->|No| E[Adjust keywords/depth]\n    E --> B\n    D --> F[Use AiCrawler to crawl content]\n    F --> G{Detailed extraction needed?}\n    G -->|Yes| H[Use AiScraper per URL]\n    G -->|No| I[Process crawled data]\n    H --> I\n    I --> J[Store/Analyze results]\n    \n    style B fill:#fff9c4\n    style F fill:#c8e6c9\n    style H fill:#c8e6c9\n```\n\n## Parameter Interaction\n\n| Parameter | Affects | Interaction Notes |\n|-----------|---------|-------------------|\n| url | All | Root domain determines scope of mapping |\n| max_crawl_depth | API calls, credits | Higher depth increases API usage and discovery scope |\n| limit | Result size | Combined with depth to control total URL count |\n| search_keywords | Filter accuracy | More specific keywords reduce false positives |\n| user_prompt | AI interpretation | Works synergistically with search_keywords |\n| include_sitemap | Initial URL seed | When True, sitemap URLs are added to discovery queue |\n| geo_location | Content variant | URLs may vary based on geo-targeted content |\n| allow_subdomains | Scope expansion | When True, expands discovery beyond main domain |\n\n## Best Practices\n\n1. **Start with low crawl depth**: Begin with `max_crawl_depth=1` to understand basic site structure before expanding\n2. **Use specific keywords**: Combine `search_keywords` with `user_prompt` for precise URL filtering\n3. **Set appropriate limits**: Use `limit` to prevent excessive API usage and manage response sizes\n4. **Enable sitemap**: Keep `include_sitemap=True` for comprehensive initial URL discovery\n5. **Consider geo-location**: If targeting region-specific pages, specify `geo_location` in the initial mapping\n\n## Common Use Cases\n\n| Use Case | Recommended Configuration |\n|----------|--------------------------|\n| Blog post discovery | `{\"search_keywords\": [\"blog\", \"article\"], \"max_crawl_depth\": 2}` |\n| E-commerce product pages | `{\"search_keywords\": [\"product\", \"shop\"], \"max_crawl_depth\": 3}` |\n| Documentation site mapping | `{\"include_sitemap\": True, \"max_crawl_depth\": 4}` |\n| Job listing discovery | `{\"search_keywords\": [\"jobs\", \"careers\", \"vacancy\"], \"max_crawl_depth\": 2}` |\n| News article aggregation | `{\"search_keywords\": [\"news\", \"article\"], \"limit\": 100}` |\n\n## Integration with Other Features\n\nThe AI-Map feature is designed to work as part of a larger scraping pipeline. After discovering URLs, users typically proceed with:\n\n1. **AiCrawler**: For bulk content extraction from discovered URLs\n2. **AiScraper**: For detailed structured data extraction from individual pages\n3. **BrowserAgent**: For interactive browsing tasks requiring user-like navigation\n\n资料来源：[readme.md](readme.md), [agentic_code_guide.md](agentic_code_guide.md)\n\n---\n\n<a id='browser-agent'></a>\n\n## Browser Agent Feature\n\n### 相关页面\n\n相关主题：[AI-Scraper Feature](#ai-scraper), [Data Models](#data-models)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/apps/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n- [examples/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/browser_agent.py)\n- [readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n- [agentic_code_guide.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/agentic_code_guide.md)\n</details>\n\n# Browser Agent Feature\n\n## Overview\n\nThe Browser Agent is a powerful browser automation tool within the Oxylabs AI Studio Python SDK that enables programmatic control of web browsers to perform complex actions such as clicking, scrolling, navigating, and extracting data from dynamic web pages. Unlike traditional scraping methods, the Browser Agent accepts natural language prompts to guide its behavior, making it particularly effective for websites that require JavaScript rendering or user interaction.\n\nThe feature serves as a bridge between high-level natural language instructions and low-level browser automation, abstracting away the complexities of web interaction while maintaining flexibility for various use cases. It integrates seamlessly with other AI Studio components like schema generation to provide structured data extraction capabilities.\n\n## Architecture\n\n### Component Overview\n\nThe Browser Agent feature is built on a client-server architecture where the Python SDK acts as a thin client communicating with Oxylabs' cloud-based browser automation infrastructure.\n\n```mermaid\ngraph TD\n    A[BrowserAgent Python Client] --> B[AI Studio API Gateway]\n    B --> C[Browser Agent Service]\n    C --> D[Browser Instance Pool]\n    D --> E[Target Website]\n    F[Schema Generation Service] --> B\n```\n\n### Key Components\n\n| Component | Location | Responsibility |\n|-----------|----------|----------------|\n| `BrowserAgent` | `src/oxylabs_ai_studio/apps/browser_agent.py` | Main client class for browser automation |\n| API Client | Base HTTP client | Handles HTTP communication with API |\n| Polling Mechanism | Built-in | Monitors job status until completion |\n| Schema Generator | Built-in | Creates OpenAPI schemas from prompts |\n\n### Class Hierarchy\n\n```\nBaseClient\n└── BrowserAgent\n    ├── run()\n    ├── run_async()\n    ├── generate_schema()\n    ├── generate_schema_async()\n    ├── call_api()\n    ├── call_api_async()\n    └── get_client() / async_client()\n```\n\n## Data Models\n\n### BrowserAgentJob\n\nThe primary output model returned by Browser Agent operations.\n\n```python\nclass DataModel(BaseModel):\n    type: Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\"]\n    content: dict[str, Any] | str | None\n\nclass BrowserAgentJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: DataModel | None = None\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the browser agent job |\n| `message` | `str \\| None` | Error message or status information if job failed |\n| `data` | `DataModel \\| None` | Contains the extracted data with type and content |\n\n### DataModel Fields\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `type` | `Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\"]` | Format of the extracted content |\n| `content` | `dict[str, Any] \\| str \\| None` | The actual extracted data |\n\n## API Reference\n\n### BrowserAgent Class\n\n**Import Statement:**\n```python\nfrom oxylabs_ai_studio.apps.browser_agent import BrowserAgent\n```\n\n**Initialization:**\n```python\nbrowser_agent = BrowserAgent(api_key=\"<API_KEY>\")\n```\n\n### Method: `run()`\n\nSynchronous method to execute browser agent tasks.\n\n**Signature:**\n```python\ndef run(\n    self,\n    url: str,\n    user_prompt: str,\n    output_format: Literal[\"json\", \"markdown\"] = \"markdown\",\n    schema: dict | None = None,\n    geo_location: str | None = None,\n    user_agent: str | None = None,\n    render_javascript: bool | str = \"auto\",\n) -> BrowserAgentJob\n```\n\n**Parameters:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `url` | `str` | Yes | - | Target URL to browse and interact with |\n| `user_prompt` | `str` | Yes | - | Natural language prompt describing the task to perform |\n| `output_format` | `Literal[\"json\", \"markdown\"]` | No | `\"markdown\"` | Desired output format for extracted data |\n| `schema` | `dict \\| None` | Conditional | `None` | OpenAPI JSON schema for structured extraction (required when `output_format=\"json\"`) |\n| `geo_location` | `str \\| None` | No | `None` | Proxy location in ISO2 format or country canonical name |\n| `user_agent` | `str \\| None` | No | `None` | Custom User-Agent request header |\n| `render_javascript` | `bool \\| str` | No | `\"auto\"` | JavaScript rendering option; can be `True`, `False`, or `\"auto\"` |\n\n**Returns:** `BrowserAgentJob` object containing the job result\n\n**Example Usage:**\n```python\nbrowser_agent = BrowserAgent(api_key=\"<API_KEY>\")\n\nprompt = \"Find if there is game 'super mario odyssey' in the store.\"\nurl = \"https://sandbox.oxylabs.io/\"\nresult = browser_agent.run(\n    url=url,\n    user_prompt=prompt,\n    output_format=\"json\",\n    schema={\"type\": \"object\", \"properties\": {\"page_url\": {\"type\": \"string\"}}, \"required\": []},\n)\nprint(result.data)\n```\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:1-200](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Method: `run_async()`\n\nAsynchronous method to execute browser agent tasks without blocking.\n\n**Signature:**\n```python\nasync def run_async(\n    self,\n    url: str,\n    user_prompt: str,\n    output_format: Literal[\"json\", \"markdown\"] = \"markdown\",\n    schema: dict | None = None,\n    geo_location: str | None = None,\n) -> BrowserAgentJob\n```\n\n**Example Usage:**\n```python\nimport asyncio\nfrom oxylabs_ai_studio.apps.browser_agent import BrowserAgent\n\nbrowser_agent = BrowserAgent(api_key=\"<API_KEY>\")\n\nasync def main():\n    prompt = \"Find if there is game 'super mario odyssey' in the store.\"\n    url = \"https://sandbox.oxylabs.io/\"\n    result = await browser_agent.run_async(\n        url=url,\n        user_prompt=prompt,\n        output_format=\"json\",\n        schema={\"type\": \"object\", \"properties\": {\"page_url\": {\"type\": \"string\"}}, \"required\": []},\n    )\n    print(result.data)\n\nasyncio.run(main())\n```\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:200-280](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Method: `generate_schema()`\n\nGenerates a JSON schema for structured data extraction based on a natural language prompt.\n\n**Signature:**\n```python\ndef generate_schema(self, prompt: str) -> dict[str, Any] | None\n```\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `prompt` | `str` | Yes | Natural language description of the data structure to extract |\n\n**Returns:** Dictionary containing the generated OpenAPI schema, or `None` if generation fails\n\n**Example Usage:**\n```python\nbrowser_agent = BrowserAgent(api_key=\"<API_KEY>\")\n\nschema = browser_agent.generate_schema(\n    prompt=\"game name, platform, review stars and price\"\n)\nprint(\"schema: \", schema)\n```\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:180-195](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Method: `generate_schema_async()`\n\nAsynchronous version of `generate_schema()`.\n\n**Signature:**\n```python\nasync def generate_schema_async(self, prompt: str) -> dict[str, Any] | None\n```\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:145-165](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n## Execution Flow\n\n### Synchronous Execution Workflow\n\n```mermaid\nsequenceDiagram\n    participant Client as BrowserAgent Client\n    participant API as AI Studio API\n    participant Service as Browser Agent Service\n    \n    Client->>API: POST /browser-agent/run\n    Note over API: Returns run_id (status: 201)\n    Client->>API: GET /browser-agent/run/data?run_id=xxx\n    API-->>Client: status: processing\n    loop Poll until complete\n        Client->>API: GET /browser-agent/run/data?run_id=xxx\n        API-->>Client: status: processing\n    end\n    API-->>Client: status: completed, data returned\n```\n\n### Job Status States\n\nThe Browser Agent job follows a state machine pattern with the following statuses:\n\n| Status | Description | Action |\n|--------|-------------|--------|\n| `processing` | Job is currently executing | Continue polling |\n| `completed` | Job finished successfully | Return result |\n| `failed` | Job encountered an error | Return error message |\n| HTTP 202 | Job still initializing | Continue polling |\n| HTTP 200 with no data | Unknown state | Continue polling |\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:40-80](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Polling Mechanism\n\nThe synchronous `run()` method implements a polling mechanism with the following characteristics:\n\n- **Poll Interval**: Configured via `POLL_INTERVAL_SECONDS` constant\n- **Timeout Handling**: Raises `TimeoutError` if job does not complete within expected timeframe\n- **Interrupt Support**: Catches `KeyboardInterrupt` to gracefully cancel operations\n\n```python\n# Polling loop structure (simplified)\nwhile True:\n    get_response = self.call_api(...)\n    resp_body = get_response.json()\n    \n    if resp_body[\"status\"] == \"completed\":\n        return BrowserAgentJob(run_id=run_id, data=resp_body[\"data\"])\n    if resp_body[\"status\"] == \"failed\":\n        return BrowserAgentJob(run_id=run_id, message=resp_body.get(\"error_code\"))\n    \n    time.sleep(POLL_INTERVAL_SECONDS)\n```\n\n## Use Cases\n\n### E-commerce Product Discovery\n\nThe Browser Agent excels at navigating websites that require user interaction:\n\n```python\nschema = browser_agent.generate_schema(\n    prompt=\"game name, platform, review stars and price\"\n)\n\nprompt = \"Find if there is game 'super mario odyssey' in the store. If there is, find the price. Use search bar to find the game.\"\nresult = browser_agent.run(\n    url=\"https://sandbox.oxylabs.io/\",\n    user_prompt=prompt,\n    output_format=\"json\",\n    schema=schema,\n    geo_location=\"Spain\",\n)\n```\n\n### Recommended Workflow for Complex Extraction\n\nFor multi-step extraction tasks, combine Browser Agent with other AI Studio tools:\n\n1. **Browser Agent**: Navigate to the target page and identify relevant URLs\n2. **AiScraper**: Extract structured data from identified pages\n3. **Schema Generation**: Create appropriate schemas for each extraction phase\n\n资料来源: [examples/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/browser_agent.py)\n\n## Error Handling\n\n### Exception Types\n\n| Exception | Cause | Handling |\n|-----------|-------|----------|\n| `TimeoutError` | Job exceeded timeout threshold | Retry with exponential backoff |\n| `KeyboardInterrupt` | User cancelled operation | Clean up and exit gracefully |\n| `Exception` | API request failed | Check API key, network connectivity |\n\n### Error Response Handling\n\n```python\nif resp_body[\"status\"] == \"failed\":\n    return BrowserAgentJob(\n        run_id=run_id,\n        message=resp_body.get(\"error_code\", None),\n        data=None,\n    )\n```\n\n### Schema Generation Errors\n\n```python\nif response.status_code != 200:\n    raise Exception(f\"Failed to generate schema: {response.text}\")\n```\n\n## Configuration Options\n\n### Proxy Location\n\nSpecify geographic location for requests:\n\n```python\nresult = browser_agent.run(\n    url=\"https://example.com\",\n    user_prompt=\"Extract product information\",\n    geo_location=\"Germany\",  # or \"DE\" for ISO2 format\n)\n```\n\nSupported formats:\n- ISO 2-letter country codes (e.g., \"DE\", \"US\")\n- Country canonical names (e.g., \"Germany\", \"United States\")\n\n### JavaScript Rendering\n\nControl JavaScript rendering behavior:\n\n| Value | Behavior |\n|-------|----------|\n| `False` | No JavaScript rendering (fastest) |\n| `True` | Always render JavaScript |\n| `\"auto\"` | Service automatically detects if rendering is needed |\n\n### User-Agent Customization\n\n```python\nresult = browser_agent.run(\n    url=\"https://example.com\",\n    user_prompt=\"Navigate and extract\",\n    user_agent=\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\"\n)\n```\n\n## Best Practices\n\n1. **Schema Definition**: Always provide a well-defined schema when using `output_format=\"json\"` for predictable results\n\n2. **Async for Multiple Tasks**: Use `run_async()` when running multiple browser agents concurrently to maximize throughput\n\n3. **Interrupt Handling**: Wrap long-running operations in try-except blocks to handle user cancellations\n\n4. **Error Retries**: Implement retry logic with exponential backoff for transient failures:\n   ```python\n   for attempt in range(3):\n       try:\n           result = browser_agent.run(url=url, user_prompt=prompt)\n           break\n       except TimeoutError:\n           time.sleep(2 ** attempt)\n   ```\n\n5. **Geo-Location**: Use appropriate `geo_location` values when targeting region-specific content\n\n## Comparison with Other Apps\n\n| Feature | Browser Agent | AI Scraper | AI Crawler |\n|---------|---------------|------------|------------|\n| Navigation Actions | ✅ | ❌ | ❌ |\n| JavaScript Interaction | ✅ | Configurable | Configurable |\n| Pagination Handling | ✅ (manual) | Manual | Automatic |\n| Single Page Focus | ✅ | ✅ | ❌ |\n| Schema Generation | ✅ | ✅ | ✅ |\n| Output Formats | json, markdown | json, markdown, csv, screenshot | json, markdown, csv, toon |\n\n## API Endpoints Reference\n\n| Endpoint | Method | Purpose |\n|----------|--------|---------|\n| `/browser-agent/run` | POST | Initiate a browser agent job |\n| `/browser-agent/run/data` | GET | Poll job status and retrieve results |\n| `/browser-agent/generate-params` | POST | Generate extraction schema from prompt |\n\n## See Also\n\n- [AI Scraper Feature](./ai_scraper.md) - Single-page content extraction\n- [AI Crawler Feature](./ai_crawler.md) - Multi-page website crawling\n- [AI Search Feature](./ai_search.md) - Search engine result extraction\n- [AI Map Feature](./ai_map.md) - Site mapping and discovery\n\n---\n\n<a id='client-architecture'></a>\n\n## Client Architecture\n\n### 相关页面\n\n相关主题：[Data Models](#data-models), [Error Handling and Logging](#error-handling-logging)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/client.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/client.py)\n- [src/oxylabs_ai_studio/utils.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/utils.py)\n- [src/oxylabs_ai_studio/__init__.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/__init__.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n</details>\n\n# Client Architecture\n\n## Overview\n\nThe Oxylabs AI Studio Python SDK follows a layered client architecture that provides a unified interface for interacting with various AI-powered web scraping and data extraction services. The architecture separates concerns between HTTP communication, API interaction, and application-specific logic, enabling modularity and maintainability.\n\nThe client layer serves as the foundation for all application modules (`AiScraper`, `AiSearch`, `AiCrawler`, `BrowserAgent`, `AiMap`) by providing shared functionality for API communication, authentication, request building, and response handling.\n\n## Architecture Components\n\n### Component Overview\n\n| Component | File | Purpose |\n|-----------|------|---------|\n| `APIClient` | `client.py` | Core HTTP client for all API communications |\n| `BaseApp` | `client.py` | Abstract base class for application modules |\n| Utility Functions | `utils.py` | Logging, retry logic, and helper utilities |\n| Application Modules | `apps/*.py` | Domain-specific API wrappers |\n\n### Class Hierarchy\n\n```mermaid\ngraph TD\n    A[APIClient] --> B[BaseApp]\n    B --> C[AiScraper]\n    B --> D[AiSearch]\n    B --> E[AiCrawler]\n    B --> F[BrowserAgent]\n    B --> G[AiMap]\n    \n    H[Requests Session] --> A\n    I[Configuration] --> A\n```\n\n## API Client (`APIClient`)\n\n### Purpose and Responsibilities\n\nThe `APIClient` class is the core HTTP communication layer that handles:\n\n- **Authentication**: Attaches API credentials to all requests\n- **Connection Management**: Manages HTTP session lifecycle\n- **Base URL Configuration**: Stores the API endpoint configuration\n- **Request Execution**: Performs HTTP calls to the Oxylabs API\n\n### Configuration Parameters\n\n| Parameter | Type | Description | Default |\n|-----------|------|-------------|---------|\n| `api_key` | `str` | Authentication key for Oxylabs API | Required |\n| `base_url` | `str` | API base endpoint | `https://ai.oxylabs.io/api/v1` |\n| `timeout` | `int` | Request timeout in seconds | Configurable |\n| `max_retries` | `int` | Maximum retry attempts for failed requests | Configurable |\n\n### Key Methods\n\n```mermaid\ngraph TD\n    A[make_request] --> B{Method Type}\n    B -->|POST| C[POST Request]\n    B -->|GET| D[GET Request]\n    C --> E[Attach JSON Body]\n    D --> F[Attach Query Params]\n    E --> G[Execute Request]\n    F --> G\n    G --> H{Response Status}\n    H -->|2xx| I[Return Response]\n    H -->|4xx/5xx| J[Raise Exception]\n```\n\nThe `APIClient` exposes methods that all application modules use for API communication:\n\n- `call_api(client, url, method, body, params)` - Generic API call method\n- `get_client()` - Returns configured HTTP client instance\n- Session management methods for connection pooling\n\n## Base Application Class (`BaseApp`)\n\n### Purpose and Responsibilities\n\nThe `BaseApp` class serves as an abstract base for all application-specific modules. It provides:\n\n- **Common API Interface**: Unified `call_api()` method across all apps\n- **Client Initialization**: Automatic HTTP client setup with authentication\n- **Polling Infrastructure**: Shared job status polling mechanism\n- **Error Handling**: Standardized exception handling patterns\n\n### Polling Mechanism\n\nAll async operations use a polling pattern to check job completion:\n\n```mermaid\ngraph TD\n    A[Submit Job Request] --> B[Get run_id]\n    B --> C[Poll Status Endpoint]\n    C --> D{Status Check}\n    D -->|202 Processing| C\n    D -->|200 Completed| E[Return Result]\n    D -->|Error| F[Return Error]\n    G[Max Timeout] -->|Exceeded| H[Raise TimeoutError]\n```\n\n### Polling Configuration\n\n| Parameter | Value | Description |\n|-----------|-------|-------------|\n| `POLL_INTERVAL_SECONDS` | `2` | Seconds between status checks |\n| `MAX_TIMEOUT_SECONDS` | `300` | Maximum wait time before timeout |\n\n## Application Modules\n\n### AiScraper\n\nLocated in `src/oxylabs_ai_studio/apps/ai_scraper.py`, this module provides structured web scraping capabilities.\n\n**Key Features:**\n- Single URL content extraction\n- Structured JSON output with custom schemas\n- Markdown, HTML, CSV, and screenshot output formats\n- JavaScript rendering support\n- Geo-location proxy rotation\n\n**Core Methods:**\n- `scrape()` - Synchronous scraping operation\n- `scrape_async()` - Asynchronous scraping operation\n- `generate_schema()` - AI-powered schema generation from natural language\n\n### AiSearch\n\nLocated in `src/oxylabs_ai_studio/apps/ai_search.py`, this module handles search engine result page (SERP) scraping.\n\n**Key Features:**\n- Full search with content retrieval\n- Instant search for quick results (up to 10 results)\n- Content extraction in markdown format\n- Geo-location targeting for localized results\n\n**Core Methods:**\n- `search()` - Full search with content\n- `instant_search()` - Fast search without content polling\n\n### AiCrawler\n\nLocated in `src/oxylabs_ai_studio/apps/ai_crawler.py`, this module provides recursive web crawling with AI-guided extraction.\n\n**Key Features:**\n- Multi-page crawling with depth control\n- AI-guided data extraction\n- Structured JSON output with generated schemas\n- Source limitation and filtering\n\n**Core Methods:**\n- `crawl()` - Start crawling operation\n- `generate_schema()` - Generate extraction schema from prompt\n\n## Request/Response Flow\n\n### Standard API Call Flow\n\n```mermaid\nsequenceDiagram\n    participant App as Application Module\n    participant Client as API Client\n    participant API as Oxylabs API\n    \n    App->>Client: call_api(url, method, body)\n    Client->>Client: Prepare request headers\n    Client->>Client: Attach auth (API Key)\n    Client->>API: HTTP Request\n    API-->>Client: Response\n    Client-->>App: Processed Response\n```\n\n### Job-Based Operation Flow\n\nFor long-running operations (scraping, crawling, searching):\n\n```mermaid\ngraph TD\n    A[Submit Job] --> B[Get run_id]\n    B --> C[Loop: Poll Status]\n    C --> D{Response Status}\n    D -->|202| C\n    D -->|200 Completed| E[Return Data]\n    D -->|Failed| F[Return Error Info]\n```\n\n## Data Models\n\n### Common Response Models\n\n| Model | Fields | Description |\n|-------|--------|-------------|\n| `AiScraperJob` | `run_id`, `message`, `data` | Scraping job result |\n| `AiSearchJob` | `run_id`, `message`, `data` | Search job result |\n| `AiCrawlerJob` | `run_id`, `message`, `data` | Crawling job result |\n| `DataModel` | `type`, `content` | Extracted data container |\n\n### Output Format Types\n\n| Format | Type | Description |\n|--------|------|-------------|\n| `json` | `dict` | Structured JSON output |\n| `markdown` | `str` | Markdown formatted text |\n| `html` | `str` | Raw HTML content |\n| `screenshot` | `str` | Base64 encoded image |\n| `csv` | `str` | CSV formatted data |\n| `toon` | `dict` | Tabular object notation |\n\n## Authentication\n\nThe SDK uses API key-based authentication passed during initialization:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n```\n\nThe API key is:\n- Stored in the `BaseApp` instance configuration\n- Automatically attached to all outgoing HTTP requests\n- Used to authenticate against the Oxylabs AI Studio API endpoint\n\n## Configuration and Utils\n\n### Logging Configuration\n\nLocated in `src/oxylabs_ai_studio/utils.py`, the SDK provides structured logging for debugging and monitoring:\n\n- Configurable log levels\n- Request/response logging\n- Error tracing with context\n\n### Error Handling\n\nThe architecture implements layered error handling:\n\n| Layer | Error Type | Handling |\n|-------|-----------|----------|\n| Client | Network errors | Retry with backoff |\n| API | HTTP errors | Exception with response details |\n| Application | Business logic | Domain-specific exceptions |\n\n### Timeout Configuration\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| Request timeout | Varies by endpoint | Per-request timeout |\n| Polling timeout | 300 seconds | Maximum wait for job completion |\n| Poll interval | 2 seconds | Time between status checks |\n\n## Usage Patterns\n\n### Synchronous Usage\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"json\",\n    schema={\"type\": \"object\", ...}\n)\n```\n\n### Asynchronous Usage\n\n```python\nimport asyncio\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nasync def main():\n    result = await scraper.scrape_async(\n        url=\"https://example.com\",\n        output_format=\"markdown\"\n    )\n    print(result.data)\n\nasyncio.run(main())\n```\n\n## Summary\n\nThe Client Architecture of oxylabs-ai-studio-py provides:\n\n1. **Separation of Concerns**: HTTP communication isolated in `APIClient`\n2. **Code Reuse**: Common functionality in `BaseApp` for all modules\n3. **Extensibility**: Easy addition of new application modules\n4. **Reliability**: Built-in polling, retry, and timeout mechanisms\n5. **Flexibility**: Support for both sync and async operations\n\nAll application modules inherit from the shared base architecture, ensuring consistent behavior and API patterns across the SDK.\n\n---\n\n<a id='data-models'></a>\n\n## Data Models\n\n### 相关页面\n\n相关主题：[Client Architecture](#client-architecture), [AI-Scraper Feature](#ai-scraper)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/models.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/models.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [src/oxylabs_ai_studio/apps/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n</details>\n\n# Data Models\n\nThe oxylabs-ai-studio-py SDK provides a set of Pydantic-based data models that standardize how API responses are structured across all applications. These models serve as the foundation for type-safe data handling, ensuring consistent response parsing regardless of which AI-powered service is being used.\n\n## Overview\n\nThe SDK implements a layered response model architecture:\n\n| Layer | Model | Purpose |\n|-------|-------|---------|\n| Container | `DataModel` | Wraps the actual extracted content with type metadata |\n| Response | `AiScraperJob`, `BrowserAgentJob`, `AiSearchJob`, `AiCrawlerJob` | Top-level job responses containing status, run ID, and data |\n\nThis design separates concerns between job metadata (run tracking, error handling) and the actual data payload, allowing flexible content types while maintaining a consistent interface.\n\n## Core Response Models\n\nAll job response models inherit from Pydantic's `BaseModel` and share a common structure with three fields.\n\n### Common Fields Across All Job Models\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the API job execution |\n| `message` | `str \\| None` | Error code or status message (nullable) |\n| `data` | Varies | The actual response payload (type depends on output format and model) |\n\n### AiScraperJob\n\nLocated in `ai_scraper.py`, this model handles single-page scraping responses.\n\n```python\nclass AiScraperJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: str | dict | None\n```\n\n**Data Type Mapping:**\n\n| Output Format | Data Type |\n|---------------|-----------|\n| `json` | `dict` |\n| `markdown` | `str` |\n| `csv` | `str` (CSV formatted) |\n| `screenshot` | `str` (base64 encoded) |\n\n资料来源：[readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)()\n\n### BrowserAgentJob\n\nLocated in `browser_agent.py`, this model handles browser automation task responses. It differs from `AiScraperJob` by using a nested `DataModel` structure.\n\n```python\nclass DataModel(BaseModel):\n    type: Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\"]\n    content: dict[str, Any] | str | None\n\nclass BrowserAgentJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: DataModel | None = None\n```\n\n**Supported Content Types:**\n\n- `json` - Structured JSON data (dict)\n- `markdown` - Markdown formatted text (str)\n- `html` - Raw HTML content (str)\n- `screenshot` - Base64 encoded image (str)\n- `csv` - CSV formatted data (str)\n\n资料来源：[agentic_code_guide.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/agentic_code_guide.md)()\n\n### AiSearchJob\n\nLocated in `ai_search.py`, this model handles search engine results pages (SERP) responses.\n\n```python\nclass AiSearchJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: Any  # Search results list\n```\n\nThe data field contains a list of search results, where each result may include:\n- URL\n- Title\n- Snippet\n- Additional metadata depending on `return_content` parameter\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)()\n\n### AiCrawlerJob\n\nLocated in `ai_crawler.py`, this model handles web crawling responses.\n\n```python\nclass AiCrawlerJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: list[str] | dict | None  # Multiple crawled pages\n```\n\nThe data field contains a list of extracted content from crawled pages, formatted according to the specified `output_format`.\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)()\n\n## DataModel Container\n\nThe `DataModel` class provides a unified container for content extraction, wrapping both the data type and actual content together.\n\n```mermaid\nclassDiagram\n    class DataModel {\n        +Literal type\n        +content: dict~str, Any~ | str | None\n    }\n    \n    class BrowserAgentJob {\n        +str run_id\n        +str | None message\n        +DataModel | None data\n    }\n    \n    BrowserAgentJob o-- DataModel : contains\n```\n\n## Schema Integration\n\nThe SDK supports both raw JSON schemas and Pydantic model integration for structured data extraction.\n\n### JSON Schema Usage\n\nPass a dictionary following JSON Schema specification:\n\n```python\nschema = {\n    \"type\": \"object\",\n    \"properties\": {\n        \"price\": {\"type\": \"string\"},\n        \"title\": {\"type\": \"string\"}\n    },\n    \"required\": []\n}\n\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"json\",\n    schema=schema\n)\n```\n\n### Pydantic Model Usage\n\nFor type-safe extraction, use Pydantic models directly:\n\n```python\nfrom pydantic import BaseModel, Field\n\nclass Game(BaseModel):\n    title: str\n    genre: list[str]\n    developer: str\n    platform: str\n    price: str\n    description: str\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\nresult = scraper.scrape(\n    url=\"https://sandbox.oxylabs.io/products/1\",\n    output_format=\"json\",\n    schema=Game.model_json_schema(),\n)\n```\n\n资料来源：[examples/scrape_pydantic_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_pydantic_schema.py)()\n\n## Response Workflow\n\n```mermaid\ngraph TD\n    A[API Request] --> B{Output Format}\n    B -->|json| C[Structured Dict]\n    B -->|markdown| D[Text String]\n    B -->|csv| E[CSV String]\n    B -->|screenshot| F[Base64 String]\n    \n    C --> G[Response Model]\n    D --> G\n    E --> G\n    F --> G\n    \n    G --> H[Job Response: run_id, message, data]\n```\n\n## Example: Accessing Response Data\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\n# JSON output\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"json\",\n    schema={\"type\": \"object\", \"properties\": {\"title\": {\"type\": \"string\"}}}\n)\n\n# Access the data\nprint(result.run_id)      # Job identifier\nprint(result.message)     # Error code if any\nprint(result.data)        # Extracted dict content\n\n# Markdown output\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"markdown\"\n)\nprint(result.data)        # String content\n```\n\n资料来源：[examples/scrape_generated_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_generated_schema.py)()\n\n## Error Handling\n\nAll job models support nullable `message` fields for error propagation:\n\n```python\nresult = scraper.scrape(url=\"https://example.com\", ...)\n\nif result.message:\n    print(f\"Error occurred: {result.message}\")\nelse:\n    print(f\"Success: {result.data}\")\n```\n\n## Output Format Summary\n\n| Format | Data Structure | Schema Required |\n|--------|---------------|-----------------|\n| `json` | `dict` | Yes |\n| `markdown` | `str` | No |\n| `html` | `str` | No |\n| `csv` | `str` | Yes |\n| `screenshot` | `str` (base64) | No |\n| `toon` | Varies | Yes (Browser Agent only) |\n\n---\n\n<a id='configuration-settings'></a>\n\n## Configuration and Settings\n\n### 相关页面\n\n相关主题：[Error Handling and Logging](#error-handling-logging), [Client Architecture](#client-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/settings.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/settings.py)\n- [src/oxylabs_ai_studio/__init__.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/__init__.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n</details>\n\n# Configuration and Settings\n\n## Overview\n\nThe oxylabs-ai-studio-py SDK provides a centralized configuration system built on Pydantic's `BaseSettings` class. This approach ensures type safety, environment variable validation, and sensible defaults for all configuration values. The configuration module serves as the single source of truth for API credentials and endpoint URLs that are shared across all application modules.\n\nAll SDK applications—including `AiScraper`, `AiCrawler`, `AiSearch`, and `BrowserAgent—consume the same configuration settings, making the system consistent and maintainable. 资料来源：[src/oxylabs_ai_studio/settings.py:1-9]()\n\n## Core Configuration Model\n\nThe `Settings` class defines the available configuration parameters with their types, defaults, and validation rules.\n\n```python\nclass Settings(BaseSettings):\n    OXYLABS_AI_STUDIO_API_KEY: str | None = None\n    OXYLABS_AI_STUDIO_API_URL: str = \"https://api-aistudio.oxylabs.io\"\n```\n\n### Configuration Parameters\n\n| Parameter | Type | Default Value | Description |\n|-----------|------|---------------|-------------|\n| `OXYLABS_AI_STUDIO_API_KEY` | `str \\| None` | `None` | API authentication key obtained from Oxylabs dashboard |\n| `OXYLABS_AI_STUDIO_API_URL` | `str` | `\"https://api-aistudio.oxylabs.io\"` | Base URL for all API requests |\n\n资料来源：[src/oxylabs_ai_studio/settings.py:1-9]()\n\n## Environment Variable Loading\n\nThe SDK automatically loads environment variables using Python's `python-dotenv` package. The `load_dotenv()` function is called at module import time, ensuring all environment variables are available before any configuration is accessed. 资料来源：[src/oxylabs_ai_studio/settings.py:3]()\n\n```mermaid\ngraph TD\n    A[Import oxylabs_ai_studio] --> B[load_dotenv executes]\n    B --> C[Environment Variables Loaded]\n    C --> D[Settings() instantiated]\n    D --> E[API_KEY available to all Apps]\n```\n\n## Application Initialization Pattern\n\nAll SDK applications accept an optional `api_key` parameter in their constructors. When provided, the key is used directly. When omitted, the applications retrieve the API key from the global `settings` object.\n\n```python\n# Direct API key usage\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\n# Environment-based API key usage\nscraper = AiScraper()  # Reads from OXYLABS_AI_STUDIO_API_KEY\n```\n\nThis dual approach provides flexibility for different deployment scenarios:\n\n1. **Explicit Parameter**: API key passed directly to constructor\n2. **Environment Variable**: API key loaded from `OXYLABS_AI_STUDIO_API_KEY` environment variable\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_scraper.py]() [src/oxylabs_ai_studio/apps/ai_crawler.py]()\n\n## Configuration Access in Applications\n\n### AiSearch Application\n\nThe `AiSearch` class initializes its HTTP client with the provided API key and uses the configured API URL for all requests.\n\n```python\ndef get_client(self) -> httpx.Client:\n    return httpx.Client(\n        headers={\n            \"Authorization\": f\"Bearer {self.api_key or settings.OXYLABS_AI_STUDIO_API_KEY}\",\n            \"Content-Type\": \"application/json\",\n        },\n        base_url=settings.OXYLABS_AI_STUDIO_API_URL,\n        timeout=httpx.Timeout(60.0, connect=10.0),\n    )\n```\n\n| Endpoint | HTTP Method | Purpose |\n|----------|-------------|---------|\n| `/search` | POST | Full search with content rendering |\n| `/search/instant` | POST | Fast search returning up to 10 results |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py]()\n\n### AiCrawler Application\n\nThe crawler uses the same client configuration pattern, with the API key and base URL sourced from settings:\n\n```python\ndef get_client(self) -> httpx.Client:\n    return httpx.Client(\n        headers={\n            \"Authorization\": f\"Bearer {self.api_key or settings.OXYLABS_AI_STUDIO_API_KEY}\",\n            \"Content-Type\": \"application/json\",\n        },\n        base_url=settings.OXYLABS_AI_STUDIO_API_URL,\n        timeout=httpx.Timeout(60.0, connect=10.0),\n    )\n```\n\n| Endpoint | HTTP Method | Purpose |\n|----------|-------------|---------|\n| `/crawl/run` | POST | Initiate a crawl job |\n| `/crawl/run/data` | GET | Retrieve crawl results |\n| `/crawl/generate-params` | POST | Generate JSON schema from prompt |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py]()\n\n### AiScraper Application\n\nThe scraper follows the identical pattern for HTTP client initialization:\n\n```python\ndef get_client(self) -> httpx.Client:\n    return httpx.Client(\n        headers={\n            \"Authorization\": f\"Bearer {self.api_key or settings.OXYLABS_AI_studio.API_KEY}\",\n            \"Content-Type\": \"application/json\",\n        },\n        base_url=settings.OXYLABS_AI_STUDIO_API_URL,\n        timeout=httpx.Timeout(60.0, connect=10.0),\n    )\n```\n\n| Endpoint | HTTP Method | Purpose |\n|----------|-------------|---------|\n| `/scrape` | POST | Initiate a scrape job |\n| `/scrape/schema` | POST | Generate JSON schema from prompt |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_scraper.py]()\n\n## HTTP Client Configuration\n\nAll applications share identical HTTP client configuration through a standardized `get_client()` method:\n\n| Parameter | Value | Description |\n|-----------|-------|-------------|\n| `Authorization` | `Bearer {API_KEY}` | OAuth 2.0 bearer token authentication |\n| `Content-Type` | `application/json` | Request payload format |\n| `timeout` | 60.0s (read), 10.0s (connect) | Request timeout configuration |\n| `base_url` | `settings.OXYLABS_AI_STUDIO_API_URL` | API base endpoint |\n\n## Setting Up Environment Variables\n\n### Recommended `.env` File\n\nCreate a `.env` file in your project root with the following content:\n\n```bash\nOXYLABS_AI_STUDIO_API_KEY=your_api_key_here\n```\n\n### Installation and Usage Flow\n\n```mermaid\ngraph LR\n    A[Install SDK<br>pip install oxylabs-ai-studio] --> B[Create .env file]\n    B --> C[Set OXYLABS_AI_STUDIO_API_KEY]\n    C --> D[Import applications]\n    D --> E[Initialize with or without api_key]\n    E --> F[Make API requests]\n```\n\n## Configuration Best Practices\n\n### Development Environment\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\n# Option 1: Use .env file\nscraper = AiScraper()  # Automatically reads from environment\n\n# Option 2: Explicit API key\nscraper = AiScraper(api_key=\"your_dev_key\")\n```\n\n### Production Environment\n\nIn production deployments, use environment variables directly:\n\n```bash\nexport OXYLABS_AI_STUDIO_API_KEY=\"your_production_key\"\n```\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper()  # Uses production API key from environment\n```\n\n### Security Considerations\n\n1. **Never commit API keys** to version control\n2. **Use environment variables** for production deployments\n3. **Use `.gitignore`** to exclude `.env` files\n4. **Rotate API keys** periodically through the Oxylabs dashboard\n\n## Module Exports\n\nThe SDK exports the `settings` object for direct access when needed:\n\n```python\nfrom oxylabs_ai_studio import settings\n\nprint(settings.OXYLABS_AI_STUDIO_API_URL)\n```\n\n资料来源：[src/oxylabs_ai_studio/__init__.py]()\n\n---\n\n<a id='error-handling-logging'></a>\n\n## Error Handling and Logging\n\n### 相关页面\n\n相关主题：[Client Architecture](#client-architecture), [Configuration and Settings](#configuration-settings)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/logger.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [src/oxylabs_ai_studio/apps/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n- [src/oxylabs_ai_studio/apps/ai_map.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_map.py)\n</details>\n\n# Error Handling and Logging\n\n## Overview\n\nThe oxylabs-ai-studio-py SDK implements a comprehensive error handling and logging system that enables developers to monitor SDK operations, debug issues, and gracefully handle failures. The system is designed with simplicity in mind while providing sufficient observability for production environments.\n\nThe logging infrastructure uses Python's standard `logging` module with a package-scoped namespace, ensuring all SDK components can be monitored uniformly. Error handling follows a polling-based pattern for asynchronous operations, with explicit timeout management and user cancellation support.\n\n## Logging Architecture\n\n### Logger Configuration\n\nThe SDK defines a centralized logging configuration through the `logger.py` module.\n\n```python\nLOGGER_NAME = \"oxylabs_ai_studio\"\nDEFAULT_LOG_LEVEL = logging.INFO\n```\n\n资料来源：[src/oxylabs_ai_studio/logger.py:1-14](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n\n### Logger Initialization\n\nThe SDK automatically configures logging upon module import using a module-level initialization pattern:\n\n```python\n_default_logger = logging.getLogger(LOGGER_NAME)\nif not _default_logger.handlers:\n    configure_logging()\n```\n\n资料来源：[src/oxylabs_ai_studio/logger.py:49-52](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n\n### Default Log Format\n\n| Component | Value |\n|-----------|-------|\n| Timestamp | `%(asctime)s` |\n| Logger Name | `%(name)s` |\n| Log Level | `%(levelname)s` |\n| Message | `%(message)s` |\n\nThe default format string produces output like: `2024-01-15 10:30:45,123 - oxylabs_ai_studio - INFO - Starting scrape operation`\n\n## Core Logging Functions\n\n### get_logger()\n\nReturns a logger instance for the SDK. Child loggers automatically inherit the parent's configuration.\n\n```python\ndef get_logger(name: str | None = None) -> logging.Logger:\n    if name is None:\n        logger_name = LOGGER_NAME\n    elif not name.startswith(LOGGER_NAME):\n        logger_name = f\"{LOGGER_NAME}.{name}\"\n    else:\n        logger_name = name\n\n    logger = logging.getLogger(logger_name)\n    if logger_name != LOGGER_NAME:\n        logger.handlers.clear()\n        logger.propagate = True\n    return logger\n```\n\n资料来源：[src/oxylabs_ai_studio/logger.py:16-32](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n\n### configure_logging()\n\nConfigures the root SDK logger with custom settings.\n\n```python\ndef configure_logging(\n    level: int = DEFAULT_LOG_LEVEL,\n    format_string: str | None = None,\n    handler: logging.Handler | None = None,\n) -> None:\n    logger = logging.getLogger(LOGGER_NAME)\n    for existing_handler in logger.handlers[:]:\n        logger.removeHandler(existing_handler)\n\n    logger.setLevel(level)\n    if handler is None:\n        handler = logging.StreamHandler(sys.stderr)\n\n    if format_string is None:\n        format_string = \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n\n    formatter = logging.Formatter(format_string)\n    handler.setFormatter(formatter)\n    logger.addHandler(handler)\n    logger.propagate = False\n```\n\n资料来源：[src/oxylabs_ai_studio/logger.py:35-48](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n\n### Configuration Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `level` | `int` | `logging.INFO` | Minimum log level to record |\n| `format_string` | `str \\| None` | `\"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"` | Custom format pattern |\n| `handler` | `logging.Handler \\| None` | `StreamHandler(sys.stderr)` | Output handler |\n\n## Error Handling Patterns\n\n### Polling-Based Job Status Handling\n\nAll async operations in the SDK follow a consistent polling pattern to check job completion status.\n\n```mermaid\ngraph TD\n    A[Start Job Request] --> B[Submit to API]\n    B --> C[Get run_id]\n    C --> D{Polling Loop}\n    D -->|HTTP 202| E[Wait POLL_INTERVAL_SECONDS]\n    E --> D\n    D -->|HTTP 200| F{Check Status}\n    F -->|completed| G[Return Success Data]\n    F -->|failed| H[Return Failure with Error Code]\n    F -->|processing| E\n    D -->|timeout| I[Raise TimeoutError]\n    D -->|KeyboardInterrupt| J[Log Cancellation & Raise]\n```\n\n### Timeout Management\n\nEach application module defines its own timeout threshold and polling configuration.\n\n| Application | Timeout (seconds) | Poll Interval (seconds) | Max Attempts |\n|-------------|-------------------|------------------------|--------------|\n| Browser Agent | 600 (10 min) | 5 | 120 |\n| AI Crawler | 600 (10 min) | 5 | 120 |\n| AI Scraper | 600 (10 min) | 5 | 120 |\n| AI Search | 600 (10 min) | 5 | 120 |\n| AI Map | 600 (10 min) | 5 | 120 |\n\n资料来源：\n- [src/oxylabs_ai_studio/apps/browser_agent.py:1-15](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py:1-25](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_map.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_map.py)\n\n### Status Response Handling\n\nThe API returns standardized status responses that the SDK interprets:\n\n```python\nif resp_body[\"status\"] == \"completed\":\n    return JobResult(run_id=run_id, data=resp_body[\"data\"])\nif resp_body[\"status\"] == \"failed\":\n    return JobResult(run_id=run_id, message=resp_body.get(\"error_code\"), data=None)\n```\n\n### API Error Responses\n\n| HTTP Status | Meaning | SDK Action |\n|-------------|---------|------------|\n| 200 | Success | Process response body |\n| 202 | Accepted, still processing | Continue polling |\n| 4xx | Client error | Raise `Exception` with response text |\n| 5xx | Server error | Raise `Exception` with response text |\n\n## Job Result Models\n\n### Common Response Structure\n\nAll job results follow a consistent Pydantic model structure:\n\n```python\nclass AiScraperJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: str | dict | None\n\nclass BrowserAgentJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: DataModel | None = None\n\nclass AiSearchJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: resp_body[\"data\"]\n\nclass AiCrawlerJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: list[dict[str, Any]] | list[str] | None = None\n```\n\n资料来源：\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/browser_agent.py:28-35](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py:20-24](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n\n### DataModel for Browser Agent\n\n```python\nclass DataModel(BaseModel):\n    type: Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\", \"toon\"]\n    content: dict[str, Any] | str | None\n```\n\n## Exception Handling\n\n### ValueError Exceptions\n\nThe SDK validates input parameters and raises `ValueError` for missing required fields:\n\n```python\nif output_format in [\"json\", \"csv\", \"toon\"] and schema is None:\n    raise ValueError(\n        \"openapi_schema is required when output_format is json, csv or toon.\",\n    )\n```\n\n资料来源：[src/oxylabs_ai_studio/apps/browser_agent.py:50-54](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Schema Generation Errors\n\n```python\nif response.status_code != 200:\n    raise Exception(f\"Failed to generate schema: {response.text}\")\n```\n\n### Timeout Errors\n\n```python\nraise TimeoutError(f\"Failed to scrape {url}: timeout.\")\nraise TimeoutError(f\"Failed to search {query=}\")\nraise TimeoutError(f\"Failed to crawl {url}: timeout.\")\nraise TimeoutError(f\"Failed to map {url}: timeout.\")\n```\n\n### API Call Errors\n\n```python\nif status_code != 200:\n    raise Exception(f\"Failed to perform instant search: `{response.text}`\")\n```\n\n### User Cancellation\n\nThe SDK gracefully handles `KeyboardInterrupt` exceptions:\n\n```python\nexcept KeyboardInterrupt:\n    logger.info(\"[Cancelled] Scraping was cancelled by user.\")\n    raise KeyboardInterrupt from None\n```\n\n| Exception Type | Trigger | User Message |\n|----------------|---------|---------------|\n| `ValueError` | Missing required parameter | Parameter-specific message |\n| `Exception` | API returns non-200 status | API response text |\n| `TimeoutError` | Job exceeds timeout threshold | Operation-specific timeout message |\n| `KeyboardInterrupt` | User cancels operation | \"[Cancelled] {operation} was cancelled by user.\" |\n\n## Logging Usage Examples\n\n### Basic Logger Usage\n\n```python\nfrom oxylabs_ai_studio.logger import get_logger\n\nlogger = get_logger(__name__)  # Creates logger for current module\nlogger.info(\"Starting operation\")\nlogger.warning(\"Potential issue detected\")\nlogger.error(\"Operation failed\")\n```\n\n### Custom Logging Configuration\n\n```python\nfrom oxylabs_ai_studio.logger import configure_logging\nimport logging\n\n# Set DEBUG level with custom format\nconfigure_logging(\n    level=logging.DEBUG,\n    format_string=\"%(asctime)s [%(levelname)s] %(name)s: %(message)s\"\n)\n```\n\n### Module-Specific Logging\n\n```python\nfrom oxylabs_ai_studio.logger import get_logger\n\n# For SDK internal modules\nbrowser_logger = get_logger(\"browser_agent\")\nscraper_logger = get_logger(\"ai_scraper\")\n\n# Child loggers propagate to parent\nbrowser_logger.info(\"Browser agent started\")  # Logged as \"oxylabs_ai_studio.browser_agent\"\n```\n\n## Best Practices\n\n### 1. Configure Logging Early\n\nSet up logging configuration before initializing SDK clients:\n\n```python\nfrom oxylabs_ai_studio.logger import configure_logging\nimport logging\n\nconfigure_logging(level=logging.DEBUG)\n\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\nscraper = AiScraper(api_key=\"your_key\")\n```\n\n### 2. Handle Timeouts Appropriately\n\nWrap SDK calls in try-except blocks:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"your_key\")\ntry:\n    result = scraper.scrape(url=\"https://example.com\", output_format=\"markdown\")\nexcept TimeoutError as e:\n    logger.error(f\"Scraping timed out: {e}\")\nexcept Exception as e:\n    logger.error(f\"Scraping failed: {e}\")\n```\n\n### 3. Check Job Status for Errors\n\nAlways verify the result's `message` field:\n\n```python\nresult = scraper.scrape(url=\"https://example.com\")\nif result.message:\n    logger.warning(f\"Job completed with message: {result.message}\")\nif result.data is None:\n    logger.error(\"Job failed - no data returned\")\n```\n\n### 4. Handle User Cancellation\n\nGracefully handle keyboard interrupts:\n\n```python\nimport logging\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\nlogger = get_logger(__name__)\ncrawler = AiCrawler(api_key=\"your_key\")\n\ntry:\n    result = crawler.crawl(url=\"https://example.com\", user_prompt=\"Extract data\")\nexcept KeyboardInterrupt:\n    logger.info(\"Crawl operation was cancelled by user\")\n    # Perform cleanup if needed\n```\n\n## Summary\n\nThe oxylabs-ai-studio-py SDK provides a unified logging and error handling system that:\n\n- Uses Python's standard `logging` module with package-scoped namespaces\n- Configures logging automatically on module import\n- Supports custom log levels, formats, and handlers\n- Implements polling-based async operation handling with configurable timeouts\n- Returns consistent Pydantic model responses with status information\n- Provides user-friendly error messages and cancellation handling\n- Follows a single pattern across all application modules for predictability\n\n---\n\n---\n\n## Doramagic Pitfall Log\n\nProject: oxylabs/oxylabs-ai-studio-py\n\nSummary: Found 8 potential pitfall items; 0 are high/blocking. Highest priority: identity - 仓库名和安装名不一致.\n\n## 1. identity · 仓库名和安装名不一致\n\n- Severity: medium\n- Evidence strength: runtime_trace\n- Finding: 仓库名 `oxylabs-ai-studio-py` 与安装入口 `oxylabs-ai-studio` 不完全一致。\n- User impact: 用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- Suggested check: 在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- Reproduction command: `pip install oxylabs-ai-studio`\n- Guardrail action: 页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。\n- Evidence: identity.distribution | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | repo=oxylabs-ai-studio-py; install=oxylabs-ai-studio\n\n## 2. capability · 能力判断依赖假设\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: README/documentation is current enough for a first validation pass.\n- User impact: 假设不成立时，用户拿不到承诺的能力。\n- Suggested check: 将假设转成下游验证清单。\n- Guardrail action: 假设必须转成验证项；没有验证结果前不能写成事实。\n- Evidence: capability.assumptions | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | README/documentation is current enough for a first validation pass.\n\n## 3. maintenance · 来源证据：v.0.2.19\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：v.0.2.19\n- User impact: 可能影响升级、迁移或版本选择。\n- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- Evidence: community_evidence:github | cevd_96a2e22cbea94aac8c2788f763ce7c04 | https://github.com/oxylabs/oxylabs-ai-studio-py/releases/tag/v0.2.19 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 4. maintenance · 维护活跃度未知\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: 未记录 last_activity_observed。\n- User impact: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Guardrail action: 维护活跃度未知时，推荐强度不能标为高信任。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | last_activity_observed missing\n\n## 5. security_permissions · 下游验证发现风险项\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 下游已经要求复核，不能在页面中弱化。\n- Suggested check: 进入安全/权限治理复核队列。\n- Guardrail action: 下游风险存在时必须保持 review/recommendation 降级。\n- Evidence: downstream_validation.risk_items | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium\n\n## 6. security_permissions · 存在评分风险\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 风险会影响是否适合普通用户安装。\n- Suggested check: 把风险写入边界卡，并确认是否需要人工复核。\n- Guardrail action: 评分风险必须进入边界卡，不能只作为内部分数。\n- Evidence: risks.scoring_risks | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium\n\n## 7. maintenance · issue/PR 响应质量未知\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: issue_or_pr_quality=unknown。\n- User impact: 用户无法判断遇到问题后是否有人维护。\n- Suggested check: 抽样最近 issue/PR，判断是否长期无人处理。\n- Guardrail action: issue/PR 响应未知时，必须提示维护风险。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | issue_or_pr_quality=unknown\n\n## 8. maintenance · 发布节奏不明确\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: release_recency=unknown。\n- User impact: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Suggested check: 确认最近 release/tag 和 README 安装命令是否一致。\n- Guardrail action: 发布节奏未知或过期时，安装说明必须标注可能漂移。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | release_recency=unknown\n\n<!-- canonical_name: oxylabs/oxylabs-ai-studio-py; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "oxylabs-ai-studio-py",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "github_repo:1003630893",
          "kind": "repo",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/oxylabs/oxylabs-ai-studio-py"
        },
        {
          "evidence_id": "art_55e0da118ad642838591ad36a30fe56c",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/oxylabs/oxylabs-ai-studio-py#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki output with a Doramagic pitfall appendix.",
      "title": "oxylabs-ai-studio-py 说明书",
      "toc": [
        "https://github.com/oxylabs/oxylabs-ai-studio-py 项目说明书",
        "目录",
        "Installation Guide",
        "Overview",
        "System Requirements",
        "Prerequisites",
        "or",
        "Installation Methods",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": true,
    "repo_commit": "e721fe2fbf86b7f28f77e74763ddd37053965bcd",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "pyproject.toml",
      "uv.lock",
      "readme.md",
      "examples/crawl_markdown.py",
      "examples/search_no_content.py",
      "examples/scrape_markdown.py",
      "examples/search_instant.py",
      "examples/crawl_generated_schema.py",
      "examples/search_with_content.py",
      "examples/scrape_generated_schema.py",
      "examples/browser_agent.py",
      "examples/scrape_pydantic_schema.py",
      "examples/ai_map.py",
      "examples/crawl_pydantic_schema.py",
      "src/oxylabs_ai_studio/logger.py",
      "src/oxylabs_ai_studio/settings.py",
      "src/oxylabs_ai_studio/client.py",
      "src/oxylabs_ai_studio/models.py",
      "src/oxylabs_ai_studio/utils.py",
      "src/oxylabs_ai_studio/__init__.py",
      "src/oxylabs_ai_studio/apps/ai_search.py",
      "src/oxylabs_ai_studio/apps/ai_scraper.py",
      "src/oxylabs_ai_studio/apps/browser_agent.py",
      "src/oxylabs_ai_studio/apps/ai_crawler.py",
      "src/oxylabs_ai_studio/apps/ai_map.py"
    ],
    "repo_inspection_verified": true,
    "review_reasons": [
      "community_discussion_evidence_below_public_threshold"
    ],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# oxylabs-ai-studio-py - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 oxylabs-ai-studio-py 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **想在安装前理解开源项目价值和边界的用户**：当前证据主要来自项目文档。 Claim：`clm_0002` unverified 0.25\n\n## 它能做什么\n\n- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`readme.md` Claim：`clm_0001` supported 0.86\n\n## 怎么开始\n\n- `pip install oxylabs-ai-studio` 证据：`readme.md` Claim：`clm_0003` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：仅建议沙盒试装\n- **为什么**：项目存在安装命令、宿主配置或本地写入线索，不建议直接进入主力环境，应先在隔离环境试装。\n\n### 30 秒判断\n\n- **现在怎么做**：仅建议沙盒试装\n- **最小安全下一步**：先跑 Prompt Preview；若仍要安装，只在隔离环境试装\n- **先别相信**：真实输出质量不能在安装前相信。\n- **继续会触碰**：命令执行、本地环境或项目文件、宿主 AI 上下文\n\n### 现在可以相信\n\n- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`readme.md` Claim：`clm_0001` supported 0.86\n- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`readme.md` Claim：`clm_0003` supported 0.86\n\n### 现在还不能相信\n\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`readme.md`\n\n### 继续会触碰什么\n\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`readme.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`readme.md`\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0004` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`readme.md` Claim：`clm_0005` supported 0.86\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`readme.md` Claim：`clm_0001` supported 0.86\n\n### 上下文规模\n\n- 文件总数：29\n- 重要文件覆盖：17/29\n- 证据索引条目：17\n- 角色 / Skill 条目：2\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 oxylabs-ai-studio-py 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 oxylabs-ai-studio-py 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 oxylabs-ai-studio-py 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 2 个角色 / Skill / 项目文档条目。\n\n- **OxyLabs AI Studio Python SDK**（project_doc）：! AI-Studio Python 1 https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/Ai-Studio2.png https://aistudio.oxylabs.io/?utm source=877&utm medium=affiliate&utm campaign=ai studio&groupid=877&utm content=ai-studio-js-github&transaction id=102f49063ab94276ae8f116d224b67 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`readme.md`\n- **Oxylabs AI Studio Python SDK Agentic Code Guide**（project_doc）：Oxylabs AI Studio Python SDK Agentic Code Guide 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`agentic_code_guide.md`\n\n## 证据索引\n\n- 共索引 17 条证据。\n\n- **OxyLabs AI Studio Python SDK**（documentation）：! AI-Studio Python 1 https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/Ai-Studio2.png https://aistudio.oxylabs.io/?utm source=877&utm medium=affiliate&utm campaign=ai studio&groupid=877&utm content=ai-studio-js-github&transaction id=102f49063ab94276ae8f116d224b67 证据：`readme.md`\n- **License**（source_file）：Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files the \"Software\" , to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 证据：`LICENSE`\n- **Oxylabs AI Studio Python SDK Agentic Code Guide**（documentation）：Oxylabs AI Studio Python SDK Agentic Code Guide 证据：`agentic_code_guide.md`\n- **Python-generated files**（source_file）：Python-generated files pycache / .py oc build/ dist/ wheels/ .egg-info 证据：`.gitignore`\n- **Ai Map**（source_file）：from oxylabs ai studio.apps.ai map import AiMap 证据：`examples/ai_map.py`\n- **Browser Agent**（source_file）：from oxylabs ai studio.apps.browser agent import BrowserAgent 证据：`examples/browser_agent.py`\n- **Crawl Generated Schema**（source_file）：from oxylabs ai studio.apps.ai crawler import AiCrawler 证据：`examples/crawl_generated_schema.py`\n- **Crawl Markdown**（source_file）：from oxylabs ai studio.apps.ai crawler import AiCrawler 证据：`examples/crawl_markdown.py`\n- **Crawl Pydantic Schema**（source_file）：from pydantic import BaseModel, Field from oxylabs ai studio.apps.ai crawler import AiCrawler 证据：`examples/crawl_pydantic_schema.py`\n- **Scrape Generated Schema**（source_file）：from oxylabs ai studio.apps.ai scraper import AiScraper 证据：`examples/scrape_generated_schema.py`\n- **Scrape Markdown**（source_file）：from oxylabs ai studio.apps.ai scraper import AiScraper 证据：`examples/scrape_markdown.py`\n- **Scrape Pydantic Schema**（source_file）：from pydantic import BaseModel from oxylabs ai studio.apps.ai scraper import AiScraper 证据：`examples/scrape_pydantic_schema.py`\n- **Search Instant**（source_file）：from oxylabs ai studio.apps.ai search import AiSearch 证据：`examples/search_instant.py`\n- **Search No Content**（source_file）：from oxylabs ai studio.apps.ai search import AiSearch 证据：`examples/search_no_content.py`\n- **Search With Content**（source_file）：from oxylabs ai studio.apps.ai search import AiSearch 证据：`examples/search_with_content.py`\n- **Makefile**（source_file）：lint: @uv run ruff format ./src @uv run ruff check ./src --fix @uv run mypy ./src 证据：`makefile`\n- **default**（source_file）：project name = \"oxylabs-ai-studio\" version = \"0.2.20\" description = \"Oxylabs studio python sdk\" readme = \"readme.md\" keywords = \"oxylabs\", \"ai\", \"studio\" requires-python = \" =3.10\" dependencies = \"httpx =0.28.1\", \"pydantic =2.0.0\", \"pydantic-settings =2.9.1\", \"python-dotenv =1.1.0\", \"tenacity =9.1.2\", 证据：`pyproject.toml`\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`readme.md`, `LICENSE`, `agentic_code_guide.md`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`readme.md`, `LICENSE`, `agentic_code_guide.md`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\nThe following material strengthens the Repomix/AI Context Pack body. Human Manual is only a reading skeleton; pitfall logs become hard operating constraints for the host AI.\n\n## Human Manual Skeleton\n\nUsage rule: this is only a reading path and salience signal, not factual authority. Concrete facts must still come from repo evidence / Claim Graph.\n\nHard rules for the host AI:\n- Do not treat page titles, order, summaries, or importance as project facts.\n- When explaining the Human Manual skeleton, state that it is only a reading path / salience signal.\n- Capability, installation, compatibility, runtime status, and risk judgments must cite repo evidence, source paths, or Claim Graph.\n\n- **Installation Guide**：importance `high`\n  - source_paths: pyproject.toml, readme.md\n- **Quick Start Guide**：importance `high`\n  - source_paths: src/oxylabs_ai_studio/client.py, src/oxylabs_ai_studio/__init__.py\n- **AI-Scraper Feature**：importance `high`\n  - source_paths: src/oxylabs_ai_studio/apps/ai_scraper.py, examples/scrape_markdown.py, examples/scrape_pydantic_schema.py, examples/scrape_generated_schema.py\n- **AI-Crawler Feature**：importance `high`\n  - source_paths: src/oxylabs_ai_studio/apps/ai_crawler.py, examples/crawl_markdown.py, examples/crawl_pydantic_schema.py, examples/crawl_generated_schema.py\n- **AI-Search Feature**：importance `high`\n  - source_paths: src/oxylabs_ai_studio/apps/ai_search.py, examples/search_with_content.py, examples/search_no_content.py, examples/search_instant.py\n- **AI-Map Feature**：importance `medium`\n  - source_paths: src/oxylabs_ai_studio/apps/ai_map.py, examples/ai_map.py\n- **Browser Agent Feature**：importance `high`\n  - source_paths: src/oxylabs_ai_studio/apps/browser_agent.py, examples/browser_agent.py\n- **Client Architecture**：importance `high`\n  - source_paths: src/oxylabs_ai_studio/client.py, src/oxylabs_ai_studio/utils.py, src/oxylabs_ai_studio/__init__.py\n\n## Repo Inspection Evidence\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `e721fe2fbf86b7f28f77e74763ddd37053965bcd`\n- inspected_files: `pyproject.toml`, `uv.lock`, `readme.md`, `examples/crawl_markdown.py`, `examples/search_no_content.py`, `examples/scrape_markdown.py`, `examples/search_instant.py`, `examples/crawl_generated_schema.py`, `examples/search_with_content.py`, `examples/scrape_generated_schema.py`, `examples/browser_agent.py`, `examples/scrape_pydantic_schema.py`, `examples/ai_map.py`, `examples/crawl_pydantic_schema.py`, `src/oxylabs_ai_studio/logger.py`, `src/oxylabs_ai_studio/settings.py`, `src/oxylabs_ai_studio/client.py`, `src/oxylabs_ai_studio/models.py`, `src/oxylabs_ai_studio/utils.py`, `src/oxylabs_ai_studio/__init__.py`\n\nHard rules for the host AI:\n- Without repo_clone_verified=true, do not claim the source code has been read.\n- Without repo_inspection_verified=true, do not turn README/docs/package observations into facts.\n- Without quick_start_verified=true, do not claim the Quick Start has been successfully run.\n\n## Doramagic Pitfall Constraints\n\nThese rules come from Doramagic discovery, validation, or compilation pitfalls. The host AI must treat them as operating constraints, not general background notes.\n\n### Constraint 1: 仓库名和安装名不一致\n\n- Trigger: 仓库名 `oxylabs-ai-studio-py` 与安装入口 `oxylabs-ai-studio` 不完全一致。\n- Host AI rule: 在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- Why it matters: 用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- Evidence: identity.distribution | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | repo=oxylabs-ai-studio-py; install=oxylabs-ai-studio\n- Hard boundary: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\n\n### Constraint 2: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | README/documentation is current enough for a first validation pass.\n- Hard boundary: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\n\n### Constraint 3: 来源证据：v.0.2.19\n\n- Trigger: GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：v.0.2.19\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能影响升级、迁移或版本选择。\n- Evidence: community_evidence:github | cevd_96a2e22cbea94aac8c2788f763ce7c04 | https://github.com/oxylabs/oxylabs-ai-studio-py/releases/tag/v0.2.19 | 来源类型 github_release 暴露的待验证使用条件。\n- Hard boundary: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\n\n### Constraint 4: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | last_activity_observed missing\n- Hard boundary: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\n\n### Constraint 5: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium\n- Hard boundary: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\n\n### Constraint 6: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium\n- Hard boundary: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\n\n### Constraint 7: issue/PR 响应质量未知\n\n- Trigger: issue_or_pr_quality=unknown。\n- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。\n- Why it matters: 用户无法判断遇到问题后是否有人维护。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | issue_or_pr_quality=unknown\n- Hard boundary: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\n\n### Constraint 8: 发布节奏不明确\n\n- Trigger: release_recency=unknown。\n- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。\n- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | release_recency=unknown\n- Hard boundary: do not present this pitfall as solved, verified, or safe to ignore unless later validation evidence explicitly closes it.\n",
      "summary": "Context and operating boundaries for host AI agents.",
      "title": "AI Context Pack"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card\n\nProject: oxylabs/oxylabs-ai-studio-py\n\n## Doramagic Trial Decision\n\nCurrent decision: it can enter pre-publication recommendation checks. First use should still start with least privilege, a temporary directory, and reversible configuration.\n\n## What The User Can Do Now\n\n- Read the Human Manual first to understand the project purpose and main workflows.\n- Use Prompt Preview for pre-install exploration; it validates interaction shape, not real execution.\n- Run official Quick Start commands only inside an isolated environment, not a primary setup.\n\n## Do Not Do Yet\n\n- Do not treat Prompt Preview as a real project execution result.\n- Do not treat metadata-only validation as sandbox installation validation.\n- Do not describe unverified capabilities as supported, working, or safe to install.\n- Do not provide production data, private files, real secrets, or primary host configuration on first trial.\n\n## Pre-Install Checklist\n\n- Host AI match: local_cli\n- Official installation entry status: official entry point found\n- Isolated temporary directory, temporary host, or container validation: required\n- Configuration rollback path: required\n- API keys, network access, file access, or host configuration changes: treat as high risk until confirmed\n- Installation command, actual output, and failure logs: must be recorded\n\n## Current Blockers\n\n- review_required: community_discussion_evidence_below_public_threshold\n\n## Project-Specific Pitfalls\n\n- 仓库名和安装名不一致 (medium): 用户照着仓库名搜索包或照着包名找仓库时容易走错入口。 Suggested check: 在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- 能力判断依赖假设 (medium): 假设不成立时，用户拿不到承诺的能力。 Suggested check: 将假设转成下游验证清单。\n- 来源证据：v.0.2.19 (medium): 可能影响升级、迁移或版本选择。 Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 维护活跃度未知 (medium): 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 下游验证发现风险项 (medium): 下游已经要求复核，不能在页面中弱化。 Suggested check: 进入安全/权限治理复核队列。\n\n## Risk And Permission Notes\n\n- no_demo: medium\n\n## Evidence Gaps\n\n- No structured evidence gaps are currently visible.\n",
      "summary": "Installation, permission, validation, and pre-recommendation risks.",
      "title": "Boundary & Risk Card"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/oxylabs/oxylabs-ai-studio-py 项目说明书\n\n生成时间：2026-05-18 03:01:39 UTC\n\n## 目录\n\n- [Installation Guide](#installation)\n- [Quick Start Guide](#quickstart)\n- [AI-Scraper Feature](#ai-scraper)\n- [AI-Crawler Feature](#ai-crawler)\n- [AI-Search Feature](#ai-search)\n- [AI-Map Feature](#ai-map)\n- [Browser Agent Feature](#browser-agent)\n- [Client Architecture](#client-architecture)\n- [Data Models](#data-models)\n- [Configuration and Settings](#configuration-settings)\n- [Error Handling and Logging](#error-handling-logging)\n\n<a id='installation'></a>\n\n## Installation Guide\n\n### 相关页面\n\n相关主题：[Quick Start Guide](#quickstart)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [pyproject.toml](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/pyproject.toml)\n- [readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n</details>\n\n# Installation Guide\n\n## Overview\n\nThis guide covers the installation process for the **Oxylabs AI Studio Python SDK** (`oxylabs-ai-studio`). The SDK provides a Python interface for interacting with Oxylabs AI Studio API services, including AI-Scraper, AI-Crawler, AI-Browser-Agent, and other data extraction tools.\n\n资料来源：[readme.md:1-10]()\n\n## System Requirements\n\n| Requirement | Minimum Version | Notes |\n|-------------|-----------------|-------|\n| Python | 3.10+ | Earlier versions are not supported |\n| Package Manager | pip | Standard Python package installer |\n| API Key | Required | Must be obtained from Oxylabs AI Studio |\n\n资料来源：[readme.md:10-11]()\n\n## Prerequisites\n\nBefore installing the SDK, ensure your environment meets the following requirements:\n\n### Python Version Check\n\n```bash\npython --version\n# or\npython3 --version\n```\n\nThe output should show Python 3.10 or higher.\n\n### pip Availability\n\n```bash\npip --version\n# or\npip3 --version\n```\n\n## Installation Methods\n\n### Standard Installation (Recommended)\n\nThe official release version can be installed directly from PyPI using pip:\n\n```bash\npip install oxylabs-ai-studio\n```\n\n资料来源：[readme.md:14]()\n\n### Installation from Source\n\nFor development or testing purposes, you can install from the source repository:\n\n```bash\ngit clone https://github.com/oxylabs/oxylabs-ai-studio-py.git\ncd oxylabs-ai-studio-py\npip install -e .\n```\n\n## Post-Installation Verification\n\nAfter installation, verify the SDK is properly installed:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\nfrom oxylabs_ai_studio.apps.browser_agent import BrowserAgent\nfrom oxylabs_ai_studio.apps.ai_map import AiMap\n\nprint(\"Oxylabs AI Studio SDK imported successfully\")\n```\n\nIf no import errors occur, the installation was successful.\n\n## SDK Components\n\nThe SDK includes the following main components:\n\n| Component | Module Path | Purpose |\n|-----------|-------------|---------|\n| AI Scraper | `oxylabs_ai_studio.apps.ai_scraper` | Scrape website content with AI |\n| AI Crawler | `oxylabs_ai_studio.apps.ai_crawler` | Crawl and extract data from sites |\n| AI Search | `oxylabs_ai_studio.apps.ai_search` | Perform AI-powered SERP searches |\n| Browser Agent | `oxylabs_ai_studio.apps.browser_agent` | Automate browser-based tasks |\n| AI Map | `oxylabs_ai_studio.apps.ai_map` | Map website structures |\n\n资料来源：[readme.md:6-7]()\n\n## Quick Start Configuration\n\nAfter installation, you need to configure your API key to use the SDK:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\n# Initialize with your API key\nscraper = AiScraper(api_key=\"<YOUR_API_KEY>\")\n\n# Example usage\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"markdown\"\n)\n```\n\nReplace `<YOUR_API_KEY>` with your actual Oxylabs AI Studio API key.\n\n## Environment Setup Recommendations\n\n### Virtual Environment (Recommended)\n\nFor isolated development, use a virtual environment:\n\n```bash\n# Create virtual environment\npython -m venv ai-studio-env\n\n# Activate on Linux/macOS\nsource ai-studio-env/bin/activate\n\n# Activate on Windows\nai-studio-env\\Scripts\\activate\n\n# Install SDK\npip install oxylabs-ai-studio\n```\n\n### Using pyproject.toml\n\nIf you're managing a project with `pyproject.toml`:\n\n```toml\n[project]\nname = \"oxylabs-ai-studio\"\nversion = \"latest\"\nrequires-python = \">=3.10\"\ndependencies = [\n    \"oxylabs-ai-studio\",\n]\n```\n\n## Dependencies\n\nThe SDK relies on the following core dependencies (automatically installed):\n\n- `httpx` - HTTP client for API requests\n- `pydantic` - Data validation using Python type hints\n- Standard library modules: `time`, `asyncio`, `logging`\n\n资料来源：[pyproject.toml](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/pyproject.toml)\n\n## Troubleshooting\n\n### Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| ImportError | Ensure Python 3.10+ is installed |\n| AuthenticationError | Verify API key is correct and active |\n| TimeoutError | Check network connectivity |\n| pip install fails | Try upgrading pip: `pip install --upgrade pip` |\n\n### Upgrade Instructions\n\nTo upgrade to the latest version:\n\n```bash\npip install --upgrade oxylabs-ai-studio\n```\n\n## Related Documentation\n\n- [Oxylabs AI Studio](https://aistudio.oxylabs.io/) - Official product page\n- [API Documentation](https://developers.oxylabs.io/) - Detailed API reference\n- [Discord Community](https://discord.gg/Pds3gBmKMH) - Get help from the community\n\n---\n\n<a id='quickstart'></a>\n\n## Quick Start Guide\n\n### 相关页面\n\n相关主题：[Installation Guide](#installation), [AI-Scraper Feature](#ai-scraper), [AI-Crawler Feature](#ai-crawler)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n- [agentic_code_guide.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/agentic_code_guide.md)\n- [examples/scrape_markdown.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_markdown.py)\n- [examples/crawl_markdown.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/crawl_markdown.py)\n- [examples/search_instant.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/search_instant.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n</details>\n\n# Quick Start Guide\n\n## Overview\n\nThe **Oxylabs AI Studio Python SDK** (`oxylabs-ai-studio`) provides a simple Python interface for interacting with [Oxylabs AI Studio API](https://aistudio.oxylabs.io/) services. This SDK enables developers to integrate AI-powered web scraping, crawling, search, and browser automation capabilities into their Python applications with minimal configuration.\n\n**Key Features:**\n\n- AI-Scraper: Extract structured data from web pages using natural language prompts\n- AI-Crawler: Automatically discover and crawl related pages starting from a URL\n- AI-Search: Perform SERP (Search Engine Results Page) searches with content extraction\n- Browser-Agent: Automate browser actions (clicks, scrolls, navigation) via prompts\n- AI-Map: Discover website structure and find pages matching specific keywords\n\n**Requirements:**\n\n| Requirement | Version |\n|-------------|---------|\n| Python | 3.10+ |\n| API Key | Valid Oxylabs AI Studio API key |\n\n资料来源：[readme.md:1-15]()\n\n---\n\n## Installation\n\nInstall the SDK using pip:\n\n```bash\npip install oxylabs-ai-studio\n```\n\n资料来源：[readme.md:16-19]()\n\n---\n\n## Core Concepts\n\n### Authentication\n\nAll applications in the SDK require an API key for authentication. You can obtain an API key from the [Oxylabs AI Studio dashboard](https://aistudio.oxylabs.io/).\n\n### Application Classes\n\nThe SDK provides five main application classes, each located in `oxylabs_ai_studio.apps`:\n\n| Application | Class | Purpose |\n|-------------|-------|---------|\n| AI-Scraper | `AiScraper` | Single-page content extraction |\n| AI-Crawler | `AiCrawler` | Multi-page website crawling |\n| AI-Search | `AiSearch` | Search engine results extraction |\n| Browser-Agent | `BrowserAgent` | Browser automation |\n| AI-Map | `AiMap` | Website structure discovery |\n\n### Output Formats\n\nEach application supports multiple output formats:\n\n| Format | Description | Applicable Apps |\n|--------|-------------|-----------------|\n| `json` | Structured JSON data (requires schema) | All apps |\n| `markdown` | Markdown formatted text | All apps |\n| `html` | Raw HTML content | Scraper, Browser-Agent |\n| `screenshot` | Base64-encoded screenshot | Scraper, Browser-Agent |\n| `csv` | Comma-separated values | Scraper, Crawler |\n| `toon` | AI-defined format | Scraper, Crawler |\n\n---\n\n## Quick Start Workflows\n\n### Mermaid: SDK Initialization Flow\n\n```mermaid\ngraph TD\n    A[Install SDK] --> B[Import Application Class]\n    B --> C[Initialize with API Key]\n    C --> D[Call Method<br/>scrape/crawl/search/run]\n    D --> E[Receive AiXxxJob Response]\n    E --> F[Access result.data]\n    \n    style A fill:#e1f5fe\n    style E fill:#fff3e0\n    style F fill:#e8f5e8\n```\n\n---\n\n## Usage Examples\n\n### AI-Scraper: Basic Scraping\n\nScrape a single URL and extract content in Markdown format:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nurl = \"https://sandbox.oxylabs.io/products/1\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"markdown\",\n    render_javascript=False,\n    geo_location=\"Germany\",\n)\nprint(result)\n```\n\n资料来源：[examples/scrape_markdown.py:1-14]()\n\n### AI-Scraper: Structured JSON Extraction\n\nExtract structured data using a JSON schema:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nschema = scraper.generate_schema(\n    prompt=\"want to parse developer, platform, type, price game title, genre (array) and description\"\n)\nprint(f\"Generated schema: {schema}\")\n\nurl = \"https://sandbox.oxylabs.io/products/3\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"json\",\n    schema=schema,\n    render_javascript=False,\n)\nprint(result)\n```\n\n资料来源：[examples/scrape_generated_schema.py:1-19]()\n\n**Parameters for `AiScraper.scrape`:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `url` | `str` | Yes | - | Target URL to scrape |\n| `output_format` | `Literal[\"json\", \"markdown\", \"csv\", \"screenshot\", \"toon\"]` | No | `\"markdown\"` | Output format |\n| `schema` | `dict \\| None` | Conditional | `None` | JSON schema (required for `json`, `csv`, `toon`) |\n| `render_javascript` | `bool` | No | `False` | Enable JavaScript rendering |\n| `geo_location` | `str` | No | `None` | Proxy location (ISO2 or country name) |\n\n资料来源：[readme.md:55-68]()\n\n---\n\n### AI-Crawler: Website Crawling\n\nCrawl a website starting from a specific URL:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nurl = \"https://oxylabs.io\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"markdown\",\n    render_javascript=False,\n    return_sources_limit=3,\n    geo_location=\"France\",\n)\nprint(\"Results:\")\nfor item in result.data:\n    print(item, \"\\n\")\n```\n\n资料来源：[examples/crawl_markdown.py:1-18]()\n\n### AI-Crawler: Structured Extraction with Pydantic Schema\n\nUse Pydantic models for type-safe schema definition:\n\n```python\nfrom pydantic import BaseModel, Field\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nclass ProxyPlan(BaseModel):\n    name: str = Field(description=\"The name of the proxy plan\")\n    price: str = Field(description=\"The price of the proxy plan\")\n    features: list[str] = Field(description=\"The features of the proxy plan\")\n\nclass ProxyPlans(BaseModel):\n    proxy_plans: list[ProxyPlan] = Field(description=\"The proxy plans\")\n\nurl = \"https://oxylabs.io/\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"json\",\n    schema=ProxyPlans.model_json_schema(),\n    render_javascript=False,\n)\nprint(\"Results:\\n\")\nfor item in result.data:\n    print(item, \"\\n\")\n```\n\n资料来源：[examples/crawl_pydantic_schema.py:1-30]()\n\n**Parameters for `AiCrawler.crawl`:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `url` | `str` | Yes | - | Starting URL to crawl |\n| `user_prompt` | `str` | Yes | - | Natural language prompt to guide extraction |\n| `output_format` | `Literal[\"json\", \"markdown\", \"csv\", \"toon\"]` | No | `\"markdown\"` | Output format |\n| `schema` | `dict \\| None` | Conditional | `None` | JSON schema (required for `json`, `csv`, `toon`) |\n| `render_javascript` | `bool` | No | `False` | Enable JavaScript rendering |\n| `return_sources_limit` | `int` | No | `25` | Max number of sources to return |\n| `geo_location` | `str` | No | `None` | Proxy location (ISO2 or country name) |\n| `max_credits` | `int \\| None` | No | `None` | Maximum credits to use |\n\n资料来源：[readme.md:33-52]()\n\n---\n\n### AI-Search: Search Engine Results\n\nPerform a search with full content extraction:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna recipe\"\nresult = search.search(\n    query=query,\n    limit=5,\n    render_javascript=False,\n    return_content=True,\n)\nprint(result.data)\n```\n\n资料来源：[readme.md:54-67]()\n\n### AI-Search: Instant Search\n\nFor fast results without content (up to 10 results):\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna recipes\"\nresult = search.instant_search(\n    query=query,\n    limit=5,\n    geo_location=\"United States\",\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_instant.py:1-13]()\n\n### AI-Search: Results Without Content\n\nOptimize for speed by disabling content extraction:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna\"\nresult = search.search(\n    query=query,\n    limit=5,\n    render_javascript=False,\n    return_content=False,\n    geo_location=\"Italy\",\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_no_content.py:1-14]()\n\n**Parameters for `AiSearch.search`:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | `str` | Yes | - | What to search for |\n| `limit` | `int` | No | `10` | Max results (max: 50) |\n| `render_javascript` | `bool` | No | `False` | Enable JavaScript rendering |\n| `return_content` | `bool` | No | `True` | Include markdown content in results |\n| `geo_location` | `str` | No | `None` | ISO 2-letter format or country name |\n\n**Instant Search Parameters:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | `str` | Yes | - | The search query |\n| `limit` | `int` | No | `10` | Max results (max: 10) |\n| `geo_location` | `str` | No | `None` | Google's canonical location name |\n\n> **Note:** When `limit <= 10` and `return_content=False`, the search automatically uses the instant endpoint (`/search/instant`) which returns results immediately without polling.\n\n资料来源：[readme.md:68-95]()\n\n---\n\n## Response Data Models\n\n### Mermaid: Response Flow\n\n```mermaid\ngraph LR\n    A[API Request] --> B{AI Studio API}\n    B --> C{Status Check}\n    C -->|Processing| D[Poll for completion]\n    C -->|Completed| E[Return AiXxxJob]\n    C -->|Failed| F[Return with error]\n    D --> C\n    \n    style E fill:#e8f5e8\n    style F fill:#ffebee\n```\n\n### AiScraperJob\n\n```python\nclass AiScraperJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: str | dict | None\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the job |\n| `message` | `str \\| None` | Error code or status message |\n| `data` | `str \\| dict \\| None` | Result data (type depends on `output_format`) |\n\n资料来源：[agentic_code_guide.md:95-104]()\n\n### BrowserAgentJob\n\n```python\nclass DataModel(BaseModel):\n    type: Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\"]\n    content: dict[str, Any] | str | None\n\nclass BrowserAgentJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: DataModel | None = None\n```\n\n资料来源：[agentic_code_guide.md:27-35]()\n\n---\n\n## Best Practices\n\n### Rate Limiting\n\nImplement rate limiting in your application to respect the limits associated with your purchased plan. This prevents service disruptions or overuse.\n\n### Retry Mechanism\n\nImplement retry logic for handling failed requests, but include a limit on the number of retries to avoid:\n\n- Infinite loops\n- Excessive API calls\n- Unnecessary costs\n\n```python\nimport time\n\nMAX_RETRIES = 3\nRETRY_DELAY = 5  # seconds\n\nfor attempt in range(MAX_RETRIES):\n    try:\n        result = scraper.scrape(url=url, output_format=\"markdown\")\n        break\n    except TimeoutError:\n        if attempt < MAX_RETRIES - 1:\n            time.sleep(RETRY_DELAY)\n        else:\n            raise\n```\n\n### Schema Generation\n\nUse the built-in `generate_schema()` method to automatically create JSON schemas from natural language prompts:\n\n```python\nschema = scraper.generate_schema(\n    prompt=\"want to parse developer, platform, type, price game title, genre (array) and description\"\n)\n```\n\nThis approach is recommended over manually writing JSON schemas.\n\n资料来源：[agentic_code_guide.md:7-18]()\n\n### JavaScript Rendering\n\n- Set `render_javascript=False` for static pages to improve performance\n- Use `render_javascript=True` for Single Page Applications (SPAs) or pages with dynamic content\n- The `AiScraper` also supports `render_javascript=\"auto\"` for automatic detection\n\n---\n\n## Next Steps\n\nAfter completing this quick start guide, explore these topics:\n\n1. **Advanced Configuration**: Configure timeouts, custom headers, and proxy settings\n2. **Error Handling**: Implement robust error handling for production applications\n3. **Async Usage**: Use async/await patterns for concurrent operations\n4. **Use Cases**: Review [use case examples](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/agentic_code_guide.md#use-cases-examples) for common workflows\n\n---\n\n## Summary\n\nThe Oxylabs AI Studio Python SDK provides a streamlined interface for AI-powered web data extraction. With just an API key and a few lines of code, you can:\n\n| Capability | SDK Component | Primary Method |\n|------------|---------------|----------------|\n| Extract data from single pages | `AiScraper` | `scrape()` |\n| Crawl entire websites | `AiCrawler` | `crawl()` |\n| Search search engines | `AiSearch` | `search()` / `instant_search()` |\n| Automate browser actions | `BrowserAgent` | `run()` / `run_async()` |\n| Discover site structure | `AiMap` | `map()` |\n\n---\n\n<a id='ai-scraper'></a>\n\n## AI-Scraper Feature\n\n### 相关页面\n\n相关主题：[AI-Crawler Feature](#ai-crawler), [Data Models](#data-models)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [examples/scrape_markdown.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_markdown.py)\n- [examples/scrape_pydantic_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_pydantic_schema.py)\n- [examples/scrape_generated_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_generated_schema.py)\n</details>\n\n# AI-Scraper Feature\n\n## Overview\n\nThe **AI-Scraper** is a core feature of the Oxylabs AI Studio Python SDK designed to scrape website content and return extracted data in multiple formats. It leverages AI capabilities to intelligently extract structured or unstructured data from web pages based on natural language prompts or JSON schemas.\n\n### Purpose and Scope\n\nThe AI-Scraper provides the following capabilities:\n\n- **Flexible Output Formats**: Supports Markdown, JSON, CSV, and screenshot output\n- **Schema-Based Extraction**: Enables structured data extraction using JSON schemas or Pydantic models\n- **AI-Powered Parsing**: Uses natural language prompts to guide data extraction\n- **JavaScript Rendering**: Supports pages requiring client-side rendering\n- **Geo-Location Targeting**: Allows scraping from specific geographic locations\n\n## Architecture\n\n```mermaid\ngraph TD\n    A[User Request] --> B[AiScraper Class]\n    B --> C{Output Format}\n    C -->|markdown| D[Markdown Parser]\n    C -->|json| E[Schema Validator]\n    C -->|csv| F[CSV Formatter]\n    C -->|screenshot| G[Screenshot Capture]\n    D --> H[API Endpoint]\n    E --> H\n    F --> H\n    G --> H\n    H --> I[Oxylabs API]\n    I --> J[Response Handler]\n    J --> K[Structured Data]\n```\n\n## Core Components\n\n### AiScraper Class\n\nThe main interface for web scraping operations. The class provides both synchronous and asynchronous methods for scraping web content.\n\n**Import Statement:**\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n```\n\n**Initialization:**\n```python\nscraper = AiScraper(api_key=\"<API_KEY>\")\n```\n\n### Key Methods\n\n| Method | Description | Type |\n|--------|-------------|------|\n| `scrape()` | Synchronous scraping operation | Sync |\n| `scrape_async()` | Asynchronous scraping operation | Async |\n| `generate_schema()` | Auto-generate JSON schema from prompt | Helper |\n\n## API Parameters\n\n### Required Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `url` | `str` | Target URL to scrape |\n| `output_format` | `Literal[\"json\", \"markdown\", \"csv\", \"screenshot\"]` | Desired output format |\n\n### Optional Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `schema` | `dict \\| None` | `None` | JSON schema for structured extraction (required for \"json\" and \"csv\" formats) |\n| `render_javascript` | `bool` | `False` | Enable JavaScript rendering |\n| `geo_location` | `str` | `None` | Proxy location in ISO2 format or country name |\n\n## Usage Patterns\n\n### Basic Markdown Scraping\n\nThe simplest use case extracts page content as Markdown without requiring a schema.\n\n**Example** ([examples/scrape_markdown.py](examples/scrape_markdown.py)):\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nurl = \"https://sandbox.oxylabs.io/products/1\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"markdown\",\n    render_javascript=False,\n    geo_location=\"Germany\",\n)\nprint(result)\n```\n\n### Schema-Based JSON Extraction\n\nFor structured data extraction, provide a JSON schema defining the expected output structure.\n\n**Example** ([examples/scrape_generated_schema.py](examples/scrape_generated_schema.py)):\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nschema = scraper.generate_schema(\n    prompt=\"want to parse developer, platform, type, price game title, genre (array) and description\"\n)\nprint(f\"Generated schema: {schema}\")\n\nurl = \"https://sandbox.oxylabs.io/products/3\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"json\",\n    schema=schema,\n    render_javascript=False,\n)\nprint(result)\n```\n\n### Pydantic Model Integration\n\nFor type-safe extraction, use Pydantic models which are automatically converted to JSON schemas.\n\n**Example** ([examples/scrape_pydantic_schema.py](examples/scrape_pydantic_schema.py)):\n```python\nfrom pydantic import BaseModel\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nclass Game(BaseModel):\n    title: str\n    genre: list[str]\n    developer: str\n    platform: str\n    game_type: str\n    description: str\n    price: str\n    availability: str\n\nurl = \"https://sandbox.oxylabs.io/products/1\"\nresult = scraper.scrape(\n    url=url,\n    output_format=\"json\",\n    schema=Game.model_json_schema(),\n    render_javascript=False,\n)\nprint(result)\n```\n\n## Async Usage\n\n### Async Interface\n\nFor high-performance applications, use the async interface:\n\n```python\nimport asyncio\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nasync def main():\n    url = \"https://sandbox.oxylabs.io/products/3\"\n    result = await scraper.scrape_async(\n        url=url,\n        output_format=\"json\",\n        schema={\"type\": \"object\", \"properties\": {\"price\": {\"type\": \"string\"}}, \"required\": []},\n        render_javascript=False,\n    )\n    print(result)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n## Response Data Model\n\n### AiScraperJob Structure\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the scraping job |\n| `message` | `str \\| None` | Status message or error description |\n| `data` | `dict \\| str \\| None` | Extracted data based on output format |\n\n### Data Type by Output Format\n\n| Output Format | Data Type | Description |\n|---------------|-----------|-------------|\n| `json` | `dict` | Parsed JSON object |\n| `markdown` | `str` | HTML content converted to Markdown |\n| `csv` | `str` | Comma-separated values string |\n| `screenshot` | `str` | Base64-encoded image data |\n\n## Schema Generation\n\nThe AI-Scraper provides a `generate_schema()` helper method that uses AI to create appropriate JSON schemas from natural language prompts.\n\n```python\nschema = scraper.generate_schema(\n    prompt=\"proxy plans which have name, price, and features\"\n)\n```\n\n**Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `prompt` | `str` | Natural language description of desired data structure |\n\n**Returns:** `dict` - A valid JSON schema object\n\n## Workflow Diagram\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant AiScraper\n    participant API\n    participant Response\n\n    User->>AiScraper: scrape(url, output_format, schema)\n    AiScraper->>AiScraper: Validate parameters\n    AiScraper->>API: POST request with payload\n    API->>API: Process scraping request\n    API->>Response: Return extracted data\n    Response->>AiScraper: AiScraperJob response\n    AiScraper->>User: Return result object\n```\n\n## Configuration Options\n\n### JavaScript Rendering\n\nThe `render_javascript` parameter controls browser rendering behavior:\n\n| Value | Behavior |\n|-------|----------|\n| `False` | No JavaScript rendering (default) |\n| `True` | Always render JavaScript |\n| `\"auto\"` | Service automatically detects if rendering is needed |\n\n### Geo-Location\n\nSpecify geographic location for proxy-based scraping:\n\n```python\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    geo_location=\"Germany\",  # Country name\n    # or \"DE\" for ISO2 format\n)\n```\n\n## Error Handling\n\nWhen a scraping operation fails, the response will include:\n\n1. `run_id` - The job identifier for troubleshooting\n2. `message` - Error description\n3. `data` - `None` when an error occurs\n\nAlways check the `message` field before accessing `data`:\n\n```python\nresult = scraper.scrape(url=url, output_format=\"json\", schema=schema)\nif result.message:\n    print(f\"Error: {result.message}\")\nelse:\n    print(result.data)\n```\n\n## Best Practices\n\n1. **Use Appropriate Schemas**: Always provide a valid JSON schema when using `output_format=\"json\"` or `output_format=\"csv\"`\n2. **Enable JS Rendering When Needed**: Set `render_javascript=True` for SPAs and dynamic content\n3. **Specify Geo-Location**: Use `geo_location` parameter when location-specific content is required\n4. **Handle Errors Gracefully**: Always check the `message` field in the response\n\n## Summary\n\nThe AI-Scraper feature provides a powerful, flexible interface for web content extraction within the Oxylabs AI Studio ecosystem. With support for multiple output formats, schema-based extraction, and both synchronous and asynchronous operation modes, it serves as a versatile tool for various web scraping use cases.\n\n---\n\n<a id='ai-crawler'></a>\n\n## AI-Crawler Feature\n\n### 相关页面\n\n相关主题：[AI-Scraper Feature](#ai-scraper), [AI-Map Feature](#ai-map)\n\n<details>\n<summary>Related Source Files</summary>\n\nThe following source files were used to generate this documentation:\n\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [examples/crawl_markdown.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/crawl_markdown.py)\n- [examples/crawl_pydantic_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/crawl_pydantic_schema.py)\n- [examples/crawl_generated_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/crawl_generated_schema.py)\n- [readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n</details>\n\n# AI-Crawler Feature\n\n## Overview\n\nThe AI-Crawler is a web crawling and content extraction module within the Oxylabs AI Studio Python SDK. It enables intelligent, AI-powered website crawling with natural language prompts to guide content extraction. The crawler navigates starting URLs, discovers relevant pages based on user-defined prompts, and returns structured or unstructured data in multiple formats.\n\n**Key Characteristics:**\n- Natural language-based extraction guidance via `user_prompt`\n- Multi-format output support (JSON, Markdown, CSV, Toon)\n- JavaScript rendering capability for dynamic web pages\n- Geographic localization through proxy positioning\n- Schema-driven structured extraction with optional automatic schema generation\n- Polling-based async job completion handling with configurable timeout\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:1-31]()\n\n## Architecture\n\n### Class Hierarchy\n\n```mermaid\ngraph TD\n    A[OxyStudioAIClient] --> B[AiCrawler]\n    B --> C[AiCrawlerJob]\n    \n    B1[BaseModel] --> C\n```\n\nThe `AiCrawler` class inherits from `OxyStudioAIClient`, which provides the underlying API client functionality including authentication, request handling, and response parsing.\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:23-31]()\n\n### Data Models\n\n```python\nclass AiCrawlerJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: list[dict[str, Any]] | list[str] | None = None\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the crawl job |\n| `message` | `str \\| None` | Error code or status message if job failed |\n| `data` | `list[dict[str, Any]] \\| list[str] \\| None` | Extracted content based on output format |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:27-30]()\n\n## Configuration Constants\n\n| Constant | Value | Purpose |\n|----------|-------|---------|\n| `CRAWLER_TIMEOUT_SECONDS` | `600` (10 minutes) | Maximum time to wait for job completion |\n| `POLL_INTERVAL_SECONDS` | `5` | Interval between status checks |\n| `POLL_MAX_ATTEMPTS` | `120` | Maximum polling attempts before timeout |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:12-14]()\n\n## Core Methods\n\n### `crawl()`\n\nThe primary method for initiating a crawl operation.\n\n```python\ndef crawl(\n    self,\n    url: str,\n    user_prompt: str,\n    output_format: Literal[\"json\", \"markdown\", \"csv\", \"toon\"] = \"markdown\",\n    schema: dict[str, Any] | None = None,\n    render_javascript: bool = False,\n    return_sources_limit: int = 25,\n    geo_location: str | None = None,\n    max_credits: int | None = None,\n) -> AiCrawlerJob\n```\n\n#### Parameters\n\n| Parameter | Type | Default | Required | Description |\n|-----------|------|---------|----------|-------------|\n| `url` | `str` | - | Yes | Starting URL to crawl |\n| `user_prompt` | `str` | - | Yes | Natural language prompt to guide extraction |\n| `output_format` | `Literal[\"json\", \"markdown\", \"csv\", \"toon\"]` | `\"markdown\"` | No | Desired output format |\n| `schema` | `dict[str, Any] \\| None` | `None` | Conditional | JSON schema for structured extraction (required for `json`, `csv`, `toon` formats) |\n| `render_javascript` | `bool` | `False` | No | Enable JavaScript rendering |\n| `return_sources_limit` | `int` | `25` | No | Maximum number of sources to return |\n| `geo_location` | `str \\| None` | `None` | No | Proxy location in ISO2 format or country name |\n| `max_credits` | `int \\| None` | `None` | No | Maximum credits to consume |\n\n#### Validation Rules\n\n```python\nif output_format in [\"json\", \"csv\", \"toon\"] and schema is None:\n    raise ValueError(\n        \"openapi_schema is required when output_format is json, csv or toon.\",\n    )\n```\n\nWhen using `json`, `csv`, or `toon` output formats, a valid JSON schema must be provided. Markdown format does not require a schema.\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:47-52]()\n\n### `generate_schema()`\n\nAutomatically generates a JSON schema based on a natural language prompt.\n\n```python\ndef generate_schema(self, prompt: str) -> dict[str, Any] | None\n```\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `prompt` | `str` | Yes | Natural language description of desired data structure |\n\n**Returns:** A dictionary containing the generated JSON schema.\n\n**Process Flow:**\n1. Sends prompt to `/crawl/generate-params` endpoint\n2. Validates response status code (must be 200)\n3. Parses and returns schema response\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:89-103]()\n\n## Workflow\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant AiCrawler\n    participant API\n    participant PollService\n    \n    User->>AiCrawler: crawl(url, user_prompt, output_format, schema)\n    AiCrawler->>API: POST /crawl/run\n    API-->>AiCrawler: run_id\n    AiCrawler->>PollService: Start polling\n    PollService->>API: GET /crawl/run/data?run_id=xxx\n    alt Status: processing\n        API-->>PollService: 202 Accepted\n        PollService->>PollService: wait(POLL_INTERVAL_SECONDS)\n        PollService->>API: GET /crawl/run/data\n    end\n    alt Status: completed\n        API-->>PollService: 200 + data\n        PollService-->>User: AiCrawlerJob(data)\n    else Status: failed\n        API-->>PollService: 200 + failed status\n        PollService-->>User: AiCrawlerJob(message=error)\n    else Timeout\n        PollService-->>User: TimeoutError\n    end\n```\n\n### Job Completion States\n\n| Status | Response | Action |\n|--------|----------|--------|\n| `processing` | `202` | Continue polling at `POLL_INTERVAL_SECONDS` |\n| `completed` | `200` with `data` | Return `AiCrawlerJob` with extracted data |\n| `failed` | `200` with `failed` | Return `AiCrawlerJob` with error message |\n| Timeout | After 10 minutes | Raise `TimeoutError` |\n| KeyboardInterrupt | User cancels | Log and re-raise `KeyboardInterrupt` |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:54-85]()\n\n## Usage Examples\n\n### Basic Markdown Crawl\n\n```python\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nurl = \"https://oxylabs.io\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"markdown\",\n    render_javascript=False,\n    return_sources_limit=3,\n    geo_location=\"France\",\n)\nprint(\"Results:\")\nfor item in result.data:\n    print(item, \"\\n\")\n```\n\n资料来源：[examples/crawl_markdown.py:1-18]()\n\n### JSON Extraction with Generated Schema\n\n```python\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nschema = crawler.generate_schema(\n    prompt=\"proxy plans which have name, price, and features\",\n)\nprint(\"schema: \", schema)\n\nurl = \"https://oxylabs.io\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"json\",\n    schema=schema,\n    render_javascript=False,\n)\nprint(\"Results:\")\nfor item in result.data:\n    print(item, \"\\n\")\n```\n\n资料来源：[examples/crawl_generated_schema.py:1-24]()\n\n### Structured Extraction with Pydantic Schema\n\n```python\nfrom pydantic import BaseModel, Field\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\ncrawler = AiCrawler(api_key=\"<API_KEY>\")\n\nclass ProxyPlan(BaseModel):\n    name: str = Field(description=\"The name of the proxy plan\")\n    price: str = Field(description=\"The price of the proxy plan\")\n    features: list[str] = Field(description=\"The features of the proxy plan\")\n\nclass ProxyPlans(BaseModel):\n    proxy_plans: list[ProxyPlan] = Field(description=\"The proxy plans\")\n\nurl = \"https://oxylabs.io/\"\nresult = crawler.crawl(\n    url=url,\n    user_prompt=\"Find all pages with proxy products pricing\",\n    output_format=\"json\",\n    schema=ProxyPlans.model_json_schema(),\n    render_javascript=False,\n)\n```\n\n资料来源：[examples/crawl_pydantic_schema.py:1-28]()\n\n## Output Formats\n\n| Format | Schema Required | Data Type in `AiCrawlerJob.data` | Use Case |\n|--------|-----------------|----------------------------------|----------|\n| `markdown` | No | `list[str]` | Content summarization, human-readable output |\n| `json` | Yes | `list[dict[str, Any]]` | Structured data processing, API integration |\n| `csv` | Yes | `list[dict[str, Any]]` | Spreadsheet imports, tabular analysis |\n| `toon` | Yes | `list[dict[str, Any]]` | Specialized structured format |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:41-46]()\n\n## Geographic Localization\n\nThe `geo_location` parameter supports multiple formats:\n\n| Format | Example | Description |\n|--------|---------|-------------|\n| ISO 2-letter code | `\"US\"` | US, GB, DE, FR, etc. |\n| Country canonical name | `\"United States\"` | Capitalized full name |\n| Coordinate formats | See SERP Localization docs | Advanced localization |\n\n资料来源：[readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n\n## Error Handling\n\n### Schema Validation Error\n\n```python\n# This raises ValueError\nresult = crawler.crawl(\n    url=\"https://example.com\",\n    user_prompt=\"Extract prices\",\n    output_format=\"json\",\n    schema=None,  # Missing schema\n)\n# ValueError: openapi_schema is required when output_format is json, csv or toon.\n```\n\n### Timeout Handling\n\n```python\ntry:\n    result = crawler.crawl(\n        url=\"https://example.com\",\n        user_prompt=\"Extract all products\",\n        output_format=\"markdown\",\n    )\nexcept TimeoutError as e:\n    print(f\"Crawl failed: {e}\")\n    # Handle timeout - consider retrying with reduced scope\n```\n\n### Keyboard Interrupt\n\nWhen a user cancels the operation mid-polling, the crawler logs the cancellation and re-raises the `KeyboardInterrupt`:\n\n```python\nexcept KeyboardInterrupt:\n    logger.info(\"[Cancelled] Crawling was cancelled by user.\")\n    raise KeyboardInterrupt from None\n```\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py:80-82]()\n\n## Best Practices\n\n### 1. Set Appropriate Source Limits\n\n```python\n# Limit to most relevant sources\nresult = crawler.crawl(\n    url=\"https://ecommerce.example.com\",\n    user_prompt=\"Product pages with pricing\",\n    return_sources_limit=10,  # Balance between coverage and performance\n)\n```\n\n### 2. Use Specific Prompts\n\n```python\n# Good: Specific and actionable\nresult = crawler.crawl(\n    url=\"https://example.com\",\n    user_prompt=\"Find all blog posts published in 2024 with author names and publication dates\",\n)\n\n# Less effective: Too vague\nresult = crawler.crawl(\n    url=\"https://example.com\",\n    user_prompt=\"Find stuff\",\n)\n```\n\n### 3. Handle JavaScript Rendering Selectively\n\n```python\n# Only enable if necessary - adds latency\nresult = crawler.crawl(\n    url=\"https://spa.example.com\",\n    user_prompt=\"Extract dashboard metrics\",\n    render_javascript=True,  # Required for SPAs\n)\n```\n\n### 4. Credit Management\n\n```python\n# Set maximum credits for cost control\nresult = crawler.crawl(\n    url=\"https://example.com\",\n    user_prompt=\"Extract product data\",\n    max_credits=100,  # Prevents runaway costs\n)\n```\n\n## Related Features\n\n| Feature | Module | Purpose |\n|---------|--------|---------|\n| AI-Scraper | `AiScraper` | Single-page extraction without crawling |\n| AI-Search | `AiSearch` | Search engine result extraction |\n| AI-Map | `AiMap` | URL discovery and site mapping |\n| Browser-Agent | `BrowserAgent` | Interactive browser automation |\n\n资料来源：[readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n\n---\n\n<a id='ai-search'></a>\n\n## AI-Search Feature\n\n### 相关页面\n\n相关主题：[AI-Scraper Feature](#ai-scraper), [Client Architecture](#client-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [examples/search_with_content.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/search_with_content.py)\n- [examples/search_no_content.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/search_no_content.py)\n- [examples/search_instant.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/search_instant.py)\n</details>\n\n# AI-Search Feature\n\n## Overview\n\nThe AI-Search feature provides a programmatic interface for performing AI-powered search engine results page (SERP) queries. It enables users to search for information and retrieve results with optional full content extraction, JavaScript rendering support, and geographic localization.\n\nThe feature offers two search modes:\n- **Standard Search**: A polling-based approach for retrieving comprehensive search results with content\n- **Instant Search**: A lightweight endpoint optimized for quick results (up to 10 results) without content\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:1-50]()\n\n## Architecture\n\n### Class Hierarchy\n\nThe AI-Search feature is built on the `OxyStudioAIClient` base class, which provides HTTP client functionality and API communication capabilities.\n\n```python\nclass AiSearch(OxyStudioAIClient):\n    \"\"\"AI Search app.\"\"\"\n```\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:37-38]()\n\n### Module Structure\n\n| Component | File | Responsibility |\n|-----------|------|----------------|\n| AiSearch | ai_search.py | Main synchronous interface |\n| AiSearchJob | ai_search.py | Response data model |\n| SearchResult | ai_search.py | Individual result data model |\n\n## Data Models\n\n### SearchResult\n\nRepresents a single search result entry.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| url | str | The URL of the search result |\n| title | str | The title of the search result |\n| description | str | The description/snippet of the search result |\n| content | str \\| None | Full content of the page (when return_content=True) |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:22-27]()\n\n### AiSearchJob\n\nRepresents the complete search job response.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| run_id | str | Unique identifier for the search job |\n| message | str \\| None | Status message or error code |\n| data | list[SearchResult] \\| None | List of search results |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:29-31]()\n\n## API Methods\n\n### Synchronous Interface\n\n#### search()\n\nPerforms a standard search with polling until results are available.\n\n```python\ndef search(\n    self,\n    query: str,\n    limit: int = 10,\n    render_javascript: bool = False,\n    return_content: bool = True,\n    geo_location: str | None = None,\n) -> AiSearchJob\n```\n\n**Parameters:**\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| query | str | required | The search query string |\n| limit | int | 10 | Maximum number of results (max: 50) |\n| render_javascript | bool | False | Enable JavaScript rendering |\n| return_content | bool | True | Include full content in results |\n| geo_location | str \\| None | None | Geographic location for localized results |\n\n**Return Type:** `AiSearchJob`\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:43-55]()\n\n#### instant_search()\n\nPerforms a fast search using the instant endpoint without polling.\n\n```python\ndef instant_search(\n    self,\n    query: str,\n    limit: int = 10,\n    geo_location: str | None = None,\n) -> AiSearchJob\n```\n\n**Parameters:**\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| query | str | required | The search query string |\n| limit | int | 10 | Maximum number of results (max: 10) |\n| geo_location | str \\| None | None | Geographic location for localized results |\n\n**Note:** Instant search automatically bypasses the polling mechanism when `limit <= 10` and `return_content=False`.\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:95-106]()\n\n### Asynchronous Interface\n\n#### search_async()\n\nAsync version of the standard search method.\n\n```python\nasync def search_async(\n    self,\n    query: str,\n    limit: int = 10,\n    render_javascript: bool = False,\n    return_content: bool = True,\n    geo_location: str | None = None,\n) -> AiSearchJob\n```\n\n#### instant_search_async()\n\nAsync version of the instant search method.\n\n```python\nasync def instant_search_async(\n    self,\n    query: str,\n    limit: int = 10,\n    geo_location: str | None = None,\n) -> AiSearchJob\n```\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:108-148]()\n\n## Workflow and State Management\n\n### Standard Search Polling Flow\n\n```mermaid\ngraph TD\n    A[Start search] --> B[Call /search/run API]\n    B --> C[Extract run_id]\n    C --> D[Call /search/run/data API]\n    D --> E{Status Check}\n    E -->|202 Pending| F[Wait POLL_INTERVAL_SECONDS]\n    E -->|200 Completed| G[Return AiSearchJob with data]\n    E -->|200 Failed| H[Return AiSearchJob with error]\n    F --> D\n    H --> I[End with error]\n    G --> J[End success]\n    \n    style A fill:#e1f5ff\n    style G fill:#c8e6c9\n    style H fill:#ffcdd2\n```\n\n### Instant Search Flow\n\n```mermaid\ngraph TD\n    A[Start instant_search] --> B[Call /search/instant API]\n    B --> C{Status 200?}\n    C -->|Yes| D[Parse response JSON]\n    C -->|No| E[Raise Exception]\n    D --> F[Return AiSearchJob]\n    F --> G[End success]\n    E --> H[End with error]\n    \n    style A fill:#e1f5ff\n    style F fill:#c8e6c9\n    style E fill:#ffcdd2\n```\n\n### Endpoint Selection Logic\n\n```mermaid\ngraph TD\n    A[search called] --> B{limit <= 10?}\n    B -->|Yes| C{return_content == False?}\n    B -->|No| D[Use standard /search/run]\n    C -->|Yes| E[Use instant /search/instant]\n    C -->|No| D\n    E --> F[Return immediately]\n    D --> G[Start polling]\n    G --> H{Status completed?}\n    H -->|Yes| I[Return results]\n    H -->|No| J{Status failed?}\n    J -->|Yes| K[Return with error]\n    J -->|No| L[Continue polling]\n    L --> G\n    \n    style A fill:#e1f5ff\n    style E fill:#c8e6c9\n    style K fill:#ffcdd2\n```\n\n## Configuration Constants\n\n| Constant | Value | Description |\n|----------|-------|-------------|\n| SEARCH_TIMEOUT_SECONDS | 180 (60 * 3) | Maximum time to wait for search completion |\n| POLL_INTERVAL_SECONDS | 5 | Time between polling attempts |\n| POLL_MAX_ATTEMPTS | 36 | Maximum number of polling attempts |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:11-13]()\n\n## Usage Examples\n\n### Search with Content\n\nRetrieves search results including full page content:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna recipe\"\nresult = search.search(\n    query=query,\n    limit=5,\n    render_javascript=False,\n    return_content=True,\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_with_content.py:1-15]()\n\n### Search Without Content\n\nPerforms a lightweight search returning only URL, title, and description:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna\"\nresult = search.search(\n    query=query,\n    limit=5,\n    render_javascript=False,\n    return_content=False,\n    geo_location=\"Italy\",\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_no_content.py:1-17]()\n\n### Instant Search\n\nFast search for up to 10 results with geographic localization:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_search import AiSearch\n\nsearch = AiSearch(api_key=\"<API_KEY>\")\n\nquery = \"lasagna recipes\"\nresult = search.instant_search(\n    query=query,\n    limit=5,\n    geo_location=\"United States\",\n)\nprint(result.data)\n```\n\n资料来源：[examples/search_instant.py:1-14]()\n\n## Geographic Localization\n\nThe `geo_location` parameter supports multiple formats:\n\n| Format | Example |\n|--------|---------|\n| ISO 2-letter code | \"US\", \"DE\", \"FR\" |\n| Country canonical name | \"United States\", \"Germany\", \"France\" |\n| Coordinate formats | Supported per SERP Localization docs |\n\nSupported locations are documented at: [SERP Localization](https://developers.oxylabs.io/scraping-solutions/web-scraper-api/features/localization/serp-localization)\n\n## Error Handling\n\n| Scenario | Behavior |\n|----------|----------|\n| Empty query | Raises `ValueError(\"query is required\")` |\n| API returns non-200 status | Raises `Exception` with response text |\n| Search timeout | Raises `TimeoutError` |\n| Keyboard interrupt | Logs cancellation and re-raises |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py:77-82]()\n\n## Key Implementation Details\n\n### Request Body Construction\n\nBoth search methods construct a standardized request body:\n\n```python\nbody = {\n    \"query\": query,\n    \"limit\": limit,\n    \"render_javascript\": render_javascript,\n    \"return_content\": return_content,\n    \"geo_location\": geo_location,\n}\n```\n\n### API Endpoints\n\n| Endpoint | Method | Purpose |\n|----------|--------|---------|\n| /search/run | POST | Create a new search job |\n| /search/run/data | GET | Poll for search results |\n| /search/instant | POST | Execute instant search |\n\n### Timeout Calculation\n\n```python\nPOLL_MAX_ATTEMPTS = SEARCH_TIMEOUT_SECONDS // POLL_INTERVAL_SECONDS\n# 180 // 5 = 36 attempts\n\n---\n\n<a id='ai-map'></a>\n\n## AI-Map Feature\n\n### 相关页面\n\n相关主题：[AI-Crawler Feature](#ai-crawler), [Client Architecture](#client-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/apps/ai_map.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_map.py)\n- [examples/ai_map.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/ai_map.py)\n</details>\n\n# AI-Map Feature\n\n## Overview\n\nThe AI-Map feature is a URL discovery and site mapping tool within the Oxylabs AI Studio Python SDK. It enables users to explore website structures by mapping URLs based on specified keywords, crawl depth, and filtering criteria. The feature automatically discovers URLs from sitemaps and linked pages, returning a structured list of discovered endpoints that match user-defined search parameters.\n\nAI-Map serves as the first step in many web scraping workflows, helping users understand the structure of a target website before proceeding with detailed content extraction using tools like AiCrawler or AiScraper. 资料来源：[readme.md](readme.md)\n\n## Core Functionality\n\nThe `AiMap` class provides a single primary method: `map()`. This method accepts a comprehensive configuration payload that controls URL discovery behavior. The feature supports:\n\n- **Keyword-based filtering**: Filter discovered URLs by search keywords or natural language prompts\n- **Crawl depth control**: Limit how deep the mapping exploration goes (1-5 levels)\n- **Result limiting**: Cap the total number of URLs returned\n- **Geographic targeting**: Discover URLs with specific geo-location configurations\n- **JavaScript rendering**: Enable JS rendering for dynamically loaded links\n- **Sitemap integration**: Include or exclude sitemap-based URL discovery\n- **Domain scope control**: Allow or restrict subdomains and external domains\n\n资料来源：[examples/ai_map.py](examples/ai_map.py)\n\n## Architecture\n\n```mermaid\ngraph TD\n    A[User calls ai_map.map payload] --> B[AiMap.map method]\n    B --> C[Build request payload]\n    C --> D[POST to /map endpoint]\n    D --> E{Response status?}\n    E -->|pending| F[Poll for completion]\n    E -->|completed| G[Return AiMapJob]\n    E -->|failed| H[Return error]\n    F --> E\n    G --> I[Extract result.data]\n    H --> J[Raise exception]\n    \n    style A fill:#e1f5ff\n    style G fill:#c8e6c9\n    style J fill:#ffcdd2\n```\n\n## Class Reference\n\n### AiMap\n\n**Module**: `oxylabs_ai_studio.apps.ai_map`\n\n**Constructor**:\n\n```python\nAiMap(api_key: str)\n```\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| api_key | str | Oxylabs API key for authentication (required) |\n\n资料来源：[examples/ai_map.py](examples/ai_map.py)\n\n### map() Method\n\n**Signature**:\n\n```python\ndef map(self, **payload) -> AiMapJob\n```\n\n**Parameters Table**:\n\n| Parameter | Type | Default | Required | Description |\n|-----------|------|---------|----------|-------------|\n| url | str | - | Yes | Starting URL or domain to map |\n| search_keywords | list[str] | None | No | Keywords for URL path filtering |\n| user_prompt | str \\| None | None | No | Natural language prompt for keyword search. Can be used together with 'search_keywords' or standalone |\n| max_crawl_depth | int | 1 | No | Maximum crawl depth (range: 1-5) |\n| limit | int | 25 | No | Maximum number of URLs to return |\n| geo_location | str | None | No | Proxy location in ISO2 format or country canonical name |\n| render_javascript | bool | False | No | Enable JavaScript rendering for dynamic content |\n| include_sitemap | bool | True | No | Include sitemap as a seed source for URL discovery |\n| max_credits | int \\| None | None | No | Maximum credits to use for this operation |\n| allow_subdomains | bool | False | No | Allow mapping of subdomain URLs |\n| allow_external_domains | bool | False | No | Allow mapping of external domain URLs |\n\n资料来源：[readme.md](readme.md)\n\n## Usage Examples\n\n### Basic URL Mapping\n\n```python\nfrom oxylabs_ai_studio.apps.ai_map import AiMap\n\nai_map = AiMap(api_key=\"<API_KEY>\")\npayload = {\n    \"url\": \"https://oxylabs.io\",\n    \"search_keywords\": [\"blog\"],\n    \"max_crawl_depth\": 3,\n    \"limit\": 50,\n    \"render_javascript\": False,\n    \"include_sitemap\": True,\n    \"max_credits\": None,\n    \"allow_subdomains\": False,\n    \"allow_external_domains\": False,\n}\nresult = ai_map.map(**payload)\nprint(result.data)\n```\n\n资料来源：[examples/ai_map.py](examples/ai_map.py)\n\n### Mapping Career Pages\n\n```python\nfrom oxylabs_ai_studio.apps.ai_map import AiMap\n\nai_map = AiMap(api_key=\"<API_KEY>\")\npayload = {\n    \"url\": \"https://career.oxylabs.io\",\n    \"search_keywords\": [\"career\", \"jobs\", \"vacancy\"],\n    \"user_prompt\": \"job ad pages\",\n    \"max_crawl_depth\": 2,\n    \"limit\": 10,\n    \"geo_location\": \"Germany\",\n    \"render_javascript\": False,\n    \"include_sitemap\": True,\n    \"max_credits\": None,\n    \"allow_subdomains\": False,\n    \"allow_external_domains\": False,\n}\nresult = ai_map.map(**payload)\nprint(result.data)\n```\n\n资料来源：[readme.md](readme.md)\n\n## Response Model\n\n### AiMapJob\n\n| Field | Type | Description |\n|-------|------|-------------|\n| run_id | str | Unique identifier for this mapping job |\n| message | str \\| None | Status message or error code |\n| data | list \\| None | Discovered URLs matching the search criteria |\n\n## Workflow Diagram: Complete Scraping Pipeline\n\n```mermaid\ngraph LR\n    A[Define target domain] --> B[Use AiMap to discover URLs]\n    B --> C{URLs discovered?}\n    C -->|Yes| D[Filter and select URLs]\n    C -->|No| E[Adjust keywords/depth]\n    E --> B\n    D --> F[Use AiCrawler to crawl content]\n    F --> G{Detailed extraction needed?}\n    G -->|Yes| H[Use AiScraper per URL]\n    G -->|No| I[Process crawled data]\n    H --> I\n    I --> J[Store/Analyze results]\n    \n    style B fill:#fff9c4\n    style F fill:#c8e6c9\n    style H fill:#c8e6c9\n```\n\n## Parameter Interaction\n\n| Parameter | Affects | Interaction Notes |\n|-----------|---------|-------------------|\n| url | All | Root domain determines scope of mapping |\n| max_crawl_depth | API calls, credits | Higher depth increases API usage and discovery scope |\n| limit | Result size | Combined with depth to control total URL count |\n| search_keywords | Filter accuracy | More specific keywords reduce false positives |\n| user_prompt | AI interpretation | Works synergistically with search_keywords |\n| include_sitemap | Initial URL seed | When True, sitemap URLs are added to discovery queue |\n| geo_location | Content variant | URLs may vary based on geo-targeted content |\n| allow_subdomains | Scope expansion | When True, expands discovery beyond main domain |\n\n## Best Practices\n\n1. **Start with low crawl depth**: Begin with `max_crawl_depth=1` to understand basic site structure before expanding\n2. **Use specific keywords**: Combine `search_keywords` with `user_prompt` for precise URL filtering\n3. **Set appropriate limits**: Use `limit` to prevent excessive API usage and manage response sizes\n4. **Enable sitemap**: Keep `include_sitemap=True` for comprehensive initial URL discovery\n5. **Consider geo-location**: If targeting region-specific pages, specify `geo_location` in the initial mapping\n\n## Common Use Cases\n\n| Use Case | Recommended Configuration |\n|----------|--------------------------|\n| Blog post discovery | `{\"search_keywords\": [\"blog\", \"article\"], \"max_crawl_depth\": 2}` |\n| E-commerce product pages | `{\"search_keywords\": [\"product\", \"shop\"], \"max_crawl_depth\": 3}` |\n| Documentation site mapping | `{\"include_sitemap\": True, \"max_crawl_depth\": 4}` |\n| Job listing discovery | `{\"search_keywords\": [\"jobs\", \"careers\", \"vacancy\"], \"max_crawl_depth\": 2}` |\n| News article aggregation | `{\"search_keywords\": [\"news\", \"article\"], \"limit\": 100}` |\n\n## Integration with Other Features\n\nThe AI-Map feature is designed to work as part of a larger scraping pipeline. After discovering URLs, users typically proceed with:\n\n1. **AiCrawler**: For bulk content extraction from discovered URLs\n2. **AiScraper**: For detailed structured data extraction from individual pages\n3. **BrowserAgent**: For interactive browsing tasks requiring user-like navigation\n\n资料来源：[readme.md](readme.md), [agentic_code_guide.md](agentic_code_guide.md)\n\n---\n\n<a id='browser-agent'></a>\n\n## Browser Agent Feature\n\n### 相关页面\n\n相关主题：[AI-Scraper Feature](#ai-scraper), [Data Models](#data-models)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/apps/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n- [examples/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/browser_agent.py)\n- [readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)\n- [agentic_code_guide.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/agentic_code_guide.md)\n</details>\n\n# Browser Agent Feature\n\n## Overview\n\nThe Browser Agent is a powerful browser automation tool within the Oxylabs AI Studio Python SDK that enables programmatic control of web browsers to perform complex actions such as clicking, scrolling, navigating, and extracting data from dynamic web pages. Unlike traditional scraping methods, the Browser Agent accepts natural language prompts to guide its behavior, making it particularly effective for websites that require JavaScript rendering or user interaction.\n\nThe feature serves as a bridge between high-level natural language instructions and low-level browser automation, abstracting away the complexities of web interaction while maintaining flexibility for various use cases. It integrates seamlessly with other AI Studio components like schema generation to provide structured data extraction capabilities.\n\n## Architecture\n\n### Component Overview\n\nThe Browser Agent feature is built on a client-server architecture where the Python SDK acts as a thin client communicating with Oxylabs' cloud-based browser automation infrastructure.\n\n```mermaid\ngraph TD\n    A[BrowserAgent Python Client] --> B[AI Studio API Gateway]\n    B --> C[Browser Agent Service]\n    C --> D[Browser Instance Pool]\n    D --> E[Target Website]\n    F[Schema Generation Service] --> B\n```\n\n### Key Components\n\n| Component | Location | Responsibility |\n|-----------|----------|----------------|\n| `BrowserAgent` | `src/oxylabs_ai_studio/apps/browser_agent.py` | Main client class for browser automation |\n| API Client | Base HTTP client | Handles HTTP communication with API |\n| Polling Mechanism | Built-in | Monitors job status until completion |\n| Schema Generator | Built-in | Creates OpenAPI schemas from prompts |\n\n### Class Hierarchy\n\n```\nBaseClient\n└── BrowserAgent\n    ├── run()\n    ├── run_async()\n    ├── generate_schema()\n    ├── generate_schema_async()\n    ├── call_api()\n    ├── call_api_async()\n    └── get_client() / async_client()\n```\n\n## Data Models\n\n### BrowserAgentJob\n\nThe primary output model returned by Browser Agent operations.\n\n```python\nclass DataModel(BaseModel):\n    type: Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\"]\n    content: dict[str, Any] | str | None\n\nclass BrowserAgentJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: DataModel | None = None\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the browser agent job |\n| `message` | `str \\| None` | Error message or status information if job failed |\n| `data` | `DataModel \\| None` | Contains the extracted data with type and content |\n\n### DataModel Fields\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `type` | `Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\"]` | Format of the extracted content |\n| `content` | `dict[str, Any] \\| str \\| None` | The actual extracted data |\n\n## API Reference\n\n### BrowserAgent Class\n\n**Import Statement:**\n```python\nfrom oxylabs_ai_studio.apps.browser_agent import BrowserAgent\n```\n\n**Initialization:**\n```python\nbrowser_agent = BrowserAgent(api_key=\"<API_KEY>\")\n```\n\n### Method: `run()`\n\nSynchronous method to execute browser agent tasks.\n\n**Signature:**\n```python\ndef run(\n    self,\n    url: str,\n    user_prompt: str,\n    output_format: Literal[\"json\", \"markdown\"] = \"markdown\",\n    schema: dict | None = None,\n    geo_location: str | None = None,\n    user_agent: str | None = None,\n    render_javascript: bool | str = \"auto\",\n) -> BrowserAgentJob\n```\n\n**Parameters:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `url` | `str` | Yes | - | Target URL to browse and interact with |\n| `user_prompt` | `str` | Yes | - | Natural language prompt describing the task to perform |\n| `output_format` | `Literal[\"json\", \"markdown\"]` | No | `\"markdown\"` | Desired output format for extracted data |\n| `schema` | `dict \\| None` | Conditional | `None` | OpenAPI JSON schema for structured extraction (required when `output_format=\"json\"`) |\n| `geo_location` | `str \\| None` | No | `None` | Proxy location in ISO2 format or country canonical name |\n| `user_agent` | `str \\| None` | No | `None` | Custom User-Agent request header |\n| `render_javascript` | `bool \\| str` | No | `\"auto\"` | JavaScript rendering option; can be `True`, `False`, or `\"auto\"` |\n\n**Returns:** `BrowserAgentJob` object containing the job result\n\n**Example Usage:**\n```python\nbrowser_agent = BrowserAgent(api_key=\"<API_KEY>\")\n\nprompt = \"Find if there is game 'super mario odyssey' in the store.\"\nurl = \"https://sandbox.oxylabs.io/\"\nresult = browser_agent.run(\n    url=url,\n    user_prompt=prompt,\n    output_format=\"json\",\n    schema={\"type\": \"object\", \"properties\": {\"page_url\": {\"type\": \"string\"}}, \"required\": []},\n)\nprint(result.data)\n```\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:1-200](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Method: `run_async()`\n\nAsynchronous method to execute browser agent tasks without blocking.\n\n**Signature:**\n```python\nasync def run_async(\n    self,\n    url: str,\n    user_prompt: str,\n    output_format: Literal[\"json\", \"markdown\"] = \"markdown\",\n    schema: dict | None = None,\n    geo_location: str | None = None,\n) -> BrowserAgentJob\n```\n\n**Example Usage:**\n```python\nimport asyncio\nfrom oxylabs_ai_studio.apps.browser_agent import BrowserAgent\n\nbrowser_agent = BrowserAgent(api_key=\"<API_KEY>\")\n\nasync def main():\n    prompt = \"Find if there is game 'super mario odyssey' in the store.\"\n    url = \"https://sandbox.oxylabs.io/\"\n    result = await browser_agent.run_async(\n        url=url,\n        user_prompt=prompt,\n        output_format=\"json\",\n        schema={\"type\": \"object\", \"properties\": {\"page_url\": {\"type\": \"string\"}}, \"required\": []},\n    )\n    print(result.data)\n\nasyncio.run(main())\n```\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:200-280](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Method: `generate_schema()`\n\nGenerates a JSON schema for structured data extraction based on a natural language prompt.\n\n**Signature:**\n```python\ndef generate_schema(self, prompt: str) -> dict[str, Any] | None\n```\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `prompt` | `str` | Yes | Natural language description of the data structure to extract |\n\n**Returns:** Dictionary containing the generated OpenAPI schema, or `None` if generation fails\n\n**Example Usage:**\n```python\nbrowser_agent = BrowserAgent(api_key=\"<API_KEY>\")\n\nschema = browser_agent.generate_schema(\n    prompt=\"game name, platform, review stars and price\"\n)\nprint(\"schema: \", schema)\n```\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:180-195](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Method: `generate_schema_async()`\n\nAsynchronous version of `generate_schema()`.\n\n**Signature:**\n```python\nasync def generate_schema_async(self, prompt: str) -> dict[str, Any] | None\n```\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:145-165](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n## Execution Flow\n\n### Synchronous Execution Workflow\n\n```mermaid\nsequenceDiagram\n    participant Client as BrowserAgent Client\n    participant API as AI Studio API\n    participant Service as Browser Agent Service\n    \n    Client->>API: POST /browser-agent/run\n    Note over API: Returns run_id (status: 201)\n    Client->>API: GET /browser-agent/run/data?run_id=xxx\n    API-->>Client: status: processing\n    loop Poll until complete\n        Client->>API: GET /browser-agent/run/data?run_id=xxx\n        API-->>Client: status: processing\n    end\n    API-->>Client: status: completed, data returned\n```\n\n### Job Status States\n\nThe Browser Agent job follows a state machine pattern with the following statuses:\n\n| Status | Description | Action |\n|--------|-------------|--------|\n| `processing` | Job is currently executing | Continue polling |\n| `completed` | Job finished successfully | Return result |\n| `failed` | Job encountered an error | Return error message |\n| HTTP 202 | Job still initializing | Continue polling |\n| HTTP 200 with no data | Unknown state | Continue polling |\n\n资料来源: [src/oxylabs_ai_studio/apps/browser_agent.py:40-80](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Polling Mechanism\n\nThe synchronous `run()` method implements a polling mechanism with the following characteristics:\n\n- **Poll Interval**: Configured via `POLL_INTERVAL_SECONDS` constant\n- **Timeout Handling**: Raises `TimeoutError` if job does not complete within expected timeframe\n- **Interrupt Support**: Catches `KeyboardInterrupt` to gracefully cancel operations\n\n```python\n# Polling loop structure (simplified)\nwhile True:\n    get_response = self.call_api(...)\n    resp_body = get_response.json()\n    \n    if resp_body[\"status\"] == \"completed\":\n        return BrowserAgentJob(run_id=run_id, data=resp_body[\"data\"])\n    if resp_body[\"status\"] == \"failed\":\n        return BrowserAgentJob(run_id=run_id, message=resp_body.get(\"error_code\"))\n    \n    time.sleep(POLL_INTERVAL_SECONDS)\n```\n\n## Use Cases\n\n### E-commerce Product Discovery\n\nThe Browser Agent excels at navigating websites that require user interaction:\n\n```python\nschema = browser_agent.generate_schema(\n    prompt=\"game name, platform, review stars and price\"\n)\n\nprompt = \"Find if there is game 'super mario odyssey' in the store. If there is, find the price. Use search bar to find the game.\"\nresult = browser_agent.run(\n    url=\"https://sandbox.oxylabs.io/\",\n    user_prompt=prompt,\n    output_format=\"json\",\n    schema=schema,\n    geo_location=\"Spain\",\n)\n```\n\n### Recommended Workflow for Complex Extraction\n\nFor multi-step extraction tasks, combine Browser Agent with other AI Studio tools:\n\n1. **Browser Agent**: Navigate to the target page and identify relevant URLs\n2. **AiScraper**: Extract structured data from identified pages\n3. **Schema Generation**: Create appropriate schemas for each extraction phase\n\n资料来源: [examples/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/browser_agent.py)\n\n## Error Handling\n\n### Exception Types\n\n| Exception | Cause | Handling |\n|-----------|-------|----------|\n| `TimeoutError` | Job exceeded timeout threshold | Retry with exponential backoff |\n| `KeyboardInterrupt` | User cancelled operation | Clean up and exit gracefully |\n| `Exception` | API request failed | Check API key, network connectivity |\n\n### Error Response Handling\n\n```python\nif resp_body[\"status\"] == \"failed\":\n    return BrowserAgentJob(\n        run_id=run_id,\n        message=resp_body.get(\"error_code\", None),\n        data=None,\n    )\n```\n\n### Schema Generation Errors\n\n```python\nif response.status_code != 200:\n    raise Exception(f\"Failed to generate schema: {response.text}\")\n```\n\n## Configuration Options\n\n### Proxy Location\n\nSpecify geographic location for requests:\n\n```python\nresult = browser_agent.run(\n    url=\"https://example.com\",\n    user_prompt=\"Extract product information\",\n    geo_location=\"Germany\",  # or \"DE\" for ISO2 format\n)\n```\n\nSupported formats:\n- ISO 2-letter country codes (e.g., \"DE\", \"US\")\n- Country canonical names (e.g., \"Germany\", \"United States\")\n\n### JavaScript Rendering\n\nControl JavaScript rendering behavior:\n\n| Value | Behavior |\n|-------|----------|\n| `False` | No JavaScript rendering (fastest) |\n| `True` | Always render JavaScript |\n| `\"auto\"` | Service automatically detects if rendering is needed |\n\n### User-Agent Customization\n\n```python\nresult = browser_agent.run(\n    url=\"https://example.com\",\n    user_prompt=\"Navigate and extract\",\n    user_agent=\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\"\n)\n```\n\n## Best Practices\n\n1. **Schema Definition**: Always provide a well-defined schema when using `output_format=\"json\"` for predictable results\n\n2. **Async for Multiple Tasks**: Use `run_async()` when running multiple browser agents concurrently to maximize throughput\n\n3. **Interrupt Handling**: Wrap long-running operations in try-except blocks to handle user cancellations\n\n4. **Error Retries**: Implement retry logic with exponential backoff for transient failures:\n   ```python\n   for attempt in range(3):\n       try:\n           result = browser_agent.run(url=url, user_prompt=prompt)\n           break\n       except TimeoutError:\n           time.sleep(2 ** attempt)\n   ```\n\n5. **Geo-Location**: Use appropriate `geo_location` values when targeting region-specific content\n\n## Comparison with Other Apps\n\n| Feature | Browser Agent | AI Scraper | AI Crawler |\n|---------|---------------|------------|------------|\n| Navigation Actions | ✅ | ❌ | ❌ |\n| JavaScript Interaction | ✅ | Configurable | Configurable |\n| Pagination Handling | ✅ (manual) | Manual | Automatic |\n| Single Page Focus | ✅ | ✅ | ❌ |\n| Schema Generation | ✅ | ✅ | ✅ |\n| Output Formats | json, markdown | json, markdown, csv, screenshot | json, markdown, csv, toon |\n\n## API Endpoints Reference\n\n| Endpoint | Method | Purpose |\n|----------|--------|---------|\n| `/browser-agent/run` | POST | Initiate a browser agent job |\n| `/browser-agent/run/data` | GET | Poll job status and retrieve results |\n| `/browser-agent/generate-params` | POST | Generate extraction schema from prompt |\n\n## See Also\n\n- [AI Scraper Feature](./ai_scraper.md) - Single-page content extraction\n- [AI Crawler Feature](./ai_crawler.md) - Multi-page website crawling\n- [AI Search Feature](./ai_search.md) - Search engine result extraction\n- [AI Map Feature](./ai_map.md) - Site mapping and discovery\n\n---\n\n<a id='client-architecture'></a>\n\n## Client Architecture\n\n### 相关页面\n\n相关主题：[Data Models](#data-models), [Error Handling and Logging](#error-handling-logging)\n\n<details>\n<summary>Relevant Source Files</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/client.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/client.py)\n- [src/oxylabs_ai_studio/utils.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/utils.py)\n- [src/oxylabs_ai_studio/__init__.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/__init__.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n</details>\n\n# Client Architecture\n\n## Overview\n\nThe Oxylabs AI Studio Python SDK follows a layered client architecture that provides a unified interface for interacting with various AI-powered web scraping and data extraction services. The architecture separates concerns between HTTP communication, API interaction, and application-specific logic, enabling modularity and maintainability.\n\nThe client layer serves as the foundation for all application modules (`AiScraper`, `AiSearch`, `AiCrawler`, `BrowserAgent`, `AiMap`) by providing shared functionality for API communication, authentication, request building, and response handling.\n\n## Architecture Components\n\n### Component Overview\n\n| Component | File | Purpose |\n|-----------|------|---------|\n| `APIClient` | `client.py` | Core HTTP client for all API communications |\n| `BaseApp` | `client.py` | Abstract base class for application modules |\n| Utility Functions | `utils.py` | Logging, retry logic, and helper utilities |\n| Application Modules | `apps/*.py` | Domain-specific API wrappers |\n\n### Class Hierarchy\n\n```mermaid\ngraph TD\n    A[APIClient] --> B[BaseApp]\n    B --> C[AiScraper]\n    B --> D[AiSearch]\n    B --> E[AiCrawler]\n    B --> F[BrowserAgent]\n    B --> G[AiMap]\n    \n    H[Requests Session] --> A\n    I[Configuration] --> A\n```\n\n## API Client (`APIClient`)\n\n### Purpose and Responsibilities\n\nThe `APIClient` class is the core HTTP communication layer that handles:\n\n- **Authentication**: Attaches API credentials to all requests\n- **Connection Management**: Manages HTTP session lifecycle\n- **Base URL Configuration**: Stores the API endpoint configuration\n- **Request Execution**: Performs HTTP calls to the Oxylabs API\n\n### Configuration Parameters\n\n| Parameter | Type | Description | Default |\n|-----------|------|-------------|---------|\n| `api_key` | `str` | Authentication key for Oxylabs API | Required |\n| `base_url` | `str` | API base endpoint | `https://ai.oxylabs.io/api/v1` |\n| `timeout` | `int` | Request timeout in seconds | Configurable |\n| `max_retries` | `int` | Maximum retry attempts for failed requests | Configurable |\n\n### Key Methods\n\n```mermaid\ngraph TD\n    A[make_request] --> B{Method Type}\n    B -->|POST| C[POST Request]\n    B -->|GET| D[GET Request]\n    C --> E[Attach JSON Body]\n    D --> F[Attach Query Params]\n    E --> G[Execute Request]\n    F --> G\n    G --> H{Response Status}\n    H -->|2xx| I[Return Response]\n    H -->|4xx/5xx| J[Raise Exception]\n```\n\nThe `APIClient` exposes methods that all application modules use for API communication:\n\n- `call_api(client, url, method, body, params)` - Generic API call method\n- `get_client()` - Returns configured HTTP client instance\n- Session management methods for connection pooling\n\n## Base Application Class (`BaseApp`)\n\n### Purpose and Responsibilities\n\nThe `BaseApp` class serves as an abstract base for all application-specific modules. It provides:\n\n- **Common API Interface**: Unified `call_api()` method across all apps\n- **Client Initialization**: Automatic HTTP client setup with authentication\n- **Polling Infrastructure**: Shared job status polling mechanism\n- **Error Handling**: Standardized exception handling patterns\n\n### Polling Mechanism\n\nAll async operations use a polling pattern to check job completion:\n\n```mermaid\ngraph TD\n    A[Submit Job Request] --> B[Get run_id]\n    B --> C[Poll Status Endpoint]\n    C --> D{Status Check}\n    D -->|202 Processing| C\n    D -->|200 Completed| E[Return Result]\n    D -->|Error| F[Return Error]\n    G[Max Timeout] -->|Exceeded| H[Raise TimeoutError]\n```\n\n### Polling Configuration\n\n| Parameter | Value | Description |\n|-----------|-------|-------------|\n| `POLL_INTERVAL_SECONDS` | `2` | Seconds between status checks |\n| `MAX_TIMEOUT_SECONDS` | `300` | Maximum wait time before timeout |\n\n## Application Modules\n\n### AiScraper\n\nLocated in `src/oxylabs_ai_studio/apps/ai_scraper.py`, this module provides structured web scraping capabilities.\n\n**Key Features:**\n- Single URL content extraction\n- Structured JSON output with custom schemas\n- Markdown, HTML, CSV, and screenshot output formats\n- JavaScript rendering support\n- Geo-location proxy rotation\n\n**Core Methods:**\n- `scrape()` - Synchronous scraping operation\n- `scrape_async()` - Asynchronous scraping operation\n- `generate_schema()` - AI-powered schema generation from natural language\n\n### AiSearch\n\nLocated in `src/oxylabs_ai_studio/apps/ai_search.py`, this module handles search engine result page (SERP) scraping.\n\n**Key Features:**\n- Full search with content retrieval\n- Instant search for quick results (up to 10 results)\n- Content extraction in markdown format\n- Geo-location targeting for localized results\n\n**Core Methods:**\n- `search()` - Full search with content\n- `instant_search()` - Fast search without content polling\n\n### AiCrawler\n\nLocated in `src/oxylabs_ai_studio/apps/ai_crawler.py`, this module provides recursive web crawling with AI-guided extraction.\n\n**Key Features:**\n- Multi-page crawling with depth control\n- AI-guided data extraction\n- Structured JSON output with generated schemas\n- Source limitation and filtering\n\n**Core Methods:**\n- `crawl()` - Start crawling operation\n- `generate_schema()` - Generate extraction schema from prompt\n\n## Request/Response Flow\n\n### Standard API Call Flow\n\n```mermaid\nsequenceDiagram\n    participant App as Application Module\n    participant Client as API Client\n    participant API as Oxylabs API\n    \n    App->>Client: call_api(url, method, body)\n    Client->>Client: Prepare request headers\n    Client->>Client: Attach auth (API Key)\n    Client->>API: HTTP Request\n    API-->>Client: Response\n    Client-->>App: Processed Response\n```\n\n### Job-Based Operation Flow\n\nFor long-running operations (scraping, crawling, searching):\n\n```mermaid\ngraph TD\n    A[Submit Job] --> B[Get run_id]\n    B --> C[Loop: Poll Status]\n    C --> D{Response Status}\n    D -->|202| C\n    D -->|200 Completed| E[Return Data]\n    D -->|Failed| F[Return Error Info]\n```\n\n## Data Models\n\n### Common Response Models\n\n| Model | Fields | Description |\n|-------|--------|-------------|\n| `AiScraperJob` | `run_id`, `message`, `data` | Scraping job result |\n| `AiSearchJob` | `run_id`, `message`, `data` | Search job result |\n| `AiCrawlerJob` | `run_id`, `message`, `data` | Crawling job result |\n| `DataModel` | `type`, `content` | Extracted data container |\n\n### Output Format Types\n\n| Format | Type | Description |\n|--------|------|-------------|\n| `json` | `dict` | Structured JSON output |\n| `markdown` | `str` | Markdown formatted text |\n| `html` | `str` | Raw HTML content |\n| `screenshot` | `str` | Base64 encoded image |\n| `csv` | `str` | CSV formatted data |\n| `toon` | `dict` | Tabular object notation |\n\n## Authentication\n\nThe SDK uses API key-based authentication passed during initialization:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n```\n\nThe API key is:\n- Stored in the `BaseApp` instance configuration\n- Automatically attached to all outgoing HTTP requests\n- Used to authenticate against the Oxylabs AI Studio API endpoint\n\n## Configuration and Utils\n\n### Logging Configuration\n\nLocated in `src/oxylabs_ai_studio/utils.py`, the SDK provides structured logging for debugging and monitoring:\n\n- Configurable log levels\n- Request/response logging\n- Error tracing with context\n\n### Error Handling\n\nThe architecture implements layered error handling:\n\n| Layer | Error Type | Handling |\n|-------|-----------|----------|\n| Client | Network errors | Retry with backoff |\n| API | HTTP errors | Exception with response details |\n| Application | Business logic | Domain-specific exceptions |\n\n### Timeout Configuration\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| Request timeout | Varies by endpoint | Per-request timeout |\n| Polling timeout | 300 seconds | Maximum wait for job completion |\n| Poll interval | 2 seconds | Time between status checks |\n\n## Usage Patterns\n\n### Synchronous Usage\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"json\",\n    schema={\"type\": \"object\", ...}\n)\n```\n\n### Asynchronous Usage\n\n```python\nimport asyncio\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\nasync def main():\n    result = await scraper.scrape_async(\n        url=\"https://example.com\",\n        output_format=\"markdown\"\n    )\n    print(result.data)\n\nasyncio.run(main())\n```\n\n## Summary\n\nThe Client Architecture of oxylabs-ai-studio-py provides:\n\n1. **Separation of Concerns**: HTTP communication isolated in `APIClient`\n2. **Code Reuse**: Common functionality in `BaseApp` for all modules\n3. **Extensibility**: Easy addition of new application modules\n4. **Reliability**: Built-in polling, retry, and timeout mechanisms\n5. **Flexibility**: Support for both sync and async operations\n\nAll application modules inherit from the shared base architecture, ensuring consistent behavior and API patterns across the SDK.\n\n---\n\n<a id='data-models'></a>\n\n## Data Models\n\n### 相关页面\n\n相关主题：[Client Architecture](#client-architecture), [AI-Scraper Feature](#ai-scraper)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/models.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/models.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [src/oxylabs_ai_studio/apps/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n</details>\n\n# Data Models\n\nThe oxylabs-ai-studio-py SDK provides a set of Pydantic-based data models that standardize how API responses are structured across all applications. These models serve as the foundation for type-safe data handling, ensuring consistent response parsing regardless of which AI-powered service is being used.\n\n## Overview\n\nThe SDK implements a layered response model architecture:\n\n| Layer | Model | Purpose |\n|-------|-------|---------|\n| Container | `DataModel` | Wraps the actual extracted content with type metadata |\n| Response | `AiScraperJob`, `BrowserAgentJob`, `AiSearchJob`, `AiCrawlerJob` | Top-level job responses containing status, run ID, and data |\n\nThis design separates concerns between job metadata (run tracking, error handling) and the actual data payload, allowing flexible content types while maintaining a consistent interface.\n\n## Core Response Models\n\nAll job response models inherit from Pydantic's `BaseModel` and share a common structure with three fields.\n\n### Common Fields Across All Job Models\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `run_id` | `str` | Unique identifier for the API job execution |\n| `message` | `str \\| None` | Error code or status message (nullable) |\n| `data` | Varies | The actual response payload (type depends on output format and model) |\n\n### AiScraperJob\n\nLocated in `ai_scraper.py`, this model handles single-page scraping responses.\n\n```python\nclass AiScraperJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: str | dict | None\n```\n\n**Data Type Mapping:**\n\n| Output Format | Data Type |\n|---------------|-----------|\n| `json` | `dict` |\n| `markdown` | `str` |\n| `csv` | `str` (CSV formatted) |\n| `screenshot` | `str` (base64 encoded) |\n\n资料来源：[readme.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/readme.md)()\n\n### BrowserAgentJob\n\nLocated in `browser_agent.py`, this model handles browser automation task responses. It differs from `AiScraperJob` by using a nested `DataModel` structure.\n\n```python\nclass DataModel(BaseModel):\n    type: Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\"]\n    content: dict[str, Any] | str | None\n\nclass BrowserAgentJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: DataModel | None = None\n```\n\n**Supported Content Types:**\n\n- `json` - Structured JSON data (dict)\n- `markdown` - Markdown formatted text (str)\n- `html` - Raw HTML content (str)\n- `screenshot` - Base64 encoded image (str)\n- `csv` - CSV formatted data (str)\n\n资料来源：[agentic_code_guide.md](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/agentic_code_guide.md)()\n\n### AiSearchJob\n\nLocated in `ai_search.py`, this model handles search engine results pages (SERP) responses.\n\n```python\nclass AiSearchJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: Any  # Search results list\n```\n\nThe data field contains a list of search results, where each result may include:\n- URL\n- Title\n- Snippet\n- Additional metadata depending on `return_content` parameter\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)()\n\n### AiCrawlerJob\n\nLocated in `ai_crawler.py`, this model handles web crawling responses.\n\n```python\nclass AiCrawlerJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: list[str] | dict | None  # Multiple crawled pages\n```\n\nThe data field contains a list of extracted content from crawled pages, formatted according to the specified `output_format`.\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)()\n\n## DataModel Container\n\nThe `DataModel` class provides a unified container for content extraction, wrapping both the data type and actual content together.\n\n```mermaid\nclassDiagram\n    class DataModel {\n        +Literal type\n        +content: dict~str, Any~ | str | None\n    }\n    \n    class BrowserAgentJob {\n        +str run_id\n        +str | None message\n        +DataModel | None data\n    }\n    \n    BrowserAgentJob o-- DataModel : contains\n```\n\n## Schema Integration\n\nThe SDK supports both raw JSON schemas and Pydantic model integration for structured data extraction.\n\n### JSON Schema Usage\n\nPass a dictionary following JSON Schema specification:\n\n```python\nschema = {\n    \"type\": \"object\",\n    \"properties\": {\n        \"price\": {\"type\": \"string\"},\n        \"title\": {\"type\": \"string\"}\n    },\n    \"required\": []\n}\n\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"json\",\n    schema=schema\n)\n```\n\n### Pydantic Model Usage\n\nFor type-safe extraction, use Pydantic models directly:\n\n```python\nfrom pydantic import BaseModel, Field\n\nclass Game(BaseModel):\n    title: str\n    genre: list[str]\n    developer: str\n    platform: str\n    price: str\n    description: str\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\nresult = scraper.scrape(\n    url=\"https://sandbox.oxylabs.io/products/1\",\n    output_format=\"json\",\n    schema=Game.model_json_schema(),\n)\n```\n\n资料来源：[examples/scrape_pydantic_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_pydantic_schema.py)()\n\n## Response Workflow\n\n```mermaid\ngraph TD\n    A[API Request] --> B{Output Format}\n    B -->|json| C[Structured Dict]\n    B -->|markdown| D[Text String]\n    B -->|csv| E[CSV String]\n    B -->|screenshot| F[Base64 String]\n    \n    C --> G[Response Model]\n    D --> G\n    E --> G\n    F --> G\n    \n    G --> H[Job Response: run_id, message, data]\n```\n\n## Example: Accessing Response Data\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\n# JSON output\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"json\",\n    schema={\"type\": \"object\", \"properties\": {\"title\": {\"type\": \"string\"}}}\n)\n\n# Access the data\nprint(result.run_id)      # Job identifier\nprint(result.message)     # Error code if any\nprint(result.data)        # Extracted dict content\n\n# Markdown output\nresult = scraper.scrape(\n    url=\"https://example.com\",\n    output_format=\"markdown\"\n)\nprint(result.data)        # String content\n```\n\n资料来源：[examples/scrape_generated_schema.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/examples/scrape_generated_schema.py)()\n\n## Error Handling\n\nAll job models support nullable `message` fields for error propagation:\n\n```python\nresult = scraper.scrape(url=\"https://example.com\", ...)\n\nif result.message:\n    print(f\"Error occurred: {result.message}\")\nelse:\n    print(f\"Success: {result.data}\")\n```\n\n## Output Format Summary\n\n| Format | Data Structure | Schema Required |\n|--------|---------------|-----------------|\n| `json` | `dict` | Yes |\n| `markdown` | `str` | No |\n| `html` | `str` | No |\n| `csv` | `str` | Yes |\n| `screenshot` | `str` (base64) | No |\n| `toon` | Varies | Yes (Browser Agent only) |\n\n---\n\n<a id='configuration-settings'></a>\n\n## Configuration and Settings\n\n### 相关页面\n\n相关主题：[Error Handling and Logging](#error-handling-logging), [Client Architecture](#client-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/settings.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/settings.py)\n- [src/oxylabs_ai_studio/__init__.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/__init__.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n</details>\n\n# Configuration and Settings\n\n## Overview\n\nThe oxylabs-ai-studio-py SDK provides a centralized configuration system built on Pydantic's `BaseSettings` class. This approach ensures type safety, environment variable validation, and sensible defaults for all configuration values. The configuration module serves as the single source of truth for API credentials and endpoint URLs that are shared across all application modules.\n\nAll SDK applications—including `AiScraper`, `AiCrawler`, `AiSearch`, and `BrowserAgent—consume the same configuration settings, making the system consistent and maintainable. 资料来源：[src/oxylabs_ai_studio/settings.py:1-9]()\n\n## Core Configuration Model\n\nThe `Settings` class defines the available configuration parameters with their types, defaults, and validation rules.\n\n```python\nclass Settings(BaseSettings):\n    OXYLABS_AI_STUDIO_API_KEY: str | None = None\n    OXYLABS_AI_STUDIO_API_URL: str = \"https://api-aistudio.oxylabs.io\"\n```\n\n### Configuration Parameters\n\n| Parameter | Type | Default Value | Description |\n|-----------|------|---------------|-------------|\n| `OXYLABS_AI_STUDIO_API_KEY` | `str \\| None` | `None` | API authentication key obtained from Oxylabs dashboard |\n| `OXYLABS_AI_STUDIO_API_URL` | `str` | `\"https://api-aistudio.oxylabs.io\"` | Base URL for all API requests |\n\n资料来源：[src/oxylabs_ai_studio/settings.py:1-9]()\n\n## Environment Variable Loading\n\nThe SDK automatically loads environment variables using Python's `python-dotenv` package. The `load_dotenv()` function is called at module import time, ensuring all environment variables are available before any configuration is accessed. 资料来源：[src/oxylabs_ai_studio/settings.py:3]()\n\n```mermaid\ngraph TD\n    A[Import oxylabs_ai_studio] --> B[load_dotenv executes]\n    B --> C[Environment Variables Loaded]\n    C --> D[Settings() instantiated]\n    D --> E[API_KEY available to all Apps]\n```\n\n## Application Initialization Pattern\n\nAll SDK applications accept an optional `api_key` parameter in their constructors. When provided, the key is used directly. When omitted, the applications retrieve the API key from the global `settings` object.\n\n```python\n# Direct API key usage\nscraper = AiScraper(api_key=\"<API_KEY>\")\n\n# Environment-based API key usage\nscraper = AiScraper()  # Reads from OXYLABS_AI_STUDIO_API_KEY\n```\n\nThis dual approach provides flexibility for different deployment scenarios:\n\n1. **Explicit Parameter**: API key passed directly to constructor\n2. **Environment Variable**: API key loaded from `OXYLABS_AI_STUDIO_API_KEY` environment variable\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_scraper.py]() [src/oxylabs_ai_studio/apps/ai_crawler.py]()\n\n## Configuration Access in Applications\n\n### AiSearch Application\n\nThe `AiSearch` class initializes its HTTP client with the provided API key and uses the configured API URL for all requests.\n\n```python\ndef get_client(self) -> httpx.Client:\n    return httpx.Client(\n        headers={\n            \"Authorization\": f\"Bearer {self.api_key or settings.OXYLABS_AI_STUDIO_API_KEY}\",\n            \"Content-Type\": \"application/json\",\n        },\n        base_url=settings.OXYLABS_AI_STUDIO_API_URL,\n        timeout=httpx.Timeout(60.0, connect=10.0),\n    )\n```\n\n| Endpoint | HTTP Method | Purpose |\n|----------|-------------|---------|\n| `/search` | POST | Full search with content rendering |\n| `/search/instant` | POST | Fast search returning up to 10 results |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_search.py]()\n\n### AiCrawler Application\n\nThe crawler uses the same client configuration pattern, with the API key and base URL sourced from settings:\n\n```python\ndef get_client(self) -> httpx.Client:\n    return httpx.Client(\n        headers={\n            \"Authorization\": f\"Bearer {self.api_key or settings.OXYLABS_AI_STUDIO_API_KEY}\",\n            \"Content-Type\": \"application/json\",\n        },\n        base_url=settings.OXYLABS_AI_STUDIO_API_URL,\n        timeout=httpx.Timeout(60.0, connect=10.0),\n    )\n```\n\n| Endpoint | HTTP Method | Purpose |\n|----------|-------------|---------|\n| `/crawl/run` | POST | Initiate a crawl job |\n| `/crawl/run/data` | GET | Retrieve crawl results |\n| `/crawl/generate-params` | POST | Generate JSON schema from prompt |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_crawler.py]()\n\n### AiScraper Application\n\nThe scraper follows the identical pattern for HTTP client initialization:\n\n```python\ndef get_client(self) -> httpx.Client:\n    return httpx.Client(\n        headers={\n            \"Authorization\": f\"Bearer {self.api_key or settings.OXYLABS_AI_studio.API_KEY}\",\n            \"Content-Type\": \"application/json\",\n        },\n        base_url=settings.OXYLABS_AI_STUDIO_API_URL,\n        timeout=httpx.Timeout(60.0, connect=10.0),\n    )\n```\n\n| Endpoint | HTTP Method | Purpose |\n|----------|-------------|---------|\n| `/scrape` | POST | Initiate a scrape job |\n| `/scrape/schema` | POST | Generate JSON schema from prompt |\n\n资料来源：[src/oxylabs_ai_studio/apps/ai_scraper.py]()\n\n## HTTP Client Configuration\n\nAll applications share identical HTTP client configuration through a standardized `get_client()` method:\n\n| Parameter | Value | Description |\n|-----------|-------|-------------|\n| `Authorization` | `Bearer {API_KEY}` | OAuth 2.0 bearer token authentication |\n| `Content-Type` | `application/json` | Request payload format |\n| `timeout` | 60.0s (read), 10.0s (connect) | Request timeout configuration |\n| `base_url` | `settings.OXYLABS_AI_STUDIO_API_URL` | API base endpoint |\n\n## Setting Up Environment Variables\n\n### Recommended `.env` File\n\nCreate a `.env` file in your project root with the following content:\n\n```bash\nOXYLABS_AI_STUDIO_API_KEY=your_api_key_here\n```\n\n### Installation and Usage Flow\n\n```mermaid\ngraph LR\n    A[Install SDK<br>pip install oxylabs-ai-studio] --> B[Create .env file]\n    B --> C[Set OXYLABS_AI_STUDIO_API_KEY]\n    C --> D[Import applications]\n    D --> E[Initialize with or without api_key]\n    E --> F[Make API requests]\n```\n\n## Configuration Best Practices\n\n### Development Environment\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\n# Option 1: Use .env file\nscraper = AiScraper()  # Automatically reads from environment\n\n# Option 2: Explicit API key\nscraper = AiScraper(api_key=\"your_dev_key\")\n```\n\n### Production Environment\n\nIn production deployments, use environment variables directly:\n\n```bash\nexport OXYLABS_AI_STUDIO_API_KEY=\"your_production_key\"\n```\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper()  # Uses production API key from environment\n```\n\n### Security Considerations\n\n1. **Never commit API keys** to version control\n2. **Use environment variables** for production deployments\n3. **Use `.gitignore`** to exclude `.env` files\n4. **Rotate API keys** periodically through the Oxylabs dashboard\n\n## Module Exports\n\nThe SDK exports the `settings` object for direct access when needed:\n\n```python\nfrom oxylabs_ai_studio import settings\n\nprint(settings.OXYLABS_AI_STUDIO_API_URL)\n```\n\n资料来源：[src/oxylabs_ai_studio/__init__.py]()\n\n---\n\n<a id='error-handling-logging'></a>\n\n## Error Handling and Logging\n\n### 相关页面\n\n相关主题：[Client Architecture](#client-architecture), [Configuration and Settings](#configuration-settings)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/oxylabs_ai_studio/logger.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [src/oxylabs_ai_studio/apps/browser_agent.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n- [src/oxylabs_ai_studio/apps/ai_map.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_map.py)\n</details>\n\n# Error Handling and Logging\n\n## Overview\n\nThe oxylabs-ai-studio-py SDK implements a comprehensive error handling and logging system that enables developers to monitor SDK operations, debug issues, and gracefully handle failures. The system is designed with simplicity in mind while providing sufficient observability for production environments.\n\nThe logging infrastructure uses Python's standard `logging` module with a package-scoped namespace, ensuring all SDK components can be monitored uniformly. Error handling follows a polling-based pattern for asynchronous operations, with explicit timeout management and user cancellation support.\n\n## Logging Architecture\n\n### Logger Configuration\n\nThe SDK defines a centralized logging configuration through the `logger.py` module.\n\n```python\nLOGGER_NAME = \"oxylabs_ai_studio\"\nDEFAULT_LOG_LEVEL = logging.INFO\n```\n\n资料来源：[src/oxylabs_ai_studio/logger.py:1-14](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n\n### Logger Initialization\n\nThe SDK automatically configures logging upon module import using a module-level initialization pattern:\n\n```python\n_default_logger = logging.getLogger(LOGGER_NAME)\nif not _default_logger.handlers:\n    configure_logging()\n```\n\n资料来源：[src/oxylabs_ai_studio/logger.py:49-52](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n\n### Default Log Format\n\n| Component | Value |\n|-----------|-------|\n| Timestamp | `%(asctime)s` |\n| Logger Name | `%(name)s` |\n| Log Level | `%(levelname)s` |\n| Message | `%(message)s` |\n\nThe default format string produces output like: `2024-01-15 10:30:45,123 - oxylabs_ai_studio - INFO - Starting scrape operation`\n\n## Core Logging Functions\n\n### get_logger()\n\nReturns a logger instance for the SDK. Child loggers automatically inherit the parent's configuration.\n\n```python\ndef get_logger(name: str | None = None) -> logging.Logger:\n    if name is None:\n        logger_name = LOGGER_NAME\n    elif not name.startswith(LOGGER_NAME):\n        logger_name = f\"{LOGGER_NAME}.{name}\"\n    else:\n        logger_name = name\n\n    logger = logging.getLogger(logger_name)\n    if logger_name != LOGGER_NAME:\n        logger.handlers.clear()\n        logger.propagate = True\n    return logger\n```\n\n资料来源：[src/oxylabs_ai_studio/logger.py:16-32](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n\n### configure_logging()\n\nConfigures the root SDK logger with custom settings.\n\n```python\ndef configure_logging(\n    level: int = DEFAULT_LOG_LEVEL,\n    format_string: str | None = None,\n    handler: logging.Handler | None = None,\n) -> None:\n    logger = logging.getLogger(LOGGER_NAME)\n    for existing_handler in logger.handlers[:]:\n        logger.removeHandler(existing_handler)\n\n    logger.setLevel(level)\n    if handler is None:\n        handler = logging.StreamHandler(sys.stderr)\n\n    if format_string is None:\n        format_string = \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n\n    formatter = logging.Formatter(format_string)\n    handler.setFormatter(formatter)\n    logger.addHandler(handler)\n    logger.propagate = False\n```\n\n资料来源：[src/oxylabs_ai_studio/logger.py:35-48](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/logger.py)\n\n### Configuration Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `level` | `int` | `logging.INFO` | Minimum log level to record |\n| `format_string` | `str \\| None` | `\"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"` | Custom format pattern |\n| `handler` | `logging.Handler \\| None` | `StreamHandler(sys.stderr)` | Output handler |\n\n## Error Handling Patterns\n\n### Polling-Based Job Status Handling\n\nAll async operations in the SDK follow a consistent polling pattern to check job completion status.\n\n```mermaid\ngraph TD\n    A[Start Job Request] --> B[Submit to API]\n    B --> C[Get run_id]\n    C --> D{Polling Loop}\n    D -->|HTTP 202| E[Wait POLL_INTERVAL_SECONDS]\n    E --> D\n    D -->|HTTP 200| F{Check Status}\n    F -->|completed| G[Return Success Data]\n    F -->|failed| H[Return Failure with Error Code]\n    F -->|processing| E\n    D -->|timeout| I[Raise TimeoutError]\n    D -->|KeyboardInterrupt| J[Log Cancellation & Raise]\n```\n\n### Timeout Management\n\nEach application module defines its own timeout threshold and polling configuration.\n\n| Application | Timeout (seconds) | Poll Interval (seconds) | Max Attempts |\n|-------------|-------------------|------------------------|--------------|\n| Browser Agent | 600 (10 min) | 5 | 120 |\n| AI Crawler | 600 (10 min) | 5 | 120 |\n| AI Scraper | 600 (10 min) | 5 | 120 |\n| AI Search | 600 (10 min) | 5 | 120 |\n| AI Map | 600 (10 min) | 5 | 120 |\n\n资料来源：\n- [src/oxylabs_ai_studio/apps/browser_agent.py:1-15](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py:1-25](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_map.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_map.py)\n\n### Status Response Handling\n\nThe API returns standardized status responses that the SDK interprets:\n\n```python\nif resp_body[\"status\"] == \"completed\":\n    return JobResult(run_id=run_id, data=resp_body[\"data\"])\nif resp_body[\"status\"] == \"failed\":\n    return JobResult(run_id=run_id, message=resp_body.get(\"error_code\"), data=None)\n```\n\n### API Error Responses\n\n| HTTP Status | Meaning | SDK Action |\n|-------------|---------|------------|\n| 200 | Success | Process response body |\n| 202 | Accepted, still processing | Continue polling |\n| 4xx | Client error | Raise `Exception` with response text |\n| 5xx | Server error | Raise `Exception` with response text |\n\n## Job Result Models\n\n### Common Response Structure\n\nAll job results follow a consistent Pydantic model structure:\n\n```python\nclass AiScraperJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: str | dict | None\n\nclass BrowserAgentJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: DataModel | None = None\n\nclass AiSearchJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: resp_body[\"data\"]\n\nclass AiCrawlerJob(BaseModel):\n    run_id: str\n    message: str | None = None\n    data: list[dict[str, Any]] | list[str] | None = None\n```\n\n资料来源：\n- [src/oxylabs_ai_studio/apps/ai_scraper.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_scraper.py)\n- [src/oxylabs_ai_studio/apps/browser_agent.py:28-35](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n- [src/oxylabs_ai_studio/apps/ai_search.py](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_search.py)\n- [src/oxylabs_ai_studio/apps/ai_crawler.py:20-24](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/ai_crawler.py)\n\n### DataModel for Browser Agent\n\n```python\nclass DataModel(BaseModel):\n    type: Literal[\"json\", \"markdown\", \"html\", \"screenshot\", \"csv\", \"toon\"]\n    content: dict[str, Any] | str | None\n```\n\n## Exception Handling\n\n### ValueError Exceptions\n\nThe SDK validates input parameters and raises `ValueError` for missing required fields:\n\n```python\nif output_format in [\"json\", \"csv\", \"toon\"] and schema is None:\n    raise ValueError(\n        \"openapi_schema is required when output_format is json, csv or toon.\",\n    )\n```\n\n资料来源：[src/oxylabs_ai_studio/apps/browser_agent.py:50-54](https://github.com/oxylabs/oxylabs-ai-studio-py/blob/main/src/oxylabs_ai_studio/apps/browser_agent.py)\n\n### Schema Generation Errors\n\n```python\nif response.status_code != 200:\n    raise Exception(f\"Failed to generate schema: {response.text}\")\n```\n\n### Timeout Errors\n\n```python\nraise TimeoutError(f\"Failed to scrape {url}: timeout.\")\nraise TimeoutError(f\"Failed to search {query=}\")\nraise TimeoutError(f\"Failed to crawl {url}: timeout.\")\nraise TimeoutError(f\"Failed to map {url}: timeout.\")\n```\n\n### API Call Errors\n\n```python\nif status_code != 200:\n    raise Exception(f\"Failed to perform instant search: `{response.text}`\")\n```\n\n### User Cancellation\n\nThe SDK gracefully handles `KeyboardInterrupt` exceptions:\n\n```python\nexcept KeyboardInterrupt:\n    logger.info(\"[Cancelled] Scraping was cancelled by user.\")\n    raise KeyboardInterrupt from None\n```\n\n| Exception Type | Trigger | User Message |\n|----------------|---------|---------------|\n| `ValueError` | Missing required parameter | Parameter-specific message |\n| `Exception` | API returns non-200 status | API response text |\n| `TimeoutError` | Job exceeds timeout threshold | Operation-specific timeout message |\n| `KeyboardInterrupt` | User cancels operation | \"[Cancelled] {operation} was cancelled by user.\" |\n\n## Logging Usage Examples\n\n### Basic Logger Usage\n\n```python\nfrom oxylabs_ai_studio.logger import get_logger\n\nlogger = get_logger(__name__)  # Creates logger for current module\nlogger.info(\"Starting operation\")\nlogger.warning(\"Potential issue detected\")\nlogger.error(\"Operation failed\")\n```\n\n### Custom Logging Configuration\n\n```python\nfrom oxylabs_ai_studio.logger import configure_logging\nimport logging\n\n# Set DEBUG level with custom format\nconfigure_logging(\n    level=logging.DEBUG,\n    format_string=\"%(asctime)s [%(levelname)s] %(name)s: %(message)s\"\n)\n```\n\n### Module-Specific Logging\n\n```python\nfrom oxylabs_ai_studio.logger import get_logger\n\n# For SDK internal modules\nbrowser_logger = get_logger(\"browser_agent\")\nscraper_logger = get_logger(\"ai_scraper\")\n\n# Child loggers propagate to parent\nbrowser_logger.info(\"Browser agent started\")  # Logged as \"oxylabs_ai_studio.browser_agent\"\n```\n\n## Best Practices\n\n### 1. Configure Logging Early\n\nSet up logging configuration before initializing SDK clients:\n\n```python\nfrom oxylabs_ai_studio.logger import configure_logging\nimport logging\n\nconfigure_logging(level=logging.DEBUG)\n\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\nscraper = AiScraper(api_key=\"your_key\")\n```\n\n### 2. Handle Timeouts Appropriately\n\nWrap SDK calls in try-except blocks:\n\n```python\nfrom oxylabs_ai_studio.apps.ai_scraper import AiScraper\n\nscraper = AiScraper(api_key=\"your_key\")\ntry:\n    result = scraper.scrape(url=\"https://example.com\", output_format=\"markdown\")\nexcept TimeoutError as e:\n    logger.error(f\"Scraping timed out: {e}\")\nexcept Exception as e:\n    logger.error(f\"Scraping failed: {e}\")\n```\n\n### 3. Check Job Status for Errors\n\nAlways verify the result's `message` field:\n\n```python\nresult = scraper.scrape(url=\"https://example.com\")\nif result.message:\n    logger.warning(f\"Job completed with message: {result.message}\")\nif result.data is None:\n    logger.error(\"Job failed - no data returned\")\n```\n\n### 4. Handle User Cancellation\n\nGracefully handle keyboard interrupts:\n\n```python\nimport logging\nfrom oxylabs_ai_studio.apps.ai_crawler import AiCrawler\n\nlogger = get_logger(__name__)\ncrawler = AiCrawler(api_key=\"your_key\")\n\ntry:\n    result = crawler.crawl(url=\"https://example.com\", user_prompt=\"Extract data\")\nexcept KeyboardInterrupt:\n    logger.info(\"Crawl operation was cancelled by user\")\n    # Perform cleanup if needed\n```\n\n## Summary\n\nThe oxylabs-ai-studio-py SDK provides a unified logging and error handling system that:\n\n- Uses Python's standard `logging` module with package-scoped namespaces\n- Configures logging automatically on module import\n- Supports custom log levels, formats, and handlers\n- Implements polling-based async operation handling with configurable timeouts\n- Returns consistent Pydantic model responses with status information\n- Provides user-friendly error messages and cancellation handling\n- Follows a single pattern across all application modules for predictability\n\n---\n\n---\n\n## Doramagic Pitfall Log\n\nProject: oxylabs/oxylabs-ai-studio-py\n\nSummary: Found 8 potential pitfall items; 0 are high/blocking. Highest priority: identity - 仓库名和安装名不一致.\n\n## 1. identity · 仓库名和安装名不一致\n\n- Severity: medium\n- Evidence strength: runtime_trace\n- Finding: 仓库名 `oxylabs-ai-studio-py` 与安装入口 `oxylabs-ai-studio` 不完全一致。\n- User impact: 用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- Suggested check: 在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- Reproduction command: `pip install oxylabs-ai-studio`\n- Guardrail action: 页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。\n- Evidence: identity.distribution | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | repo=oxylabs-ai-studio-py; install=oxylabs-ai-studio\n\n## 2. capability · 能力判断依赖假设\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: README/documentation is current enough for a first validation pass.\n- User impact: 假设不成立时，用户拿不到承诺的能力。\n- Suggested check: 将假设转成下游验证清单。\n- Guardrail action: 假设必须转成验证项；没有验证结果前不能写成事实。\n- Evidence: capability.assumptions | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | README/documentation is current enough for a first validation pass.\n\n## 3. maintenance · 来源证据：v.0.2.19\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：v.0.2.19\n- User impact: 可能影响升级、迁移或版本选择。\n- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- Evidence: community_evidence:github | cevd_96a2e22cbea94aac8c2788f763ce7c04 | https://github.com/oxylabs/oxylabs-ai-studio-py/releases/tag/v0.2.19 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 4. maintenance · 维护活跃度未知\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: 未记录 last_activity_observed。\n- User impact: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Guardrail action: 维护活跃度未知时，推荐强度不能标为高信任。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | last_activity_observed missing\n\n## 5. security_permissions · 下游验证发现风险项\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 下游已经要求复核，不能在页面中弱化。\n- Suggested check: 进入安全/权限治理复核队列。\n- Guardrail action: 下游风险存在时必须保持 review/recommendation 降级。\n- Evidence: downstream_validation.risk_items | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium\n\n## 6. security_permissions · 存在评分风险\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 风险会影响是否适合普通用户安装。\n- Suggested check: 把风险写入边界卡，并确认是否需要人工复核。\n- Guardrail action: 评分风险必须进入边界卡，不能只作为内部分数。\n- Evidence: risks.scoring_risks | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium\n\n## 7. maintenance · issue/PR 响应质量未知\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: issue_or_pr_quality=unknown。\n- User impact: 用户无法判断遇到问题后是否有人维护。\n- Suggested check: 抽样最近 issue/PR，判断是否长期无人处理。\n- Guardrail action: issue/PR 响应未知时，必须提示维护风险。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | issue_or_pr_quality=unknown\n\n## 8. maintenance · 发布节奏不明确\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: release_recency=unknown。\n- User impact: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Suggested check: 确认最近 release/tag 和 README 安装命令是否一致。\n- Guardrail action: 发布节奏未知或过期时，安装说明必须标注可能漂移。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | release_recency=unknown\n\n<!-- canonical_name: oxylabs/oxylabs-ai-studio-py; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki output with a Doramagic pitfall appendix.",
      "title": "Human Manual"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log\n\nProject: oxylabs/oxylabs-ai-studio-py\n\nSummary: Found 8 potential pitfall items; 0 are high/blocking. Highest priority: identity - 仓库名和安装名不一致.\n\n## 1. identity · 仓库名和安装名不一致\n\n- Severity: medium\n- Evidence strength: runtime_trace\n- Finding: 仓库名 `oxylabs-ai-studio-py` 与安装入口 `oxylabs-ai-studio` 不完全一致。\n- User impact: 用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- Suggested check: 在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- Reproduction command: `pip install oxylabs-ai-studio`\n- Guardrail action: 页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。\n- Evidence: identity.distribution | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | repo=oxylabs-ai-studio-py; install=oxylabs-ai-studio\n\n## 2. capability · 能力判断依赖假设\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: README/documentation is current enough for a first validation pass.\n- User impact: 假设不成立时，用户拿不到承诺的能力。\n- Suggested check: 将假设转成下游验证清单。\n- Guardrail action: 假设必须转成验证项；没有验证结果前不能写成事实。\n- Evidence: capability.assumptions | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | README/documentation is current enough for a first validation pass.\n\n## 3. maintenance · 来源证据：v.0.2.19\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：v.0.2.19\n- User impact: 可能影响升级、迁移或版本选择。\n- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- Evidence: community_evidence:github | cevd_96a2e22cbea94aac8c2788f763ce7c04 | https://github.com/oxylabs/oxylabs-ai-studio-py/releases/tag/v0.2.19 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 4. maintenance · 维护活跃度未知\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: 未记录 last_activity_observed。\n- User impact: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Guardrail action: 维护活跃度未知时，推荐强度不能标为高信任。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | last_activity_observed missing\n\n## 5. security_permissions · 下游验证发现风险项\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 下游已经要求复核，不能在页面中弱化。\n- Suggested check: 进入安全/权限治理复核队列。\n- Guardrail action: 下游风险存在时必须保持 review/recommendation 降级。\n- Evidence: downstream_validation.risk_items | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium\n\n## 6. security_permissions · 存在评分风险\n\n- Severity: medium\n- Evidence strength: source_linked\n- Finding: no_demo\n- User impact: 风险会影响是否适合普通用户安装。\n- Suggested check: 把风险写入边界卡，并确认是否需要人工复核。\n- Guardrail action: 评分风险必须进入边界卡，不能只作为内部分数。\n- Evidence: risks.scoring_risks | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | no_demo; severity=medium\n\n## 7. maintenance · issue/PR 响应质量未知\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: issue_or_pr_quality=unknown。\n- User impact: 用户无法判断遇到问题后是否有人维护。\n- Suggested check: 抽样最近 issue/PR，判断是否长期无人处理。\n- Guardrail action: issue/PR 响应未知时，必须提示维护风险。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | issue_or_pr_quality=unknown\n\n## 8. maintenance · 发布节奏不明确\n\n- Severity: low\n- Evidence strength: source_linked\n- Finding: release_recency=unknown。\n- User impact: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Suggested check: 确认最近 release/tag 和 README 安装命令是否一致。\n- Guardrail action: 发布节奏未知或过期时，安装说明必须标注可能漂移。\n- Evidence: evidence.maintainer_signals | github_repo:1003630893 | https://github.com/oxylabs/oxylabs-ai-studio-py | release_recency=unknown\n",
      "summary": "Identity, installation, configuration, runtime, and safety pitfalls before user trial.",
      "title": "Pitfall Log"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# oxylabs-ai-studio-py - Prompt Preview\n\n> Copy the prompt below into your AI host before installing anything.\n> Its purpose is to let you safely feel the project's workflow, not to claim the project has already run.\n\n## Copy this prompt\n\n```text\nYou are using an independent Doramagic capability pack for oxylabs/oxylabs-ai-studio-py.\n\nProject:\n- Name: oxylabs-ai-studio-py\n- Repository: https://github.com/oxylabs/oxylabs-ai-studio-py\n- Summary: Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.\n- Host target: local_cli\n\nGoal:\nHelp me evaluate this project for the following task without installing it yet: Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.\n\nBefore taking action:\n1. Restate my task, success standard, and boundary.\n2. Identify whether the next step requires tools, browser access, network access, filesystem access, credentials, package installation, or host configuration.\n3. Use only the Doramagic Project Pack, the upstream repository, and the source-linked evidence listed below.\n4. If a real command, install step, API call, file write, or host integration is required, mark it as \"requires post-install verification\" and ask for approval first.\n5. If evidence is missing, say \"evidence is missing\" instead of filling the gap.\n\nPreviewable capabilities:\n- Capability 1: Structured data gathering from any website using AI-powered scraper, crawler, and browser automation. Scraping and crawling with natural language prompts. Equip your LLM agents with fresh data. AI Studio python SDK for intelligent web data gathering.\n\nCapabilities that require post-install verification:\n- Capability 1: Use the source-backed project context to guide one small, checkable workflow step.\n\nCore service flow:\n1. quickstart: Quick Start Guide. Produce one small intermediate artifact and wait for confirmation.\n2. ai-scraper: AI-Scraper Feature. Produce one small intermediate artifact and wait for confirmation.\n3. ai-crawler: AI-Crawler Feature. Produce one small intermediate artifact and wait for confirmation.\n4. ai-search: AI-Search Feature. Produce one small intermediate artifact and wait for confirmation.\n5. browser-agent: Browser Agent Feature. Produce one small intermediate artifact and wait for confirmation.\n\nSource-backed evidence to keep in mind:\n- https://github.com/oxylabs/oxylabs-ai-studio-py\n- https://github.com/oxylabs/oxylabs-ai-studio-py#readme\n- src/oxylabs_ai_studio/client.py\n- src/oxylabs_ai_studio/__init__.py\n- src/oxylabs_ai_studio/apps/ai_scraper.py\n- examples/scrape_markdown.py\n- examples/scrape_pydantic_schema.py\n- examples/scrape_generated_schema.py\n- src/oxylabs_ai_studio/apps/ai_crawler.py\n- examples/crawl_markdown.py\n\nFirst response rules:\n1. Start Step 1 only.\n2. Explain the one service action you will perform first.\n3. Ask exactly three questions about my target workflow, success standard, and sandbox boundary.\n4. Stop and wait for my answers.\n\nStep 1 follow-up protocol:\n- After I answer the first three questions, stay in Step 1.\n- Produce six parts only: clarified task, success standard, boundary conditions, two or three options, tradeoffs for each option, and one recommendation.\n- End by asking whether I confirm the recommendation.\n- Do not move to Step 2 until I explicitly confirm.\n\nConversation rules:\n- Advance one step at a time and wait for confirmation after each small artifact.\n- Write outputs as recommendations or planned checks, not as completed execution.\n- Do not claim tests passed, files changed, commands ran, APIs were called, or the project was installed.\n- If the user asks for execution, first provide the sandbox setup, expected output, rollback, and approval checkpoint.\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start\n\nProject: oxylabs/oxylabs-ai-studio-py\n\n## Official Entry Points\n\n### Python / pip · 官方安装入口\n\n```bash\npip install oxylabs-ai-studio\n```\n\nSource：https://github.com/oxylabs/oxylabs-ai-studio-py#readme\n\n## Sources\n\n- repo: https://github.com/oxylabs/oxylabs-ai-studio-py\n- docs: https://github.com/oxylabs/oxylabs-ai-studio-py#readme\n",
      "summary": "Entry points extracted from official README or installation documentation.",
      "title": "Quick Start"
    }
  },
  "validation_id": "dval_79126fc4f2384013954c78fe80c83a06"
}
