Python ve TypeScript için Microsoft Web IQ SDK'larını kullanma

Python ve TypeScript'te kullanılabilen Microsoft Web IQ API'sine yönelik resmi SDK'lar. Bu SDK'lar, uygulamalarınıza LLM yanıtlarını doğru ve güncel bilgilerle temellendirmek için tasarlanmış web araması, video arama, göz atma, haber arama ve resim arama işlemlerine gerçek zamanlı erişim sağlar.

Python TypeScript
Paket pip install webiq npm install @microsoft/webiq
Çalışma Zamanı Python 3.11+ Node.js 22+
Lisans MIT MIT

Installation

Python

pip install webiq

TypeScript

npm install @microsoft/webiq

Quickstart

Python Kılavuzu

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 Kılavuzu

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 Anahtarı

# 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 Kimliği

Herhangi bir Azure Kimliği TokenCredential iletin.

# 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 kaynakları ve yöntemleri

İstemci beş kaynak ad alanını kullanıma sunar: web, videos, browse, newsve images.

client.web.search() — Web'de arama yapıp dayanak sağlamak için sayfa içeriğini alın.

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() — İsteğe bağlı oynatma listesi desteğiyle alakalı video içeriğini bulun.

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[] }

Göz atmak

client.browse.fetch() — Herhangi bir URL'den içerik ayıklayın. Canlı taramayı ve JavaScript işlemeyi destekler.

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() — Sorguyla en ilgili bölümleri içeren en son haber makalelerini alın.

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() — En boy oranına, boyuta ve güvenli aramaya göre filtreleme özelliğine sahip görüntüleri bulun.

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 yöntemleri aynı parametreleri camelCase biçiminde kullanır (örneğin, maxResults, contentFormat, liveCrawl, aspectRatio). Çağırma kuralı için yukarıdaki TypeScript Hızlı Başlangıç bölümüne bakın.


Asenkron Destek

Python Desteği

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 Desteği

TypeScript doğal olarak asenkrondur. Eşzamanlılık için Promise.all kullanın:

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

Configuration

Zaman Aşımı ve Yeniden Deneme

İstemci, retry ve timeout öğelerini en üst düzey seçenekler olarak kabul eder. Her kaynak yönteminde, çağrı başına ayar istemci düzeyi varsayılanını geçersiz kılar. SDK, 500, 502, 503, 504, 408 ögelerini üstel geri çekilme ve jitter ile otomatik olarak yeniden dener; yanıt gövdesi bir retryAfter alanı içeriyorsa (ör. "30s"), SDK geri çekilme gecikmesi yerine bu ipucunu bekler. 429 ve 430, asla otomatik olarak yeniden denenmez; uygulamanızın kendi geri çekilme politikasını uygulayabilmesi için hemen RateLimitError olarak ortaya çıkar. İstemci tarafı zaman aşımları da yeniden denenmiyor (APIConnectionError hatası verir).

# 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,
  }),
});

Özelleştirilmiş HTTP istemcisi (proxy, TLS, ...)

Gelişmiş HTTP ayarları için : ara sunucu, özel TLS, bağlantı havuzu vb. SDK, çağıranın sahip olduğu istemcileri kapatmaz .

# 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 }),
});

İptal (TypeScript)

Her TypeScript kaynak yöntemi, AbortSignal aracılığıyla bir options.signal kabul eder. Sinyal iptal edildiğinde, uçuş içi istek iptal edilir, yeniden denemeler durur ve sinyalin reason değiştirilmeden yeniden fırlatılır (APIConnectionError ile sarmalama yapılmaz).

// 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)]),
});

Telemetri Hook

Günlüğe kaydetme, ölçümler veya hata ayıklama için her isteği/yanıtı izleyin.

# 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 alanlar şunlardır:

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

Hata İşleme

Her iki SDK da yapılandırılmış hata işleme için türlenmiş özel durumlar sağlar. Tüm hatalar WebIQError'dan devralır.

Exception HTTP Durumu Tetik
AuthenticationError 401 Geçersiz veya eksik API anahtarı
PermissionDeniedError 403 Kimliği doğrulandı ancak kaynak için yetkilendirilmedi
RateLimitError 429, 430 Oran sınırı / eşzamanlı istek sınırı aşıldı
APIStatusError 400, 404, 500, 503, 504, ... Diğer tüm HTTP hataları
APIConnectionError — Ağ sorunları, DNS hataları, zaman aşımları
WebIQError — Tüm SDK hataları için temel sınıf

PermissionDeniedError ve RateLimitError, APIStatusError'nin alt sınıflarıdır, bu nedenle APIStatusError üzerindeki daha genel bir işleyici bunları yine de yakalar. SDK, yeniden deneme429 / 430 yanıtlarını otomatik olarak gerçekleştirmez; sunucunun geri çekilme ipucu, uygulamanızın buna göre işlem yapabilmesi için error.retryAfter (Python) / error.retry_after (TypeScript) üzerinde gösterilir.

# 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);
  }
}

Hata Ayrıntılarını İnceleme

Tüm APIStatusError örnekler (RateLimitError ve PermissionDeniedError dahil) tam hata yanıtı gövdesini gösterir. Python SDK'sindeki giriş doğrulama sorunlarının çoğu (örneğinmax_results, aralık dışında, boşquery) Pydantic tarafından istemci tarafında yakalanır ve herhangi bir istek gönderilmeden önce pydantic.ValidationError fırlatılır; sunucu bir isteği reddettiği zaman aşağıdaki desen geçerlidir. browse.fetch birini tetiklemenin kullanışlı bir yoludur; eksik veya filtrelenmiş bir URL, yapılandırılmış bir hata olarak görünür:

# 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);

Hata Ayıklama İpuçları

  • traceId — her yanıt uçtan uca hata ayıklama için bir traceId alan içerir. Destek birimiyle iletişim kurarken ekleyin.
  • Telemetri kancası — her istek denemesini, durum kodunu ve zamanlamayı günlüğe kaydetmek için bir geri çağırma bağlayın.
  • Hata gövdesi — APIStatusError.body, errorCategory, technicalDetails, traceId ve errorCode dahil olmak üzere tam sunucu yanıtını içerir.