Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd0a0348

Browse files
benjambnejch
authored andcommitted
feat: implement secure files API
1 parentfcd72fe commitd0a0348

File tree

6 files changed

+221
-0
lines changed

6 files changed

+221
-0
lines changed

‎docs/api-objects.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ API examples
5252
gl_objects/repositories
5353
gl_objects/repository_tags
5454
gl_objects/search
55+
gl_objects/secure_files
5556
gl_objects/settings
5657
gl_objects/snippets
5758
gl_objects/statistics

‎docs/gl_objects/secure_files.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
############
2+
Secure Files
3+
############
4+
5+
secure files
6+
============
7+
8+
References
9+
----------
10+
11+
* v4 API:
12+
13+
+:class:`gitlab.v4.objects.SecureFile`
14+
+:class:`gitlab.v4.objects.SecureFileManager`
15+
+:attr:`gitlab.v4.objects.Project.secure_files`
16+
17+
* GitLab API: https://docs.gitlab.com/ee/api/secure_files.html
18+
19+
Examples
20+
--------
21+
22+
Get a project secure file::
23+
24+
secure_files = gl.projects.get(1, lazy=True).secure_files.get(1)
25+
print(secure_files.name)
26+
27+
List project secure files::
28+
29+
secure_files = gl.projects.get(1, lazy=True).secure_files.list()
30+
print(secure_files[0].name)
31+
32+
Create project secure file::
33+
34+
secure_file = gl.projects.get(1).secure_files.create({"name": "test", "file": "secure.txt"})
35+
36+
Download a project secure file::
37+
38+
content = secure_file.download()
39+
print(content)
40+
with open("/tmp/secure.txt", "wb") as f:
41+
secure_file.download(streamed=True, action=f.write)
42+
43+
Remove a project secure file::
44+
45+
gl.projects.get(1).secure_files.delete(1)
46+
# or
47+
secure_file.delete()

‎gitlab/v4/objects/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
from .releasesimport*
5454
from .repositoriesimport*
5555
from .runnersimport*
56+
from .secure_filesimport*
5657
from .settingsimport*
5758
from .sidekiqimport*
5859
from .snippetsimport*

