Skip to content

Commit e59cdc5

Browse files
authored
feat: add support for asynchronous Branch, Directory and File deletion (#272)
1 parent 434a5fc commit e59cdc5

3 files changed

Lines changed: 185 additions & 6 deletions

File tree

‎crowdin_api/api_resources/source_files/resource.py‎

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,12 @@ def get_branch(self, branchId: int, projectId: Optional[int] = None):
116116
path=self.get_branch_path(projectId=projectId, branchId=branchId),
117117
)
118118

119-
def delete_branch(self, branchId: int, projectId: Optional[int] = None):
119+
def delete_branch(
120+
self,
121+
branchId: int,
122+
projectId: Optional[int] = None,
123+
prefer: Optional[str] = None,
124+
):
120125
"""
121126
Delete Branch.
122127
@@ -125,12 +130,34 @@ def delete_branch(self, branchId: int, projectId: Optional[int] = None):
125130
"""
126131

127132
projectId = projectId or self.get_project_id()
133+
headers = {"Prefer": prefer} if prefer is not None else None
128134

129135
return self.requester.request(
130136
method="delete",
137+
headers=headers,
131138
path=f"projects/{projectId}/branches/{branchId}",
132139
)
133140

141+
def check_branch_deletion_status(
142+
self,
143+
branchId: int,
144+
jobIdentifier: str,
145+
projectId: Optional[int] = None,
146+
):
147+
"""
148+
Check Branch Deletion Status.
149+
150+
Link to documentation:
151+
https://developer.crowdin.com/api/v2/#operation/api.projects.branches.jobs.get
152+
"""
153+
154+
projectId = projectId or self.get_project_id()
155+
156+
return self.requester.request(
157+
method="get",
158+
path=f"projects/{projectId}/branches/{branchId}/jobs/{jobIdentifier}",
159+
)
160+
134161
def edit_branch(
135162
self,
136163
branchId: int,
@@ -241,7 +268,12 @@ def get_directory(self, directoryId: int, projectId: Optional[int] = None):
241268
path=self.get_directory_path(projectId=projectId, directoryId=directoryId),
242269
)
243270

244-
def delete_directory(self, directoryId: int, projectId: Optional[int] = None):
271+
def delete_directory(
272+
self,
273+
directoryId: int,
274+
projectId: Optional[int] = None,
275+
prefer: Optional[str] = None,
276+
):
245277
"""
246278
Delete Directory.
247279
@@ -250,12 +282,34 @@ def delete_directory(self, directoryId: int, projectId: Optional[int] = None):
250282
"""
251283

252284
projectId = projectId or self.get_project_id()
285+
headers = {"Prefer": prefer} if prefer is not None else None
253286

254287
return self.requester.request(
255288
method="delete",
289+
headers=headers,
256290
path=self.get_directory_path(projectId=projectId, directoryId=directoryId),
257291
)
258292

293+
def check_directory_deletion_status(
294+
self,
295+
directoryId: int,
296+
jobIdentifier: str,
297+
projectId: Optional[int] = None,
298+
):
299+
"""
300+
Check Directory Deletion Status.
301+
302+
Link to documentation:
303+
https://developer.crowdin.com/api/v2/#operation/api.projects.directories.jobs.get
304+
"""
305+
306+
projectId = projectId or self.get_project_id()
307+
308+
return self.requester.request(
309+
method="get",
310+
path=f"projects/{projectId}/directories/{directoryId}/jobs/{jobIdentifier}",
311+
)
312+
259313
def edit_directory(
260314
self,
261315
directoryId: int,
@@ -451,7 +505,12 @@ def update_file(
451505
},
452506
)
453507

454-
def delete_file(self, fileId: int, projectId: Optional[int] = None):
508+
def delete_file(
509+
self,
510+
fileId: int,
511+
projectId: Optional[int] = None,
512+
prefer: Optional[str] = None,
513+
):
455514
"""
456515
Delete File.
457516
@@ -460,12 +519,34 @@ def delete_file(self, fileId: int, projectId: Optional[int] = None):
460519
"""
461520

462521
projectId = projectId or self.get_project_id()
522+
headers = {"Prefer": prefer} if prefer is not None else None
463523

464524
return self.requester.request(
465525
method="delete",
526+
headers=headers,
466527
path=self.get_file_path(projectId=projectId, fileId=fileId),
467528
)
468529

