Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Offizielle SDKs für die Microsoft Web IQ API, verfügbar in Python und TypeScript. Diese SDKs bieten Ihren Anwendungen Echtzeitzugriff auf die Websuche, die Videosuche, das Browsen, die Nachrichtensuche und die Bildersuche — konzipiert, um LLM-Antworten mit genauen, aktuellen Informationen zu fundieren.
| Python | TypeScript | |
|---|---|---|
| Pakete | pip install webiq |
npm install @microsoft/webiq |
| Laufzeit | Python 3.11+ | Node.js 22+ |
| Lizenz | MIT | MIT |
Installation
Python
pip install webiq
TypeScript
npm install @microsoft/webiq
Quickstart
Python Leitfaden
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)
TypeScript-Leitfaden
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
API-Schlüssel
# 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
Übergeben Sie eine beliebige 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(),
});
SDK-Ressourcen und -Methoden
Der Client macht fünf Ressourcennamespaces verfügbar: web, videos, browse, news und images.
Web Search
client.web.search() — Durchsuchen Sie das Web, und rufen Sie Seiteninhalte zur Fundierung ab.
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 }
Videossuche
client.videos.search() – Suchen Sie relevante Videoinhalte mit optionaler Wiedergabelistenunterstützung.
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[] }
Durchsuchen
client.browse.fetch() — Inhalte aus einer beliebigen URL extrahieren. Unterstützt Live-Crawling und JavaScript-Rendering.
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 }
News Search
client.news.search() – Holen Sie sich die neuesten Nachrichtenartikel mit den Passagen, die für die Abfrage am relevantesten sind.
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 }
Image Search
client.images.search() — Bilder mit Filterung nach Seitenverhältnis, Größe und sicherer Suche suchen.
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
TypeScript-Methoden verwenden dieselben Parameter in camelCase (z. B. maxResults, contentFormat, liveCrawl, aspectRatio). Informationen zur Aufrufkonvention finden Sie oben im TypeScript-Schnellstart.
Asynchroner Support
Python Support
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())
TypeScript-Unterstützung
TypeScript ist nativ asynchron. Verwenden Sie Promise.all für Parallelität:
const [web, news, videos] = await Promise.all([
client.web.search('TypeScript'),
client.news.search('programming'),
client.videos.search('tutorial'),
]);
Configuration
Timeout und Wiederholen
Der Client akzeptiert timeout und retry als Optionen auf oberster Ebene. Bei jedem Aufruf timeout jeder Ressourcenmethode wird der Standardwert auf Clientebene außer Kraft gesetzt. Das SDK versucht 408, 502, 500, 503, 504 automatisch erneut mit exponentiellem Backoff und Jitter; wenn der Antworttext ein retryAfter-Feld (z. B. "30s") enthält, wartet das SDK auf diesen Hinweis anstelle der Backoff-Verzögerung.
429 und 430 werden niemals automatisch wiederholt – sie werden sofort als RateLimitError angezeigt, damit Ihre Anwendung eine eigene Back-off-Richtlinie anwenden kann. Clientseitige Timeouts werden ebenfalls nicht erneut versucht (sie lösen APIConnectionError aus).
# 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,
}),
});
Angepasster HTTP-Client (Proxy, TLS, ...)
Für erweiterte HTTP-Einstellungen – Proxy, benutzerdefiniertes TLS, Verbindungspooling usw. Das SDK schließt keine aufrufereigenen Clients.
# 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 }),
});
Stornierung (TypeScript)
Jede TypeScript-Ressourcenmethode akzeptiert eine AbortSignal Via options.signal. Wenn das Signal abbricht, wird die In-Flight-Anforderung abgebrochen, die Wiederholungsversuche beendet, und reason des Signals wird unverändert erneut geworfen (ohne APIConnectionError-Wrapper).
// 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)]),
});
Telemetrie-Hook
Überwachen Sie jede Anfrage/Antwort auf Protokollierung, Metriken oder Debugging.
# 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)`);
},
});
Die TelemetryEvent Felder sind:
-
Python (snake_case):
method,path,transport,attempt,request_id,status_code,trace_id,retry_after,elapsed_ms,error,error_body -
TypeScript (camelCase):
method,path,transport,attempt,statusCode,requestId,retryAfter,traceId,elapsedMs,error,errorBody
Fehlerbehandlung
Beide SDKs bieten typierte Ausnahmen für die strukturierte Fehlerbehandlung. Alle Fehler erben von WebIQError.
| Exception | HTTP-Status | Trigger |
|---|---|---|
AuthenticationError |
401 | Ungültiger oder fehlender API-Schlüssel |
PermissionDeniedError |
403 | Authentifiziert, aber nicht für die Ressource autorisiert |
RateLimitError |
429, 430 | Ratenlimit / Grenze für gleichzeitige Anfragen überschritten |
APIStatusError |
400, 404, 500, 503, 504, ... | Alle anderen HTTP-Fehler |
APIConnectionError |
— | Netzwerkprobleme, DNS-Fehler, Timeouts |
WebIQError |
— | Basisklasse für alle SDK-Fehler |
PermissionDeniedError und RateLimitError sind beide Unterklassen von APIStatusError, sodass ein breiterer Handler für APIStatusError sie weiterhin erfasst. Das SDK führt keine429 / 430-Antworten automatisch erneut aus – der Back-off-Hinweis des Servers ist über error.retry_after (Python) / error.retryAfter (TypeScript) für Ihre Anwendung verfügbar.
# 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);
}
}
Fehlerdetails überprüfen
Alle APIStatusError Instanzen (einschließlich PermissionDeniedError und RateLimitError) machen den vollständigen Fehlerantworttext verfügbar. Die meisten Eingabevalidierungsprobleme im Python SDK (z. B. max_results außerhalb des Bereichs, leer query) werden clientseitig von Pydantic abgefangen und lösen pydantic.ValidationError aus, bevor eine Anforderung gesendet wird; das folgende Muster gilt, wenn der Server eine Anforderung ablehnt.
browse.fetch ist eine bequeme Möglichkeit, eins auszulösen – eine fehlende oder gefilterte URL wird als strukturierter Fehler angezeigt:
# 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);
Tipps zum Debuggen
-
traceId— Jede Antwort enthält eintraceIdFeld für das End-to-End-Debugging. Schließen Sie sie ein, wenn Sie sich an den Support wenden. - Telemetrie-Hook – Fügen Sie einen Rückruf an, um jeden Anforderungsversuch, Statuscode und Zeitangaben zu protokollieren.
-
Fehlertext -
APIStatusError.bodyenthält die vollständige Serverantwort, einschließlicherrorCode,errorCategory,technicalDetailsundtraceId.