@@ -599,3 +599,224 @@ def update(self, obj, **kwargs):
599
599
r = self ._raw_put (url , data = data , content_type = 'application/json' )
600
600
raise_error_from_response (r , GitlabUpdateError )
601
601
return r .json ()
602
+
603
+ def _build_url (self , path ):
604
+ """Returns the full url from path.
605
+
606
+ If path is already a url, return it unchanged. If it's a path, append
607
+ it to the stored url.
608
+
609
+ This is a low-level method, different from _construct_url _build_url
610
+ have no knowledge of GitlabObject's.
611
+
612
+ Returns:
613
+ str: The full URL
614
+ """
615
+ if path .startswith ('http://' ) or path .startswith ('https://' ):
616
+ return path
617
+ else :
618
+ return '%s%s' % (self ._url , path )
619
+
620
+ def http_request (self , verb , path , query_data = {}, post_data = {},
621
+ streamed = False , ** kwargs ):
622
+ """Make an HTTP request to the Gitlab server.
623
+
624
+ Args:
625
+ verb (str): The HTTP method to call ('get', 'post', 'put',
626
+ 'delete')
627
+ path (str): Path or full URL to query ('/projects' or
628
+ 'http://whatever/v4/api/projecs')
629
+ query_data (dict): Data to send as query parameters
630
+ post_data (dict): Data to send in the body (will be converted to
631
+ json)
632
+ streamed (bool): Whether the data should be streamed
633
+ **kwargs: Extra data to make the query (e.g. sudo, per_page, page)
634
+
635
+ Returns:
636
+ A requests result object.
637
+
638
+ Raises:
639
+ GitlabHttpError: When the return code is not 2xx
640
+ """
641
+ url = self ._build_url (path )
642
+ params = query_data .copy ()
643
+ params .update (kwargs )
644
+ opts = self ._get_session_opts (content_type = 'application/json' )
645
+ result = self .session .request (verb , url , json = post_data ,
646
+ params = params , stream = streamed , ** opts )
647
+ if not (200 <= result .status_code < 300 ):
648
+ raise GitlabHttpError (response_code = result .status_code )
649
+ return result
650
+
651
+ def http_get (self , path , query_data = {}, streamed = False , ** kwargs ):
652
+ """Make a GET request to the Gitlab server.
653
+
654
+ Args:
655
+ path (str): Path or full URL to query ('/projects' or
656
+ 'http://whatever/v4/api/projecs')
657
+ query_data (dict): Data to send as query parameters
658
+ streamed (bool): Whether the data should be streamed
659
+ **kwargs: Extra data to make the query (e.g. sudo, per_page, page)
660
+
661
+ Returns:
662
+ A requests result object is streamed is True or the content type is
663
+ not json.
664
+ The parsed json data otherwise.
665
+
666
+ Raises:
667
+ GitlabHttpError: When the return code is not 2xx
668
+ GitlabParsingError: IF the json data could not be parsed
669
+ """
670
+ result = self .http_request ('get' , path , query_data = query_data ,
671
+ streamed = streamed , ** kwargs )
672
+ if (result .headers ['Content-Type' ] == 'application/json' and
673
+ not streamed ):
674
+ try :
675
+ return result .json ()
676
+ except Exception as e :
677
+ raise GitlaParsingError (
678
+ message = "Failed to parse the server message" )
679
+ else :
680
+ return r
681
+
682
+ def http_list (self , path , query_data = {}, ** kwargs ):
683
+ """Make a GET request to the Gitlab server for list-oriented queries.
684
+
685
+ Args:
686
+ path (str): Path or full URL to query ('/projects' or
687
+ 'http://whatever/v4/api/projecs')
688
+ query_data (dict): Data to send as query parameters
689
+ **kwargs: Extra data to make the query (e.g. sudo, per_page, page,
690
+ all)
691
+
692
+ Returns:
693
+ GitlabList: A generator giving access to the objects. If an ``all``
694
+ kwarg is defined and True, returns a list of all the objects (will
695
+ possibly make numerous calls to the Gtilab server and eat a lot of
696
+ memory)
697
+
698
+ Raises:
699
+ GitlabHttpError: When the return code is not 2xx
700
+ GitlabParsingError: IF the json data could not be parsed
701
+ """
702
+ url = self ._build_url (path )
703
+ get_all = kwargs .pop ('all' , False )
704
+ obj_gen = GitlabList (self , url , query_data , ** kwargs )
705
+ return list (obj_gen ) if get_all else obj_gen
706
+
707
+ def http_post (self , path , query_data = {}, post_data = {}, ** kwargs ):
708
+ """Make a POST request to the Gitlab server.
709
+
710
+ Args:
711
+ path (str): Path or full URL to query ('/projects' or
712
+ 'http://whatever/v4/api/projecs')
713
+ query_data (dict): Data to send as query parameters
714
+ post_data (dict): Data to send in the body (will be converted to
715
+ json)
716
+ **kwargs: Extra data to make the query (e.g. sudo, per_page, page)
717
+
718
+ Returns:
719
+ The parsed json returned by the server.
720
+
721
+ Raises:
722
+ GitlabHttpError: When the return code is not 2xx
723
+ GitlabParsingError: IF the json data could not be parsed
724
+ """
725
+ result = self .http_request ('post' , path , query_data = query_data ,
726
+ post_data = post_data , ** kwargs )
727
+ try :
728
+ return result .json ()
729
+ except Exception as e :
730
+ raise GitlabParsingError (message = "Failed to parse the server message" )
731
+
732
+ def http_put (self , path , query_data = {}, post_data = {}, ** kwargs ):
733
+ """Make a PUT request to the Gitlab server.
734
+
735
+ Args:
736
+ path (str): Path or full URL to query ('/projects' or
737
+ 'http://whatever/v4/api/projecs')
738
+ query_data (dict): Data to send as query parameters
739
+ post_data (dict): Data to send in the body (will be converted to
740
+ json)
741
+ **kwargs: Extra data to make the query (e.g. sudo, per_page, page)
742
+
743
+ Returns:
744
+ The parsed json returned by the server.
745
+
746
+ Raises:
747
+ GitlabHttpError: When the return code is not 2xx
748
+ GitlabParsingError: IF the json data could not be parsed
749
+ """
750
+ result = self .hhtp_request ('put' , path , query_data = query_data ,
751
+ post_data = post_data , ** kwargs )
752
+ try :
753
+ return result .json ()
754
+ except Exception as e :
755
+ raise GitlabParsingError (message = "Failed to parse the server message" )
756
+
757
+ def http_delete (self , path , ** kwargs ):
758
+ """Make a PUT request to the Gitlab server.
759
+
760
+ Args:
761
+ path (str): Path or full URL to query ('/projects' or
762
+ 'http://whatever/v4/api/projecs')
763
+ **kwargs: Extra data to make the query (e.g. sudo, per_page, page)
764
+
765
+ Returns:
766
+ True.
767
+
768
+ Raises:
769
+ GitlabHttpError: When the return code is not 2xx
770
+ """
771
+ result = self .http_request ('delete' , path , ** kwargs )
772
+ return True
773
+
774
+
775
+ class GitlabList (object ):
776
+ """Generator representing a list of remote objects.
777
+
778
+ The object handles the links returned by a query to the API, and will call
779
+ the API again when needed.
780
+ """
781
+
782
+ def __init__ (self , gl , url , query_data , ** kwargs ):
783
+ self ._gl = gl
784
+ self ._query (url , query_data , ** kwargs )
785
+
786
+ def _query (self , url , query_data = {}, ** kwargs ):
787
+ result = self ._gl .http_request ('get' , url , query_data = query_data ,
788
+ ** kwargs )
789
+ try :
790
+ self ._next_url = result .links ['next' ]['url' ]
791
+ except KeyError :
792
+ self ._next_url = None
793
+ self ._current_page = result .headers .get ('X-Page' )
794
+ self ._next_page = result .headers .get ('X-Next-Page' )
795
+ self ._per_page = result .headers .get ('X-Per-Page' )
796
+ self ._total_pages = result .headers .get ('X-Total-Pages' )
797
+ self ._total = result .headers .get ('X-Total' )
798
+
799
+ try :
800
+ self ._data = result .json ()
801
+ except Exception as e :
802
+ raise GitlabParsingError (message = "Failed to parse the server message" )
803
+
804
+ self ._current = 0
805
+
806
+ def __iter__ (self ):
807
+ return self
808
+
809
+ def __next__ (self ):
810
+ return self .next ()
811
+
812
+ def next (self ):
813
+ try :
814
+ item = self ._data [self ._current ]
815
+ self ._current += 1
816
+ return item
817
+ except IndexError :
818
+ if self ._next_url :
819
+ self ._query (self ._next_url )
820
+ return self ._data [self ._current ]
821
+
822
+ raise StopIteration
0 commit comments