14
14
15
15
"""Internal HTTP client module.
16
16
17
- This module provides utilities for making HTTP calls using the requests library.
17
+ This module provides utilities for making HTTP calls using the requests/httpx library.
18
18
"""
19
19
20
20
from google .auth import transport
21
+ import httpx
22
+ from httpx import _utils as httpx_utils
21
23
import requests
22
24
from requests .packages .urllib3 .util import retry # pylint: disable=import-error
23
-
25
+ from firebase_admin . _httpx_utils import HttpxAuthorizedClient , CustomRetryTransport
24
26
25
27
if hasattr (retry .Retry .DEFAULT , 'allowed_methods' ):
26
28
_ANY_METHOD = {'allowed_methods' : None }
33
35
connect = 1 , read = 1 , status = 4 , status_forcelist = [500 , 503 ],
34
36
raise_on_status = False , backoff_factor = 0.5 , ** _ANY_METHOD )
35
37
38
+ DEFAULT_TRANSPORT_CONFIG = CustomRetryTransport (status_forcelist = [500 , 503 ],
39
+ backoff_factor = 0.5 )
36
40
37
41
DEFAULT_TIMEOUT_SECONDS = 120
38
42
@@ -46,7 +50,8 @@ class HttpClient:
46
50
47
51
def __init__ (
48
52
self , credential = None , session = None , base_url = '' , headers = None ,
49
- retries = DEFAULT_RETRY_CONFIG , timeout = DEFAULT_TIMEOUT_SECONDS ):
53
+ retries = DEFAULT_RETRY_CONFIG , timeout = DEFAULT_TIMEOUT_SECONDS ,
54
+ http2 = False , request_handler = DEFAULT_TRANSPORT_CONFIG ):
50
55
"""Creates a new HttpClient instance from the provided arguments.
51
56
52
57
If a credential is provided, initializes a new HTTP session authorized with it. If neither
@@ -62,19 +67,33 @@ def __init__(
62
67
Pass a False value to disable retries (optional).
63
68
timeout: HTTP timeout in seconds. Defaults to 120 seconds when not specified. Set to
64
69
None to disable timeouts (optional).
70
+ http2: A boolean indicating whether to use HTTP/2 for requests (optional).
71
+ request_handler: A custom httpx transport to use for HTTP/2 requests. Default settings
72
+ would be similar to retries default (optional).
65
73
"""
66
74
if credential :
67
- self ._session = transport .requests .AuthorizedSession (credential )
75
+ self ._session = (
76
+ transport .requests .AuthorizedSession (credential )
77
+ if not http2
78
+ else HttpxAuthorizedClient (credential , request_handler )
79
+ )
68
80
elif session :
69
81
self ._session = session
70
82
else :
71
- self ._session = requests .Session () # pylint: disable=redefined-variable-type
83
+ self ._session = (
84
+ requests .Session ()
85
+ if not http2
86
+ else httpx .Client (http2 = True , transport = request_handler )
87
+ ) # pylint: disable=redefined-variable-type
72
88
73
89
if headers :
74
90
self ._session .headers .update (headers )
75
- if retries :
91
+ if retries and not http2 :
76
92
self ._session .mount ('http://' , requests .adapters .HTTPAdapter (max_retries = retries ))
77
93
self ._session .mount ('https://' , requests .adapters .HTTPAdapter (max_retries = retries ))
94
+ if request_handler and http2 :
95
+ self ._session ._mounts = {httpx_utils .URLPattern ('http://' ): request_handler , # pylint: disable=protected-access
96
+ httpx_utils .URLPattern ('https://' ): request_handler }
78
97
self ._base_url = base_url
79
98
self ._timeout = timeout
80
99
0 commit comments