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

Commit7b864b8

Browse files
feat(api): add support for wiki attachments (#2722)
Added UploadMixin in mixin moduleAdded UploadMixin dependency for Project, ProjectWiki, GroupWikiAdded api tests for wiki uploadAdded unit test for mixinAdded docs sections to wikis.rst
1 parentf4ce867 commit7b864b8

File tree

6 files changed

+262
-59
lines changed

6 files changed

+262
-59
lines changed

‎docs/gl_objects/wikis.rst‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,41 @@ Update a wiki page::
5454
Delete a wiki page::
5555

5656
page.delete()
57+
58+
59+
File uploads
60+
============
61+
62+
Reference
63+
---------
64+
65+
* v4 API:
66+
67+
+:attr:`gitlab.v4.objects.ProjectWiki.upload`
68+
+:attr:`gitlab.v4.objects.GrouptWiki.upload`
69+
70+
71+
* Gitlab API for Projects: https://docs.gitlab.com/ee/api/wikis.html#upload-an-attachment-to-the-wiki-repository
72+
* Gitlab API for Groups: https://docs.gitlab.com/ee/api/group_wikis.html#upload-an-attachment-to-the-wiki-repository
73+
74+
Examples
75+
--------
76+
77+
Upload a file into a project wiki using a filesystem path::
78+
79+
page = project.wikis.get(page_slug)
80+
page.upload("filename.txt", filepath="/some/path/filename.txt")
81+
82+
Upload a file into a project wiki with raw data::
83+
84+
page.upload("filename.txt", filedata="Raw data")
85+
86+
Upload a file into a group wiki using a filesystem path::
87+
88+
page = group.wikis.get(page_slug)
89+
page.upload("filename.txt", filepath="/some/path/filename.txt")
90+
91+
Upload a file into a group wiki using raw data::
92+
93+
page.upload("filename.txt", filedata="Raw data")
94+

‎gitlab/mixins.py‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,3 +944,73 @@ def promote(self, **kwargs: Any) -> Dict[str, Any]:
944944
ifTYPE_CHECKING:
945945
assertnotisinstance(result,requests.Response)
946946
returnresult
947+
948+
949+
classUploadMixin(_RestObjectBase):
950+
_id_attr:Optional[str]
951+
_attrs:Dict[str,Any]
952+
_module:ModuleType
953+
_parent_attrs:Dict[str,Any]
954+
_updated_attrs:Dict[str,Any]
955+
_upload_path:str
956+
manager:base.RESTManager
957+
958+
def_get_upload_path(self)->str:
959+
"""Formats _upload_path with object attributes.
960+
961+
Returns:
962+
The upload path
963+
"""
964+
ifTYPE_CHECKING:
965+
assertisinstance(self._upload_path,str)
966+
data=self.attributes
967+
returnself._upload_path.format(**data)
968+
969+
@cli.register_custom_action(("Project","ProjectWiki"), ("filename","filepath"))
970+
@exc.on_http_error(exc.GitlabUploadError)
971+
defupload(
972+
self,
973+
filename:str,
974+
filedata:Optional[bytes]=None,
975+
filepath:Optional[str]=None,
976+
**kwargs:Any,
977+
)->Dict[str,Any]:
978+
"""Upload the specified file.
979+
980+
.. note::
981+
982+
Either ``filedata`` or ``filepath`` *MUST* be specified.
983+
984+
Args:
985+
filename: The name of the file being uploaded
986+
filedata: The raw data of the file being uploaded
987+
filepath: The path to a local file to upload (optional)
988+
989+
Raises:
990+
GitlabAuthenticationError: If authentication is not correct
991+
GitlabUploadError: If the file upload fails
992+
GitlabUploadError: If ``filedata`` and ``filepath`` are not
993+
specified
994+
GitlabUploadError: If both ``filedata`` and ``filepath`` are
995+
specified
996+
997+
Returns:
998+
A ``dict`` with info on the uploaded file
999+
"""
1000+
iffilepathisNoneandfiledataisNone:
1001+
raiseexc.GitlabUploadError("No file contents or path specified")
1002+
1003+
iffiledataisnotNoneandfilepathisnotNone:
1004+
raiseexc.GitlabUploadError("File contents and file path specified")
1005+
1006+
iffilepathisnotNone:
1007+
withopen(filepath,"rb")asf:
1008+
filedata=f.read()
1009+
1010+
file_info= {"file": (filename,filedata)}
1011+
path=self._get_upload_path()
1012+
server_data=self.manager.gitlab.http_post(path,files=file_info,**kwargs)
1013+
1014+
ifTYPE_CHECKING:
1015+
assertisinstance(server_data,dict)
1016+
returnserver_data

‎gitlab/v4/objects/projects.py‎

Lines changed: 5 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
RefreshMixin,
3131
SaveMixin,
3232
UpdateMixin,
33+
UploadMixin,
3334
)
3435
fromgitlab.typesimportRequiredOptional
3536

