gitcode-api 1.0.3__tar.gz → 1.1.0__tar.gz

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 (30) hide show
  1. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/PKG-INFO +33 -17
  2. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/README.md +30 -13
  3. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/resources/_shared.py +60 -7
  4. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/resources/account.py +242 -7
  5. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/resources/collaboration.py +1039 -77
  6. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/resources/misc.py +256 -21
  7. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/resources/repositories.py +408 -6
  8. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api.egg-info/PKG-INFO +33 -17
  9. gitcode_api-1.1.0/gitcode_api.egg-info/requires.txt +1 -0
  10. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/pyproject.toml +3 -4
  11. gitcode_api-1.1.0/tests/test_client.py +89 -0
  12. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/tests/test_resources_misc.py +1 -0
  13. gitcode_api-1.0.3/gitcode_api.egg-info/requires.txt +0 -2
  14. gitcode_api-1.0.3/tests/test_client.py +0 -35
  15. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/LICENSE +0 -0
  16. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/__init__.py +0 -0
  17. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/_base_client.py +0 -0
  18. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/_client.py +0 -0
  19. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/_exceptions.py +0 -0
  20. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/_models.py +0 -0
  21. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api/resources/__init__.py +0 -0
  22. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api.egg-info/SOURCES.txt +0 -0
  23. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api.egg-info/dependency_links.txt +0 -0
  24. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/gitcode_api.egg-info/top_level.txt +0 -0
  25. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/setup.cfg +0 -0
  26. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/tests/test_base_client.py +0 -0
  27. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/tests/test_models.py +0 -0
  28. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/tests/test_resources_account.py +0 -0
  29. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/tests/test_resources_collaboration.py +0 -0
  30. {gitcode_api-1.0.3 → gitcode_api-1.1.0}/tests/test_resources_repositories.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitcode-api
3
- Version: 1.0.3
3
+ Version: 1.1.0
4
4
  Summary: Easy to use Python SDK for the GitCode REST API, community-maintained.
5
5
  Author-email: Hugo Huang <hugo@hugohuang.com>
6
6
  License-Expression: MIT
7
- Project-URL: github, https://github.com/Trenza1ore/GitCode-API
7
+ Project-URL: documentation, https://gitcode-api.readthedocs.io
8
8
  Project-URL: gitcode, https://gitcode.com/SushiNinja/GitCode-API
9
- Project-URL: documentation, https://gitcode-api.readthedocs.io/en/latest/index.html
9
+ Project-URL: github, https://github.com/Trenza1ore/GitCode-API
10
10
  Keywords: gitcode,git,devops,api,sdk,python,httpx,client
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Programming Language :: Python
@@ -23,12 +23,11 @@ Requires-Python: <4,>=3.9
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
25
  Requires-Dist: httpx
26
- Requires-Dist: python-dotenv
27
26
  Dynamic: license-file
28
27
 
29
28
  # GitCode-API
30
29
 
