Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Официальные SDK для API Microsoft Web IQ, доступные в Python и TypeScript. Эти пакеты SDK предоставляют приложениям доступ в режиме реального времени к веб-поиску, поиску видео, обзору, поиску новостей и поиску изображений — они предназначены для улучшения ответов LLM с помощью точной и актуальной информации.
| Python | TypeScript | |
|---|---|---|
| Пакет | pip install webiq |
npm install @microsoft/webiq |
| время выполнения | Python 3.11+ | Node.js 22+ |
| Лицензия | MIT | MIT |
Installation
Python
pip install webiq
TypeScript
npm install @microsoft/webiq
Quickstart
Руководство по 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
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
# 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 });
Майкрософт Ентра айди
Передайте любой объект 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
Клиент предоставляет пять пространств имен ресурсов: web, videos, browse, news и images.
Web Search
client.web.search() — выполните поиск в Интернете и получите содержимое страницы для обоснования.
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() — Найдите соответствующее видео с необязательной поддержкой плейлистов.
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[] }
Просмотр
client.browse.fetch() — извлечение содержимого из любого URL-адреса. Поддерживает обход данных в реальном времени и отрисовку 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 }
News Search
client.news.search() — Получите последние новостные статьи с фрагментами, наиболее релевантными запросу.
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() — поиск изображений с фильтрацией по пропорциям, размеру и безопасному поиску.
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 используют те же параметры в нотации camelCase (например, maxResults, contentFormat, liveCrawl, aspectRatio). Ознакомьтесь с кратким руководством по TypeScript выше для получения сведений о соглашении о вызовах.
Поддержка асинхронной работы
Поддержка Python
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
TypeScript изначально поддерживает асинхронность. Используйте Promise.all для параллелизма:
const [web, news, videos] = await Promise.all([
client.web.search('TypeScript'),
client.news.search('programming'),
client.videos.search('tutorial'),
]);
Configuration
Тайм-аут и повтор
Клиент принимает timeout и retry в качестве параметров верхнего уровня. Параметр для каждого вызова timeout в каждом методе ресурса переопределяет значение по умолчанию на уровне клиента. SDK автоматически повторяет попытки 408, 500, 502, 503, 504 с экспоненциальной задержкой и джиттером; если тело ответа включает поле retryAfter (например, "30s"), SDK ждёт этой подсказки вместо задержки обратного повтора.
429 и 430никогда не повторяются автоматически — они сразу же возвращаются как RateLimitError, чтобы приложение могло применить собственную политику повторных попыток с задержкой. Время ожидания на стороне клиента также не повторяется (при них возникает 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,
}),
});
Настроенный HTTP-клиент (прокси, TLS, ...)
Для расширенных параметров HTTP — прокси, настраиваемого TLS, пула подключений и т. д. Пакет SDK не закрывает клиентские объекты, переданные вызывающей стороной.
# 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 }),
});
Отмена (TypeScript)
Каждый метод ресурса TypeScript принимает AbortSignal через options.signal. Когда сигнал прерывается, запрос в процессе выполнения отменяется, повторные попытки прекращаются, а reason сигнала повторно выбрасывается без изменений (без оболочки 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)]),
});
Хук телеметрии
Отслеживайте каждый запрос и каждый ответ для ведения журнала, метрик или отладки.
# 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)`);
},
});
Поля TelemetryEvent :
-
Python (snake_case):
method,request_id,transport,status_code,error,attempt,trace_id,retry_after,elapsed_ms,path,error_body -
TypeScript (camelCase):
method,path,statusCode,error,elapsedMs,transport,attempt,requestId,traceId,retryAfter,errorBody
Обработка ошибок
Оба пакета SDK предоставляют типизированные исключения для структурированной обработки ошибок. Все ошибки наследуются от WebIQError.
| Исключение | Состояние HTTP | Триггер |
|---|---|---|
AuthenticationError |
401 | Недопустимый или отсутствующий ключ API |
PermissionDeniedError |
403 | Аутентифицирован, но не авторизован для доступа к ресурсу |
RateLimitError |
429, 430 | Превышен лимит запросов / превышен лимит на одновременные запросы |
APIStatusError |
400, 404, 500, 503, 504, ... | Все остальные ошибки HTTP |
APIConnectionError |
— | Проблемы с сетью, сбои DNS, тайм-ауты |
WebIQError |
— | Базовый класс для всех ошибок пакета SDK |
PermissionDeniedError и RateLimitError оба подкласса APIStatusError, так что более широкий обработчик APIStatusError по-прежнему перехватывает их. SDK не выполняет повторные попытки для ответов 429 / 430 автоматически — указание сервера по интервалу ожидания доступно через error.retry_after (Python) / error.retryAfter (TypeScript), которое ваше приложение должно обработать.
# 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);
}
}
Просмотр сведений об ошибке
Все APIStatusError экземпляры (включая PermissionDeniedError и RateLimitError) предоставляют полный текст ответа на ошибку. Большинство проблем проверки входных данных в пакете SDK Python (например, значение max_results вне диапазона, пустой query) перехватываются клиентом на стороне Pydantic и генерируется pydantic.ValidationError перед отправкой любого запроса; приведенный ниже шаблон применяется, когда сервер отклоняет запрос.
browse.fetch — удобный способ вызвать такую ошибку: отсутствующие или отфильтрованные URL-адреса отображаются как структурированная ошибка:
# 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);
Советы по отладке
-
traceId— каждый ответ содержит полеtraceIdдля сквозной отладки. Укажите его при обращении в службу поддержки. - Перехватчик телеметрии — подключите обратный вызов для журналирования каждой попытки запроса, кода состояния и времени выполнения.
-
Тело ошибки —
APIStatusError.bodyсодержит полный ответ сервера, включаяerrorCode,errorCategorytechnicalDetailsиtraceId.