@@ -366,3 +366,20 @@ default an exception is raised for these errors. | |||
| 366 | 366 | ||
| 367 | 367 | gl = gitlab.gitlab(url, token, api_version=4) | |
| 368 | 368 | gl.projects.list(all=True, retry_transient_errors=True) | |
| 369 | + | ||
| 370 | + Timeout | ||
| 371 | + ------- | ||
| 372 | + | ||
| 373 | + python-gitlab will by default use the ``timeout`` option from it's configuration | ||
| 374 | + for all requests. This is passed downwards to the ``requests`` module at the | ||
| 375 | + time of making the HTTP request. However if you would like to override the | ||
| 376 | + global timeout parameter for a particular call, you can provide the ``timeout`` | ||
| 377 | + parameter to that API invocation: | ||
| 378 | + | ||
| 379 | + .. code-block:: python | ||
| 380 | + | ||
| 381 | + import gitlab | ||
| 382 | + | ||
| 383 | + gl = gitlab.gitlab(url, token, api_version=4) | ||
| 384 | + gl.projects.import_github(ACCESS_TOKEN, 123456, "root", timeout=120.0) | ||
| 385 | + | ||
@@ -491,6 +491,8 @@ def http_request( | |||
| 491 | 491 | ||
| 492 | 492 | verify = opts.pop("verify") | |
| 493 | 493 | timeout = opts.pop("timeout") | |
| 494 | + # If timeout was passed into kwargs, allow it to override the default | ||
| 495 | + timeout = kwargs.get("timeout", timeout) | ||
| 494 | 496 | ||
| 495 | 497 | # We need to deal with json vs. data when uploading files | |
| 496 | 498 | if files: | |
@@ -844,6 +844,33 @@ def resp_update_submodule(url, request): | |||
| 844 | 844 | self.assertEqual(ret["message"], "Message") | |
| 845 | 845 | self.assertEqual(ret["id"], "ed899a2f4b50b4370feeea94676502b42383c746") | |
| 846 | 846 | ||
| 847 | + def test_import_github(self): | ||
| 848 | + @urlmatch( | ||
| 849 | + scheme="http", | ||
| 850 | + netloc="localhost", | ||
| 851 | + path="/api/v4/import/github", | ||
| 852 | + method="post", | ||
| 853 | + ) | ||
| 854 | + def resp_import_github(url, request): | ||
| 855 | + headers = {"content-type": "application/json"} | ||
| 856 | + content = """{ | ||
| 857 | + "id": 27, | ||
| 858 | + "name": "my-repo", | ||
| 859 | + "full_path": "/root/my-repo", | ||
| 860 | + "full_name": "Administrator / my-repo" | ||
| 861 | + }""" | ||
| 862 | + content = content.encode("utf-8") | ||
| 863 | + return response(200, content, headers, None, 25, request) | ||
| 864 | + | ||
| 865 | + with HTTMock(resp_import_github): | ||
| 866 | + base_path = "/root" | ||
| 867 | + name = "my-repo" | ||
| 868 | + ret = self.gl.projects.import_github("githubkey", 1234, base_path, name) | ||
| 869 | + self.assertIsInstance(ret, dict) | ||
| 870 | + self.assertEqual(ret["name"], name) | ||
| 871 | + self.assertEqual(ret["full_path"], "/".join((base_path, name))) | ||
| 872 | + self.assertTrue(ret["full_name"].endswith(name)) | ||
| 873 | + | ||
| 847 | 874 | def _default_config(self): | |
| 848 | 875 | fd, temp_path = tempfile.mkstemp() | |
| 849 | 876 | os.write(fd, valid_config) | |
@@ -4744,6 +4744,69 @@ def import_project( | |||
| 4744 | 4744 | "/projects/import", post_data=data, files=files, **kwargs | |
| 4745 | 4745 | ) | |
| 4746 | 4746 | ||
| 4747 | + def import_github( | ||
| 4748 | + self, personal_access_token, repo_id, target_namespace, new_name=None, **kwargs | ||
| 4749 | + ): | ||
| 4750 | + """Import a project from Github to Gitlab (schedule the import) | ||
| 4751 | + | ||
| 4752 | + This method will return when an import operation has been safely queued, | ||
| 4753 | + or an error has occurred. After triggering an import, check the | ||
| 4754 | + `import_status` of the newly created project to detect when the import | ||
| 4755 | + operation has completed. | ||
| 4756 | + | ||
| 4757 | + NOTE: this request may take longer than most other API requests. | ||
| 4758 | + So this method will specify a 60 second default timeout if none is specified. | ||
| 4759 | + A timeout can be specified via kwargs to override this functionality. | ||
| 4760 | + | ||
| 4761 | + Args: | ||
| 4762 | + personal_access_token (str): GitHub personal access token | ||
| 4763 | + repo_id (int): Github repository ID | ||
| 4764 | + target_namespace (str): Namespace to import repo into | ||
| 4765 | + new_name (str): New repo name (Optional) | ||
| 4766 | + **kwargs: Extra options to send to the server (e.g. sudo) | ||
| 4767 | + | ||
| 4768 | + Raises: | ||
| 4769 | + GitlabAuthenticationError: If authentication is not correct | ||
| 4770 | + GitlabListError: If the server failed to perform the request | ||
| 4771 | + | ||
| 4772 | + Returns: | ||
| 4773 | + dict: A representation of the import status. | ||
| 4774 | + | ||
| 4775 | + Example: | ||
| 4776 | + ``` | ||
| 4777 | + gl = gitlab.Gitlab_from_config() | ||
| 4778 | + print "Triggering import" | ||
| 4779 | + result = gl.projects.import_github(ACCESS_TOKEN, | ||
| 4780 | + 123456, | ||
| 4781 | + "my-group/my-subgroup") | ||
| 4782 | + project = gl.projects.get(ret['id']) | ||
| 4783 | + print "Waiting for import to complete" | ||
| 4784 | + while project.import_status == u'started': | ||
| 4785 | + time.sleep(1.0) | ||
| 4786 | + project = gl.projects.get(project.id) | ||
| 4787 | + print "Github import complete" | ||
| 4788 | + ``` | ||
| 4789 | + """ | ||
| 4790 | + data = { | ||
| 4791 | + "personal_access_token": personal_access_token, | ||
| 4792 | + "repo_id": repo_id, | ||
| 4793 | + "target_namespace": target_namespace, | ||
| 4794 | + } | ||
| 4795 | + if new_name: | ||
| 4796 | + data["new_name"] = new_name | ||
| 4797 | + if ( | ||
| 4798 | + "timeout" not in kwargs | ||
| 4799 | + or self.gitlab.timeout is None | ||
| 4800 | + or self.gitlab.timeout < 60.0 | ||
| 4801 | + ): | ||
| 4802 | + # Ensure that this HTTP request has a longer-than-usual default timeout | ||
| 4803 | + # The base gitlab object tends to have a default that is <10 seconds, | ||
| 4804 | + # and this is too short for this API command, typically. | ||
| 4805 | + # On the order of 24 seconds has been measured on a typical gitlab instance. | ||
| 4806 | + kwargs["timeout"] = 60.0 | ||
| 4807 | + result = self.gitlab.http_post("/import/github", post_data=data, **kwargs) | ||
| 4808 | + return result | ||
| 4809 | + | ||
| 4747 | 4810 | ||
| 4748 | 4811 | class RunnerJob(RESTObject): | |
| 4749 | 4812 | pass | |
0 commit comments