gitcode-api 1.2.20__py3-none-any.whl → 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. gitcode_api/__init__.py +8 -2
  2. gitcode_api/_base_client.py +7 -2
  3. gitcode_api/_exceptions.py +8 -0
  4. gitcode_api/exceptions.py +19 -0
  5. gitcode_api/llm/mcp.py +5 -5
  6. gitcode_api/models.py +205 -0
  7. gitcode_api/resources/__init__.py +1 -1
  8. gitcode_api/resources/_shared/__init__.py +18 -0
  9. gitcode_api/resources/_shared/base.py +129 -0
  10. gitcode_api/resources/{_shared.py → _shared/fetch_template.py} +133 -259
  11. gitcode_api/resources/account/__init__.py +17 -0
  12. gitcode_api/resources/account/oauth_resource_group.py +159 -0
  13. gitcode_api/resources/account/orgs_resource_group.py +422 -0
  14. gitcode_api/resources/account/search_resource_group.py +236 -0
  15. gitcode_api/resources/account/users_resource_group.py +249 -0
  16. gitcode_api/resources/collaboration/__init__.py +20 -0
  17. gitcode_api/resources/collaboration/_helpers.py +10 -0
  18. gitcode_api/resources/collaboration/issues_resource_group.py +855 -0
  19. gitcode_api/resources/collaboration/labels_resource_group.py +248 -0
  20. gitcode_api/resources/collaboration/members_resource_group.py +195 -0
  21. gitcode_api/resources/collaboration/milestones_resource_group.py +192 -0
  22. gitcode_api/resources/collaboration/pulls_resource_group.py +1300 -0
  23. gitcode_api/resources/misc/__init__.py +14 -0
  24. gitcode_api/resources/misc/releases_resource_group.py +445 -0
  25. gitcode_api/resources/misc/tags_resource_group.py +286 -0
  26. gitcode_api/resources/misc/webhooks_resource_group.py +192 -0
  27. gitcode_api/resources/repositories/__init__.py +17 -0
  28. gitcode_api/resources/repositories/branches_resource_group.py +151 -0
  29. gitcode_api/resources/repositories/commits_resource_group.py +333 -0
  30. gitcode_api/resources/repositories/repo_contents_resource_group.py +459 -0
  31. gitcode_api/resources/repositories/repos_resource_group.py +1279 -0
  32. gitcode_api/version.txt +1 -1
  33. {gitcode_api-1.2.20.dist-info → gitcode_api-1.3.0.dist-info}/METADATA +3 -3
  34. gitcode_api-1.3.0.dist-info/RECORD +52 -0
  35. gitcode_api/resources/account.py +0 -1086
  36. gitcode_api/resources/collaboration.py +0 -2818
  37. gitcode_api/resources/misc.py +0 -901
  38. gitcode_api/resources/repositories.py +0 -2197
  39. gitcode_api-1.2.20.dist-info/RECORD +0 -31
  40. {gitcode_api-1.2.20.dist-info → gitcode_api-1.3.0.dist-info}/WHEEL +0 -0
  41. {gitcode_api-1.2.20.dist-info → gitcode_api-1.3.0.dist-info}/entry_points.txt +0 -0
  42. {gitcode_api-1.2.20.dist-info → gitcode_api-1.3.0.dist-info}/licenses/LICENSE +0 -0
  43. {gitcode_api-1.2.20.dist-info → gitcode_api-1.3.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1300 @@
1
+ """AbstractPullsResource, PullsResource, and AsyncPullsResource resource group."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import List, Optional, Union
5
+
6
+ from ..._models import (
7
+ APIObject,
8
+ Issue,
9
+ Label,
10
+ MergeResult,
11
+ MergeStatus,
12
+ PullRequest,
13
+ PullRequestAssigneeCount,
14
+ PullRequestComment,
15
+ PullRequestCount,
16
+ PullRequestFile,
17
+ PullRequestOperationLog,
18
+ RepositoryGitCodeTemplate,
19
+ UserSummary,
20
+ as_model,
21
+ )
22
+ from ...constants import GITCODE_PULL_REQUEST_TEMPLATE_PATH_RE
23
+ from .._shared import (
24
+ AsyncResource,
25
+ SyncResource,
26
+ get_gitcode_template_body_async,
27
+ get_gitcode_template_body_sync,
28
+ list_gitcode_template_rows_async,
29
+ list_gitcode_template_rows_sync,
30
+ )
31
+ from ._helpers import _comma_join
32
+
33
+ # mypy: disable-error-code=override
34
+ # pylint: disable=invalid-overridden-method,protected-access,redefined-builtin,duplicate-code
35
+
36
+
37
+ class AbstractPullsResource(ABC):
38
+ """Interface for Pulls resource endpoints."""
39
+
40
+ @abstractmethod
41
+ def list(
42
+ self,
43
+ *,
44
+ owner: Optional[str] = None,
45
+ repo: Optional[str] = None,
46
+ state: Optional[str] = None,
47
+ sort: Optional[str] = None,
48
+ direction: Optional[str] = None,
49
+ page: Optional[int] = None,
50
+ per_page: Optional[int] = None,
51
+ **params,
52
+ ) -> Union[List[PullRequest], PullRequestCount]:
53
+ """List pull requests for a repository.
54
+
55
+ When ``only_count`` is true in ``params`` (or passed via ``**params``), the API returns a
56
+ JSON object with counts per state instead of an array (see Pull Request API).
57
+
58
+ :param owner: Repository owner path. Uses the client default when omitted.
59
+ :param repo: Repository path (name). Uses the client default when omitted.
60
+ :param state: PR state filter: ``all``, ``open``, ``closed``, ``locked``, ``merged`` (default ``all`` in API).
61
+ :param sort: Sort field, typically ``created`` or ``updated``.
62
+ :param direction: ``asc`` or ``desc`` (API default is usually ``desc``).
63
+ :param page: Current page number.
64
+ :param per_page: Page size (max 100 per API documentation).
65
+ :param params: Extra query parameters from the Pull Request API, for example ``base``,
66
+ ``since``, ``author``, ``assignee``, ``reviewer``, ``milestone_number``, ``labels`` (comma-separated),
67
+ ``merged_after``, ``merged_before``, ``created_after``, ``created_before``, ``updated_after``,
68
+ ``updated_before``, ``only_count`` (boolean), and ISO 8601 timestamps (URL-encoded when sent).
69
+ :returns: A list of pull requests, or an :class:`~gitcode_api._models.APIObject` for count-only responses.
70
+ """
71
+
72
+ @abstractmethod
73
+ def get(self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None) -> PullRequest:
74
+ """Get a single pull request.
75
+
76
+ :param number: Pull request number in the repository.
77
+ :param owner: Repository owner path. Uses the client default when omitted.
78
+ :param repo: Repository path. Uses the client default when omitted.
79
+ :returns: Pull request details.
80
+ """
81
+
82
+ @abstractmethod
83
+ def create(
84
+ self,
85
+ *,
86
+ title: str,
87
+ head: str,
88
+ base: str,
89
+ owner: Optional[str] = None,
90
+ repo: Optional[str] = None,
91
+ body: Optional[str] = None,
92
+ draft: Optional[bool] = None,
93
+ assignees: Optional[List[str]] = None,
94
+ testers: Optional[List[str]] = None,
95
+ labels: Optional[List[str]] = None,
96
+ milestone_number: Optional[int] = None,
97
+ issue: Optional[str] = None,
98
+ prune_source_branch: Optional[bool] = None,
99
+ squash: Optional[bool] = None,
100
+ squash_commit_message: Optional[str] = None,
101
+ fork_path: Optional[str] = None,
102
+ ) -> PullRequest:
103
+ """Create a pull request.
104
+
105
+ :param title: Pull request title.
106
+ :param head: Source branch ref (head branch, in forks use ``owner:branch`` like "SushiNinja:develop").
107
+ :param base: Target branch ref (base branch).
108
+ :param owner: Repository owner path. Uses the client default when omitted.
109
+ :param repo: Repository path. Uses the client default when omitted.
110
+ :param body: Description body.
111
+ :param draft: Whether to create as draft.
112
+ :param assignees: Assignee logins; sent as a comma-separated string per API.
113
+ :param testers: Tester logins; comma-separated in the JSON body.
114
+ :param labels: Label names; comma-separated in the JSON body.
115
+ :param milestone_number: Target milestone number.
116
+ :param issue: Related issue reference when supported by the API.
117
+ :param prune_source_branch: Whether to delete the source branch after merge when applicable.
118
+ :param squash: Squash-merge preference where supported.
119
+ :param squash_commit_message: Custom squash commit message.
120
+ :param fork_path: Fork ``owner/repo`` when opening a PR from a fork, like "SushiNinja/agent-core-contrib".
121
+ :returns: Created pull request.
122
+ """
123
+
124
+ @abstractmethod
125
+ def update(
126
+ self,
127
+ *,
128
+ number: Union[int, str],
129
+ owner: Optional[str] = None,
130
+ repo: Optional[str] = None,
131
+ title: Optional[str] = None,
132
+ body: Optional[str] = None,
133
+ state: Optional[str] = None,
134
+ base: Optional[str] = None,
135
+ labels: Optional[List[str]] = None,
136
+ draft: Optional[bool] = None,
137
+ ) -> PullRequest:
138
+ """Update a pull request.
139
+
140
+ :param number: Pull request number in the repository.
141
+ :param owner: Repository owner path. Uses the client default when omitted.
142
+ :param repo: Repository path. Uses the client default when omitted.
143
+ :param title: New title.
144
+ :param body: New description.
145
+ :param state: New state as accepted by the API (for example close or reopen semantics).
146
+ :param base: New base branch name.
147
+ :param labels: Replacement labels; comma-separated in the JSON body.
148
+ :param draft: Draft flag.
149
+ :returns: Updated pull request.
150
+ """
151
+
152
+ @abstractmethod
153
+ def merge(
154
+ self,
155
+ *,
156
+ number: Union[int, str],
157
+ owner: Optional[str] = None,
158
+ repo: Optional[str] = None,
159
+ merge_commit_message: Optional[str] = None,
160
+ squash: Optional[bool] = None,
161
+ ) -> MergeResult:
162
+ """Merge a pull request.
163
+
164
+ :param number: Pull request number.
165
+ :param owner: Repository owner path. Uses the client default when omitted.
166
+ :param repo: Repository path. Uses the client default when omitted.
167
+ :param merge_commit_message: Optional merge commit message.
168
+ :param squash: Whether to squash merge when supported.
169
+ :returns: Merge result payload.
170
+ """
171
+
172
+ @abstractmethod
173
+ def get_merge_status(
174
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
175
+ ) -> MergeStatus:
176
+ """Get mergeability status for a pull request (GET on the merge resource).
177
+
178
+ :param number: Pull request number.
179
+ :param owner: Repository owner path. Uses the client default when omitted.
180
+ :param repo: Repository path. Uses the client default when omitted.
181
+ :returns: Merge status / mergeability information.
182
+ """
183
+
184
+ @abstractmethod
185
+ def list_commits(
186
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
187
+ ) -> List[APIObject]:
188
+ """List commits included in a pull request.
189
+
190
+ :param number: Pull request number.
191
+ :param owner: Repository owner path. Uses the client default when omitted.
192
+ :param repo: Repository path. Uses the client default when omitted.
193
+ :returns: Commit objects (wrapped as :class:`~gitcode_api._models.APIObject`).
194
+ """
195
+
196
+ @abstractmethod
197
+ def list_files(
198
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
199
+ ) -> List[PullRequestFile]:
200
+ """List files changed by a pull request.
201
+
202
+ :param number: Pull request number.
203
+ :param owner: Repository owner path. Uses the client default when omitted.
204
+ :param repo: Repository path. Uses the client default when omitted.
205
+ :returns: File change entries.
206
+ """
207
+
208
+ @abstractmethod
209
+ def list_comments(
210
+ self,
211
+ *,
212
+ number: Union[int, str],
213
+ owner: Optional[str] = None,
214
+ repo: Optional[str] = None,
215
+ page: Optional[int] = None,
216
+ per_page: Optional[int] = None,
217
+ ) -> List[PullRequestComment]:
218
+ """List comments on a pull request.
219
+
220
+ :param number: Pull request number.
221
+ :param owner: Repository owner path. Uses the client default when omitted.
222
+ :param repo: Repository path. Uses the client default when omitted.
223
+ :param page: Page number.
224
+ :param per_page: Page size.
225
+ :returns: Pull request review comments.
226
+ """
227
+
228
+ @abstractmethod
229
+ def create_comment(
230
+ self,
231
+ *,
232
+ number: Union[int, str],
233
+ body: str,
234
+ owner: Optional[str] = None,
235
+ repo: Optional[str] = None,
236
+ commit_id: Optional[str] = None,
237
+ path: Optional[str] = None,
238
+ position: Optional[int] = None,
239
+ ) -> PullRequestComment:
240
+ """Create a pull request (review) comment.
241
+
242
+ :param number: Pull request number.
243
+ :param body: Comment body.
244
+ :param owner: Repository owner path. Uses the client default when omitted.
245
+ :param repo: Repository path. Uses the client default when omitted.
246
+ :param commit_id: Commit SHA the comment applies to.
247
+ :param path: File path in the diff.
248
+ :param position: Line or diff position as defined by the API.
249
+ :returns: Created comment.
250
+ """
251
+
252
+ @abstractmethod
253
+ def get_comment(
254
+ self,
255
+ *,
256
+ comment_id: Union[int, str],
257
+ owner: Optional[str] = None,
258
+ repo: Optional[str] = None,
259
+ ) -> PullRequestComment:
260
+ """Get a single pull request comment by id (global comment endpoint).
261
+
262
+ :param comment_id: Comment id.
263
+ :param owner: Repository owner path. Uses the client default when omitted.
264
+ :param repo: Repository path. Uses the client default when omitted.
265
+ :returns: Pull request comment.
266
+ """
267
+
268
+ @abstractmethod
269
+ def update_comment(
270
+ self,
271
+ *,
272
+ comment_id: Union[int, str],
273
+ body: str,
274
+ owner: Optional[str] = None,
275
+ repo: Optional[str] = None,
276
+ ) -> PullRequestComment:
277
+ """Update a pull request comment.
278
+
279
+ :param comment_id: Comment id.
280
+ :param body: Updated body.
281
+ :param owner: Repository owner path. Uses the client default when omitted.
282
+ :param repo: Repository path. Uses the client default when omitted.
283
+ :returns: Updated comment.
284
+ """
285
+
286
+ @abstractmethod
287
+ def delete_comment(
288
+ self, *, comment_id: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
289
+ ) -> None:
290
+ """Delete a pull request comment.
291
+
292
+ :param comment_id: Comment id.
293
+ :param owner: Repository owner path. Uses the client default when omitted.
294
+ :param repo: Repository path. Uses the client default when omitted.
295
+ """
296
+
297
+ @abstractmethod
298
+ def list_labels(
299
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
300
+ ) -> List[Label]:
301
+ """List labels attached to a pull request.
302
+
303
+ :param number: Pull request number.
304
+ :param owner: Repository owner path. Uses the client default when omitted.
305
+ :param repo: Repository path. Uses the client default when omitted.
306
+ :returns: Labels on the pull request.
307
+ """
308
+
309
+ @abstractmethod
310
+ def add_labels(
311
+ self, *, number: Union[int, str], labels: List[str], owner: Optional[str] = None, repo: Optional[str] = None
312
+ ) -> List[Label]:
313
+ """Add labels to a pull request.
314
+
315
+ :param number: Pull request number.
316
+ :param labels: Label names (JSON array body per API).
317
+ :param owner: Repository owner path. Uses the client default when omitted.
318
+ :param repo: Repository path. Uses the client default when omitted.
319
+ :returns: Labels after the operation.
320
+ """
321
+
322
+ @abstractmethod
323
+ def replace_labels(
324
+ self, *, number: Union[int, str], labels: List[str], owner: Optional[str] = None, repo: Optional[str] = None
325
+ ) -> List[Label]:
326
+ """Replace all labels on a pull request.
327
+
328
+ :param number: Pull request number.
329
+ :param labels: Complete new label set (JSON array body).
330
+ :param owner: Repository owner path. Uses the client default when omitted.
331
+ :param repo: Repository path. Uses the client default when omitted.
332
+ :returns: Labels after replacement.
333
+ """
334
+
335
+ @abstractmethod
336
+ def remove_label(
337
+ self, *, number: Union[int, str], label: str, owner: Optional[str] = None, repo: Optional[str] = None
338
+ ) -> None:
339
+ """Remove a label from a pull request.
340
+
341
+ :param number: Pull request number.
342
+ :param label: Label name to remove.
343
+ :param owner: Repository owner path. Uses the client default when omitted.
344
+ :param repo: Repository path. Uses the client default when omitted.
345
+ """
346
+
347
+ @abstractmethod
348
+ def request_review(
349
+ self,
350
+ *,
351
+ number: Union[int, str],
352
+ owner: Optional[str] = None,
353
+ repo: Optional[str] = None,
354
+ event: str,
355
+ body: Optional[str] = None,
356
+ ) -> None:
357
+ """Submit a pull request review event (approve, request changes, etc., per API).
358
+
359
+ :param number: Pull request number.
360
+ :param owner: Repository owner path. Uses the client default when omitted.
361
+ :param repo: Repository path. Uses the client default when omitted.
362
+ :param event: Review event name as required by GitCode (for example ``APPROVE``; see API docs).
363
+ :param body: Optional comment body accompanying the event.
364
+ :returns: Review result object.
365
+ """
366
+
367
+ @abstractmethod
368
+ def list_operation_logs(
369
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None, **params
370
+ ) -> List[PullRequestOperationLog]:
371
+ """List operation logs for a pull request.
372
+
373
+ :param number: Pull request number.
374
+ :param owner: Repository owner path. Uses the client default when omitted.
375
+ :param repo: Repository path. Uses the client default when omitted.
376
+ :param params: Additional query parameters accepted by the operate_logs endpoint.
377
+ :returns: Log entries as generic API objects.
378
+ """
379
+
380
+ @abstractmethod
381
+ def request_test(
382
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None, **payload
383
+ ) -> None:
384
+ """Request testing for a pull request.
385
+
386
+ :param number: Pull request number.
387
+ :param owner: Repository owner path. Uses the client default when omitted.
388
+ :param repo: Repository path. Uses the client default when omitted.
389
+ :param payload: JSON fields required by the test request endpoint.
390
+ :returns: Test request result.
391
+ """
392
+
393
+ @abstractmethod
394
+ def update_testers(
395
+ self, *, number: Union[int, str], testers: List[str], owner: Optional[str] = None, repo: Optional[str] = None
396
+ ) -> None:
397
+ """Replace pull request testers.
398
+
399
+ :param number: Pull request number.
400
+ :param testers: New tester list; serialized as a comma-separated ``testers`` field in JSON.
401
+ :param owner: Repository owner path. Uses the client default when omitted.
402
+ :param repo: Repository path. Uses the client default when omitted.
403
+ :returns: API response payload.
404
+ """
405
+
406
+ @abstractmethod
407
+ def add_testers(
408
+ self, *, number: Union[int, str], testers: List[str], owner: Optional[str] = None, repo: Optional[str] = None
409
+ ) -> List[UserSummary]:
410
+ """Add testers to a pull request.
411
+
412
+ :param number: Pull request number.
413
+ :param testers: Usernames to add; comma-separated in the JSON body.
414
+ :param owner: Repository owner path. Uses the client default when omitted.
415
+ :param repo: Repository path. Uses the client default when omitted.
416
+ :returns: API response payload.
417
+ """
418
+
419
+ @abstractmethod
420
+ def update_assignees(
421
+ self, *, number: Union[int, str], assignees: List[str], owner: Optional[str] = None, repo: Optional[str] = None
422
+ ) -> None:
423
+ """Replace pull request assignees.
424
+
425
+ :param number: Pull request number.
426
+ :param assignees: New assignee list; comma-separated in the JSON body.
427
+ :param owner: Repository owner path. Uses the client default when omitted.
428
+ :param repo: Repository path. Uses the client default when omitted.
429
+ :returns: API response payload.
430
+ """
431
+
432
+ @abstractmethod
433
+ def add_assignees(
434
+ self, *, number: Union[int, str], assignees: List[str], owner: Optional[str] = None, repo: Optional[str] = None
435
+ ) -> PullRequestAssigneeCount:
436
+ """Add assignees to a pull request.
437
+
438
+ :param number: Pull request number.
439
+ :param assignees: Usernames to add; comma-separated in the JSON body.
440
+ :param owner: Repository owner path. Uses the client default when omitted.
441
+ :param repo: Repository path. Uses the client default when omitted.
442
+ :returns: API response payload.
443
+ """
444
+
445
+ @abstractmethod
446
+ def remove_assignees(
447
+ self, *, number: Union[int, str], assignees: List[str], owner: Optional[str] = None, repo: Optional[str] = None
448
+ ) -> None:
449
+ """Remove assignees from a pull request.
450
+
451
+ :param number: Pull request number.
452
+ :param assignees: Usernames to remove; comma-separated in the JSON body.
453
+ :param owner: Repository owner path. Uses the client default when omitted.
454
+ :param repo: Repository path. Uses the client default when omitted.
455
+ """
456
+
457
+ @abstractmethod
458
+ def list_issues(
459
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
460
+ ) -> List[Issue]:
461
+ """List issues linked to a pull request.
462
+
463
+ :param number: Pull request number.
464
+ :param owner: Repository owner path. Uses the client default when omitted.
465
+ :param repo: Repository path. Uses the client default when omitted.
466
+ :returns: Linked issues.
467
+ """
468
+
469
+ @abstractmethod
470
+ def list_enterprise(self, *, enterprise: str, **params) -> List[PullRequest]:
471
+ """List enterprise pull requests.
472
+
473
+ :param enterprise: Enterprise path or login.
474
+ :param params: Query parameters for the enterprise pull_requests listing.
475
+ :returns: Pull requests in the enterprise scope.
476
+ """
477
+
478
+ @abstractmethod
479
+ def list_org(self, *, org: str, **params) -> List[PullRequest]:
480
+ """List pull requests for an organization scope.
481
+
482
+ :param org: Organization path (``GET .../org/{org}/pull_requests``).
483
+ :param params: Query parameters accepted by that listing.
484
+ :returns: Organization-scoped pull requests.
485
+ """
486
+
487
+ @abstractmethod
488
+ def list_issue_pull_requests(self, *, enterprise: str, number: Union[int, str]) -> List[PullRequest]:
489
+ """List pull requests associated with an enterprise issue.
490
+
491
+ :param enterprise: Enterprise path or login.
492
+ :param number: Enterprise issue number or id in the path.
493
+ :returns: Related pull requests.
494
+ """
495
+
496
+ @abstractmethod
497
+ def list_templates(
498
+ self,
499
+ *,
500
+ owner: Optional[str] = None,
501
+ repo: Optional[str] = None,
502
+ ) -> List[RepositoryGitCodeTemplate]:
503
+ """List active pull request templates under ``.gitcode/`` for this repository.
504
+
505
+ Resolution tries the repository, then the owner's ``.gitcode`` repository, then any
506
+ parent main and ``parent/.gitcode`` pairs discovered from forks (each candidate is
507
+ inspected with ``GET /repos/{owner}/{repo}``; when ``fork`` is true, its parent's repos
508
+ are appended, deduplicated, and visited in order). The first source with matching
509
+ templates wins.
510
+
511
+ Version 1.2.19: Now also supporting GitHub-mirrored repos with a ``.github/`` folder.
512
+
513
+ :param owner: Repository owner path. Uses the client default when omitted.
514
+ :param repo: Repository path. Uses the client default when omitted.
515
+ :returns: Template metadata entries (paths and SHAs); empty when none match.
516
+ """
517
+
518
+ @abstractmethod
519
+ def get_template(
520
+ self,
521
+ *,
522
+ path: str,
523
+ owner: Optional[str] = None,
524
+ repo: Optional[str] = None,
525
+ encoding: str = "utf-8",
526
+ **decoding_kwargs,
527
+ ) -> str:
528
+ """Load a single pull request template file body from the default branch.
529
+
530
+ Uses the same resolution order as :meth:`list_templates`. The path must match the
531
+ active pull request template naming convention (see GitCode ``.gitcode`` documentation).
532
+
533
+ :param path: Repository-relative path such as ``.gitcode/PULL_REQUEST_TEMPLATE.md``.
534
+ :param owner: Repository owner path. Uses the client default when omitted.
535
+ :param repo: Repository path. Uses the client default when omitted.
536
+ :param encoding: Codec to use when decoding raw file bytes. Default ``utf-8``.
537
+ :param decoding_kwargs: Keyword arguments forwarded to :meth:`bytes.decode`, such as
538
+ ``errors`` (``"strict"``, ``"ignore"``, or ``"replace"``).
539
+ :returns: Decoded template file contents.
540
+ """
541
+
542
+
543
+ class PullsResource(SyncResource, AbstractPullsResource):
544
+ """Synchronous pull request endpoints."""
545
+
546
+ def list(
547
+ self,
548
+ *,
549
+ owner: Optional[str] = None,
550
+ repo: Optional[str] = None,
551
+ state: Optional[str] = None,
552
+ sort: Optional[str] = None,
553
+ direction: Optional[str] = None,
554
+ page: Optional[int] = None,
555
+ per_page: Optional[int] = None,
556
+ **params,
557
+ ) -> Union[List[PullRequest], PullRequestCount]:
558
+ path = self._client._repo_path("pulls", owner=owner, repo=repo)
559
+ response = self._request(
560
+ "GET",
561
+ path,
562
+ params={
563
+ "state": state,
564
+ "sort": sort,
565
+ "direction": direction,
566
+ "page": page,
567
+ "per_page": per_page,
568
+ **params,
569
+ },
570
+ )
571
+ if isinstance(response, dict):
572
+ return as_model(response, PullRequestCount)
573
+ return [as_model(item, PullRequest) for item in response]
574
+
575
+ def get(self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None) -> PullRequest:
576
+ return self._model("GET", self._client._repo_path("pulls", number, owner=owner, repo=repo), PullRequest)
577
+
578
+ def create(
579
+ self,
580
+ *,
581
+ title: str,
582
+ head: str,
583
+ base: str,
584
+ owner: Optional[str] = None,
585
+ repo: Optional[str] = None,
586
+ body: Optional[str] = None,
587
+ draft: Optional[bool] = None,
588
+ assignees: Optional[List[str]] = None,
589
+ testers: Optional[List[str]] = None,
590
+ labels: Optional[List[str]] = None,
591
+ milestone_number: Optional[int] = None,
592
+ issue: Optional[str] = None,
593
+ prune_source_branch: Optional[bool] = None,
594
+ squash: Optional[bool] = None,
595
+ squash_commit_message: Optional[str] = None,
596
+ fork_path: Optional[str] = None,
597
+ ) -> PullRequest:
598
+ return self._model(
599
+ "POST",
600
+ self._client._repo_path("pulls", owner=owner, repo=repo),
601
+ PullRequest,
602
+ json={
603
+ "title": title,
604
+ "head": head,
605
+ "base": base,
606
+ "body": body,
607
+ "draft": draft,
608
+ "assignees": _comma_join(assignees),
609
+ "testers": _comma_join(testers),
610
+ "labels": _comma_join(labels),
611
+ "milestone_number": milestone_number,
612
+ "issue": issue,
613
+ "prune_source_branch": prune_source_branch,
614
+ "squash": squash,
615
+ "squash_commit_message": squash_commit_message,
616
+ "fork_path": fork_path,
617
+ },
618
+ )
619
+
620
+ def update(
621
+ self,
622
+ *,
623
+ number: Union[int, str],
624
+ owner: Optional[str] = None,
625
+ repo: Optional[str] = None,
626
+ title: Optional[str] = None,
627
+ body: Optional[str] = None,
628
+ state: Optional[str] = None,
629
+ base: Optional[str] = None,
630
+ labels: Optional[List[str]] = None,
631
+ draft: Optional[bool] = None,
632
+ ) -> PullRequest:
633
+ return self._model(
634
+ "PATCH",
635
+ self._client._repo_path("pulls", number, owner=owner, repo=repo),
636
+ PullRequest,
637
+ json={
638
+ "title": title,
639
+ "body": body,
640
+ "state": state,
641
+ "base": base,
642
+ "labels": _comma_join(labels),
643
+ "draft": draft,
644
+ },
645
+ )
646
+
647
+ def merge(
648
+ self,
649
+ *,
650
+ number: Union[int, str],
651
+ owner: Optional[str] = None,
652
+ repo: Optional[str] = None,
653
+ merge_commit_message: Optional[str] = None,
654
+ squash: Optional[bool] = None,
655
+ ) -> MergeResult:
656
+ return self._model(
657
+ "PUT",
658
+ self._client._repo_path("pulls", number, "merge", owner=owner, repo=repo),
659
+ MergeResult,
660
+ json={"merge_commit_message": merge_commit_message, "squash": squash},
661
+ )
662
+
663
+ def get_merge_status(
664
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
665
+ ) -> MergeStatus:
666
+ return self._model(
667
+ "GET",
668
+ self._client._repo_path("pulls", number, "merge", owner=owner, repo=repo),
669
+ MergeStatus,
670
+ )
671
+
672
+ def list_commits(
673
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
674
+ ) -> List[APIObject]:
675
+ data = self._request("GET", self._client._repo_path("pulls", number, "commits", owner=owner, repo=repo))
676
+ return [as_model(item, APIObject) for item in data]
677
+
678
+ def list_files(
679
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
680
+ ) -> List[PullRequestFile]:
681
+ return self._models(
682
+ "GET",
683
+ self._client._repo_path("pulls", number, "files", owner=owner, repo=repo),
684
+ PullRequestFile,
685
+ )
686
+
687
+ def list_comments(
688
+ self,
689
+ *,
690
+ number: Union[int, str],
691
+ owner: Optional[str] = None,
692
+ repo: Optional[str] = None,
693
+ page: Optional[int] = None,
694
+ per_page: Optional[int] = None,
695
+ ) -> List[PullRequestComment]:
696
+ return self._models(
697
+ "GET",
698
+ self._client._repo_path("pulls", number, "comments", owner=owner, repo=repo),
699
+ PullRequestComment,
700
+ params={"page": page, "per_page": per_page},
701
+ )
702
+
703
+ def create_comment(
704
+ self,
705
+ *,
706
+ number: Union[int, str],
707
+ body: str,
708
+ owner: Optional[str] = None,
709
+ repo: Optional[str] = None,
710
+ commit_id: Optional[str] = None,
711
+ path: Optional[str] = None,
712
+ position: Optional[int] = None,
713
+ ) -> PullRequestComment:
714
+ return self._model(
715
+ "POST",
716
+ self._client._repo_path("pulls", number, "comments", owner=owner, repo=repo),
717
+ PullRequestComment,
718
+ json={"body": body, "commit_id": commit_id, "path": path, "position": position},
719
+ )
720
+
721
+ def get_comment(
722
+ self,
723
+ *,
724
+ comment_id: Union[int, str],
725
+ owner: Optional[str] = None,
726
+ repo: Optional[str] = None,
727
+ ) -> PullRequestComment:
728
+ return self._model(
729
+ "GET",
730
+ self._client._repo_path("pulls", "comments", comment_id, owner=owner, repo=repo),
731
+ PullRequestComment,
732
+ )
733
+
734
+ def update_comment(
735
+ self,
736
+ *,
737
+ comment_id: Union[int, str],
738
+ body: str,
739
+ owner: Optional[str] = None,
740
+ repo: Optional[str] = None,
741
+ ) -> PullRequestComment:
742
+ return self._model(
743
+ "PATCH",
744
+ self._client._repo_path("pulls", "comments", comment_id, owner=owner, repo=repo),
745
+ PullRequestComment,
746
+ json={"body": body},
747
+ )
748
+
749
+ def delete_comment(
750
+ self, *, comment_id: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
751
+ ) -> None:
752
+ self._request("DELETE", self._client._repo_path("pulls", "comments", comment_id, owner=owner, repo=repo))
753
+
754
+ def list_labels(
755
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
756
+ ) -> List[Label]:
757
+ return self._models(
758
+ "GET",
759
+ self._client._repo_path("pulls", number, "labels", owner=owner, repo=repo),
760
+ Label,
761
+ )
762
+
763
+ def add_labels(
764
+ self, *, number: Union[int, str], labels: List[str], owner: Optional[str] = None, repo: Optional[str] = None
765
+ ) -> List[Label]:
766
+ return self._models(
767
+ "POST",
768
+ self._client._repo_path("pulls", number, "labels", owner=owner, repo=repo),
769
+ Label,
770
+ json=labels,
771
+ )
772
+
773
+ def replace_labels(
774
+ self, *, number: Union[int, str], labels: List[str], owner: Optional[str] = None, repo: Optional[str] = None
775
+ ) -> List[Label]:
776
+ return self._models(
777
+ "PUT",
778
+ self._client._repo_path("pulls", number, "labels", owner=owner, repo=repo),
779
+ Label,
780
+ json=labels,
781
+ )
782
+
783
+ def remove_label(
784
+ self, *, number: Union[int, str], label: str, owner: Optional[str] = None, repo: Optional[str] = None
785
+ ) -> None:
786
+ self._request("DELETE", self._client._repo_path("pulls", number, "labels", label, owner=owner, repo=repo))
787
+
788
+ def request_review(
789
+ self,
790
+ *,
791
+ number: Union[int, str],
792
+ owner: Optional[str] = None,
793
+ repo: Optional[str] = None,
794
+ event: str,
795
+ body: Optional[str] = None,
796
+ ) -> None:
797
+ self._request(
798
+ "POST",
799
+ self._client._repo_path("pulls", number, "review", owner=owner, repo=repo),
800
+ json={"event": event, "body": body},
801
+ )
802
+
803
+ def list_operation_logs(
804
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None, **params
805
+ ) -> List[PullRequestOperationLog]:
806
+ data = self._request(
807
+ "GET",
808
+ self._client._repo_path("pulls", number, "operate_logs", owner=owner, repo=repo),
809
+ params=params,
810
+ )
811
+ return [as_model(item, PullRequestOperationLog) for item in data]
812
+
813
+ def request_test(
814
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None, **payload
815
+ ) -> None:
816
+ self._request(
817
+ "POST",
818
+ self._client._repo_path("pulls", number, "test", owner=owner, repo=repo),
819
+ json=payload,
820
+ )
821
+
822
+ def update_testers(
823
+ self, *, number: Union[int, str], testers: List[str], owner: Optional[str] = None, repo: Optional[str] = None
824
+ ) -> None:
825
+ self._request(
826
+ "PATCH",
827
+ self._client._repo_path("pulls", number, "testers", owner=owner, repo=repo),
828
+ json={"testers": _comma_join(testers)},
829
+ )
830
+
831
+ def add_testers(
832
+ self, *, number: Union[int, str], testers: List[str], owner: Optional[str] = None, repo: Optional[str] = None
833
+ ) -> List[UserSummary]:
834
+ data = self._request(
835
+ "POST",
836
+ self._client._repo_path("pulls", number, "testers", owner=owner, repo=repo),
837
+ json={"testers": _comma_join(testers)},
838
+ )
839
+ return [as_model(item, UserSummary) for item in data]
840
+
841
+ def update_assignees(
842
+ self, *, number: Union[int, str], assignees: List[str], owner: Optional[str] = None, repo: Optional[str] = None
843
+ ) -> None:
844
+ self._request(
845
+ "PATCH",
846
+ self._client._repo_path("pulls", number, "assignees", owner=owner, repo=repo),
847
+ json={"assignees": _comma_join(assignees)},
848
+ )
849
+
850
+ def add_assignees(
851
+ self, *, number: Union[int, str], assignees: List[str], owner: Optional[str] = None, repo: Optional[str] = None
852
+ ) -> PullRequestAssigneeCount:
853
+ return self._model(
854
+ "POST",
855
+ self._client._repo_path("pulls", number, "assignees", owner=owner, repo=repo),
856
+ PullRequestAssigneeCount,
857
+ json={"assignees": _comma_join(assignees)},
858
+ )
859
+
860
+ def remove_assignees(
861
+ self, *, number: Union[int, str], assignees: List[str], owner: Optional[str] = None, repo: Optional[str] = None
862
+ ) -> None:
863
+ self._request(
864
+ "DELETE",
865
+ self._client._repo_path("pulls", number, "assignees", owner=owner, repo=repo),
866
+ json={"assignees": _comma_join(assignees)},
867
+ )
868
+
869
+ def list_issues(
870
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
871
+ ) -> List[Issue]:
872
+ return self._models("GET", self._client._repo_path("pulls", number, "issues", owner=owner, repo=repo), Issue)
873
+
874
+ def list_enterprise(self, *, enterprise: str, **params) -> List[PullRequest]:
875
+ return self._models(
876
+ "GET", self._client._path("enterprises", enterprise, "pull_requests"), PullRequest, params=params
877
+ )
878
+
879
+ def list_org(self, *, org: str, **params) -> List[PullRequest]:
880
+ return self._models("GET", self._client._path("org", org, "pull_requests"), PullRequest, params=params)
881
+
882
+ def list_issue_pull_requests(self, *, enterprise: str, number: Union[int, str]) -> List[PullRequest]:
883
+ return self._models(
884
+ "GET",
885
+ self._client._path("enterprises", enterprise, "issues", number, "pull_requests"),
886
+ PullRequest,
887
+ )
888
+
889
+ def list_templates(
890
+ self,
891
+ *,
892
+ owner: Optional[str] = None,
893
+ repo: Optional[str] = None,
894
+ ) -> List[RepositoryGitCodeTemplate]:
895
+ resolved_owner, resolved_repo = self._client._resolve_repo_context(owner, repo)
896
+ rows = list_gitcode_template_rows_sync(
897
+ self._client, resolved_owner, resolved_repo, GITCODE_PULL_REQUEST_TEMPLATE_PATH_RE
898
+ )
899
+ return [
900
+ as_model(
901
+ {
902
+ "path": path,
903
+ "sha": sha,
904
+ "template_owner": template_owner,
905
+ "template_repo": template_repo,
906
+ },
907
+ RepositoryGitCodeTemplate,
908
+ )
909
+ for template_owner, template_repo, path, sha in rows
910
+ ]
911
+
912
+ def get_template(
913
+ self,
914
+ *,
915
+ path: str,
916
+ owner: Optional[str] = None,
917
+ repo: Optional[str] = None,
918
+ encoding: str = "utf-8",
919
+ **decoding_kwargs,
920
+ ) -> str:
921
+ resolved_owner, resolved_repo = self._client._resolve_repo_context(owner, repo)
922
+ return get_gitcode_template_body_sync(
923
+ self._client,
924
+ path,
925
+ GITCODE_PULL_REQUEST_TEMPLATE_PATH_RE,
926
+ resolved_owner,
927
+ resolved_repo,
928
+ encoding=encoding,
929
+ **decoding_kwargs,
930
+ )
931
+
932
+
933
+ class AsyncPullsResource(AsyncResource, AbstractPullsResource):
934
+ """Asynchronous pull request endpoints.
935
+
936
+ Methods correspond to :class:`PullsResource` with identical arguments and semantics,
937
+ including ``only_count`` responses documented in the Pull Request API under ``docs/rest_api``.
938
+ """
939
+
940
+ async def list(
941
+ self,
942
+ *,
943
+ owner: Optional[str] = None,
944
+ repo: Optional[str] = None,
945
+ state: Optional[str] = None,
946
+ sort: Optional[str] = None,
947
+ direction: Optional[str] = None,
948
+ page: Optional[int] = None,
949
+ per_page: Optional[int] = None,
950
+ **params,
951
+ ) -> Union[List[PullRequest], PullRequestCount]:
952
+ response = await self._request(
953
+ "GET",
954
+ self._client._repo_path("pulls", owner=owner, repo=repo),
955
+ params={
956
+ "state": state,
957
+ "sort": sort,
958
+ "direction": direction,
959
+ "page": page,
960
+ "per_page": per_page,
961
+ **params,
962
+ },
963
+ )
964
+ if isinstance(response, dict):
965
+ return as_model(response, PullRequestCount)
966
+ return [as_model(item, PullRequest) for item in response]
967
+
968
+ async def get(
969
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
970
+ ) -> PullRequest:
971
+ return await self._model("GET", self._client._repo_path("pulls", number, owner=owner, repo=repo), PullRequest)
972
+
973
+ async def create(
974
+ self,
975
+ *,
976
+ title: str,
977
+ head: str,
978
+ base: str,
979
+ owner: Optional[str] = None,
980
+ repo: Optional[str] = None,
981
+ body: Optional[str] = None,
982
+ draft: Optional[bool] = None,
983
+ assignees: Optional[List[str]] = None,
984
+ testers: Optional[List[str]] = None,
985
+ labels: Optional[List[str]] = None,
986
+ milestone_number: Optional[int] = None,
987
+ issue: Optional[str] = None,
988
+ prune_source_branch: Optional[bool] = None,
989
+ squash: Optional[bool] = None,
990
+ squash_commit_message: Optional[str] = None,
991
+ fork_path: Optional[str] = None,
992
+ ) -> PullRequest:
993
+ return await self._model(
994
+ "POST",
995
+ self._client._repo_path("pulls", owner=owner, repo=repo),
996
+ PullRequest,
997
+ json={
998
+ "title": title,
999
+ "head": head,
1000
+ "base": base,
1001
+ "body": body,
1002
+ "draft": draft,
1003
+ "assignees": _comma_join(assignees),
1004
+ "testers": _comma_join(testers),
1005
+ "labels": _comma_join(labels),
1006
+ "milestone_number": milestone_number,
1007
+ "issue": issue,
1008
+ "prune_source_branch": prune_source_branch,
1009
+ "squash": squash,
1010
+ "squash_commit_message": squash_commit_message,
1011
+ "fork_path": fork_path,
1012
+ },
1013
+ )
1014
+
1015
+ async def update(
1016
+ self,
1017
+ *,
1018
+ number: Union[int, str],
1019
+ owner: Optional[str] = None,
1020
+ repo: Optional[str] = None,
1021
+ title: Optional[str] = None,
1022
+ body: Optional[str] = None,
1023
+ state: Optional[str] = None,
1024
+ base: Optional[str] = None,
1025
+ labels: Optional[List[str]] = None,
1026
+ draft: Optional[bool] = None,
1027
+ ) -> PullRequest:
1028
+ return await self._model(
1029
+ "PATCH",
1030
+ self._client._repo_path("pulls", number, owner=owner, repo=repo),
1031
+ PullRequest,
1032
+ json={
1033
+ "title": title,
1034
+ "body": body,
1035
+ "state": state,
1036
+ "base": base,
1037
+ "labels": _comma_join(labels),
1038
+ "draft": draft,
1039
+ },
1040
+ )
1041
+
1042
+ async def merge(
1043
+ self,
1044
+ *,
1045
+ number: Union[int, str],
1046
+ owner: Optional[str] = None,
1047
+ repo: Optional[str] = None,
1048
+ merge_commit_message: Optional[str] = None,
1049
+ squash: Optional[bool] = None,
1050
+ ) -> MergeResult:
1051
+ return await self._model(
1052
+ "PUT",
1053
+ self._client._repo_path("pulls", number, "merge", owner=owner, repo=repo),
1054
+ MergeResult,
1055
+ json={"merge_commit_message": merge_commit_message, "squash": squash},
1056
+ )
1057
+
1058
+ async def get_merge_status(
1059
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
1060
+ ) -> MergeStatus:
1061
+ return await self._model(
1062
+ "GET", self._client._repo_path("pulls", number, "merge", owner=owner, repo=repo), MergeStatus
1063
+ )
1064
+
1065
+ async def list_commits(
1066
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
1067
+ ) -> List[APIObject]:
1068
+ data = await self._request("GET", self._client._repo_path("pulls", number, "commits", owner=owner, repo=repo))
1069
+ return [as_model(item, APIObject) for item in data]
1070
+
1071
+ async def list_files(
1072
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
1073
+ ) -> List[PullRequestFile]:
1074
+ return await self._models(
1075
+ "GET", self._client._repo_path("pulls", number, "files", owner=owner, repo=repo), PullRequestFile
1076
+ )
1077
+
1078
+ async def list_comments(
1079
+ self,
1080
+ *,
1081
+ number: Union[int, str],
1082
+ owner: Optional[str] = None,
1083
+ repo: Optional[str] = None,
1084
+ page: Optional[int] = None,
1085
+ per_page: Optional[int] = None,
1086
+ ) -> List[PullRequestComment]:
1087
+ return await self._models(
1088
+ "GET",
1089
+ self._client._repo_path("pulls", number, "comments", owner=owner, repo=repo),
1090
+ PullRequestComment,
1091
+ params={"page": page, "per_page": per_page},
1092
+ )
1093
+
1094
+ async def create_comment(
1095
+ self,
1096
+ *,
1097
+ number: Union[int, str],
1098
+ body: str,
1099
+ owner: Optional[str] = None,
1100
+ repo: Optional[str] = None,
1101
+ commit_id: Optional[str] = None,
1102
+ path: Optional[str] = None,
1103
+ position: Optional[int] = None,
1104
+ ) -> PullRequestComment:
1105
+ return await self._model(
1106
+ "POST",
1107
+ self._client._repo_path("pulls", number, "comments", owner=owner, repo=repo),
1108
+ PullRequestComment,
1109
+ json={"body": body, "commit_id": commit_id, "path": path, "position": position},
1110
+ )
1111
+
1112
+ async def get_comment(
1113
+ self, *, comment_id: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
1114
+ ) -> PullRequestComment:
1115
+ return await self._model(
1116
+ "GET", self._client._repo_path("pulls", "comments", comment_id, owner=owner, repo=repo), PullRequestComment
1117
+ )
1118
+
1119
+ async def update_comment(
1120
+ self, *, comment_id: Union[int, str], body: str, owner: Optional[str] = None, repo: Optional[str] = None
1121
+ ) -> PullRequestComment:
1122
+ return await self._model(
1123
+ "PATCH",
1124
+ self._client._repo_path("pulls", "comments", comment_id, owner=owner, repo=repo),
1125
+ PullRequestComment,
1126
+ json={"body": body},
1127
+ )
1128
+
1129
+ async def delete_comment(
1130
+ self, *, comment_id: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
1131
+ ) -> None:
1132
+ await self._request("DELETE", self._client._repo_path("pulls", "comments", comment_id, owner=owner, repo=repo))
1133
+
1134
+ async def list_labels(
1135
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
1136
+ ) -> List[Label]:
1137
+ return await self._models(
1138
+ "GET", self._client._repo_path("pulls", number, "labels", owner=owner, repo=repo), Label
1139
+ )
1140
+
1141
+ async def add_labels(
1142
+ self, *, number: Union[int, str], labels: List[str], owner: Optional[str] = None, repo: Optional[str] = None
1143
+ ) -> List[Label]:
1144
+ return await self._models(
1145
+ "POST", self._client._repo_path("pulls", number, "labels", owner=owner, repo=repo), Label, json=labels
1146
+ )
1147
+
1148
+ async def replace_labels(
1149
+ self, *, number: Union[int, str], labels: List[str], owner: Optional[str] = None, repo: Optional[str] = None
1150
+ ) -> List[Label]:
1151
+ return await self._models(
1152
+ "PUT", self._client._repo_path("pulls", number, "labels", owner=owner, repo=repo), Label, json=labels
1153
+ )
1154
+
1155
+ async def remove_label(
1156
+ self, *, number: Union[int, str], label: str, owner: Optional[str] = None, repo: Optional[str] = None
1157
+ ) -> None:
1158
+ await self._request("DELETE", self._client._repo_path("pulls", number, "labels", label, owner=owner, repo=repo))
1159
+
1160
+ async def request_review(
1161
+ self,
1162
+ *,
1163
+ number: Union[int, str],
1164
+ owner: Optional[str] = None,
1165
+ repo: Optional[str] = None,
1166
+ event: str,
1167
+ body: Optional[str] = None,
1168
+ ) -> None:
1169
+ await self._request(
1170
+ "POST",
1171
+ self._client._repo_path("pulls", number, "review", owner=owner, repo=repo),
1172
+ json={"event": event, "body": body},
1173
+ )
1174
+
1175
+ async def list_operation_logs(
1176
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None, **params
1177
+ ) -> List[PullRequestOperationLog]:
1178
+ data = await self._request(
1179
+ "GET", self._client._repo_path("pulls", number, "operate_logs", owner=owner, repo=repo), params=params
1180
+ )
1181
+ return [as_model(item, PullRequestOperationLog) for item in data]
1182
+
1183
+ async def request_test(
1184
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None, **payload
1185
+ ) -> None:
1186
+ await self._request(
1187
+ "POST",
1188
+ self._client._repo_path("pulls", number, "test", owner=owner, repo=repo),
1189
+ json=payload,
1190
+ )
1191
+
1192
+ async def update_testers(
1193
+ self, *, number: Union[int, str], testers: List[str], owner: Optional[str] = None, repo: Optional[str] = None
1194
+ ) -> None:
1195
+ await self._request(
1196
+ "PATCH",
1197
+ self._client._repo_path("pulls", number, "testers", owner=owner, repo=repo),
1198
+ json={"testers": _comma_join(testers)},
1199
+ )
1200
+
1201
+ async def add_testers(
1202
+ self, *, number: Union[int, str], testers: List[str], owner: Optional[str] = None, repo: Optional[str] = None
1203
+ ) -> List[UserSummary]:
1204
+ data = await self._request(
1205
+ "POST",
1206
+ self._client._repo_path("pulls", number, "testers", owner=owner, repo=repo),
1207
+ json={"testers": _comma_join(testers)},
1208
+ )
1209
+ return [as_model(item, UserSummary) for item in data]
1210
+
1211
+ async def update_assignees(
1212
+ self, *, number: Union[int, str], assignees: List[str], owner: Optional[str] = None, repo: Optional[str] = None
1213
+ ) -> None:
1214
+ await self._request(
1215
+ "PATCH",
1216
+ self._client._repo_path("pulls", number, "assignees", owner=owner, repo=repo),
1217
+ json={"assignees": _comma_join(assignees)},
1218
+ )
1219
+
1220
+ async def add_assignees(
1221
+ self, *, number: Union[int, str], assignees: List[str], owner: Optional[str] = None, repo: Optional[str] = None
1222
+ ) -> PullRequestAssigneeCount:
1223
+ return await self._model(
1224
+ "POST",
1225
+ self._client._repo_path("pulls", number, "assignees", owner=owner, repo=repo),
1226
+ PullRequestAssigneeCount,
1227
+ json={"assignees": _comma_join(assignees)},
1228
+ )
1229
+
1230
+ async def remove_assignees(
1231
+ self, *, number: Union[int, str], assignees: List[str], owner: Optional[str] = None, repo: Optional[str] = None
1232
+ ) -> None:
1233
+ await self._request(
1234
+ "DELETE",
1235
+ self._client._repo_path("pulls", number, "assignees", owner=owner, repo=repo),
1236
+ json={"assignees": _comma_join(assignees)},
1237
+ )
1238
+
1239
+ async def list_issues(
1240
+ self, *, number: Union[int, str], owner: Optional[str] = None, repo: Optional[str] = None
1241
+ ) -> List[Issue]:
1242
+ return await self._models(
1243
+ "GET", self._client._repo_path("pulls", number, "issues", owner=owner, repo=repo), Issue
1244
+ )
1245
+
1246
+ async def list_enterprise(self, *, enterprise: str, **params) -> List[PullRequest]:
1247
+ return await self._models(
1248
+ "GET", self._client._path("enterprises", enterprise, "pull_requests"), PullRequest, params=params
1249
+ )
1250
+
1251
+ async def list_org(self, *, org: str, **params) -> List[PullRequest]:
1252
+ return await self._models("GET", self._client._path("org", org, "pull_requests"), PullRequest, params=params)
1253
+
1254
+ async def list_issue_pull_requests(self, *, enterprise: str, number: Union[int, str]) -> List[PullRequest]:
1255
+ return await self._models(
1256
+ "GET", self._client._path("enterprises", enterprise, "issues", number, "pull_requests"), PullRequest
1257
+ )
1258
+
1259
+ async def list_templates(
1260
+ self,
1261
+ *,
1262
+ owner: Optional[str] = None,
1263
+ repo: Optional[str] = None,
1264
+ ) -> List[RepositoryGitCodeTemplate]:
1265
+ resolved_owner, resolved_repo = self._client._resolve_repo_context(owner, repo)
1266
+ rows = await list_gitcode_template_rows_async(
1267
+ self._client, resolved_owner, resolved_repo, GITCODE_PULL_REQUEST_TEMPLATE_PATH_RE
1268
+ )
1269
+ return [
1270
+ as_model(
1271
+ {
1272
+ "path": path,
1273
+ "sha": sha,
1274
+ "template_owner": template_owner,
1275
+ "template_repo": template_repo,
1276
+ },
1277
+ RepositoryGitCodeTemplate,
1278
+ )
1279
+ for template_owner, template_repo, path, sha in rows
1280
+ ]
1281
+
1282
+ async def get_template(
1283
+ self,
1284
+ *,
1285
+ path: str,
1286
+ owner: Optional[str] = None,
1287
+ repo: Optional[str] = None,
1288
+ encoding: str = "utf-8",
1289
+ **decoding_kwargs,
1290
+ ) -> str:
1291
+ resolved_owner, resolved_repo = self._client._resolve_repo_context(owner, repo)
1292
+ return await get_gitcode_template_body_async(
1293
+ self._client,
1294
+ path,
1295
+ GITCODE_PULL_REQUEST_TEMPLATE_PATH_RE,
1296
+ resolved_owner,
1297
+ resolved_repo,
1298
+ encoding=encoding,
1299
+ **decoding_kwargs,
1300
+ )