4
4
5
5
from __future__ import annotations
6
6
7
+ import gzip
8
+ import json
7
9
import logging
8
10
import platform
9
11
import pprint
10
12
import sys
11
13
import time
12
- from typing import TYPE_CHECKING , Any , List , Mapping , Optional
14
+ from typing import TYPE_CHECKING , List , Mapping , Optional
13
15
14
16
import pkg_resources
15
17
import requests
16
- from requests import Response , Session
18
+ from requests import HTTPError , Response , Session
17
19
18
20
if TYPE_CHECKING :
19
21
from typing_extensions import NotRequired , TypedDict
@@ -67,39 +69,58 @@ class TestRunRecord(TypedDict):
67
69
attempts : List [TestRunAttemptRecord ]
68
70
69
71
70
- class CreateTestSuiteRunRequest (TypedDict ):
72
+ class CreateTestSuiteRunInlineRequest (TypedDict ):
71
73
branch : NotRequired [Optional [str ]]
72
74
commit : NotRequired [Optional [str ]]
73
75
start_time : str
74
76
end_time : str
75
77
test_runs : List [TestRunRecord ]
76
78
77
79
80
+ class CreateTestSuiteRunUploadRequest (TypedDict ):
81
+ upload_id : str
82
+
83
+
84
+ class CreateTestSuiteRunUploadUrlResponse (TypedDict ):
85
+ upload_id : str
86
+
87
+
78
88
class TestSuiteRunPendingSummary (TypedDict ):
79
89
run_id : str
80
90
suite_id : str
81
91
branch : NotRequired [Optional [str ]]
82
92
commit : NotRequired [Optional [str ]]
83
93
84
94
85
- def send_api_request (
86
- api_key : str ,
87
- method : Literal ['GET' , 'POST' ],
95
+ def __new_requests_session () -> Session :
96
+ session = Session ()
97
+ session .headers ['User-Agent' ] = USER_AGENT
98
+
99
+ return session
100
+
101
+
102
+ def __send_api_request (
103
+ session : Session ,
104
+ api_key : Optional [str ],
105
+ method : Literal ['GET' , 'POST' , 'PUT' ],
88
106
url : str ,
89
107
logger : logging .Logger ,
90
108
headers : Optional [Mapping [str , str | bytes | None ]] = None ,
91
- json : Optional [Any ] = None ,
109
+ body : Optional [str | bytes ] = None ,
92
110
verify : Optional [bool | str ] = None ,
93
111
) -> Response :
94
- session = Session ()
95
- session .headers .update ({
96
- 'Authorization' : f'Bearer { api_key } ' ,
97
- 'User-Agent' : USER_AGENT ,
98
- })
99
-
100
112
for idx in range (NUM_REQUEST_TRIES ):
101
113
try :
102
- response = session .request (method , url , headers = headers , json = json , verify = verify )
114
+ response = session .request (
115
+ method ,
116
+ url ,
117
+ headers = {
118
+ ** ({'Authorization' : f'Bearer { api_key } ' } if api_key is not None else {}),
119
+ ** (headers if headers is not None else {})
120
+ },
121
+ data = body ,
122
+ verify = verify ,
123
+ )
103
124
if response .status_code not in [429 , 500 , 502 , 503 , 504 ]:
104
125
return response
105
126
elif idx + 1 != NUM_REQUEST_TRIES :
@@ -124,7 +145,7 @@ def send_api_request(
124
145
125
146
126
147
def create_test_suite_run (
127
- request : CreateTestSuiteRunRequest ,
148
+ request : CreateTestSuiteRunInlineRequest ,
128
149
test_suite_id : str ,
129
150
api_key : str ,
130
151
base_url : Optional [str ],
@@ -133,7 +154,53 @@ def create_test_suite_run(
133
154
) -> TestSuiteRunPendingSummary :
134
155
logger .debug (f'creating test suite run { pprint .pformat (request )} ' )
135
156
136
- run_response = send_api_request (
157
+ session = __new_requests_session ()
158
+
159
+ create_upload_url_response = __send_api_request (
160
+ session = session ,
161
+ api_key = api_key ,
162
+ method = 'POST' ,
163
+ url = (
164
+ f'{ base_url if base_url is not None else BASE_URL } /api/v1/test-suites/{ test_suite_id } '
165
+ '/runs/upload'
166
+ ),
167
+ logger = logger ,
168
+ verify = not insecure_disable_tls_validation ,
169
+ )
170
+
171
+ create_upload_url_response .raise_for_status ()
172
+ if create_upload_url_response .status_code != 201 :
173
+ raise HTTPError (
174
+ f'Expected 201 response but received { create_upload_url_response .status_code } ' )
175
+
176
+ upload_presigned_url = create_upload_url_response .headers .get ('Location' , None )
177
+ if upload_presigned_url is None :
178
+ raise HTTPError ('Location response header not found' )
179
+
180
+ create_upload_url_response_body : CreateTestSuiteRunUploadUrlResponse = (
181
+ create_upload_url_response .json ()
182
+ )
183
+ upload_id = create_upload_url_response_body ['upload_id' ]
184
+
185
+ gzipped_request = gzip .compress (json .dumps (request ).encode ('utf8' ))
186
+ upload_response = __send_api_request (
187
+ session = session ,
188
+ api_key = None ,
189
+ method = 'PUT' ,
190
+ url = upload_presigned_url ,
191
+ logger = logger ,
192
+ headers = {
193
+ 'Content-Encoding' : 'gzip' ,
194
+ 'Content-Type' : 'application/json' ,
195
+ },
196
+ body = gzipped_request ,
197
+ verify = not insecure_disable_tls_validation ,
198
+ )
199
+ upload_response .raise_for_status ()
200
+
201
+ request_body : CreateTestSuiteRunUploadRequest = {'upload_id' : upload_id }
202
+ run_response = __send_api_request (
203
+ session = session ,
137
204
api_key = api_key ,
138
205
method = 'POST' ,
139
206
url = (
@@ -142,7 +209,7 @@ def create_test_suite_run(
142
209
),
143
210
logger = logger ,
144
211
headers = {'Content-Type' : 'application/json' },
145
- json = request ,
212
+ body = json . dumps ( request_body ). encode ( 'utf8' ) ,
146
213
verify = not insecure_disable_tls_validation ,
147
214
)
148
215
run_response .raise_for_status ()
@@ -162,7 +229,10 @@ def get_test_suite_manifest(
162
229
) -> TestSuiteManifest :
163
230
logger .debug (f'fetching manifest for test suite { test_suite_id } ' )
164
231
165
- manifest_response = send_api_request (
232
+ session = __new_requests_session ()
233
+
234
+ manifest_response = __send_api_request (
235
+ session = session ,
166
236
api_key = api_key ,
167
237
method = 'GET' ,
168
238
url = (
0 commit comments