1
- from gitlab import cli
1
+ from typing import Any , Callable , cast , Dict , List , Optional , TYPE_CHECKING , Union
2
+
3
+ import requests
4
+
5
+ from gitlab import cli , client
2
6
from gitlab import exceptions as exc
3
7
from gitlab import types , utils
4
8
from gitlab .base import RequiredOptional , RESTManager , RESTObject
@@ -163,7 +167,7 @@ class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTO
163
167
164
168
@cli .register_custom_action ("Project" , ("forked_from_id" ,))
165
169
@exc .on_http_error (exc .GitlabCreateError )
166
- def create_fork_relation (self , forked_from_id , ** kwargs ) :
170
+ def create_fork_relation (self , forked_from_id : int , ** kwargs : Any ) -> None :
167
171
"""Create a forked from/to relation between existing projects.
168
172
169
173
Args:
@@ -179,7 +183,7 @@ def create_fork_relation(self, forked_from_id, **kwargs):
179
183
180
184
@cli .register_custom_action ("Project" )
181
185
@exc .on_http_error (exc .GitlabDeleteError )
182
- def delete_fork_relation (self , ** kwargs ) :
186
+ def delete_fork_relation (self , ** kwargs : Any ) -> None :
183
187
"""Delete a forked relation between existing projects.
184
188
185
189
Args:
@@ -194,7 +198,7 @@ def delete_fork_relation(self, **kwargs):
194
198
195
199
@cli .register_custom_action ("Project" )
196
200
@exc .on_http_error (exc .GitlabGetError )
197
- def languages (self , ** kwargs ) :
201
+ def languages (self , ** kwargs : Any ) -> Union [ Dict [ str , Any ], requests . Response ] :
198
202
"""Get languages used in the project with percentage value.
199
203
200
204
Args:
@@ -209,7 +213,7 @@ def languages(self, **kwargs):
209
213
210
214
@cli .register_custom_action ("Project" )
211
215
@exc .on_http_error (exc .GitlabCreateError )
212
- def star (self , ** kwargs ) :
216
+ def star (self , ** kwargs : Any ) -> None :
213
217
"""Star a project.
214
218
215
219
Args:
@@ -221,11 +225,13 @@ def star(self, **kwargs):
221
225
"""
222
226
path = "/projects/%s/star" % self .get_id ()
223
227
server_data = self .manager .gitlab .http_post (path , ** kwargs )
228
+ if TYPE_CHECKING :
229
+ assert isinstance (server_data , dict )
224
230
self ._update_attrs (server_data )
225
231
226
232
@cli .register_custom_action ("Project" )
227
233
@exc .on_http_error (exc .GitlabDeleteError )
228
- def unstar (self , ** kwargs ) :
234
+ def unstar (self , ** kwargs : Any ) -> None :
229
235
"""Unstar a project.
230
236
231
237
Args:
@@ -237,11 +243,13 @@ def unstar(self, **kwargs):
237
243
"""
238
244
path = "/projects/%s/unstar" % self .get_id ()
239
245
server_data = self .manager .gitlab .http_post (path , ** kwargs )
246
+ if TYPE_CHECKING :
247
+ assert isinstance (server_data , dict )
240
248
self ._update_attrs (server_data )
241
249
242
250
@cli .register_custom_action ("Project" )
243
251
@exc .on_http_error (exc .GitlabCreateError )
244
- def archive (self , ** kwargs ) :
252
+ def archive (self , ** kwargs : Any ) -> None :
245
253
"""Archive a project.
246
254
247
255
Args:
@@ -253,11 +261,13 @@ def archive(self, **kwargs):
253
261
"""
254
262
path = "/projects/%s/archive" % self .get_id ()
255
263
server_data = self .manager .gitlab .http_post (path , ** kwargs )
264
+ if TYPE_CHECKING :
265
+ assert isinstance (server_data , dict )
256
266
self ._update_attrs (server_data )
257
267
258
268
@cli .register_custom_action ("Project" )
259
269
@exc .on_http_error (exc .GitlabDeleteError )
260
- def unarchive (self , ** kwargs ) :
270
+ def unarchive (self , ** kwargs : Any ) -> None :
261
271
"""Unarchive a project.
262
272
263
273
Args:
@@ -269,13 +279,21 @@ def unarchive(self, **kwargs):
269
279
"""
270
280
path = "/projects/%s/unarchive" % self .get_id ()
271
281
server_data = self .manager .gitlab .http_post (path , ** kwargs )
282
+ if TYPE_CHECKING :
283
+ assert isinstance (server_data , dict )
272
284
self ._update_attrs (server_data )
273
285
274
286
@cli .register_custom_action (
275
287
"Project" , ("group_id" , "group_access" ), ("expires_at" ,)
276
288
)
277
289
@exc .on_http_error (exc .GitlabCreateError )
278
- def share (self , group_id , group_access , expires_at = None , ** kwargs ):
290
+ def share (
291
+ self ,
292
+ group_id : int ,
293
+ group_access : int ,
294
+ expires_at : Optional [str ] = None ,
295
+ ** kwargs : Any
296
+ ) -> None :
279
297
"""Share the project with a group.
280
298
281
299
Args:
@@ -297,7 +315,7 @@ def share(self, group_id, group_access, expires_at=None, **kwargs):
297
315
298
316
@cli .register_custom_action ("Project" , ("group_id" ,))
299
317
@exc .on_http_error (exc .GitlabDeleteError )
300
- def unshare (self , group_id , ** kwargs ) :
318
+ def unshare (self , group_id : int , ** kwargs : Any ) -> None :
301
319
"""Delete a shared project link within a group.
302
320
303
321
Args:
@@ -314,7 +332,13 @@ def unshare(self, group_id, **kwargs):
314
332
# variables not supported in CLI
315
333
@cli .register_custom_action ("Project" , ("ref" , "token" ))
316
334
@exc .on_http_error (exc .GitlabCreateError )
317
- def trigger_pipeline (self , ref , token , variables = None , ** kwargs ):
335
+ def trigger_pipeline (
336
+ self ,
337
+ ref : str ,
338
+ token : str ,
339
+ variables : Optional [Dict [str , Any ]] = None ,
340
+ ** kwargs : Any
341
+ ) -> ProjectPipeline :
318
342
"""Trigger a CI build.
319
343
320
344
See https://gitlab.com/help/ci/triggers/README.md#trigger-a-build
@@ -333,11 +357,13 @@ def trigger_pipeline(self, ref, token, variables=None, **kwargs):
333
357
path = "/projects/%s/trigger/pipeline" % self .get_id ()
334
358
post_data = {"ref" : ref , "token" : token , "variables" : variables }
335
359
attrs = self .manager .gitlab .http_post (path , post_data = post_data , ** kwargs )
360
+ if TYPE_CHECKING :
361
+ assert isinstance (attrs , dict )
336
362
return ProjectPipeline (self .pipelines , attrs )
337
363
338
364
@cli .register_custom_action ("Project" )
339
365
@exc .on_http_error (exc .GitlabHousekeepingError )
340
- def housekeeping (self , ** kwargs ) :
366
+ def housekeeping (self , ** kwargs : Any ) -> None :
341
367
"""Start the housekeeping task.
342
368
343
369
Args:
@@ -354,7 +380,13 @@ def housekeeping(self, **kwargs):
354
380
# see #56 - add file attachment features
355
381
@cli .register_custom_action ("Project" , ("filename" , "filepath" ))
356
382
@exc .on_http_error (exc .GitlabUploadError )
357
- def upload (self , filename , filedata = None , filepath = None , ** kwargs ):
383
+ def upload (
384
+ self ,
385
+ filename : str ,
386
+ filedata : Optional [bytes ] = None ,
387
+ filepath : Optional [str ] = None ,
388
+ ** kwargs : Any
389
+ ) -> Dict [str , Any ]:
358
390
"""Upload the specified file into the project.
359
391
360
392
.. note::
@@ -394,13 +426,20 @@ def upload(self, filename, filedata=None, filepath=None, **kwargs):
394
426
file_info = {"file" : (filename , filedata )}
395
427
data = self .manager .gitlab .http_post (url , files = file_info )
396
428
429
+ if TYPE_CHECKING :
430
+ assert isinstance (data , dict )
397
431
return {"alt" : data ["alt" ], "url" : data ["url" ], "markdown" : data ["markdown" ]}
398
432
399
433
@cli .register_custom_action ("Project" , optional = ("wiki" ,))
400
434
@exc .on_http_error (exc .GitlabGetError )
401
435
def snapshot (
402
- self , wiki = False , streamed = False , action = None , chunk_size = 1024 , ** kwargs
403
- ):
436
+ self ,
437
+ wiki : bool = False ,
438
+ streamed : bool = False ,
439
+ action : Optional [Callable ] = None ,
440
+ chunk_size : int = 1024 ,
441
+ ** kwargs : Any
442
+ ) -> Optional [bytes ]:
404
443
"""Return a snapshot of the repository.
405
444
406
445
Args:
@@ -424,11 +463,15 @@ def snapshot(
424
463
result = self .manager .gitlab .http_get (
425
464
path , streamed = streamed , raw = True , ** kwargs
426
465
)
466
+ if TYPE_CHECKING :
467
+ assert isinstance (result , requests .Response )
427
468
return utils .response_content (result , streamed , action , chunk_size )
428
469
429
470
@cli .register_custom_action ("Project" , ("scope" , "search" ))
430
471
@exc .on_http_error (exc .GitlabSearchError )
431
- def search (self , scope , search , ** kwargs ):
472
+ def search (
473
+ self , scope : str , search : str , ** kwargs : Any
474
+ ) -> Union [client .GitlabList , List [Dict [str , Any ]]]:
432
475
"""Search the project resources matching the provided string.'
433
476
434
477
Args:
@@ -449,7 +492,7 @@ def search(self, scope, search, **kwargs):
449
492
450
493
@cli .register_custom_action ("Project" )
451
494
@exc .on_http_error (exc .GitlabCreateError )
452
- def mirror_pull (self , ** kwargs ) :
495
+ def mirror_pull (self , ** kwargs : Any ) -> None :
453
496
"""Start the pull mirroring process for the project.
454
497
455
498
Args:
@@ -464,7 +507,7 @@ def mirror_pull(self, **kwargs):
464
507
465
508
@cli .register_custom_action ("Project" , ("to_namespace" ,))
466
509
@exc .on_http_error (exc .GitlabTransferProjectError )
467
- def transfer_project (self , to_namespace , ** kwargs ) :
510
+ def transfer_project (self , to_namespace : str , ** kwargs : Any ) -> None :
468
511
"""Transfer a project to the given namespace ID
469
512
470
513
Args:
@@ -484,8 +527,14 @@ def transfer_project(self, to_namespace, **kwargs):
484
527
@cli .register_custom_action ("Project" , ("ref_name" , "job" ), ("job_token" ,))
485
528
@exc .on_http_error (exc .GitlabGetError )
486
529
def artifacts (
487
- self , ref_name , job , streamed = False , action = None , chunk_size = 1024 , ** kwargs
488
- ):
530
+ self ,
531
+ ref_name : str ,
532
+ job : str ,
533
+ streamed : bool = False ,
534
+ action : Optional [Callable ] = None ,
535
+ chunk_size : int = 1024 ,
536
+ ** kwargs : Any
537
+ ) -> Optional [bytes ]:
489
538
"""Get the job artifacts archive from a specific tag or branch.
490
539
491
540
Args:
@@ -513,20 +562,22 @@ def artifacts(
513
562
result = self .manager .gitlab .http_get (
514
563
path , job = job , streamed = streamed , raw = True , ** kwargs
515
564
)
565
+ if TYPE_CHECKING :
566
+ assert isinstance (result , requests .Response )
516
567
return utils .response_content (result , streamed , action , chunk_size )
517
568
518
569
@cli .register_custom_action ("Project" , ("ref_name" , "artifact_path" , "job" ))
519
570
@exc .on_http_error (exc .GitlabGetError )
520
571
def artifact (
521
572
self ,
522
- ref_name ,
523
- artifact_path ,
524
- job ,
525
- streamed = False ,
526
- action = None ,
527
- chunk_size = 1024 ,
528
- ** kwargs
529
- ):
573
+ ref_name : str ,
574
+ artifact_path : str ,
575
+ job : str ,
576
+ streamed : bool = False ,
577
+ action : Optional [ Callable ] = None ,
578
+ chunk_size : int = 1024 ,
579
+ ** kwargs : Any
580
+ ) -> Optional [ bytes ] :
530
581
"""Download a single artifact file from a specific tag or branch from within the job’s artifacts archive.
531
582
532
583
Args:
@@ -558,6 +609,8 @@ def artifact(
558
609
result = self .manager .gitlab .http_get (
559
610
path , streamed = streamed , raw = True , ** kwargs
560
611
)
612
+ if TYPE_CHECKING :
613
+ assert isinstance (result , requests .Response )
561
614
return utils .response_content (result , streamed , action , chunk_size )
562
615
563
616
@@ -725,16 +778,19 @@ class ProjectManager(CRUDMixin, RESTManager):
725
778
)
726
779
_types = {"avatar" : types .ImageAttribute , "topic" : types .ListAttribute }
727
780
781
+ def get (self , id : Union [str , int ], lazy : bool = False , ** kwargs : Any ) -> Project :
782
+ return cast (Project , super ().get (id = id , lazy = lazy , ** kwargs ))
783
+
728
784
def import_project (
729
785
self ,
730
- file ,
731
- path ,
732
- name = None ,
733
- namespace = None ,
734
- overwrite = False ,
735
- override_params = None ,
736
- ** kwargs
737
- ):
786
+ file : str ,
787
+ path : str ,
788
+ name : Optional [ str ] = None ,
789
+ namespace : Optional [ str ] = None ,
790
+ overwrite : bool = False ,
791
+ override_params : Optional [ Dict [ str , Any ]] = None ,
792
+ ** kwargs : Any
793
+ ) -> Union [ Dict [ str , Any ], requests . Response ] :
738
794
"""Import a project from an archive file.
739
795
740
796
Args:
@@ -769,15 +825,15 @@ def import_project(
769
825
770
826
def import_bitbucket_server (
771
827
self ,
772
- bitbucket_server_url ,
773
- bitbucket_server_username ,
774
- personal_access_token ,
775
- bitbucket_server_project ,
776
- bitbucket_server_repo ,
777
- new_name = None ,
778
- target_namespace = None ,
779
- ** kwargs
780
- ):
828
+ bitbucket_server_url : str ,
829
+ bitbucket_server_username : str ,
830
+ personal_access_token : str ,
831
+ bitbucket_server_project : str ,
832
+ bitbucket_server_repo : str ,
833
+ new_name : Optional [ str ] = None ,
834
+ target_namespace : Optional [ str ] = None ,
835
+ ** kwargs : Any
836
+ ) -> Union [ Dict [ str , Any ], requests . Response ] :
781
837
"""Import a project from BitBucket Server to Gitlab (schedule the import)
782
838
783
839
This method will return when an import operation has been safely queued,
@@ -856,8 +912,13 @@ def import_bitbucket_server(
856
912
return result
857
913
858
914
def import_github (
859
- self , personal_access_token , repo_id , target_namespace , new_name = None , ** kwargs
860
- ):
915
+ self ,
916
+ personal_access_token : str ,
917
+ repo_id : int ,
918
+ target_namespace : str ,
919
+ new_name : Optional [str ] = None ,
920
+ ** kwargs : Any
921
+ ) -> Union [Dict [str , Any ], requests .Response ]:
861
922
"""Import a project from Github to Gitlab (schedule the import)
862
923
863
924
This method will return when an import operation has been safely queued,
@@ -944,7 +1005,9 @@ class ProjectForkManager(CreateMixin, ListMixin, RESTManager):
944
1005
)
945
1006
_create_attrs = RequiredOptional (optional = ("namespace" ,))
946
1007
947
- def create (self , data , ** kwargs ):
1008
+ def create (
1009
+ self , data : Optional [Dict [str , Any ]] = None , ** kwargs : Any
1010
+ ) -> ProjectFork :
948
1011
"""Creates a new object.
949
1012
950
1013
Args:
@@ -960,8 +1023,10 @@ def create(self, data, **kwargs):
960
1023
RESTObject: A new instance of the managed object class build with
961
1024
the data sent by the server
962
1025
"""
1026
+ if TYPE_CHECKING :
1027
+ assert self .path is not None
963
1028
path = self .path [:- 1 ] # drop the 's'
964
- return CreateMixin .create (self , data , path = path , ** kwargs )
1029
+ return cast ( ProjectFork , CreateMixin .create (self , data , path = path , ** kwargs ) )
965
1030
966
1031
967
1032
class ProjectRemoteMirror (SaveMixin , RESTObject ):
0 commit comments