3232 import graphql
3333 import httpx
3434
35- from ._backends .graphql import GitlabTransport
35+ from ._backends .graphql import GitlabAsyncTransport , GitlabTransport
3636
3737 _GQL_INSTALLED = True
3838except ImportError : # pragma: no cover
@@ -1278,14 +1278,13 @@ def next(self) -> Dict[str, Any]:
12781278 raise StopIteration
12791279
12801280
1281- class GraphQL :
1281+ class _BaseGraphQL :
12821282 def __init__ (
12831283 self ,
12841284 url : Optional [str ] = None ,
12851285 * ,
12861286 token : Optional [str ] = None ,
12871287 ssl_verify : Union [bool , str ] = True ,
1288- client : Optional [httpx .Client ] = None ,
12891288 timeout : Optional [float ] = None ,
12901289 user_agent : str = gitlab .const .USER_AGENT ,
12911290 fetch_schema_from_transport : bool = False ,
@@ -1308,9 +1307,50 @@ def __init__(
13081307 self ._max_retries = max_retries
13091308 self ._obey_rate_limit = obey_rate_limit
13101309 self ._retry_transient_errors = retry_transient_errors
1310+ self ._client_opts = self ._get_client_opts ()
1311+ self ._fetch_schema_from_transport = fetch_schema_from_transport
1312+
1313+ def _get_client_opts (self ) -> Dict [str , Any ]:
1314+ headers = {"User-Agent" : self ._user_agent }
1315+
1316+ if self ._token :
1317+ headers ["Authorization" ] = f"Bearer { self ._token } "
1318+
1319+ return {
1320+ "headers" : headers ,
1321+ "timeout" : self ._timeout ,
1322+ "verify" : self ._ssl_verify ,
1323+ }
1324+
13111325
1312- opts = self ._get_client_opts ()
1313- self ._http_client = client or httpx .Client (** opts )
1326+ class GraphQL (_BaseGraphQL ):
1327+ def __init__ (
1328+ self ,
1329+ url : Optional [str ] = None ,
1330+ * ,
1331+ token : Optional [str ] = None ,
1332+ ssl_verify : Union [bool , str ] = True ,
1333+ client : Optional [httpx .Client ] = None ,
1334+ timeout : Optional [float ] = None ,
1335+ user_agent : str = gitlab .const .USER_AGENT ,
1336+ fetch_schema_from_transport : bool = False ,
1337+ max_retries : int = 10 ,
1338+ obey_rate_limit : bool = True ,
1339+ retry_transient_errors : bool = False ,
1340+ ) -> None :
1341+ super ().__init__ (
1342+ url = url ,
1343+ token = token ,
1344+ ssl_verify = ssl_verify ,
1345+ timeout = timeout ,
1346+ user_agent = user_agent ,
1347+ fetch_schema_from_transport = fetch_schema_from_transport ,
1348+ max_retries = max_retries ,
1349+ obey_rate_limit = obey_rate_limit ,
1350+ retry_transient_errors = retry_transient_errors ,
1351+ )
1352+
1353+ self ._http_client = client or httpx .Client (** self ._client_opts )
13141354 self ._transport = GitlabTransport (self ._url , client = self ._http_client )
13151355 self ._client = gql .Client (
13161356 transport = self ._transport ,
@@ -1324,19 +1364,81 @@ def __enter__(self) -> "GraphQL":
13241364 def __exit__ (self , * args : Any ) -> None :
13251365 self ._http_client .close ()
13261366
1327- def _get_client_opts (self ) -> Dict [str , Any ]:
1328- headers = {"User-Agent" : self ._user_agent }
1367+ def execute (
1368+ self , request : Union [str , graphql .Source ], * args : Any , ** kwargs : Any
1369+ ) -> Any :
1370+ parsed_document = self ._gql (request )
1371+ retry = utils .Retry (
1372+ max_retries = self ._max_retries ,
1373+ obey_rate_limit = self ._obey_rate_limit ,
1374+ retry_transient_errors = self ._retry_transient_errors ,
1375+ )
13291376
1330- if self ._token :
1331- headers ["Authorization" ] = f"Bearer { self ._token } "
1377+ while True :
1378+ try :
1379+ result = self ._client .execute (parsed_document , * args , ** kwargs )
1380+ except gql .transport .exceptions .TransportServerError as e :
1381+ if retry .handle_retry_on_status (
1382+ status_code = e .code , headers = self ._transport .response_headers
1383+ ):
1384+ continue
13321385
1333- return {
1334- "headers" : headers ,
1335- "timeout" : self . _timeout ,
1336- "verify" : self . _ssl_verify ,
1337- }
1386+ if e . code == 401 :
1387+ raise gitlab . exceptions . GitlabAuthenticationError (
1388+ response_code = e . code ,
1389+ error_message = str ( e ) ,
1390+ )
13381391
1339- def execute (
1392+ raise gitlab .exceptions .GitlabHttpError (
1393+ response_code = e .code ,
1394+ error_message = str (e ),
1395+ )
1396+
1397+ return result
1398+
1399+
1400+ class AsyncGraphQL (_BaseGraphQL ):
1401+ def __init__ (
1402+ self ,
1403+ url : Optional [str ] = None ,
1404+ * ,
1405+ token : Optional [str ] = None ,
1406+ ssl_verify : Union [bool , str ] = True ,
1407+ client : Optional [httpx .AsyncClient ] = None ,
1408+ timeout : Optional [float ] = None ,
1409+ user_agent : str = gitlab .const .USER_AGENT ,
1410+ fetch_schema_from_transport : bool = False ,
1411+ max_retries : int = 10 ,
1412+ obey_rate_limit : bool = True ,
1413+ retry_transient_errors : bool = False ,
1414+ ) -> None :
1415+ super ().__init__ (
1416+ url = url ,
1417+ token = token ,
1418+ ssl_verify = ssl_verify ,
1419+ timeout = timeout ,
1420+ user_agent = user_agent ,
1421+ fetch_schema_from_transport = fetch_schema_from_transport ,
1422+ max_retries = max_retries ,
1423+ obey_rate_limit = obey_rate_limit ,
1424+ retry_transient_errors = retry_transient_errors ,
1425+ )
1426+
1427+ self ._http_client = client or httpx .AsyncClient (** self ._client_opts )
1428+ self ._transport = GitlabAsyncTransport (self ._url , client = self ._http_client )
1429+ self ._client = gql .Client (
1430+ transport = self ._transport ,
1431+ fetch_schema_from_transport = fetch_schema_from_transport ,
1432+ )
1433+ self ._gql = gql .gql
1434+
1435+ async def __aenter__ (self ) -> "AsyncGraphQL" :
1436+ return self
1437+
1438+ async def __aexit__ (self , * args : Any ) -> None :
1439+ await self ._http_client .aclose ()
1440+
1441+ async def execute (
13401442 self , request : Union [str , graphql .Source ], * args : Any , ** kwargs : Any
13411443 ) -> Any :
13421444 parsed_document = self ._gql (request )
@@ -1348,7 +1450,9 @@ def execute(
13481450
13491451 while True :
13501452 try :
1351- result = self ._client .execute (parsed_document , * args , ** kwargs )
1453+ result = await self ._client .execute_async (
1454+ parsed_document , * args , ** kwargs
1455+ )
13521456 except gql .transport .exceptions .TransportServerError as e :
13531457 if retry .handle_retry_on_status (
13541458 status_code = e .code , headers = self ._transport .response_headers
0 commit comments