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.
Erstellen Sie eine Python-Clientbibliothek, die in das Microsoft Entra SDK für AgentID integriert ist, um Token abzurufen und nachgeschaltete APIs aufzurufen. Integrieren Sie diesen Client dann in Flask-, FastAPI- oder Django-Anwendungen, um authentifizierte Anforderungen zu verarbeiten.
Voraussetzungen
- Ein Azure-Konto mit einem aktiven Abonnement. Kostenlos ein Konto erstellen.
- Python (Version 3.7 oder höher) mit Pip auf Ihrem Entwicklungscomputer installiert.
- Das Microsoft Entra SDK für AgentID wird in Ihrer Umgebung bereitgestellt und ausgeführt. Anweisungen zur Einrichtung finden Sie im Installationshandbuch .
- Downstream-APIs , die im SDK mit Basis-URLs und erforderlichen Bereichen konfiguriert sind.
- Geeignete Berechtigungen in microsoft Entra ID – Ihr Konto muss über Berechtigungen zum Registrieren von Anwendungen verfügen und API-Berechtigungen erteilen.
Konfiguration
Bevor Sie Ihre Clientbibliothek erstellen, installieren Sie die erforderliche Abhängigkeit zum Erstellen von HTTP-Anforderungen:
pip install requests
Clientbibliotheksimplementierung
Erstellen Sie eine wiederverwendbare Clientklasse, die HTTP-Aufrufe an das Microsoft Entra SDK für AgentID umschließt. Diese Klasse behandelt die Tokenweiterleitung, Anforderungskonfiguration und Fehlerbehandlung:
# sidecar_client.py
import os
import json
import requests
from typing import Dict, Any, Optional, List
from urllib.parse import urlencode
class SidecarClient:
"""Client for interacting with the Microsoft Entra SDK for AgentID."""
def __init__(self, base_url: Optional[str] = None, timeout: int = 10):
self.base_url = base_url or os.getenv('SIDECAR_URL', 'http://localhost:5000')
self.timeout = timeout
def get_authorization_header(
self,
incoming_token: str,
service_name: str,
scopes: Optional[List[str]] = None,
tenant: Optional[str] = None,
agent_identity: Optional[str] = None,
agent_username: Optional[str] = None
) -> str:
"""Get authorization header from the SDK."""
params = {}
if scopes:
params['optionsOverride.Scopes'] = scopes
if tenant:
params['optionsOverride.AcquireTokenOptions.Tenant'] = tenant
if agent_identity:
params['AgentIdentity'] = agent_identity
if agent_username:
params['AgentUsername'] = agent_username
response = requests.get(
f"{self.base_url}/AuthorizationHeader/{service_name}",
params=params,
headers={'Authorization': incoming_token},
timeout=self.timeout
)
response.raise_for_status()
data = response.json()
return data['authorizationHeader']
def call_downstream_api(
self,
incoming_token: str,
service_name: str,
relative_path: str,
method: str = 'GET',
body: Optional[Dict[str, Any]] = None,
scopes: Optional[List[str]] = None
) -> Any:
"""Call downstream API via the SDK."""
params = {'optionsOverride.RelativePath': relative_path}
if method != 'GET':
params['optionsOverride.HttpMethod'] = method
if scopes:
params['optionsOverride.Scopes'] = scopes
headers = {'Authorization': incoming_token}
json_body = None
if body:
headers['Content-Type'] = 'application/json'
json_body = body
response = requests.request(
method,
f"{self.base_url}/DownstreamApi/{service_name}",
params=params,
headers=headers,
json=json_body,
timeout=self.timeout
)
response.raise_for_status()
data = response.json()
if data['statusCode'] >= 400:
raise Exception(f"API error {data['statusCode']}: {data['content']}")
return json.loads(data['content'])
# Usage
sidecar = SidecarClient(base_url='http://localhost:5000')
# Get authorization header
auth_header = sidecar.get_authorization_header(token, 'Graph')
# Call API
profile = sidecar.call_downstream_api(token, 'Graph', 'me')
Flask-Integration
Integrieren Sie die Clientbibliothek in eine Flask-Anwendung, indem Sie das eingehende Token in einer Hilfsfunktion extrahieren und in Routinghandlern verwenden, um nachgeschaltete APIs aufzurufen:
from flask import Flask, request, jsonify
from sidecar_client import SidecarClient
app = Flask(__name__)
sidecar = SidecarClient()
def get_token():
"""Extract token from request."""
token = request.headers.get('Authorization')
if not token:
raise ValueError('No authorization token provided')
return token
@app.route('/api/profile')
def profile():
try:
token = get_token()
profile_data = sidecar.call_downstream_api(
token,
'Graph',
'me'
)
return jsonify(profile_data)
except ValueError as e:
return jsonify({'error': str(e)}), 401
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/api/messages')
def messages():
try:
token = get_token()
messages_data = sidecar.call_downstream_api(
token,
'Graph',
'me/messages?$top=10'
)
return jsonify(messages_data)
except ValueError as e:
return jsonify({'error': str(e)}), 401
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/api/messages/send', methods=['POST'])
def send_message():
try:
token = get_token()
message = request.json
result = sidecar.call_downstream_api(
token,
'Graph',
'me/sendMail',
method='POST',
body={'message': message}
)
return jsonify({'success': True, 'result': result})
except ValueError as e:
return jsonify({'error': str(e)}), 401
except Exception as e:
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
FastAPI-Integration
Verwenden Sie für FastAPI-Anwendungen das Abhängigkeitseinfügungssystem mit der Header Abhängigkeit, um das Autorisierungstoken zu extrahieren und zu überprüfen, bevor Sie es an Routinghandler übergeben:
from fastapi import FastAPI, Header, HTTPException
from sidecar_client import SidecarClient
from typing import Optional
app = FastAPI()
sidecar = SidecarClient()
async def get_token(authorization: Optional[str] = Header(None)):
if not authorization:
raise HTTPException(status_code=401, detail="No authorization token")
return authorization
@app.get("/api/profile")
async def get_profile(token: str = Depends(get_token)):
try:
return sidecar.call_downstream_api(token, 'Graph', 'me')
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/api/messages")
async def get_messages(token: str = Depends(get_token)):
try:
return sidecar.call_downstream_api(
token,
'Graph',
'me/messages?$top=10'
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
Django-Integration
Erstellen Sie für Django-Anwendungen Ansichtsklassen, die das Autorisierungstoken aus Anforderungsheadern extrahieren, und verwenden Sie sie, um nachgeschaltete APIs aufzurufen:
# views.py
from django.http import JsonResponse
from django.views import View
from sidecar_client import SidecarClient
sidecar = SidecarClient()
class ProfileView(View):
def get(self, request):
token = request.META.get('HTTP_AUTHORIZATION')
if not token:
return JsonResponse({'error': 'No authorization token'}, status=401)
try:
profile = sidecar.call_downstream_api(token, 'Graph', 'me')
return JsonResponse(profile)
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
class MessagesView(View):
def get(self, request):
token = request.META.get('HTTP_AUTHORIZATION')
if not token:
return JsonResponse({'error': 'No authorization token'}, status=401)
try:
messages = sidecar.call_downstream_api(
token,
'Graph',
'me/messages?$top=10'
)
return JsonResponse(messages)
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
Fortgeschritten: Nutzung von requests.Session
Um die Leistung und Resilienz zu verbessern, verwenden Sie ein requests.Session Objekt mit Wiederholungslogik. Dieser Ansatz ermöglicht automatische Wiederholungen für vorübergehende Fehler und Verbindungspooling, um den Aufwand zu reduzieren:
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
class SidecarClient:
def __init__(self, base_url: Optional[str] = None):
self.base_url = base_url or os.getenv('SIDECAR_URL', 'http://localhost:5000')
# Configure session with retry logic
self.session = requests.Session()
retry = Retry(
total=3,
backoff_factor=0.3,
status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
self.session.mount('http://', adapter)
self.session.mount('https://', adapter)
def call_downstream_api(self, token, service_name, relative_path, **kwargs):
# Use self.session instead of requests
response = self.session.get(...)
return response
Bewährte Methoden
Wenn Sie das Microsoft Entra SDK für AgentID aus Python verwenden, befolgen Sie die folgenden Methoden, um zuverlässige und wartungsfähige Anwendungen zu erstellen:
-
Clientinstanz wiederverwenden: Erstellen Sie eine einzelne
SidecarClientInstanz, und verwenden Sie sie in der gesamten Anwendung wieder, anstatt neue Instanzen pro Anforderung zu erstellen. Dadurch wird die Leistung und die Ressourcennutzung verbessert. - Legen Sie geeignete Timeouts fest: Konfigurieren Sie Anforderungstimeouts basierend auf der nachgeschalteten API-Latenz. Dadurch wird verhindert, dass Ihre Anwendung unbegrenzt hängen bleibt, wenn der SDK- oder downstream-Dienst langsam ist.
- Implementieren der Fehlerbehandlung: Fügen Sie eine ordnungsgemäße Fehlerbehandlungs- und Wiederholungslogik hinzu, insbesondere für vorübergehende Fehler. Unterscheiden Sie zwischen Clientfehlern (4xx) und Serverfehlern (5xx), um geeignete Antworten zu ermitteln.
- Verwenden Sie Typenhinweise: Hinzufügen von Typenhinweisen zu Funktionsparametern und Rückgabewerten zur besseren Codeklarheit und zum Abfangen von Fehlern während der Entwicklungsphase.
-
Aktivieren von Verbindungspooling: Verwenden Sie ein
requests.SessionObjekt für die Wiederverwendung zwischen Anforderungen, wodurch der Aufwand reduziert und der Durchsatz für mehrere API-Aufrufe verbessert wird.
Andere Sprachhandbücher
Nächste Schritte
Beginnen Sie mit einem Szenario: