Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Oficjalne zestawy SDK dla internetowego interfejsu API IQ Microsoft dostępne w Python i TypeScript. Te zestawy SDK zapewniają aplikacjom dostęp w czasie rzeczywistym do wyszukiwania w Internecie, wyszukiwania wideo, przeglądania, wyszukiwania wiadomości i wyszukiwania obrazów — zaprojektowane po to, aby ugruntować odpowiedzi modeli LLM za pomocą dokładnych i aktualnych informacji.
| Python | TypeScript | |
|---|---|---|
| Pakiet | pip install webiq |
npm install @microsoft/webiq |
| Czas działania | Python 3.11+ | Node.js 22+ |
| Licencja | MIT | MIT |
Installation
Python
pip install webiq
TypeScript
npm install @microsoft/webiq
Szybki start
Przewodnik po Pythonie
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)
Przewodnik 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);
Authentication
Klucz 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
Przekaż dowolny 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(),
});
Zasoby i metody zestawu SDK
Klient uwidacznia pięć przestrzeni nazw zasobów: web, browse, videos, news i images.
wyszukiwanie w sieci Web
client.web.search() — Wyszukaj w internecie i pobierz zawartość strony na potrzeby ugruntowania odpowiedzi.
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 }
Wyszukiwanie filmów
client.videos.search() — Znajdź odpowiednią zawartość wideo z opcjonalną obsługą listy odtwarzania.
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[] }
Przeglądaj
client.browse.fetch() — Wyodrębnij zawartość z dowolnego adresu URL. Obsługuje przeszukiwanie na żywo i renderowanie JavaScript.
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 }
wyszukiwanie wiadomości
client.news.search() — Uzyskaj najnowsze artykuły z wiadomościami z fragmentami najbardziej istotnymi dla zapytania.
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 }
wyszukiwanie obrazów
client.images.search() — Znajdź obrazy z filtrowaniem według współczynnika proporcji, rozmiaru i bezpiecznego wyszukiwania.
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 TypeScript używają tych samych parametrów w camelCase (np. maxResults, contentFormat, liveCrawl, aspectRatio). Zapoznaj się z powyższym przewodnikiem Szybki start języka TypeScript, aby zapoznać się z konwencją wywołań.
Wsparcie asynchroniczne
Obsługa Pythona
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())
Obsługa języka TypeScript
Język TypeScript jest natywnie asynchroniczny. Użyj Promise.all dla współbieżności:
const [web, news, videos] = await Promise.all([
client.web.search('TypeScript'),
client.news.search('programming'),
client.videos.search('tutorial'),
]);
Configuration
Limit czasu i ponowienie próby
Klient akceptuje timeout i retry jako opcje najwyższego poziomu. Ustawienie dla każdego wywołania timeout w każdej metodzie zasobu zastępuje wartość domyślną na poziomie klienta. Zestaw SDK automatycznie ponawia 408, 502, 500, 503, 504 z wykładniczym opóźnieniem i jitterem; jeśli body odpowiedzi zawiera pole retryAfter (np. "30s"), zestaw SDK czeka na tę wskazówkę zamiast opóźnienia backoff.
429 i 430nigdy nie są automatycznie ponawiane — są natychmiast zwracane jako RateLimitError, aby aplikacja mogła zastosować własną strategię ponawiania z opóźnieniem. Limity czasu po stronie klienta również nie są ponawiane (powodują zgłoszenie 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,
}),
});
Dostosowany klient HTTP (serwer proxy, TLS, ...)
Zaawansowane ustawienia HTTP — serwer proxy, niestandardowy protokół TLS, pula połączeń itp. Zestaw SDK nie zamyka klientów należących do wywołującego.
# 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 }),
});
Anulowanie (TypeScript)
Każda metoda zasobu TypeScript akceptuje AbortSignal za pośrednictwem options.signal. Po przerwaniu sygnału żądanie w locie zostanie anulowane, ponowne próby zostaną zatrzymane, a element reason sygnału zostanie ponownie zgłoszony bez zmian (bez zawijania 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)]),
});
Hook telemetrii
Monitoruj każde żądanie/odpowiedź na potrzeby rejestrowania, metryk lub debugowania.
# 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)`);
},
});
Pola TelemetryEvent:
-
Python (snake_case):
method,path,transport,elapsed_ms,attempt,retry_after,status_code,request_id,trace_id,error,error_body -
TypeScript (camelCase):
method,path,attempt,transport,statusCode,requestId,traceId,retryAfter,elapsedMs,error,errorBody
Obsługa błędów
Oba zestawy SDK zapewniają wyjątki typizowane do ustrukturyzowanej obsługi błędów. Wszystkie błędy dziedziczą z WebIQError.
| Wyjątek | Status HTTP | Wyzwalacz |
|---|---|---|
AuthenticationError |
401 | Nieprawidłowy lub brak klucza interfejsu API |
PermissionDeniedError |
403 | Uwierzytelnione, ale brak uprawnień do zasobu |
RateLimitError |
429, 430 | Przekroczono limit liczby żądań / limit żądań współbieżnych |
APIStatusError |
400, 404, 500, 503, 504, ... | Wszystkie inne błędy HTTP |
APIConnectionError |
— | Problemy z siecią, błędy DNS, przekroczenia limitu czasu |
WebIQError |
— | Klasa podstawowa dla wszystkich błędów zestawu SDK |
PermissionDeniedError i RateLimitError są oba podklasami APIStatusError, więc szersza procedura obsługi w APIStatusError nadal je przechwytuje. Zestaw SDK nie ponawia automatycznie odpowiedzi HTTP/API 429 / 430 — wskazówka dotycząca opóźnienia ponowienia jest udostępniana w error.retry_after (Python) / error.retryAfter (TypeScript), aby aplikacja mogła odpowiednio zareagować.
# 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);
}
}
Sprawdzanie szczegółów błędu
Wszystkie APIStatusError wystąpienia (w tym PermissionDeniedError i RateLimitError) udostępniają pełną treść ciała odpowiedzi błędu. Większość problemów z walidacją danych wejściowych w zestawie SDK Python (np. max_results poza zakresem, puste query) jest przechwytywana po stronie klienta przez Pydantic i zgłaszana pydantic.ValidationError przed wysłaniem żądania; wzorzec poniżej ma zastosowanie, gdy serwer odrzuca żądanie.
browse.fetch to wygodny sposób wywołania takiego błędu — brakujący lub odfiltrowany adres URL pojawia się jako błąd ustrukturyzowany:
# 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);
Wskazówki dotyczące debugowania
-
traceId— każda odpowiedź zawiera poletraceIddo debugowania end-to-end. Dołącz go podczas kontaktowania się z pomocą techniczną. - Hook telemetrii — dołącz wywołanie zwrotne w celu rejestrowania każdej próby żądania, kodu stanu i czasów.
-
Treść błędu —
APIStatusError.bodyzawiera pełną odpowiedź serwera, w tymerrorCode,errorCategory,technicalDetailsitraceId.