‎gitlab/v4/objects/projects.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
from .releasesimportProjectReleaseManager# noqa: F401
8383
from .repositoriesimportRepositoryMixin
8484
from .runnersimportProjectRunnerManager# noqa: F401
85+
from .secure_filesimportSecureFileManager# noqa: F401
8586
from .snippetsimportProjectSnippetManager# noqa: F401
8687
from .statisticsimport (# noqa: F401
8788
ProjectAdditionalStatisticsManager,
@@ -209,6 +210,7 @@ class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTO
209210
remote_mirrors:"ProjectRemoteMirrorManager"
210211
repositories:ProjectRegistryRepositoryManager
211212
runners:ProjectRunnerManager
213+
secure_files:SecureFileManager
212214
services:ProjectServiceManager
213215
snippets:ProjectSnippetManager
214216
storage:"ProjectStorageManager"

‎gitlab/v4/objects/secure_files.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
"""
2+
GitLab API:
3+
https://docs.gitlab.com/ee/api/secure_files.html
4+
"""
5+
fromtypingimportAny,Callable,cast,Iterator,Optional,TYPE_CHECKING,Union
6+
7+
importrequests
8+
9+
fromgitlabimportcli
10+
fromgitlabimportexceptionsasexc
11+
fromgitlabimportutils
12+
fromgitlab.baseimportRESTManager,RESTObject
13+
fromgitlab.mixinsimportNoUpdateMixin,ObjectDeleteMixin
14+
fromgitlab.typesimportFileAttribute,RequiredOptional
15+
16+
__all__= ["SecureFile","SecureFileManager"]
17+
18+
19+
classSecureFile(ObjectDeleteMixin,RESTObject):
20+
@cli.register_custom_action("SecureFile")
21+
@exc.on_http_error(exc.GitlabGetError)
22+
defdownload(
23+
self,
24+
streamed:bool=False,
25+
action:Optional[Callable[[bytes],None]]=None,
26+
chunk_size:int=1024,
27+
*,
28+
iterator:bool=False,
29+
**kwargs:Any,
30+
)->Optional[Union[bytes,Iterator[Any]]]:
31+
"""Download the secure file.
32+
33+
Args:
34+
streamed: If True the data will be processed by chunks of
35+
`chunk_size` and each chunk is passed to `action` for
36+
treatment
37+
iterator: If True directly return the underlying response
38+
iterator
39+
action: Callable responsible of dealing with chunk of
40+
data
41+
chunk_size: Size of each chunk
42+
**kwargs: Extra options to send to the server (e.g. sudo)
43+
44+
Raises:
45+
GitlabAuthenticationError: If authentication is not correct
46+
GitlabGetError: If the artifacts could not be retrieved
47+
48+
Returns:
49+
The artifacts if `streamed` is False, None otherwise."""
50+
path=f"{self.manager.path}/{self.id}/download"
51+
result=self.manager.gitlab.http_get(
52+
path,streamed=streamed,raw=True,**kwargs
53+
)
54+
ifTYPE_CHECKING:
55+
assertisinstance(result,requests.Response)
56+
returnutils.response_content(
57+
result,streamed,action,chunk_size,iterator=iterator
58+
)
59+
60+
61+
classSecureFileManager(NoUpdateMixin,RESTManager):
62+
_path="/projects/{project_id}/secure_files"
63+
_obj_cls=SecureFile
64+
_from_parent_attrs= {"project_id":"id"}
65+
_create_attrs=RequiredOptional(required=("name","file"))
66+
_types= {"file":FileAttribute}
67+
68+
defget(self,id:Union[str,int],lazy:bool=False,**kwargs:Any)->SecureFile:
69+
returncast(SecureFile,super().get(id=id,lazy=lazy,**kwargs))
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
"""
2+
GitLab API: https://docs.gitlab.com/ee/api/secure_files.html
3+
"""
4+
5+
importpytest
6+
importresponses
7+
8+
fromgitlab.v4.objectsimportSecureFile
9+
10+
secure_file_content= {
11+
"id":1,
12+
"name":"myfile.jks",
13+
"checksum":"16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aac",
14+
"checksum_algorithm":"sha256",
15+
"created_at":"2022-02-22T22:22:22.222Z",
16+
"expires_at":None,
17+
"metadata":None,
18+
}
19+
20+
21+
@pytest.fixture
22+
defresp_list_secure_files():
23+
withresponses.RequestsMock(assert_all_requests_are_fired=False)asrsps:
24+
rsps.add(
25+
method=responses.GET,
26+
url="http://localhost/api/v4/projects/1/secure_files",
27+
json=[secure_file_content],
28+
content_type="application/json",
29+
status=200,
30+
)
31+
yieldrsps
32+
33+
34+
@pytest.fixture
35+
defresp_create_secure_file():
36+
withresponses.RequestsMock(assert_all_requests_are_fired=False)asrsps:
37+
rsps.add(
38+
method=responses.POST,
39+
url="http://localhost/api/v4/projects/1/secure_files",
40+
json=secure_file_content,
41+
content_type="application/json",
42+
status=200,
43+
)
44+
yieldrsps
45+
46+
47+
@pytest.fixture
48+
defresp_download_secure_file(binary_content):
49+
withresponses.RequestsMock(assert_all_requests_are_fired=False)asrsps:
50+
rsps.add(
51+
method=responses.GET,
52+
url="http://localhost/api/v4/projects/1/secure_files/1",
53+
json=secure_file_content,
54+
content_type="application/json",
55+
status=200,
56+
)
57+
rsps.add(
58+
method=responses.GET,
59+
url="http://localhost/api/v4/projects/1/secure_files/1/download",
60+
body=binary_content,
61+
content_type="application/octet-stream",
62+
status=200,
63+
)
64+
yieldrsps
65+
66+
67+
@pytest.fixture
68+
defresp_remove_secure_file(no_content):
69+
withresponses.RequestsMock()asrsps:
70+
rsps.add(
71+
method=responses.DELETE,
72+
url="http://localhost/api/v4/projects/1/secure_files/1",
73+
json=no_content,
74+
content_type="application/json",
75+
status=204,
76+
)
77+
yieldrsps
78+
79+
80+
deftest_list_secure_files(project,resp_list_secure_files):
81+
secure_files=project.secure_files.list()
82+
assertlen(secure_files)==1
83+
assertsecure_files[0].id==1
84+
assertsecure_files[0].name=="myfile.jks"
85+
86+
87+
deftest_create_secure_file(project,resp_create_secure_file):
88+
secure_files=project.secure_files.create({"name":"test","file":"myfile.jks"})
89+
assertsecure_files.id==1
90+
assertsecure_files.name=="myfile.jks"
91+
92+
93+
deftest_download_secure_file(project,binary_content,resp_download_secure_file):
94+
secure_file=project.secure_files.get(1)
95+
secure_content=secure_file.download()
96+
assertisinstance(secure_file,SecureFile)
97+
assertsecure_content==binary_content
98+
99+
100+
deftest_remove_secure_file(project,resp_remove_secure_file):
101+
project.secure_files.delete(1)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp