├── requirements.txt ├── CONTRIBUTORS.md ├── setup.py ├── LICENSE ├── .gitignore ├── README.md └── pytea ├── __init__.py └── resources.py /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2018.1.18 2 | chardet==3.0.4 3 | idna==2.6 4 | parse==1.8.2 5 | pkg-resources==0.0.0 6 | requests==2.18.4 7 | urllib3==1.24.2 8 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | Contributors 2 | ============ 3 | 4 | Pytea has been improved by: 5 | 6 | + [happydig](https://github.com/happydig): [issue: code formatted with YAML](https://github.com/arount/pytea/issues/1) 7 | 8 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/env/bin python 2 | 3 | from setuptools import setup 4 | 5 | setup( 6 | name='pytea', 7 | version='0.0', 8 | description='Gitea API wrapper for python', 9 | url='http://github.com/arount/pytea', 10 | author='Arount', 11 | author_email='arount@riseup.net', 12 | license='WTFPL', 13 | packages=['pytea'], 14 | zip_safe=False 15 | ) 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | .static_storage/ 57 | .media/ 58 | local_settings.py 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # pyenv 77 | .python-version 78 | 79 | # celery beat schedule file 80 | celerybeat-schedule 81 | 82 | # SageMath parsed files 83 | *.sage.py 84 | 85 | # Environments 86 | .env 87 | .venv 88 | env/ 89 | venv/ 90 | ENV/ 91 | env.bak/ 92 | venv.bak/ 93 | 94 | # Spyder project settings 95 | .spyderproject 96 | .spyproject 97 | 98 | # Rope project settings 99 | .ropeproject 100 | 101 | # mkdocs documentation 102 | /site 103 | 104 | # mypy 105 | .mypy_cache/ 106 | 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pytea 2 | 3 | [Gitea API](https://try.gitea.io/api/swagger) wrapper for Python (3 only). 4 | 5 | 6 | ## Install 7 | 8 | ### From sources 9 | 10 | ```python 11 | python setup.py install 12 | ``` 13 | 14 | ### With Pip 15 | 16 | ```python 17 | pip install git+https://github.com/arount/pytea 18 | ``` 19 | 20 | 21 | ## Basic usage 22 | 23 | 24 | ```python 25 | import pytea 26 | 27 | api = pytea.API('http://192.168.100.10:3000') 28 | api.get('/version') 29 | api.get('/orgs/an-organisation/members') 30 | ``` 31 | 32 | 33 | ### Authentification token 34 | 35 | 36 | Setup authentification token: 37 | 38 | ```python 39 | import pytea 40 | api = pytea.API('http://192.168.100.10:3000', token="AUTH-TOKEN") 41 | api.delete('/admin/users/arount') 42 | ``` 43 | 44 | 45 | ### Main API methods 46 | 47 | 48 | ```python 49 | api.get('route') # Send GET query to route 50 | api.post('route') # Send POST query to route 51 | api.patch('route') # Send PATCH query to route 52 | api.put('route') # Send PUT query to route 53 | ``` 54 | 55 | 56 | ### Alternative API method 57 | 58 | 59 | ```python 60 | # Send GET query to route with parameters 61 | api.call('route', method='get', params={"body": "Egg, bacon, sausages and SPAM") 62 | ``` 63 | 64 | 65 | ## Exceptions 66 | 67 | 68 | Exceptions are raised before sending query. If API respond error message no exception will be raised (for the moment, at least) 69 | 70 | 71 | ### Authentification token 72 | 73 | 74 | If auth token is not set when you are trying to access to a protected resource: 75 | 76 | ```python 77 | api = pytea.API('http://192.168.100.10:3000') 78 | api.delete('/admin/users/arount') 79 | ``` 80 | 81 | 82 | ``` 83 | pytea.PyteaRequestException: Resource '/admin/users/{username}' require an authentification token. 84 | ``` 85 | 86 | 87 | ### Resource do not exists 88 | 89 | 90 | ```python 91 | api.get('/fake/route') 92 | ``` 93 | 94 | 95 | ``` 96 | pytea.PyteaRequestException: Path '/fake/route' did not match with any resource 97 | ``` 98 | 99 | 100 | ### Method do not exists for resource 101 | 102 | 103 | ```python 104 | api.delete('/markdown') 105 | ``` 106 | 107 | 108 | ``` 109 | pytea.PyteaRequestException: Resource '/markdown' did not expect method DELETE 110 | ``` 111 | 112 | -------------------------------------------------------------------------------- /pytea/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/env/bin python 2 | 3 | ''' 4 | Gitea API wrapper for Python. 5 | API doc: https://try.gitea.io/api/swagger 6 | ''' 7 | 8 | import parse 9 | import requests 10 | 11 | from pytea.resources import resources 12 | 13 | 14 | class PyteaRequestException(Exception): 15 | pass 16 | 17 | 18 | class API(object): 19 | ''' 20 | Gitea API wrapper. 21 | ''' 22 | 23 | _api_baseroute = '/api/v1' 24 | 25 | def __init__(self, baseuri, token=None): 26 | if baseuri.endswith('/'): 27 | baseuri = baseuri[0:-1] 28 | 29 | self._baseuri = ''.join([baseuri, self._api_baseroute]) 30 | self._token = token 31 | 32 | # Aliases to `call`, this should be prefered entry-points 33 | def post(self, path, params=None): 34 | return self.call(path, method='post', params=params) 35 | 36 | def get(self, path, params=None): 37 | return self.call(path, method='get', params=params) 38 | 39 | def delete(self, path, params=None): 40 | return self.call(path, method='delete', params=params) 41 | 42 | def patch(self, path, params=None): 43 | return self.call(path, method='patch', params=params) 44 | 45 | def put(self, path, params=None): 46 | return self.call(path, method='put', params=params) 47 | 48 | 49 | def call(self, path, method, params=None): 50 | ''' 51 | Compute, check and execute request to API. 52 | Returns requests.Response object. 53 | ''' 54 | # Handle parameters 55 | if params is None: 56 | params = {} 57 | method = method.lower() 58 | resource = self.get_resource(path).copy() 59 | 60 | # Check if request needs auth token 61 | if path.split('/')[1] == 'admin' and self._token is None: 62 | raise PyteaRequestException( 63 | 'Resource \'{}\' require an authentification token.'.format(resource['path']) 64 | ) 65 | else: 66 | params['token'] = self._token 67 | 68 | # Check if `resource` expect to be called with `method` HTTP method 69 | if not self._resource_has_method(resource, method): 70 | raise PyteaRequestException('Resource \'{}\' did not expect method {}'.format( 71 | resource['path'], 72 | method.upper() 73 | )) 74 | 75 | # Check if all required parameters are given 76 | required_params = self.clean_resource_params(resource['path'], resource[method]['parameters']) 77 | for key in required_params: 78 | if key not in params.keys(): 79 | raise PyteaRequestException('Resource \'{}\' with method {} expect parameter \'{}\''.format( 80 | resource['path'], 81 | method.upper(), 82 | key 83 | )) 84 | 85 | func = getattr(requests, method) 86 | final_uri = ''.join([self._baseuri, path]) 87 | return func(final_uri, params=params) 88 | 89 | 90 | def clean_resource_params(self, resource_path, params): 91 | ''' 92 | Remove params in resource hash already given in resource's uri. 93 | Example: 94 | /foo/{bar}/{baz} expect `bar` and `baz`, but since they are in uri we don't want 95 | to check that again. 96 | 97 | Returns cleaned params hash 98 | ''' 99 | to_rm = [] 100 | for name in params: 101 | if '{{{}}}'.format(name) in resource_path: 102 | to_rm.append(name) 103 | 104 | for key in to_rm: 105 | params.pop(key, None) 106 | 107 | return params 108 | 109 | 110 | def get_resource(self, path): 111 | ''' 112 | Returns resource's hash from URI (path) 113 | Augment resource's hash with non-formated path for convenience. 114 | Returns augmented resource hash. 115 | ''' 116 | key = self._get_resource_path(path) 117 | if key is None: 118 | raise PyteaRequestException('Path \'{}\' did not match with any resource'.format(path)) 119 | 120 | resource = resources[key].copy() 121 | resource['path'] = key 122 | return resource 123 | 124 | 125 | def _resource_has_method(self, resource, method): 126 | ''' 127 | Check if `resource` (path to resource) accept `method` (HTTP method). 128 | ''' 129 | if method not in resource.keys(): 130 | return False 131 | return True 132 | 133 | def _get_resource_path(self, path): 134 | ''' 135 | Get raw resource's path (/foo/{bar}) from formatted one (/foo/bar). 136 | ''' 137 | # Two or more routes can match with `path` 138 | # The one with more characters is the good one. 139 | # I guess?.. 140 | possibilities = [] 141 | for method in resources: 142 | compiled = parse.compile(method) 143 | reparsed = compiled.parse(path) 144 | if reparsed is not None: 145 | possibilities.append(method) 146 | 147 | if len(possibilities) == 0: 148 | return None 149 | 150 | # Return only best possibility 151 | return sorted(possibilities, key=len)[-1] 152 | 153 | -------------------------------------------------------------------------------- /pytea/resources.py: -------------------------------------------------------------------------------- 1 | resources = { 2 | u'/user/times': { 3 | u'get': { 4 | 'parameters': {} 5 | } 6 | }, 7 | u'/repos/{owner}/{repo}/issues/{index}/times': { 8 | u'post': { 9 | 'parameters': { 10 | u'owner': True, 11 | u'repo': True, 12 | u'body': False, 13 | u'id': True 14 | } 15 | }, 16 | u'get': { 17 | 'parameters': { 18 | u'owner': True, 19 | u'repo': True 20 | } 21 | } 22 | }, 23 | u'/repos/{owner}/{repo}/statuses/{sha}': { 24 | u'post': { 25 | 'parameters': { 26 | u'owner': True, 27 | u'repo': True, 28 | u'body': False, 29 | u'sha': True 30 | } 31 | }, 32 | u'get': { 33 | 'parameters': { 34 | u'owner': True, 35 | u'repo': True, 36 | u'sha': True 37 | } 38 | } 39 | }, 40 | u'/orgs/{org}/members': { 41 | u'get': { 42 | 'parameters': { 43 | u'org': True 44 | } 45 | } 46 | }, 47 | u'/users/search': { 48 | u'get': { 49 | 'parameters': { 50 | u'q': False, 51 | u'limit': False 52 | } 53 | } 54 | }, 55 | u'/repos/{owner}/{repo}/branches/{branch}': { 56 | u'get': { 57 | 'parameters': { 58 | u'owner': True, 59 | u'repo': True, 60 | u'branch': True 61 | } 62 | } 63 | }, 64 | u'/users/{username}/repos': { 65 | u'get': { 66 | 'parameters': { 67 | u'username': True 68 | } 69 | } 70 | }, 71 | u'/repos/{owner}/{repo}/issues/comments/{id}': { 72 | u'delete': { 73 | 'parameters': { 74 | u'owner': True, 75 | u'repo': True, 76 | u'id': True 77 | } 78 | }, 79 | u'patch': { 80 | 'parameters': { 81 | u'owner': True, 82 | u'repo': True, 83 | u'body': False, 84 | u'id': True 85 | } 86 | } 87 | }, 88 | u'/admin/users/{username}/orgs': { 89 | u'post': { 90 | 'parameters': { 91 | u'username': True 92 | } 93 | } 94 | }, 95 | u'/user/gpg_keys': { 96 | u'post': { 97 | 'parameters': { 98 | u'Form': False 99 | } 100 | }, 101 | u'get': { 102 | 'parameters': {} 103 | } 104 | }, 105 | u'/repos/{owner}/{repo}/keys/{id}': { 106 | u'get': { 107 | 'parameters': { 108 | u'owner': True, 109 | u'repo': True, 110 | u'id': True 111 | } 112 | }, 113 | u'delete': { 114 | 'parameters': { 115 | u'owner': True, 116 | u'repo': True, 117 | u'id': True 118 | } 119 | } 120 | }, 121 | u'/repos/{owner}/{repo}/keys': { 122 | u'post': { 123 | 'parameters': { 124 | u'owner': True, 125 | u'repo': True, 126 | u'body': False 127 | } 128 | }, 129 | u'get': { 130 | 'parameters': { 131 | u'owner': True, 132 | u'repo': True 133 | } 134 | } 135 | }, 136 | u'/orgs/{org}/public_members': { 137 | u'get': { 138 | 'parameters': { 139 | u'org': True 140 | } 141 | } 142 | }, 143 | u'/teams/{id}': { 144 | u'get': { 145 | 'parameters': { 146 | u'id': True 147 | } 148 | }, 149 | u'delete': { 150 | 'parameters': { 151 | u'id': True 152 | } 153 | }, 154 | u'patch': { 155 | 'parameters': { 156 | u'body': False, 157 | u'id': True 158 | } 159 | } 160 | }, 161 | u'/user/gpg_keys/{id}': { 162 | u'get': { 163 | 'parameters': { 164 | u'id': True 165 | } 166 | }, 167 | u'delete': { 168 | 'parameters': { 169 | u'id': True 170 | } 171 | } 172 | }, 173 | u'/repos/{owner}/{repo}': { 174 | u'get': { 175 | 'parameters': { 176 | u'owner': True, 177 | u'repo': True 178 | } 179 | }, 180 | u'delete': { 181 | 'parameters': { 182 | u'owner': True, 183 | u'repo': True 184 | } 185 | } 186 | }, 187 | u'/repos/{owner}/{repo}/times': { 188 | u'get': { 189 | 'parameters': { 190 | u'owner': True, 191 | u'repo': True 192 | } 193 | } 194 | }, 195 | u'/users/{username}/tokens': { 196 | u'post': { 197 | 'parameters': { 198 | u'name': False 199 | } 200 | }, 201 | u'get': { 202 | 'parameters': {} 203 | } 204 | }, 205 | u'/user/following/{username}': { 206 | u'put': { 207 | 'parameters': { 208 | u'username': True 209 | } 210 | }, 211 | u'delete': { 212 | 'parameters': { 213 | u'username': True 214 | } 215 | } 216 | }, 217 | u'/teams/{id}/repos': { 218 | u'get': { 219 | 'parameters': { 220 | u'id': True 221 | } 222 | } 223 | }, 224 | u'/markdown/raw': { 225 | u'post': { 226 | 'parameters': { 227 | u'body': False 228 | } 229 | } 230 | }, 231 | u'/orgs/{org}': { 232 | u'get': { 233 | 'parameters': { 234 | u'org': True 235 | } 236 | }, 237 | u'patch': { 238 | 'parameters': { 239 | u'body': False, 240 | u'org': True 241 | } 242 | } 243 | }, 244 | u'/users/{username}/followers': { 245 | u'get': { 246 | 'parameters': { 247 | u'username': True 248 | } 249 | } 250 | }, 251 | u'/repos/{owner}/{repo}/releases': { 252 | u'get': { 253 | 'parameters': { 254 | u'owner': True, 255 | u'repo': True, 256 | u'body': False 257 | } 258 | } 259 | }, 260 | u'/teams/{id}/members/{username}': { 261 | u'put': { 262 | 'parameters': { 263 | u'username': True, 264 | u'id': True 265 | } 266 | }, 267 | u'delete': { 268 | 'parameters': { 269 | u'username': True, 270 | u'id': True 271 | } 272 | } 273 | }, 274 | u'/repos/{owner}/{repo}/milestones': { 275 | u'post': { 276 | 'parameters': { 277 | u'owner': True, 278 | u'repo': True, 279 | u'body': False 280 | } 281 | }, 282 | u'get': { 283 | 'parameters': { 284 | u'owner': True, 285 | u'repo': True, 286 | u'id': True 287 | } 288 | } 289 | }, 290 | u'/repos/{owner}/{repo}/collaborators': { 291 | u'get': { 292 | 'parameters': { 293 | u'owner': True, 294 | u'repo': True 295 | } 296 | } 297 | }, 298 | u'/repos/{owner}/{repo}/releases/{id}': { 299 | u'delete': { 300 | 'parameters': { 301 | u'owner': True, 302 | u'repo': True, 303 | u'id': True 304 | } 305 | }, 306 | u'patch': { 307 | 'parameters': { 308 | u'owner': True, 309 | u'repo': True, 310 | u'body': False, 311 | u'id': True 312 | } 313 | } 314 | }, 315 | u'/repos/{owner}/{repo}/subscription': { 316 | u'put': { 317 | 'parameters': { 318 | u'owner': True, 319 | u'repo': True 320 | } 321 | }, 322 | u'get': { 323 | 'parameters': { 324 | u'owner': True, 325 | u'repo': True 326 | } 327 | }, 328 | u'delete': { 329 | 'parameters': { 330 | u'owner': True, 331 | u'repo': True 332 | } 333 | } 334 | }, 335 | u'/repos/{owner}/{repo}/issues/comments': { 336 | u'get': { 337 | 'parameters': { 338 | u'owner': True, 339 | u'repo': True, 340 | u'string': False 341 | } 342 | } 343 | }, 344 | u'/teams/{id}/members': { 345 | u'get': { 346 | 'parameters': { 347 | u'id': True 348 | } 349 | } 350 | }, 351 | u'/repos/{owner}/{repo}/raw/{filepath}': { 352 | u'get': { 353 | 'parameters': { 354 | u'owner': True, 355 | u'repo': True, 356 | u'filepath': True 357 | } 358 | } 359 | }, 360 | u'/orgs/{org}/hooks': { 361 | u'get': { 362 | 'parameters': {} 363 | } 364 | }, 365 | u'/repos/{owner}/{repo}/issue/{index}/labels/{id}': { 366 | u'delete': { 367 | 'parameters': { 368 | u'owner': True, 369 | u'repo': True, 370 | u'id': True, 371 | u'index': True 372 | } 373 | } 374 | }, 375 | u'/repos/{owner}/{repo}/branches': { 376 | u'get': { 377 | 'parameters': { 378 | u'owner': True, 379 | u'repo': True 380 | } 381 | } 382 | }, 383 | u'/users/{username}': { 384 | u'get': { 385 | 'parameters': { 386 | u'username': True 387 | } 388 | } 389 | }, 390 | u'/user/orgs': { 391 | u'get': { 392 | 'parameters': {} 393 | } 394 | }, 395 | u'/repos/{owner}/{repo}/hooks': { 396 | u'post': { 397 | 'parameters': { 398 | u'owner': True, 399 | u'repo': True, 400 | u'body': False 401 | } 402 | }, 403 | u'get': { 404 | 'parameters': { 405 | u'owner': True, 406 | u'repo': True 407 | } 408 | } 409 | }, 410 | u'/repos/{owner}/{repo}/subscribers': { 411 | u'get': { 412 | 'parameters': { 413 | u'owner': True, 414 | u'repo': True 415 | } 416 | } 417 | }, 418 | u'/admin/users': { 419 | u'post': { 420 | 'parameters': { 421 | u'body': False 422 | } 423 | } 424 | }, 425 | u'/orgs/{org}/repos': { 426 | u'get': { 427 | 'parameters': { 428 | u'org': True 429 | } 430 | } 431 | }, 432 | u'/users/{username}/following': { 433 | u'get': { 434 | 'parameters': { 435 | u'username': True 436 | } 437 | } 438 | }, 439 | u'/repos/{owner}/{repo}/mirror-sync': { 440 | u'post': { 441 | 'parameters': { 442 | u'owner': True, 443 | u'repo': True 444 | } 445 | } 446 | }, 447 | u'/repos/{owner}/{repo}/editorconfig/{filepath}': { 448 | u'get': { 449 | 'parameters': { 450 | u'owner': True, 451 | u'repo': True, 452 | u'filepath': True 453 | } 454 | } 455 | }, 456 | u'/user/following': { 457 | u'get': { 458 | 'parameters': {} 459 | } 460 | }, 461 | u'/admin/users/{username}/repos': { 462 | u'post': { 463 | 'parameters': { 464 | u'username': True 465 | } 466 | } 467 | }, 468 | u'/org/{org}/repos': { 469 | u'post': { 470 | 'parameters': { 471 | u'body': False, 472 | u'org': True 473 | } 474 | } 475 | }, 476 | u'/repos/{owner}/{repo}/issue/{index}/labels': { 477 | u'put': { 478 | 'parameters': { 479 | u'owner': True, 480 | u'repo': True, 481 | u'body': False, 482 | u'index': True 483 | } 484 | }, 485 | u'post': { 486 | 'parameters': { 487 | u'owner': True, 488 | u'repo': True, 489 | u'body': False, 490 | u'index': True 491 | } 492 | }, 493 | u'delete': { 494 | 'parameters': { 495 | u'owner': True, 496 | u'repo': True, 497 | u'index': True 498 | } 499 | } 500 | }, 501 | u'/repos/{owner}/{repo}/pulls/{index}/merge': { 502 | u'post': { 503 | 'parameters': { 504 | u'owner': True, 505 | u'repo': True, 506 | u'index': True 507 | } 508 | }, 509 | u'get': { 510 | 'parameters': { 511 | u'owner': True, 512 | u'repo': True, 513 | u'index': True 514 | } 515 | } 516 | }, 517 | u'/user/repos': { 518 | u'post': { 519 | 'parameters': { 520 | u'body': False 521 | } 522 | }, 523 | u'get': { 524 | 'parameters': {} 525 | } 526 | }, 527 | u'/users/{follower}/following/{followee}': { 528 | u'get': { 529 | 'parameters': { 530 | u'follower': True, 531 | u'followee': True 532 | } 533 | } 534 | }, 535 | u'/repos/{owner}/{repo}/collaborators/{collaborator}': { 536 | u'put': { 537 | 'parameters': { 538 | u'owner': True, 539 | u'repo': True, 540 | u'body': False, 541 | u'collaborator': True 542 | } 543 | }, 544 | u'get': { 545 | 'parameters': { 546 | u'owner': True, 547 | u'repo': True, 548 | u'collaborator': True 549 | } 550 | }, 551 | u'delete': { 552 | 'parameters': { 553 | u'owner': True, 554 | u'repo': True, 555 | u'collaborator': True 556 | } 557 | } 558 | }, 559 | u'/user/keys': { 560 | u'post': { 561 | 'parameters': { 562 | u'body': False 563 | } 564 | }, 565 | u'get': { 566 | 'parameters': {} 567 | } 568 | }, 569 | u'/repos/{owner}/{repo}/times/{tracker}': { 570 | u'get': { 571 | 'parameters': { 572 | u'owner': True, 573 | u'repo': True, 574 | u'user': True 575 | } 576 | } 577 | }, 578 | u'/repos/search': { 579 | u'get': { 580 | 'parameters': { 581 | u'exclusive': False, 582 | u'uid': False, 583 | u'q': False, 584 | u'limit': False, 585 | u'mode': False, 586 | u'page': False 587 | } 588 | } 589 | }, 590 | u'/users/{username}/gpg_keys': { 591 | u'get': { 592 | 'parameters': { 593 | u'username': True 594 | } 595 | } 596 | }, 597 | u'/orgs/{org}/hooks/': { 598 | u'post': { 599 | 'parameters': {} 600 | } 601 | }, 602 | u'/user/subscriptions': { 603 | u'get': { 604 | 'parameters': {} 605 | } 606 | }, 607 | u'/markdown': { 608 | u'post': { 609 | 'parameters': { 610 | u'body': False 611 | } 612 | } 613 | }, 614 | u'/repos/{owner}/{repo}/issue/{index}/comments': { 615 | u'get': { 616 | 'parameters': { 617 | u'owner': True, 618 | u'repo': True, 619 | u'id': True, 620 | u'string': False 621 | } 622 | } 623 | }, 624 | u'/orgs/{org}/teams': { 625 | u'post': { 626 | 'parameters': { 627 | u'body': False, 628 | u'org': True 629 | } 630 | }, 631 | u'get': { 632 | 'parameters': { 633 | u'org': True 634 | } 635 | } 636 | }, 637 | u'/user/emails': { 638 | u'post': { 639 | 'parameters': { 640 | u'body': False 641 | } 642 | }, 643 | u'get': { 644 | 'parameters': {} 645 | }, 646 | u'delete': { 647 | 'parameters': { 648 | u'body': False 649 | } 650 | } 651 | }, 652 | u'/repos/{owner}/{repo}/issues': { 653 | u'post': { 654 | 'parameters': { 655 | u'owner': True, 656 | u'repo': True, 657 | u'body': False 658 | } 659 | }, 660 | u'get': { 661 | 'parameters': { 662 | u'owner': True, 663 | u'repo': True, 664 | u'state': False, 665 | u'page': False 666 | } 667 | } 668 | }, 669 | u'/user/following/{followee}': { 670 | u'get': { 671 | 'parameters': { 672 | u'followee': True 673 | } 674 | } 675 | }, 676 | u'/user/{username}/orgs': { 677 | u'get': { 678 | 'parameters': { 679 | u'username': False 680 | } 681 | } 682 | }, 683 | u'/repos/migrate': { 684 | u'post': { 685 | 'parameters': { 686 | u'body': False 687 | } 688 | } 689 | }, 690 | u'/users/{username}/subscriptions': { 691 | u'get': { 692 | 'parameters': { 693 | u'username': False 694 | } 695 | } 696 | }, 697 | u'/user/starred/{owner}/{repo}': { 698 | u'put': { 699 | 'parameters': { 700 | u'owner': True, 701 | u'repo': True 702 | } 703 | }, 704 | u'get': { 705 | 'parameters': { 706 | u'owner': True, 707 | u'repo': True 708 | } 709 | }, 710 | u'delete': { 711 | 'parameters': { 712 | u'owner': True, 713 | u'repo': True 714 | } 715 | } 716 | }, 717 | u'/orgs/{org}/hooks/{id}': { 718 | u'get': { 719 | 'parameters': {} 720 | }, 721 | u'delete': { 722 | 'parameters': {} 723 | }, 724 | u'patch': { 725 | 'parameters': {} 726 | } 727 | }, 728 | u'/repos/{owner}/{repo}/hooks/{id}': { 729 | u'get': { 730 | 'parameters': { 731 | u'owner': True, 732 | u'repo': True, 733 | u'id': True 734 | } 735 | }, 736 | u'patch': { 737 | 'parameters': { 738 | u'owner': True, 739 | u'repo': True, 740 | u'body': False 741 | } 742 | } 743 | }, 744 | u'/repos/{owner}/{repo}/archive/{filepath}': { 745 | u'get': { 746 | 'parameters': { 747 | u'owner': True, 748 | u'repo': True, 749 | u'archive': True 750 | } 751 | } 752 | }, 753 | u'/repos/{owner}/{repo}/stargazers': { 754 | u'get': { 755 | 'parameters': { 756 | u'owner': True, 757 | u'repo': True 758 | } 759 | } 760 | }, 761 | u'/user/keys/{id}': { 762 | u'get': { 763 | 'parameters': { 764 | u'id': True 765 | } 766 | }, 767 | u'delete': { 768 | 'parameters': { 769 | u'id': True 770 | } 771 | } 772 | }, 773 | u'/user': { 774 | u'get': { 775 | 'parameters': {} 776 | } 777 | }, 778 | u'/admin/users/{username}': { 779 | u'delete': { 780 | 'parameters': { 781 | u'username': True 782 | } 783 | }, 784 | u'patch': { 785 | 'parameters': { 786 | u'username': True, 787 | u'body': False 788 | } 789 | } 790 | }, 791 | u'/repos/{owner}/{repo}/milestones/{id}': { 792 | u'get': { 793 | 'parameters': {} 794 | }, 795 | u'delete': { 796 | 'parameters': { 797 | u'owner': True, 798 | u'repo': True, 799 | u'body': True 800 | } 801 | }, 802 | u'patch': { 803 | 'parameters': { 804 | u'owner': True, 805 | u'repo': True, 806 | u'body': False 807 | } 808 | } 809 | }, 810 | u'/admin/users/{username}/keys': { 811 | u'post': { 812 | 'parameters': { 813 | u'username': True 814 | } 815 | } 816 | }, 817 | u'/orgs/{org}/members/{username}': { 818 | u'get': { 819 | 'parameters': { 820 | u'username': True, 821 | u'org': True 822 | } 823 | }, 824 | u'delete': { 825 | 'parameters': { 826 | u'username': True, 827 | u'org': True 828 | } 829 | } 830 | }, 831 | u'/orgs/{org}/public_members/{username}': { 832 | u'put': { 833 | 'parameters': { 834 | u'username': True, 835 | u'org': True 836 | } 837 | }, 838 | u'get': { 839 | 'parameters': { 840 | u'username': True, 841 | u'org': True 842 | } 843 | }, 844 | u'delete': { 845 | 'parameters': { 846 | u'username': True, 847 | u'org': True 848 | } 849 | } 850 | }, 851 | u'/repos/{owner}/{repo}/commits/{ref}/statuses': { 852 | u'get': { 853 | 'parameters': { 854 | u'owner': True, 855 | u'repo': True, 856 | u'ref': True 857 | } 858 | } 859 | }, 860 | u'/users/{username}/keys': { 861 | u'get': { 862 | 'parameters': { 863 | u'username': True 864 | } 865 | } 866 | }, 867 | u'/repos/{owner}/{repo}/labels': { 868 | u'post': { 869 | 'parameters': { 870 | u'owner': True, 871 | u'repo': True, 872 | u'body': False 873 | } 874 | }, 875 | u'get': { 876 | 'parameters': { 877 | u'owner': True, 878 | u'repo': True 879 | } 880 | } 881 | }, 882 | u'/repos/{owner}/{repo}/issues/{index}': { 883 | u'get': { 884 | 'parameters': { 885 | u'owner': True, 886 | u'repo': True, 887 | u'index': True 888 | } 889 | }, 890 | u'patch': { 891 | 'parameters': { 892 | u'owner': True, 893 | u'repo': True, 894 | u'body': False, 895 | u'index': True 896 | } 897 | } 898 | }, 899 | u'/repos/{owner}/{repo}/issues/{index}/labels': { 900 | u'get': { 901 | 'parameters': { 902 | u'owner': True, 903 | u'repo': True, 904 | u'index': True 905 | } 906 | } 907 | }, 908 | u'/repos/{owner}/{repo}/forks': { 909 | u'post': { 910 | 'parameters': { 911 | u'owner': True, 912 | u'repo': True, 913 | u'body': False 914 | } 915 | }, 916 | u'get': { 917 | 'parameters': { 918 | u'owner': True, 919 | u'repo': True 920 | } 921 | } 922 | }, 923 | u'/repos/{owner}/{repo}/pulls': { 924 | u'post': { 925 | 'parameters': { 926 | u'owner': True, 927 | u'repo': True, 928 | u'body': False 929 | } 930 | }, 931 | u'get': { 932 | 'parameters': { 933 | u'owner': True, 934 | u'repo': True 935 | } 936 | } 937 | }, 938 | u'/user/starred': { 939 | u'get': { 940 | 'parameters': {} 941 | } 942 | }, 943 | u'/repos/{owner}/{repo}/pulls/{index}': { 944 | u'get': { 945 | 'parameters': { 946 | u'owner': True, 947 | u'repo': True, 948 | u'index': True 949 | } 950 | }, 951 | u'patch': { 952 | 'parameters': { 953 | u'owner': True, 954 | u'repo': True, 955 | u'body': False, 956 | u'index': True 957 | } 958 | } 959 | }, 960 | u'/repos/{owner}/{repo}/labels/{id}': { 961 | u'get': { 962 | 'parameters': { 963 | u'owner': True, 964 | u'repo': True, 965 | u'id': True 966 | } 967 | }, 968 | u'delete': { 969 | 'parameters': { 970 | u'owner': True, 971 | u'repo': True, 972 | u'id': True 973 | } 974 | }, 975 | u'patch': { 976 | 'parameters': { 977 | u'owner': True, 978 | u'repo': True, 979 | u'body': False, 980 | u'id': True 981 | } 982 | } 983 | }, 984 | u'/repositories/{id}': { 985 | u'get': { 986 | 'parameters': { 987 | u'id': True 988 | } 989 | } 990 | }, 991 | u'/repos/{user}/{repo}/hooks/{id}': { 992 | u'delete': { 993 | 'parameters': { 994 | u'owner': True, 995 | u'repo': True, 996 | u'id': True 997 | } 998 | } 999 | }, 1000 | u'/repos/{owner}/{repo}/issues/{index}/comments': { 1001 | u'post': { 1002 | 'parameters': { 1003 | u'owner': True, 1004 | u'repo': True, 1005 | u'body': False, 1006 | u'id': True 1007 | } 1008 | } 1009 | }, 1010 | u'/admin/users/{username}/keys/{id}': { 1011 | u'delete': { 1012 | 'parameters': { 1013 | u'username': True, 1014 | u'id': True 1015 | } 1016 | } 1017 | }, 1018 | u'/users/{username}/starred': { 1019 | u'get': { 1020 | 'parameters': { 1021 | u'username': True 1022 | } 1023 | } 1024 | }, 1025 | u'/user/followers': { 1026 | u'get': { 1027 | 'parameters': {} 1028 | } 1029 | }, 1030 | u'/repos/{owner}/{repo}/issues/{index}/comments/{id}': { 1031 | u'delete': { 1032 | 'parameters': { 1033 | u'owner': True, 1034 | u'repo': True, 1035 | u'id': True, 1036 | u'index': True 1037 | } 1038 | }, 1039 | u'patch': { 1040 | 'parameters': { 1041 | u'owner': True, 1042 | u'repo': True, 1043 | u'body': False, 1044 | u'id': True, 1045 | u'index': True 1046 | } 1047 | } 1048 | }, 1049 | u'/teams/{id}/repos/{org}/{repo}': { 1050 | u'put': { 1051 | 'parameters': { 1052 | u'repo': True, 1053 | u'org': True, 1054 | u'id': True 1055 | } 1056 | }, 1057 | u'delete': { 1058 | 'parameters': { 1059 | u'repo': True, 1060 | u'org': True, 1061 | u'id': True 1062 | } 1063 | } 1064 | }, 1065 | u'/version': { 1066 | u'get': { 1067 | 'parameters': {} 1068 | } 1069 | } 1070 | } 1071 | --------------------------------------------------------------------------------