5
5
from functools import update_wrapper
6
6
import logging
7
7
import os .path
8
- import re
9
8
import pty
9
+ import re
10
10
import sys
11
11
import tempfile
12
+ import typing as ty
12
13
13
14
import click
14
15
import requests
15
16
16
17
import git_pw
17
18
from git_pw import config
18
19
19
- if 0 : # noqa
20
- from typing import Any # noqa
21
- from typing import Callable # noqa
22
- from typing import Dict # noqa
23
- from typing import IO # noqa
24
- from typing import List # noqa
25
- from typing import Optional # noqa
26
- from typing import Tuple # noqa
27
- from typing import Union # noqa
28
-
29
- Filters = List [Tuple [str , str ]]
30
-
31
20
CONF = config .CONF
32
21
LOG = logging .getLogger (__name__ )
33
22
23
+ Filters = ty .List [ty .Tuple [str , str ]]
24
+
34
25
35
26
class HTTPTokenAuth (requests .auth .AuthBase ):
36
27
"""Attaches HTTP Token Authentication to the given Request object."""
37
- def __init__ (self , token ):
28
+ def __init__ (self , token : str ):
38
29
self .token = token
39
30
40
- def __call__ (self , r ):
31
+ def __call__ (
32
+ self , r : requests .PreparedRequest ,
33
+ ) -> requests .PreparedRequest :
41
34
r .headers ['Authorization' ] = self ._token_auth_str (self .token )
42
35
return r
43
36
44
37
@staticmethod
45
- def _token_auth_str (token ): # type: ( str) -> str
38
+ def _token_auth_str (token : str ) -> str :
46
39
"""Return a Token auth string."""
47
40
return 'Token {}' .format (token .strip ())
48
41
49
42
50
- def _get_auth (optional = False ):
51
- # type: (bool) -> Optional[requests.auth.AuthBase]
43
+ def _get_auth (optional : bool = False ) -> ty .Optional [requests .auth .AuthBase ]:
52
44
if CONF .token :
53
45
return HTTPTokenAuth (CONF .token )
54
46
elif CONF .username and CONF .password :
@@ -61,13 +53,13 @@ def _get_auth(optional=False):
61
53
return None
62
54
63
55
64
- def _get_headers (): # type: () -> Dict[str, str]
56
+ def _get_headers () -> ty . Dict [str , str ]:
65
57
return {
66
58
'User-Agent' : 'git-pw ({})' .format (git_pw .__version__ ),
67
59
}
68
60
69
61
70
- def _get_server (): # type: () -> str
62
+ def _get_server () -> str :
71
63
if CONF .server :
72
64
server = CONF .server .rstrip ('/' )
73
65
@@ -91,7 +83,7 @@ def _get_server(): # type: () -> str
91
83
sys .exit (1 )
92
84
93
85
94
- def _get_project (): # type: () -> str
86
+ def _get_project () -> str :
95
87
if CONF .project and CONF .project .strip () == '*' :
96
88
return '' # just don't bother filtering on project
97
89
elif CONF .project :
@@ -104,7 +96,9 @@ def _get_project(): # type: () -> str
104
96
sys .exit (1 )
105
97
106
98
107
- def _handle_error (operation , exc ):
99
+ def _handle_error (
100
+ operation : str , exc : requests .exceptions .RequestException ,
101
+ ) -> None :
108
102
if exc .response is not None and exc .response .content :
109
103
# server errors should always be reported
110
104
if exc .response .status_code in range (500 , 512 ): # 5xx Server Error
@@ -128,8 +122,9 @@ def _handle_error(operation, exc):
128
122
sys .exit (1 )
129
123
130
124
131
- def _get (url , params = None , stream = False ):
132
- # type: (str, Filters, bool) -> requests.Response
125
+ def _get (
126
+ url : str , params : Filters = None , stream : bool = False ,
127
+ ) -> requests .Response :
133
128
"""Make GET request and handle errors."""
134
129
LOG .debug ('GET %s' , url )
135
130
@@ -149,8 +144,9 @@ def _get(url, params=None, stream=False):
149
144
return rsp
150
145
151
146
152
- def _post (url , data ):
153
- # type: (str, dict) -> requests.Response
147
+ def _post (
148
+ url : str , data : ty .List [ty .Tuple [str , ty .Any ]],
149
+ ) -> requests .Response :
154
150
"""Make POST request and handle errors."""
155
151
LOG .debug ('POST %s, data=%r' , url , data )
156
152
@@ -166,14 +162,16 @@ def _post(url, data):
166
162
return rsp
167
163
168
164
169
- def _patch (url , data ):
170
- # type: (str, dict) -> requests.Response
165
+ def _patch (
166
+ url : str , data : ty .List [ty .Tuple [str , ty .Any ]],
167
+ ) -> requests .Response :
171
168
"""Make PATCH request and handle errors."""
172
169
LOG .debug ('PATCH %s, data=%r' , url , data )
173
170
174
171
try :
175
- rsp = requests .patch (url , auth = _get_auth (), headers = _get_headers (),
176
- data = data )
172
+ rsp = requests .patch (
173
+ url , auth = _get_auth (), headers = _get_headers (), data = data ,
174
+ )
177
175
rsp .raise_for_status ()
178
176
except requests .exceptions .RequestException as exc :
179
177
_handle_error ('update' , exc )
@@ -183,8 +181,7 @@ def _patch(url, data):
183
181
return rsp
184
182
185
183
186
- def _delete (url ):
187
- # type: (str) -> requests.Response
184
+ def _delete (url : str ) -> requests .Response :
188
185
"""Make DELETE request and handle errors."""
189
186
LOG .debug ('DELETE %s' , url )
190
187
@@ -199,8 +196,7 @@ def _delete(url):
199
196
return rsp
200
197
201
198
202
- def version ():
203
- # type: () -> Optional[Tuple[int, int]]
199
+ def version () -> ty .Tuple [int , int ]:
204
200
"""Get the version of the server from the URL, if present."""
205
201
server = _get_server ()
206
202
@@ -212,8 +208,9 @@ def version():
212
208
return (1 , 0 )
213
209
214
210
215
- def download (url , params = None , output = None ):
216
- # type: (str, Filters, IO) -> Optional[str]
211
+ def download (
212
+ url : str , params : Filters = None , output : ty .IO = None ,
213
+ ) -> ty .Optional [str ]:
217
214
"""Retrieve a specific API resource and save it to a file/stdout.
218
215
219
216
The ``Content-Disposition`` header is assumed to be present and
@@ -261,8 +258,7 @@ def download(url, params=None, output=None):
261
258
return output_path
262
259
263
260
264
- def index (resource_type , params = None ):
265
- # type: (str, Filters) -> dict
261
+ def index (resource_type : str , params : Filters = None ) -> dict :
266
262
"""List API resources.
267
263
268
264
GET /{resource}/
@@ -288,8 +284,11 @@ def index(resource_type, params=None):
288
284
return _get (url , params ).json ()
289
285
290
286
291
- def detail (resource_type , resource_id , params = None ):
292
- # type: (str, int, Filters) -> Dict
287
+ def detail (
288
+ resource_type : str ,
289
+ resource_id : ty .Union [str , int ],
290
+ params : Filters = None ,
291
+ ) -> ty .Dict :
293
292
"""Retrieve a specific API resource.
294
293
295
294
GET /{resource}/{resourceID}/
@@ -308,8 +307,9 @@ def detail(resource_type, resource_id, params=None):
308
307
return _get (url , params , stream = False ).json ()
309
308
310
309
311
- def create (resource_type , data ):
312
- # type: (str, dict) -> dict
310
+ def create (
311
+ resource_type : str , data : ty .List [ty .Tuple [str , ty .Any ]],
312
+ ) -> dict :
313
313
"""Create a new API resource.
314
314
315
315
POST /{resource}/
@@ -327,8 +327,7 @@ def create(resource_type, data):
327
327
return _post (url , data ).json ()
328
328
329
329
330
- def delete (resource_type , resource_id ):
331
- # type: (str, Union[str, int]) -> None
330
+ def delete (resource_type : str , resource_id : ty .Union [str , int ]) -> None :
332
331
"""Delete a specific API resource.
333
332
334
333
DELETE /{resource}/{resourceID}/
@@ -346,8 +345,11 @@ def delete(resource_type, resource_id):
346
345
_delete (url )
347
346
348
347
349
- def update (resource_type , resource_id , data ):
350
- # type: (str, Union[int, str], dict) -> dict
348
+ def update (
349
+ resource_type : str ,
350
+ resource_id : ty .Union [str , int ],
351
+ data : ty .List [ty .Tuple [str , ty .Any ]],
352
+ ) -> dict :
351
353
"""Update a specific API resource.
352
354
353
355
PATCH /{resource}/{resourceID}/
@@ -366,8 +368,9 @@ def update(resource_type, resource_id, data):
366
368
return _patch (url , data ).json ()
367
369
368
370
369
- def validate_minimum_version (min_version , msg ):
370
- # type: (Tuple[int, int], str) -> Callable[[Any], Any]
371
+ def validate_minimum_version (
372
+ min_version : ty .Tuple [int , int ], msg : str ,
373
+ ) -> ty .Callable [[ty .Any ], ty .Any ]:
371
374
372
375
def inner (f ):
373
376
@click .pass_context
@@ -383,7 +386,7 @@ def new_func(ctx, *args, **kwargs):
383
386
return inner
384
387
385
388
386
- def validate_multiple_filter_support (f ) :
389
+ def validate_multiple_filter_support (f : ty . Callable ) -> ty . Callable :
387
390
388
391
@click .pass_context
389
392
def new_func (ctx , * args , ** kwargs ):
@@ -412,7 +415,9 @@ def new_func(ctx, *args, **kwargs):
412
415
return update_wrapper (new_func , f )
413
416
414
417
415
- def retrieve_filter_ids (resource_type , filter_name , filter_value ):
418
+ def retrieve_filter_ids (
419
+ resource_type : str , filter_name : str , filter_value : str ,
420
+ ) -> ty .List [ty .Tuple [str , str ]]:
416
421
"""Retrieve IDs for items passed through by filter.
417
422
418
423
Some filters require client-side filtering, e.g. filtering patches by
0 commit comments