@@ -158,8 +159,11 @@ class ProjectGroupManager(ListMixin, RESTManager):
158159
_types= {"skip_groups":types.ArrayAttribute}
159160

160161

161-
classProject(RefreshMixin,SaveMixin,ObjectDeleteMixin,RepositoryMixin,RESTObject):
162+
classProject(
163+
RefreshMixin,SaveMixin,ObjectDeleteMixin,RepositoryMixin,UploadMixin,RESTObject
164+
):
162165
_repr_attr="path_with_namespace"
166+
_upload_path="/projects/{id}/uploads"
163167

164168
access_tokens:ProjectAccessTokenManager
165169
accessrequests:ProjectAccessRequestManager
@@ -437,59 +441,6 @@ def housekeeping(self, **kwargs: Any) -> None:
437441
path=f"/projects/{self.encoded_id}/housekeeping"
438442
self.manager.gitlab.http_post(path,**kwargs)
439443

440-
# see #56 - add file attachment features
441-
@cli.register_custom_action("Project", ("filename","filepath"))
442-
@exc.on_http_error(exc.GitlabUploadError)
443-
defupload(
444-
self,
445-
filename:str,
446-
filedata:Optional[bytes]=None,
447-
filepath:Optional[str]=None,
448-
**kwargs:Any,
449-
)->Dict[str,Any]:
450-
"""Upload the specified file into the project.
451-
452-
.. note::
453-
454-
Either ``filedata`` or ``filepath`` *MUST* be specified.
455-
456-
Args:
457-
filename: The name of the file being uploaded
458-
filedata: The raw data of the file being uploaded
459-
filepath: The path to a local file to upload (optional)
460-
461-
Raises:
462-
GitlabConnectionError: If the server cannot be reached
463-
GitlabUploadError: If the file upload fails
464-
GitlabUploadError: If ``filedata`` and ``filepath`` are not
465-
specified
466-
GitlabUploadError: If both ``filedata`` and ``filepath`` are
467-
specified
468-
469-
Returns:
470-
A ``dict`` with the keys:
471-
* ``alt`` - The alternate text for the upload
472-
* ``url`` - The direct url to the uploaded file
473-
* ``markdown`` - Markdown for the uploaded file
474-
"""
475-
iffilepathisNoneandfiledataisNone:
476-
raiseexc.GitlabUploadError("No file contents or path specified")
477-
478-
iffiledataisnotNoneandfilepathisnotNone:
479-
raiseexc.GitlabUploadError("File contents and file path specified")
480-
481-
iffilepathisnotNone:
482-
withopen(filepath,"rb")asf:
483-
filedata=f.read()
484-
485-
url=f"/projects/{self.encoded_id}/uploads"
486-
file_info= {"file": (filename,filedata)}
487-
data=self.manager.gitlab.http_post(url,files=file_info,**kwargs)
488-
489-
ifTYPE_CHECKING:
490-
assertisinstance(data,dict)
491-
return {"alt":data["alt"],"url":data["url"],"markdown":data["markdown"]}
492-
493444
@cli.register_custom_action("Project")
494445
@exc.on_http_error(exc.GitlabRestoreError)
495446
defrestore(self,**kwargs:Any)->None:

‎gitlab/v4/objects/wikis.py‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
fromtypingimportAny,cast,Union
22

33
fromgitlab.baseimportRESTManager,RESTObject
4-
fromgitlab.mixinsimportCRUDMixin,ObjectDeleteMixin,SaveMixin
4+
fromgitlab.mixinsimportCRUDMixin,ObjectDeleteMixin,SaveMixin,UploadMixin
55
fromgitlab.typesimportRequiredOptional
66

77
__all__= [
@@ -12,9 +12,10 @@
1212
]
1313

1414

15-
classProjectWiki(SaveMixin,ObjectDeleteMixin,RESTObject):
15+
classProjectWiki(SaveMixin,ObjectDeleteMixin,UploadMixin,RESTObject):
1616
_id_attr="slug"
1717
_repr_attr="slug"
18+
_upload_path="/projects/{project_id}/wikis/attachments"
1819

1920

2021
classProjectWikiManager(CRUDMixin,RESTManager):
@@ -33,9 +34,10 @@ def get(
3334
returncast(ProjectWiki,super().get(id=id,lazy=lazy,**kwargs))
3435

3536

36-
classGroupWiki(SaveMixin,ObjectDeleteMixin,RESTObject):
37+
classGroupWiki(SaveMixin,ObjectDeleteMixin,UploadMixin,RESTObject):
3738
_id_attr="slug"
3839
_repr_attr="slug"
40+
_upload_path="/groups/{group_id}/wikis/attachments"
3941

4042

4143
classGroupWikiManager(CRUDMixin,RESTManager):

‎tests/functional/api/test_wikis.py‎

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,59 @@
44
"""
55

66

7-
deftest_wikis(project):
7+
deftest_project_wikis(project):
88
page=project.wikis.create({"title":"title/subtitle","content":"test content"})
99
page.content="update content"
1010
page.title="subtitle"
1111

1212
page.save()
1313

1414
page.delete()
15+
16+
17+
deftest_project_wiki_file_upload(project):
18+
page=project.wikis.create(
19+
{"title":"title/subtitle","content":"test page content"}
20+
)
21+
filename="test.txt"
22+
file_contents="testing contents"
23+
24+
uploaded_file=page.upload(filename,file_contents)
25+
26+
link=uploaded_file["link"]
27+
file_name=uploaded_file["file_name"]
28+
file_path=uploaded_file["file_path"]
29+
assertfile_name==filename
30+
assertfile_path.startswith("uploads/")
31+
assertfile_path.endswith(f"/{filename}")
32+
assertlink["url"]==file_path
33+
assertlink["markdown"]==f"[{file_name}]({file_path})"
34+
35+
36+
deftest_group_wikis(group):
37+
page=group.wikis.create({"title":"title/subtitle","content":"test content"})
38+
page.content="update content"
39+
page.title="subtitle"
40+
41+
page.save()
42+
43+
page.delete()
44+
45+
46+
deftest_group_wiki_file_upload(group):
47+
page=group.wikis.create(
48+
{"title":"title/subtitle","content":"test page content"}
49+
)
50+
filename="test.txt"
51+
file_contents="testing contents"
52+
53+
uploaded_file=page.upload(filename,file_contents)
54+
55+
link=uploaded_file["link"]
56+
file_name=uploaded_file["file_name"]
57+
file_path=uploaded_file["file_path"]
58+
assertfile_name==filename
59+
assertfile_path.startswith("uploads/")
60+
assertfile_path.endswith(f"/{filename}")
61+
assertlink["url"]==file_path
62+
assertlink["markdown"]==f"[{file_name}]({file_path})"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp