Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Officiële SDK's voor de Microsoft Web IQ API, beschikbaar in Python en TypeScript. Deze SDK's bieden uw toepassingen realtime toegang tot zoeken op internet, video's zoeken, browsefunctionaliteit, nieuws zoeken en afbeeldingen zoeken, ontworpen om LLM-antwoorden te onderbouwen met nauwkeurige, up-to-date informatie.
| Python | TypeScript | |
|---|---|---|
| Pakket | pip install webiq |
npm install @microsoft/webiq |
| Runtime | Python 3.11+ | Node.js 22+ |
| Licentie | MIT | MIT |
Installation
Python
pip install webiq
TypeScript
npm install @microsoft/webiq
Quickstart
Handleiding voor Python
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-handleiding
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);
Authenticatie
API-sleutel
# 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
Geef een Azure identiteit TokenCredentialdoor.
# 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-bronnen en methoden
De client maakt vijf resourcenaamruimten beschikbaar: web, videos, browse, newsen images.
Web Search
client.web.search() — Zoek op internet en haal pagina-inhoud op voor onderbouwing.
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 }
Video's doorzoeken
client.videos.search() — Zoek relevante video-inhoud met optionele afspeellijstondersteuning.
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[] }
Bekijk
client.browse.fetch() — Inhoud extraheren uit elke URL. Biedt ondersteuning voor live crawling en 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() — Haal de meest recente nieuwsartikelen op met de passages die het meest relevant zijn voor de query.
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() — Afbeeldingen zoeken met filteren op hoogte-breedteverhouding, grootte en veilig zoeken.
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 gebruiken dezelfde parameters in camelCase (bijvoorbeeld maxResults, contentFormat, liveCrawl, aspectRatio). Zie de Quick Start van TypeScript hierboven voor de aanroepconventie.
Asynchrone ondersteuning
Python-ondersteuning
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-ondersteuning
TypeScript is van nature asynchroon. Gebruik Promise.all voor gelijktijdigheid:
const [web, news, videos] = await Promise.all([
client.web.search('TypeScript'),
client.news.search('programming'),
client.videos.search('tutorial'),
]);
Configuration
Time-out en opnieuw proberen
De client accepteert timeout en retry als opties op het hoogste niveau. Per aanroep overschrijft timeout op elke resourcemethode de standaardwaarde op clientniveau. De SDK probeert 408, 500, 502, 503, 504 automatisch opnieuw met exponentiële backoff en jitter; als de antwoordtekst een retryAfter-veld bevat (bijvoorbeeld "30s"), wacht de SDK op die hint in plaats van de backoffvertraging.
429 en 430 worden nooit automatisch opnieuw geprobeerd — ze komen onmiddellijk naar voren als RateLimitError, zodat uw toepassing een eigen back-off-beleid kan toepassen. Time-outs aan de clientzijde worden ook niet opnieuw geprobeerd (ze genereren 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,
}),
});
Aangepaste HTTP-client (proxy, TLS, ...)
Voor geavanceerde HTTP-instellingen: proxy, aangepaste TLS, verbindingspooling, enzovoort. De SDK sluit geen clients die eigendom zijn van de aanroeper.
# 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 }),
});
Annuleren (TypeScript)
Elke TypeScript-resourcemethode accepteert een AbortSignal via options.signal. Wanneer het signaal wordt afgebroken, wordt de lopende aanvraag geannuleerd, stoppen nieuwe pogingen en wordt de reason van het signaal ongewijzigd opnieuw opgegooid (geen APIConnectionError wrapping).
// 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
Bewaak elk verzoek/antwoord voor logboekregistratie, metrische gegevens of foutopsporing.
# 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)`);
},
});
De TelemetryEvent velden zijn:
-
Python (snake_case):
method,path,transport,attempt,status_code,request_id,trace_id,retry_after,elapsed_ms,error,error_body -
TypeScript (camelCase):
method,transport,path,attempt,statusCode,requestId,traceId,elapsedMs,error,retryAfter,errorBody
Foutafhandeling
Beide SDK's bieden getypte uitzonderingen voor gestructureerde foutafhandeling. Alle fouten zijn afgeleid van WebIQError.
| Exception | HTTP-status | Trigger |
|---|---|---|
AuthenticationError |
401 | Ongeldige of ontbrekende API-sleutel |
PermissionDeniedError |
403 | Aangemeld, maar niet geautoriseerd voor de bron |
RateLimitError |
429, 430 | Aanvraagsnelheidslimiet / limiet voor gelijktijdige aanvragen overschreden |
APIStatusError |
400, 404, 500, 503, 504, ... | Alle andere HTTP-fouten |
APIConnectionError |
— | Netwerkproblemen, DNS-fouten, time-outs |
WebIQError |
— | Basisklasse voor alle SDK-fouten |
PermissionDeniedError en RateLimitError zijn beide subklassen van APIStatusError, dus een bredere handler op APIStatusError vangt ze nog steeds. De SDK probeert responses niet automatisch opnieuw429 / 430. De back-off-hint van de server wordt weergegeven op error.retry_after (Python) / error.retryAfter (TypeScript), waarop uw toepassing actie kan ondernemen.
# 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);
}
}
Foutdetails controleren
Alle APIStatusError instanties (inclusief PermissionDeniedError en RateLimitError) maken de volledige hoofdtekst van het foutantwoord beschikbaar. De meeste invoervalidatieproblemen op de Python SDK (bijvoorbeeld max_results buiten bereik, leeg query) worden aan de clientzijde door Pydantic opgevangen en resulteren in pydantic.ValidationError voordat een aanvraag wordt verzonden. Het onderstaande patroon is van toepassing wanneer de server een aanvraag weigert.
browse.fetch is een handige manier om er een te activeren: een ontbrekende of gefilterde URL wordt weergegeven als een gestructureerde fout:
# 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);
Tips voor foutopsporing
-
traceId— elk antwoord bevat eentraceIdveld voor end-to-end foutopsporing. Vermeld dit wanneer u contact opneemt met support. - Telemetriehook — koppel een callback om elke aanvraagpoging, statuscode en timinginformatie te registreren.
-
Hoofdtekst van de fout :
APIStatusError.bodybevat het volledige serverantwoord, inclusieferrorCode,errorCategory,technicalDetailsentraceId.