1- from typing import Any , AsyncIterable , Callable , Dict , Optional
1+ from typing import Any , AsyncIterable , Callable , Dict , List , Optional
22
33import asyncio
44import json
55import os
66import time
77from functools import wraps
8+ from importlib import metadata as importlib_metadata
89
910import httpx
1011from dotenv import load_dotenv
@@ -60,6 +61,7 @@ class HTTPClient:
6061 _instance = None
6162 base_url = os .getenv ("PAREA_BASE_URL" , "https://parea-ai-backend-us-9ac16cdbc7a7b006.onporter.run/api/parea/v1" )
6263 api_key = None
64+ integrations : List [str ] = []
6365
6466 def __new__ (cls , * args , ** kwargs ):
6567 if cls ._instance is None :
@@ -71,6 +73,20 @@ def __new__(cls, *args, **kwargs):
7173 def set_api_key (self , api_key : str ):
7274 self .api_key = api_key
7375
76+ def add_integration (self , integration : str ):
77+ if integration not in self .integrations :
78+ self .integrations .append (integration )
79+
80+ def _get_headers (self , api_key : Optional [str ] = None ) -> Dict [str , str ]:
81+ headers = {
82+ "x-api-key" : self .api_key or api_key ,
83+ "x-sdk-version" : get_version (),
84+ "x-sdk-language" : "python" ,
85+ }
86+ if self .integrations :
87+ headers ["x-sdk-integrations" ] = "," .join (self .integrations )
88+ return headers
89+
7490 @retry_on_502
7591 def request (
7692 self ,
@@ -83,7 +99,7 @@ def request(
8399 """
84100 Makes an HTTP request to the specified endpoint.
85101 """
86- headers = { "x-api-key" : self .api_key } if self . api_key else api_key
102+ headers = self ._get_headers ( api_key = api_key )
87103 try :
88104 response = self .sync_client .request (method , endpoint , json = data , headers = headers , params = params )
89105 response .raise_for_status ()
@@ -106,7 +122,7 @@ async def request_async(
106122 """
107123 Makes an asynchronous HTTP request to the specified endpoint.
108124 """
109- headers = { "x-api-key" : self .api_key } if self . api_key else api_key
125+ headers = self ._get_headers ( api_key = api_key )
110126 try :
111127 response = await self .async_client .request (method , endpoint , json = data , headers = headers , params = params )
112128 response .raise_for_status ()
@@ -128,7 +144,7 @@ def stream_request(
128144 """
129145 Makes a streaming HTTP request to the specified endpoint, yielding chunks of data.
130146 """
131- headers = { "x-api-key" : self .api_key } if self . api_key else api_key
147+ headers = self ._get_headers ( api_key = api_key )
132148 try :
133149 with self .sync_client .stream (method , endpoint , json = data , headers = headers , params = params , timeout = None ) as response :
134150 response .raise_for_status ()
@@ -151,7 +167,7 @@ async def stream_request_async(
151167 """
152168 Makes an asynchronous streaming HTTP request to the specified endpoint, yielding chunks of data.
153169 """
154- headers = { "x-api-key" : self .api_key } if self . api_key else api_key
170+ headers = self ._get_headers ( api_key = api_key )
155171 try :
156172 async with self .async_client .stream (method , endpoint , json = data , headers = headers , params = params , timeout = None ) as response :
157173 response .raise_for_status ()
@@ -200,3 +216,10 @@ def parse_event_data(byte_data):
200216 except Exception as e :
201217 print (f"Error parsing event data: { e } " )
202218 return None
219+
220+
221+ def get_version () -> str :
222+ try :
223+ return importlib_metadata .version ("parea-ai" )
224+ except importlib_metadata .PackageNotFoundError : # pragma: no cover
225+ return "unknown"
0 commit comments