Použití sad SDK webového IQ Microsoft pro Python a TypeScript

Oficiální sady SDK pro rozhraní API pro webové IQ Microsoft dostupné v Python a TypeScriptu Tyto sady SDK poskytují vašim aplikacím přístup v reálném čase k vyhledávání na webu, vyhledávání videí, procházení, vyhledávání zpráv a hledání obrázků – navržené k podložení odpovědí LLM pomocí přesných a aktuálních informací.

Python TypeScript
Balíček pip install webiq npm install @microsoft/webiq
Runtime Python 3.11 nebo novější Node.js 22 a více
Licence MIT MIT

Installation

Python

pip install webiq

TypeScript

npm install @microsoft/webiq

Rychlý start

Průvodce Pythonem

import os
from webiq import WebIQClient
from webiq.types import BrowseContentFormat, ContentFormat

with WebIQClient(api_key=os.environ["WEBIQ_API_KEY"]) as client:
    # Web search
    web = client.web.search(
        "Python programming",
        max_results=5,
        content_format=ContentFormat.passage,
    )
    for r in web.webResults or []:
        print(r.title, r.url)

    # Videos search
    videos = client.videos.search("machine learning tutorial", max_results=5)
    for v in videos.videoResults or []:
        print(v.title, v.length)

    # Browse a URL
    page = client.browse.fetch("https://www.microsoft.com", content_format=BrowseContentFormat.markdown)
    print(page.content)

    # News search
    news = client.news.search("technology", max_results=5)
    for item in news.newsResults or []:
        print(item.title, "-", item.source)

    # Image search
    images = client.images.search("golden gate bridge", max_results=5)
    for img in images.imageResults or []:
        print(img.title, img.url)

Průvodce TypeScript

import { WebIQClient, BrowseContentFormat, ContentFormat } from '@microsoft/webiq';

async function main() {
  const client = new WebIQClient({ apiKey: process.env.WEBIQ_API_KEY });

  // Web search
  const web = await client.web.search('TypeScript programming', {
    maxResults: 5,
    contentFormat: ContentFormat.PASSAGE,
  });
  for (const r of web.webResults ?? []) console.log(r.title, r.url);

  // Videos search
  const videos = await client.videos.search('machine learning tutorial');
  for (const v of videos.videoResults ?? []) console.log(v.title, v.length);

  // Browse a URL
  const page = await client.browse.fetch('https://www.microsoft.com', {
    contentFormat: BrowseContentFormat.MARKDOWN,
  });
  console.log(page.content);

  // News search
  const news = await client.news.search('technology', { maxResults: 5 });
  for (const item of news.newsResults ?? []) console.log(item.title, '-', item.source);

  // Image search
  const images = await client.images.search('golden gate bridge', { maxResults: 5 });
  for (const img of images.imageResults ?? []) console.log(img.title, img.url);

  await client.close();
}

main().catch(console.error);

Autentizace

Klíč API

# Python
import os
from webiq import WebIQClient

client = WebIQClient(api_key=os.environ["WEBIQ_API_KEY"])
// TypeScript
import { WebIQClient } from '@microsoft/webiq';

const client = new WebIQClient({ apiKey: process.env.WEBIQ_API_KEY });

Microsoft Entra ID

Předejte libovolnou identitu Azure Identity TokenCredential.

# Python — uses `azure-identity`
from azure.identity import DefaultAzureCredential
from webiq import WebIQClient

client = WebIQClient(credential=DefaultAzureCredential())
// TypeScript — uses `@azure/identity`
import { DefaultAzureCredential } from '@azure/identity';
import { WebIQClient } from '@microsoft/webiq';

const client = new WebIQClient({
  credential: new DefaultAzureCredential(),
});

Zdroje a metody sady SDK

Klient zveřejňuje pět jmenných prostorů prostředků: web, videos, browse, news a images.

client.web.search() — Vyhledejte na webu a získejte obsah stránky pro ukotvení odpovědí.

response = client.web.search(
    query="search terms",          # Required, 1–1000 chars
    max_results=10,                # 1–50 (default 10)
    language="en",                 # ISO 639-1 code
    region="US",                   # Country/region code
    location="lat:40.7;long:-74.0",  # Optional
    content_format=ContentFormat.passage,   # passage (default) | text | html | markdown (full-page content)
    max_length=3000,               # Max content chars (default 3000)
)
# response.webResults → list of { title, url, content, lastUpdatedAt, crawledAt, language, isAdult }

client.videos.search() — Najděte relevantní videoobsah s volitelnou podporou playlistu.