31
- ![PyPI - Version](https://img.shields.io/pypi/v/gitcode-api) ![GitHub Badge](https://img.shields.io/badge/github-repo-blue?logo=github&link=https%3A%2F%2Fgithub.com%2FTrenza1ore%2FGitCode-API) ![GitCode Badge](https://img.shields.io/badge/gitcode-repo-brown?logo=gitcode&link=https%3A%2F%2Fgitcode.com%2FSushiNinja%2FGitCode-API) ![PyPI - License](https://img.shields.io/pypi/l/gitcode-api)
30
+ ![PyPI - Version](https://img.shields.io/pypi/v/gitcode-api?link=https%3A%2F%2Fpypi.org%2Fproject%2Fgitcode-api%2F) ![GitHub Badge](https://img.shields.io/badge/github-repo-blue?logo=github&link=https%3A%2F%2Fgithub.com%2FTrenza1ore%2FGitCode-API) ![GitCode Badge](https://img.shields.io/badge/gitcode-repo-brown?logo=gitcode&link=https%3A%2F%2Fgitcode.com%2FSushiNinja%2FGitCode-API) ![PyPI - License](https://img.shields.io/pypi/l/gitcode-api)
32
31
 
33
32
  ![Docs](https://img.shields.io/badge/%E6%96%87%E6%A1%A3-Docs-cyan?style=for-the-badge&logo=readthedocs&link=https%3A%2F%2Fgitcode-api.readthedocs.io%2Fen%2Flatest%2Findex.html) ![中文README](https://img.shields.io/badge/%E4%B8%AD%E6%96%87-README-brown?style=for-the-badge&logo=googledocs&link=README.zh.md) ![English README](https://img.shields.io/badge/English-README-blue?style=for-the-badge&logo=googledocs&link=README.md)
34
33
 
@@ -50,18 +49,6 @@ Install from PyPI:
50
49
  pip install gitcode-api
51
50
  ```
52
51
 
53
- For local development from source:
54
-
55
- ```bash
56
- uv sync
57
- ```
58
-
59
- Install documentation dependencies:
60
-
61
- ```bash
62
- uv sync --group docs
63
- ```
64
-
65
52
  ## Authentication
66
53
 
67
54
  Pass `api_key=` directly, or set `GITCODE_ACCESS_TOKEN` in your environment:
@@ -113,6 +100,35 @@ async def main() -> None:
113
100
  asyncio.run(main())
114
101
  ```
115
102
 
103
+ ### Context managers
104
+
105
+ `GitCode` and `AsyncGitCode` (and the lower-level `SyncAPIClient` / `AsyncAPIClient`) support `with` / `async with`. When the SDK creates the underlying httpx client for you, leaving the block calls `close()` / `await close()` on that client automatically.
106
+
107
+ ```python
108
+ from gitcode_api import GitCode
109
+
110
+ with GitCode(owner="SushiNinja", repo="GitCode-API") as client:
111
+ repo = client.repos.get()
112
+ print(repo.full_name)
113
+ ```
114
+
115
+ ```python
116
+ import asyncio
117
+
118
+ from gitcode_api import AsyncGitCode
119
+
120
+
121
+ async def main() -> None:
122
+ async with AsyncGitCode(owner="SushiNinja", repo="GitCode-API") as client:
123
+ pulls = await client.pulls.list(state="open", per_page=20)
124
+ print(len(pulls))
125
+
126
+
127
+ asyncio.run(main())
128
+ ```
129
+
130
+ If you pass a custom `http_client=`, the SDK does not close it; you still own that client’s lifecycle (for example `async with httpx.AsyncClient(...) as http:` plus `AsyncGitCode(http_client=http)`).
131
+
116
132
  ## Common Workflows
117
133
 
118
134
  Create a pull request:
@@ -1,6 +1,6 @@
1
1
  # GitCode-API
2
2
 
3
- ![PyPI - Version](https://img.shields.io/pypi/v/gitcode-api) ![GitHub Badge](https://img.shields.io/badge/github-repo-blue?logo=github&link=https%3A%2F%2Fgithub.com%2FTrenza1ore%2FGitCode-API) ![GitCode Badge](https://img.shields.io/badge/gitcode-repo-brown?logo=gitcode&link=https%3A%2F%2Fgitcode.com%2FSushiNinja%2FGitCode-API) ![PyPI - License](https://img.shields.io/pypi/l/gitcode-api)
3
+ ![PyPI - Version](https://img.shields.io/pypi/v/gitcode-api?link=https%3A%2F%2Fpypi.org%2Fproject%2Fgitcode-api%2F) ![GitHub Badge](https://img.shields.io/badge/github-repo-blue?logo=github&link=https%3A%2F%2Fgithub.com%2FTrenza1ore%2FGitCode-API) ![GitCode Badge](https://img.shields.io/badge/gitcode-repo-brown?logo=gitcode&link=https%3A%2F%2Fgitcode.com%2FSushiNinja%2FGitCode-API) ![PyPI - License](https://img.shields.io/pypi/l/gitcode-api)
4
4
 
5
5
  ![Docs](https://img.shields.io/badge/%E6%96%87%E6%A1%A3-Docs-cyan?style=for-the-badge&logo=readthedocs&link=https%3A%2F%2Fgitcode-api.readthedocs.io%2Fen%2Flatest%2Findex.html) ![中文README](https://img.shields.io/badge/%E4%B8%AD%E6%96%87-README-brown?style=for-the-badge&logo=googledocs&link=README.zh.md) ![English README](https://img.shields.io/badge/English-README-blue?style=for-the-badge&logo=googledocs&link=README.md)
6
6
 
@@ -22,18 +22,6 @@ Install from PyPI:
22
22
  pip install gitcode-api
23
23
  ```
24
24
 
25
- For local development from source:
26
-
27
- ```bash
28
- uv sync
29
- ```
30
-
31
- Install documentation dependencies:
32
-
33
- ```bash
34
- uv sync --group docs
35
- ```
36
-
37
25
  ## Authentication
38
26
 
39
27
  Pass `api_key=` directly, or set `GITCODE_ACCESS_TOKEN` in your environment:
@@ -85,6 +73,35 @@ async def main() -> None:
85
73
  asyncio.run(main())
86
74
  ```
87
75
 
76
+ ### Context managers
77
+
78
+ `GitCode` and `AsyncGitCode` (and the lower-level `SyncAPIClient` / `AsyncAPIClient`) support `with` / `async with`. When the SDK creates the underlying httpx client for you, leaving the block calls `close()` / `await close()` on that client automatically.
79
+
80
+ ```python
81
+ from gitcode_api import GitCode
82
+
83
+ with GitCode(owner="SushiNinja", repo="GitCode-API") as client:
84
+ repo = client.repos.get()
85
+ print(repo.full_name)
86
+ ```
87
+
88
+ ```python
89
+ import asyncio
90
+
91
+ from gitcode_api import AsyncGitCode
92
+
93
+
94
+ async def main() -> None:
95
+ async with AsyncGitCode(owner="SushiNinja", repo="GitCode-API") as client:
96
+ pulls = await client.pulls.list(state="open", per_page=20)
97
+ print(len(pulls))
98
+
99
+
100
+ asyncio.run(main())
101
+ ```
102
+
103
+ If you pass a custom `http_client=`, the SDK does not close it; you still own that client’s lifecycle (for example `async with httpx.AsyncClient(...) as http:` plus `AsyncGitCode(http_client=http)`).
104
+
88
105
  ## Common Workflows
89
106
 
90
107
  Create a pull request:
@@ -23,21 +23,51 @@ class SyncResource:
23
23
  data: Optional[Dict[str, Any]] = None,
24
24
  raw: bool = False,
25
25
  ) -> Any:
26
- """Dispatch a low-level request through the owning client."""
26
+ """Dispatch a low-level request through the owning client.
27
+
28
+ :param method: HTTP verb (for example ``GET`` or ``POST``).
29
+ :param path: Absolute or root-relative URL path.
30
+ :param params: Optional query string parameters.
31
+ :param json: Optional JSON-serializable request body.
32
+ :param data: Optional form or body fields.
33
+ :param raw: When ``True``, return the raw response body (for example bytes).
34
+ :returns: Parsed JSON, raw body, or other value from the client.
35
+ """
27
36
  return self._client.request(method, path, params=params, json=json, data=data, raw=raw)
28
37
 
29
38
  def _model(self, method: str, path: str, model_type: type[ModelT], **kwargs: Any) -> ModelT:
30
- """Send a request and wrap a JSON object in ``model_type``."""
39
+ """Send a request and wrap a JSON object in ``model_type``.
40
+
41
+ :param method: HTTP verb.
42
+ :param path: Request path.
43
+ :param model_type: Model class for the top-level JSON object.
44
+ :param kwargs: Forwarded to :meth:`_request` (``params``, ``json``, ``data``, ``raw``, etc.).
45
+ :returns: An instance of ``model_type``.
46
+ """
31
47
  data = self._request(method, path, **kwargs)
32
48
  return as_model(data, model_type)
33
49
 
34
50
  def _models(self, method: str, path: str, model_type: type[ModelT], **kwargs: Any) -> List[ModelT]:
35
- """Send a request and wrap a JSON array in ``model_type`` instances."""
51
+ """Send a request and wrap a JSON array in ``model_type`` instances.
52
+
53
+ :param method: HTTP verb.
54
+ :param path: Request path.
55
+ :param model_type: Model class for each element of the JSON array.
56
+ :param kwargs: Forwarded to :meth:`_request`.
57
+ :returns: A list of ``model_type`` instances.
58
+ """
36
59
  data = self._request(method, path, **kwargs)
37
60
  return as_model_list(data, model_type)
38
61
 
39
62
  def _maybe_model(self, method: str, path: str, model_type: type[ModelT], **kwargs: Any) -> Union[ModelT, APIObject]:
40
- """Wrap dict responses as models and scalar responses as ``APIObject``."""
63
+ """Wrap dict responses as models and scalar responses as ``APIObject``.
64
+
65
+ :param method: HTTP verb.
66
+ :param path: Request path.
67
+ :param model_type: Model class when the response is a JSON object.
68
+ :param kwargs: Forwarded to :meth:`_request`.
69
+ :returns: ``model_type`` for dict bodies; otherwise ``APIObject`` wrapping a ``value`` field.
70
+ """
41
71
  data = self._request(method, path, **kwargs)
42
72
  if isinstance(data, dict):
43
73
  return as_model(data, model_type)
@@ -61,15 +91,38 @@ class AsyncResource:
61
91
  data: Optional[Dict[str, Any]] = None,
62
92
  raw: bool = False,
63
93
  ) -> Any:
64
- """Dispatch a low-level async request through the owning client."""
94
+ """Dispatch a low-level async request through the owning client.
95
+
96
+ :param method: HTTP verb (for example ``GET`` or ``POST``).
97
+ :param path: Absolute or root-relative URL path.
98
+ :param params: Optional query string parameters.
99
+ :param json: Optional JSON-serializable request body.
100
+ :param data: Optional form or body fields.
101
+ :param raw: When ``True``, return the raw response body (for example bytes).
102
+ :returns: Parsed JSON, raw body, or other value from the client.
103
+ """
65
104
  return await self._client.request(method, path, params=params, json=json, data=data, raw=raw)
66
105
 
67
106
  async def _model(self, method: str, path: str, model_type: type[ModelT], **kwargs: Any) -> ModelT:
68
- """Send a request and wrap a JSON object in ``model_type``."""
107
+ """Send a request and wrap a JSON object in ``model_type``.
108
+
109
+ :param method: HTTP verb.
110
+ :param path: Request path.
111
+ :param model_type: Model class for the top-level JSON object.
112
+ :param kwargs: Forwarded to :meth:`_request`.
113
+ :returns: An instance of ``model_type``.
114
+ """
69
115
  data = await self._request(method, path, **kwargs)
70
116
  return as_model(data, model_type)
71
117
 
72
118
  async def _models(self, method: str, path: str, model_type: type[ModelT], **kwargs: Any) -> List[ModelT]:
73
- """Send a request and wrap a JSON array in ``model_type`` instances."""
119
+ """Send a request and wrap a JSON array in ``model_type`` instances.
120
+
121
+ :param method: HTTP verb.
122
+ :param path: Request path.
123
+ :param model_type: Model class for each element of the JSON array.
124
+ :param kwargs: Forwarded to :meth:`_request`.
125
+ :returns: A list of ``model_type`` instances.
126
+ """
74
127
  data = await self._request(method, path, **kwargs)
75
128
  return as_model_list(data, model_type)