530+
def check_file_deletion_status(
531+
self,
532+
fileId: int,
533+
jobIdentifier: str,
534+
projectId: Optional[int] = None,
535+
):
536+
"""
537+
Check File Deletion Status.
538+
539+
Link to documentation:
540+
https://developer.crowdin.com/api/v2/#operation/api.projects.files.jobs.get
541+
"""
542+
543+
projectId = projectId or self.get_project_id()
544+
545+
return self.requester.request(
546+
method="get",
547+
path=f"projects/{projectId}/files/{fileId}/jobs/{jobIdentifier}",
548+
)
549+
469550
def edit_file(
470551
self,
471552
fileId: int,

‎crowdin_api/api_resources/source_files/tests/test_source_files_resources.py‎

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,40 @@ def test_delete_branch(self, m_request, base_absolut_url):
142142
resource = self.get_resource(base_absolut_url)
143143
assert resource.delete_branch(projectId=1, branchId=2) == "response"
144144
m_request.assert_called_once_with(
145-
method="delete", path=resource.get_branch_path(projectId=1, branchId=2)
145+
method="delete",
146+
headers=None,
147+
path=resource.get_branch_path(projectId=1, branchId=2),
148+
)
149+
150+
@mock.patch("crowdin_api.requester.APIRequester.request")
151+
def test_delete_branch_async(self, m_request, base_absolut_url):
152+
m_request.return_value = "response"
153+
154+
resource = self.get_resource(base_absolut_url)
155+
assert (
156+
resource.delete_branch(projectId=1, branchId=2, prefer="respond-async")
157+
== "response"
158+
)
159+
m_request.assert_called_once_with(
160+
method="delete",
161+
headers={"Prefer": "respond-async"},
162+
path=resource.get_branch_path(projectId=1, branchId=2),
163+
)
164+
165+
@mock.patch("crowdin_api.requester.APIRequester.request")
166+
def test_check_branch_deletion_status(self, m_request, base_absolut_url):
167+
m_request.return_value = "response"
168+
169+
resource = self.get_resource(base_absolut_url)
170+
assert (
171+
resource.check_branch_deletion_status(
172+
projectId=1, branchId=2, jobIdentifier="job"
173+
)
174+
== "response"
175+
)
176+
m_request.assert_called_once_with(
177+
method="get",
178+
path="projects/1/branches/2/jobs/job",
146179
)
147180

148181
@mock.patch("crowdin_api.requester.APIRequester.request")
@@ -299,9 +332,41 @@ def test_delete_directory(self, m_request, base_absolut_url):
299332
assert resource.delete_directory(projectId=1, directoryId=2) == "response"
300333
m_request.assert_called_once_with(
301334
method="delete",
335+
headers=None,
336+
path=resource.get_directory_path(projectId=1, directoryId=2),
337+
)
338+
339+
@mock.patch("crowdin_api.requester.APIRequester.request")
340+
def test_delete_directory_async(self, m_request, base_absolut_url):
341+
m_request.return_value = "response"
342+
343+
resource = self.get_resource(base_absolut_url)
344+
assert (
345+
resource.delete_directory(projectId=1, directoryId=2, prefer="respond-async")
346+
== "response"
347+
)
348+
m_request.assert_called_once_with(
349+
method="delete",
350+
headers={"Prefer": "respond-async"},
302351
path=resource.get_directory_path(projectId=1, directoryId=2),
303352
)
304353

354+
@mock.patch("crowdin_api.requester.APIRequester.request")
355+
def test_check_directory_deletion_status(self, m_request, base_absolut_url):
356+
m_request.return_value = "response"
357+
358+
resource = self.get_resource(base_absolut_url)
359+
assert (
360+
resource.check_directory_deletion_status(
361+
projectId=1, directoryId=2, jobIdentifier="job"
362+
)
363+
== "response"
364+
)
365+
m_request.assert_called_once_with(
366+
method="get",
367+
path="projects/1/directories/2/jobs/job",
368+
)
369+
305370
@mock.patch("crowdin_api.requester.APIRequester.request")
306371
def test_edit_directory(self, m_request, base_absolut_url):
307372
m_request.return_value = "response"
@@ -552,7 +617,40 @@ def test_delete_file(self, m_request, base_absolut_url):
552617
resource = self.get_resource(base_absolut_url)
553618
assert resource.delete_file(projectId=1, fileId=2) == "response"
554619
m_request.assert_called_once_with(
555-
method="delete", path=resource.get_file_path(projectId=1, fileId=2)
620+
method="delete",
621+
headers=None,
622+
path=resource.get_file_path(projectId=1, fileId=2),
623+
)
624+
625+
@mock.patch("crowdin_api.requester.APIRequester.request")
626+
def test_delete_file_async(self, m_request, base_absolut_url):
627+
m_request.return_value = "response"
628+
629+
resource = self.get_resource(base_absolut_url)
630+
assert (
631+
resource.delete_file(projectId=1, fileId=2, prefer="respond-async")
632+
== "response"
633+
)
634+
m_request.assert_called_once_with(
635+
method="delete",
636+
headers={"Prefer": "respond-async"},
637+
path=resource.get_file_path(projectId=1, fileId=2),
638+
)
639+
640+
@mock.patch("crowdin_api.requester.APIRequester.request")
641+
def test_check_file_deletion_status(self, m_request, base_absolut_url):
642+
m_request.return_value = "response"
643+
644+
resource = self.get_resource(base_absolut_url)
645+
assert (
646+
resource.check_file_deletion_status(
647+
projectId=1, fileId=2, jobIdentifier="job"
648+
)
649+
== "response"
650+
)
651+
m_request.assert_called_once_with(
652+
method="get",
653+
path="projects/1/files/2/jobs/job",
556654
)
557655

558656
@mock.patch("crowdin_api.requester.APIRequester.request")

‎crowdin_api/tests/test_requester.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ def test__request_wrong_response(self, requests_mock, base_absolut_url):
195195
with pytest.raises(ParsingError):
196196
requester._request(method="get", path=path)
197197

198-
@pytest.mark.parametrize("status_code", (200, 299))
198+
@pytest.mark.parametrize("status_code", (200, 202, 299))
199199
def test__request_with_success_status(self, status_code, requests_mock, base_absolut_url):
200200
path = "test"
201201
requester = APIRequester(base_url=base_absolut_url)

0 commit comments

Comments
 (0)