response = client.videos.search(
    query="search terms",          # Required, 1–1000 chars
    max_results=30,                # 1–30 (default 30)
    language="en",
    region="US",
    enable_playlist=True,          # Include playlist results
    freshness="month",             # week | month | year
)
# response.videoResults → list of { title, url, description, length, viewCount, moments[], thumbnailUrl, ... }
# response.playlists   → list of { title, videos[] }

Procházet

client.browse.fetch() — Extrahujte obsah z libovolné adresy URL. Podporuje procházení v reálném čase a vykreslování JavaScriptu.

response = client.browse.fetch(
    url="https://www.microsoft.com",   # Required
    max_length=10000,                  # Max content chars, 1–500000
    live_crawl="fallback",             # "none" (cached only, default) | "fallback" (crawl if not cached) | "force" (always crawl, bypass cache)
    include_web_links=True,            # Include outbound hyperlinks
    include_image_links=True,          # Include image URLs
    render_dynamic_pages=False,        # JS rendering (requires live_crawl="fallback")
    content_format=BrowseContentFormat.markdown,   # text | html | markdown
)
# response → { url, title, content, isAdult, lastUpdatedAt, crawledAt, retryAfter, traceId }

client.news.search() — Získejte nejnovější zpravodajské články s nejrelevantnějšími pasážemi pro dotaz.

response = client.news.search(
    query="search terms",          # Required, 1–1000 chars
    max_results=10,                # 1–20 (default 10)
    language="en",
    region="US",
    location="lat:40.7;long:-74.0",  # Optional
    content_format=ContentFormat.passage,
    max_length=3000,
)
# response.newsResults → list of { title, url, content, source, lastUpdatedAt, thumbnail, isAdult }

client.images.search() — Najděte obrázky s filtrováním podle poměru stran, velikosti a bezpečného hledání.

from webiq.types import ImageAspectRatio, ImageSize, SafeSearch

response = client.images.search(
    query="search terms",          # Required, 1–1000 chars
    max_results=30,                # 1–30 (default 30)
    language="en",
    region="US",
    aspect_ratio=ImageAspectRatio.wide,   # square | wide | tall
    image_size=ImageSize.large,           # small | medium | large | extraLarge
    safe_search=SafeSearch.strict,        # off | strict
    watermark_free=True,
)
# response.imageResults → list of { title, url, hostPageUrl, caption, width, height, thumbnailUrl, ... }

Note

Metody TypeScriptu používají stejné parametry ve camelCase (např maxResults. , contentFormat, liveCrawl, aspectRatio). Viz výše uvedený TypeScript Quick Start, kde najdete informace o konvenci volání.


Podpora asynchronního režimu

Podpora Pythonu

import asyncio
from webiq import WebIQAsyncClient

async def main():
    async with WebIQAsyncClient(api_key="your-api-key") as client:
        web, news = await asyncio.gather(
            client.web.search("async Python"),
            client.news.search("programming"),
        )
        for r in web.webResults or []:
            print(r.title)

asyncio.run(main())

Podpora TypeScriptu

TypeScript je nativně asynchronní. Používá se Promise.all pro souběžnost:

const [web, news, videos] = await Promise.all([
  client.web.search('TypeScript'),
  client.news.search('programming'),
  client.videos.search('tutorial'),
]);

Configuration

Časový limit a opakování

Klient přijímá timeout a retry jako možnosti nejvyšší úrovně. Nastavení pro jednotlivá volání timeout na každé metodě prostředku přepíše výchozí nastavení na úrovni klienta. SDK automaticky opakuje pokusy 408, 500, 502, 503, 504 s exponenciálním prodlužováním intervalů a náhodnou odchylkou zpoždění; pokud tělo odpovědi obsahuje pole retryAfter (např. "30s"), SDK počká na tento pokyn místo prodlevy backoffu. 429 a 430 se nikdy automaticky nezopakují – okamžitě se projeví jako RateLimitError, aby vaše aplikace mohla použít vlastní strategii back-off. Časové limity na straně klienta se také znovu nezkoušejí (vyvolávají APIConnectionError).

# Python
from webiq import WebIQClient, RetryPolicy

client = WebIQClient(
    api_key="your-api-key",
    timeout=10.0,                  # seconds (default: 10.0)
    retry=RetryPolicy(
        max_retries=2,             # defaults shown
        base_delay_s=0.25,
        max_delay_s=4.0,
    ),
)

# Per-call override
response = client.web.search("query", language="de", region="DE", timeout=30.0)
// TypeScript
import { WebIQClient, RetryPolicy } from '@microsoft/webiq';

const client = new WebIQClient({
  apiKey: 'your-api-key',
  timeout: 10000, // milliseconds (default: 10000)
  retry: new RetryPolicy({
    maxRetries: 2, // defaults shown
    baseDelaySeconds: 0.25,
    maxDelaySeconds: 4.0,
  }),
});

Přizpůsobený klient HTTP (proxy, TLS, ...)

Pro upřesňující nastavení HTTP – proxy server, vlastní protokol TLS, sdružování připojení atd. Sada SDK nezavírá klienty vlastněné volajícím.

# Python — pass a pre-configured `httpx.Client` via `http_client`
import httpx
from webiq import WebIQClient, WebIQAsyncClient

# sync
http_client = httpx.Client(
  base_url="https://api.microsoft.ai/v3",
  proxy="http://proxy:8080",
)
client = WebIQClient(api_key="your-api-key", http_client=http_client)

# async
http_client = httpx.AsyncClient(
  base_url="https://api.microsoft.ai/v3",
  proxy="http://proxy:8080",
)
client = WebIQAsyncClient(api_key="your-api-key", http_client=http_client)
// TypeScript — pass a custom `fetchFn` that wraps the global `fetch`
import { ProxyAgent } from 'undici';
import { WebIQClient } from '@microsoft/webiq';

const proxyAgent = new ProxyAgent('http://my-proxy:8080');

const client = new WebIQClient({
  apiKey: 'your-api-key',
  // Spread `init` so headers, body, and the SDK's internal `AbortSignal` are preserved.
  fetchFn: (url, init) => fetch(url, { ...init, dispatcher: proxyAgent }),
});

Zrušení (TypeScript)

Každá metoda prostředku TypeScript přijímá AbortSignal prostřednictvím options.signal. Když dojde k abortu signálu, probíhající požadavek se zruší, opakování se zastaví a jeho reason se znovu vyvolá beze změny (bez zabalení do APIConnectionError).

// Apply a wall-clock budget that includes retries (the `timeout` option is per attempt only)
const result = await client.web.search('latest news', {
  signal: AbortSignal.timeout(5_000),
});

// Combine signals (e.g. an inbound request signal plus a wall-clock cap)
const result2 = await client.web.search('latest news', {
  signal: AbortSignal.any([req.signal, AbortSignal.timeout(5_000)]),
});

Telemetrický hook

Monitorujte všechny požadavky a odpovědi pro protokolování, metriky nebo ladění.

# Python
from webiq import WebIQClient, TelemetryEvent

def on_request(event: TelemetryEvent):
    print(f"{event.method} {event.path} → {event.status_code} ({event.elapsed_ms}ms)")

client = WebIQClient(api_key="your-api-key", telemetry_hook=on_request)
// TypeScript
import { WebIQClient, TelemetryEvent } from '@microsoft/webiq';

const client = new WebIQClient({
  apiKey: 'your-api-key',
  telemetryHook: (event: TelemetryEvent) => {
    console.log(`${event.method} ${event.path} → ${event.statusCode} (${event.elapsedMs}ms)`);
  },
});

Pole TelemetryEvent jsou:

  • Python (snake_case): method, path, attempt, transport, status_code, request_id, trace_id, elapsed_ms, error, retry_after, error_body
  • TypeScript (camelCase): method, path, transport, attempt, statusCode, requestId, traceId, retryAfter, elapsedMs, error, errorBody

Zpracování chyb

Obě sady SDK poskytují typované výjimky pro strukturované zpracování chyb. Všechny chyby dědí z WebIQError.

Exception Stav HTTP Aktivační událost
AuthenticationError 401 Neplatný nebo chybějící klíč rozhraní API
PermissionDeniedError 403 Ověřen, ale neautorizováno pro prostředek
RateLimitError 429, 430 Překročení limitu počtu požadavků nebo limitu souběžných požadavků
APIStatusError 400, 404, 500, 503, 504, ... Všechny ostatní chyby HTTP
APIConnectionError — Problémy se sítí, selhání DNS, vypršení časových limitů
WebIQError — Základní třída pro všechny chyby SDK

PermissionDeniedError a RateLimitError jsou obě podtřídy APIStatusError, takže širší obslužná rutina na APIStatusError je stále zachytí. Sada SDK neopakuje automaticky požadavky při odpovědích 429 / 430 — pokyn serveru k prodlevě je k dispozici v error.retryAfter (Python) / error.retry_after (TypeScript), aby na něj vaše aplikace mohla reagovat.

# Python
from webiq import (
    WebIQError,
    APIConnectionError,
    APIStatusError,
    AuthenticationError,
    PermissionDeniedError,
    RateLimitError,
)

try:
    response = client.web.search("test")
except PermissionDeniedError as e:
    # 403 — authenticated, but not allowed to call this resource
    print(f"Forbidden (HTTP {e.status_code}): {e}")
except AuthenticationError as e:
    # 401 — invalid or missing API key
    print(f"Auth failed (HTTP {e.status_code}): {e}")
except RateLimitError as e:
    # 429 or 430 — rate limit / concurrent-request limit (never auto-retried)
    print(f"Rate limited. Retry after: {e.retry_after}")
except APIStatusError as e:
    print(f"API error (HTTP {e.status_code}): {e}")
except APIConnectionError as e:
    print(f"Connection failed: {e}")
except WebIQError as e:
    print(f"SDK error: {e}")
// TypeScript
import {
  WebIQError,
  APIConnectionError,
  APIStatusError,
  AuthenticationError,
  PermissionDeniedError,
  RateLimitError,
} from '@microsoft/webiq';

try {
  const results = await client.web.search('test');
} catch (error) {
  if (error instanceof PermissionDeniedError) {
    // 403 — authenticated, but not allowed to call this resource
    console.error(`Forbidden (HTTP ${error.statusCode}):`, error.message);
  } else if (error instanceof AuthenticationError) {
    // 401 — invalid or missing API key
    console.error(`Auth failed (HTTP ${error.statusCode}):`, error.message);
  } else if (error instanceof RateLimitError) {
    // 429 or 430 — rate limit / concurrent-request limit (never auto-retried)
    console.error(`Rate limited. Retry after: ${error.retryAfter}`);
  } else if (error instanceof APIStatusError) {
    console.error(`API error (HTTP ${error.statusCode}):`, error.message);
  } else if (error instanceof APIConnectionError) {
    console.error('Connection failed:', error.message);
  }
}

Prohlížení detailů chyby

Všechny instance APIStatusError (včetně PermissionDeniedError a RateLimitError) zpřístupňují celý text odpovědi na chybu. Většina problémů s ověřováním vstupu v sadě Python SDK (např. max_results mimo rozsah, prázdné query) je zachycena na straně klienta knihovnou Pydantic, která vyvolá pydantic.ValidationError před odesláním jakéhokoli požadavku; níže uvedený vzor platí, když server odmítne požadavek. browse.fetch je pohodlný způsob, jak aktivovat jednu takovou chybu – chybějící nebo filtrovaná adresa URL se zobrazí jako strukturovaná chyba:

# Python
from webiq import WebIQClient
from webiq.errors import APIStatusError

client = WebIQClient(api_key="your-api-key")

try:
    response = client.browse.fetch("https://www.not-microsoft.com")
except APIStatusError as e:
    print(f"Status: {e.status_code}")                          # e.g. 404
    print(f"Message: {e}")                                      # e.g. "No result is found"
    if isinstance(e.body, dict):
        print(f"Error code: {e.body.get('errorCode')}")        # e.g. "BrowseApiDocNotFound"
        print(f"Category: {e.body.get('errorCategory')}")      # e.g. "UserError"
        print(f"Details: {e.body.get('technicalDetails')}")    # e.g. "NotFound"
        print(f"Trace ID: {e.body.get('traceId')}")
        print(f"Retry after: {e.body.get('retryAfter')}")
// TypeScript
import { WebIQClient, APIStatusError } from '@microsoft/webiq';

async function main() {
  const client = new WebIQClient({ apiKey: 'your-api-key' });

  try {
    await client.browse.fetch('https://www.not-microsoft.com');
  } catch (error) {
    if (error instanceof APIStatusError) {
      console.error(`Status: ${error.statusCode}`); // e.g. 404
      console.error(`Message: ${error.message}`); // e.g. "No result is found"

      // Full error body from the API response
      if (error.body && typeof error.body === 'object') {
        const body = error.body as Record<string, unknown>;
        console.error(`Error code: ${body.errorCode}`); // e.g. "BrowseApiDocNotFound"
        console.error(`Category: ${body.errorCategory}`); // e.g. "UserError"
        console.error(`Details: ${body.technicalDetails}`); // e.g. "NotFound"
        console.error(`Trace ID: ${body.traceId}`); // for debugging with support
        console.error(`Retry after: ${body.retryAfter}`); // for retryable errors
      }
    }
  }
}

main().catch(console.error);

Tipy pro ladění

  • traceId — každá odpověď obsahuje traceId pole pro kompletní ladění. Při kontaktování podpory ji zahrňte.
  • Telemetrický hook – připojte callback, který bude protokolovat každý pokus o požadavek, stavový kód a časování.
  • Tělo chyby – APIStatusError.body obsahuje úplnou odpověď serveru, včetně errorCode, errorCategory, technicalDetails a traceId.