Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Buat pustaka klien Python yang terintegrasi dengan Microsoft Entra SDK for AgentID untuk mendapatkan token dan memanggil API hilir. Kemudian integrasikan klien ini ke dalam aplikasi Flask, FastAPI, atau Django untuk menangani permintaan terautentikasi.
Prasyarat
- Sebuah akun Azure dengan langganan aktif. Buat akun secara gratis.
- Python (versi 3.7 atau yang lebih baru) dengan pip yang diinstal pada komputer pengembangan Anda.
- Microsoft Entra SDK for AgentID disebarkan dan berjalan di lingkungan Anda. Lihat Panduan Penginstalan untuk instruksi penyiapan.
- API hilir yang dikonfigurasi di SDK dengan URL dasar dan cakupan yang diperlukan.
- Izin yang sesuai di ID Microsoft Entra - Akun Anda harus memiliki izin untuk mendaftarkan aplikasi dan memberikan izin API.
Pengaturan
Sebelum membuat pustaka klien Anda, instal dependensi yang diperlukan untuk membuat permintaan HTTP:
pip install requests
Implementasi pustaka klien
Buat kelas klien yang dapat digunakan kembali yang membungkus panggilan HTTP ke Microsoft Entra SDK untuk AgentID. Kelas ini menangani penerusan token, konfigurasi permintaan, dan penanganan kesalahan:
# 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')
Integrasi Flask
Integrasikan perpustakaan klien ke dalam aplikasi Flask dengan mengekstrak token masuk dalam fungsi bantu dan menggunakannya di pengendali rute untuk memanggil API hilir.
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)
Integrasi FastAPI
Untuk aplikasi FastAPI, gunakan sistem injeksi dependensi dengan dependensi Header untuk mengekstrak dan memvalidasi token otorisasi sebelum meneruskannya ke pengelola rute.
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))
Integrasi Django
Untuk aplikasi Django, buat kelas tampilan yang mengekstrak token otorisasi dari header permintaan dan gunakan untuk memanggil API hilir:
# 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)
Tingkat lanjut: menggunakan permintaan. Sesi
Untuk meningkatkan performa dan ketahanan, gunakan requests.Session objek dengan logika coba lagi. Pendekatan ini memungkinkan percobaan ulang otomatis untuk kegagalan sementara dan pengumpulan koneksi untuk mengurangi overhead:
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
Praktik terbaik
Saat menggunakan Microsoft Entra SDK untuk AgentID dari Python, ikuti praktik ini untuk membangun aplikasi yang andal dan dapat dipertahankan:
-
Gunakan Kembali Instans Klien: Buat satu
SidecarClientinstans dan gunakan kembali di seluruh aplikasi Anda daripada membuat instans baru per permintaan. Ini meningkatkan performa dan penggunaan sumber daya. - Atur Batas Waktu yang Sesuai: Konfigurasikan batas waktu permintaan berdasarkan latensi API hilir Anda. Ini mencegah aplikasi Anda menggantung tanpa batas waktu jika SDK atau layanan hilir lambat.
- Terapkan Penanganan Kesalahan: Tambahkan penanganan kesalahan yang tepat dan coba lagi logika, terutama untuk kegagalan sementara. Membedakan antara kesalahan klien (4xx) dan kesalahan server (5xx) untuk menentukan respons yang sesuai.
- Gunakan Petunjuk Jenis: Tambahkan petunjuk jenis ke parameter fungsi dan kembalikan nilai untuk kejelasan kode yang lebih baik dan untuk menangkap kesalahan pada waktu pengembangan.
-
Aktifkan Pengumpulan Koneksi: Gunakan
requests.Sessionobjek untuk penggunaan kembali koneksi di seluruh permintaan, yang mengurangi overhead dan meningkatkan throughput untuk beberapa panggilan API.
Panduan bahasa lain
Langkah selanjutnya
Mulailah dengan skenario: