@@ -30,7 +30,7 @@ def confirm(message: str, default: bool) -> bool:
3030 return answer == 'y'
3131
3232
33- def parse_api_response (name : str , response : requests .Response ):
33+ def parse_api_response (name : str , response : requests .Response ) -> bytes :
3434 # The connection worked, but we may have received an HTTP error
3535 if response .status_code >= 300 :
3636 print (response .text )
@@ -44,17 +44,10 @@ def parse_api_response(name: str, response: requests.Response):
4444 if response .status_code == 204 :
4545 return None
4646
47- # We got a successful HTTP response. It worked. Return the full response
48- try :
49- result = json .loads (response .text )
50- except json .decoder .JSONDecodeError :
51- print (response .text )
52- raise RuntimeError (f'Failed to JSON decode the response for API request { name } ' )
53-
54- return result
47+ return response .content
5548
5649
57- def do_api_request (name : str , method : str = 'GET' , jsonData : dict = {}):
50+ def do_api_request (name : str , method : str = 'GET' , jsonData : dict = {}, decode : bool = True ):
5851 '''Perform an API call to the given endpoint and return its data.
5952
6053 Based on whether `domjudge_webapp_folder_or_api_url` is a folder or URL this
@@ -64,16 +57,18 @@ def do_api_request(name: str, method: str = 'GET', jsonData: dict = {}):
6457 name (str): the endpoint to call
6558 method (str): the method to use, GET or PUT are supported
6659 jsonData (dict): the JSON data to PUT. Only used when method is PUT
60+ decode (bool): whether to decode the returned JSON data, default true
6761
6862 Returns:
69- The endpoint contents.
63+ The endpoint contents, either as raw bytes or JSON decoded .
7064
7165 Raises:
72- RuntimeError when the response is not JSON or the HTTP status code is non 2xx.
66+ RuntimeError when the HTTP status code is non-2xx or the response
67+ cannot be JSON decoded.
7368 '''
7469
7570 if os .path .isdir (domjudge_webapp_folder_or_api_url ):
76- return api_via_cli (name , method , {}, {}, jsonData )
71+ result = api_via_cli (name , method , {}, {}, jsonData )
7772 else :
7873 global ca_check
7974 url = f'{ domjudge_webapp_folder_or_api_url } /{ name } '
@@ -86,7 +81,7 @@ def do_api_request(name: str, method: str = 'GET', jsonData: dict = {}):
8681 if method == 'GET' :
8782 response = requests .get (url , headers = headers , verify = ca_check , auth = auth )
8883 elif method == 'PUT' :
89- response = requests .put (url , headers = headers , verify = ca_check , json = jsonData , auth = auth )
84+ response = requests .put (url , headers = headers , verify = ca_check , auth = auth , json = jsonData )
9085 else :
9186 raise RuntimeError ("Method not supported" )
9287 except requests .exceptions .SSLError :
@@ -99,7 +94,16 @@ def do_api_request(name: str, method: str = 'GET', jsonData: dict = {}):
9994 return do_api_request (name )
10095 except requests .exceptions .RequestException as e :
10196 raise RuntimeError (e )
102- return parse_api_response (name , response )
97+ result = parse_api_response (name , response )
98+
99+ if decode :
100+ try :
101+ result = json .loads (result )
102+ except json .decoder .JSONDecodeError as e :
103+ print (result )
104+ raise RuntimeError (f'Failed to JSON decode the response for API request { name } ' )
105+
106+ return result
103107
104108
105109def upload_file (name : str , apifilename : str , file : str , data : dict = {}):
@@ -121,7 +125,7 @@ def upload_file(name: str, apifilename: str, file: str, data: dict = {}):
121125 '''
122126
123127 if os .path .isdir (domjudge_webapp_folder_or_api_url ):
124- return api_via_cli (name , 'POST' , data , {apifilename : file })
128+ response = api_via_cli (name , 'POST' , data , {apifilename : file })
125129 else :
126130 global ca_check
127131 files = [(apifilename , open (file , 'rb' ))]
@@ -155,7 +159,7 @@ def api_via_cli(name: str, method: str = 'GET', data: dict = {}, files: dict = {
155159 jsonData (dict): the JSON data to use. Only used when method is POST or PUT
156160
157161 Returns:
158- The parsed endpoint contents.
162+ The raw endpoint contents.
159163
160164 Raises:
161165 RuntimeError when the command exit code is not 0.
@@ -180,10 +184,14 @@ def api_via_cli(name: str, method: str = 'GET', data: dict = {}, files: dict = {
180184 command .append (name )
181185
182186 result = subprocess .run (command , capture_output = True )
183- response = result .stdout .decode ('ascii' )
184187
185188 if result .returncode != 0 :
186- print (response )
189+ print (
190+ f"Command: { command } \n Output:\n " +
191+ result .stdout .decode ('utf-8' ) +
192+ result .stderr .decode ('utf-8' ),
193+ file = sys .stderr
194+ )
187195 raise RuntimeError (f'API request { name } failed' )
188196
189- return json . loads ( response )
197+ return result . stdout
0 commit comments