gitcode-api 1.2.7__tar.gz → 1.2.9__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.
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/PKG-INFO +33 -9
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/README.md +27 -6
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/cli.py +0 -1
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/llm/__init__.py +3 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/llm/_tool.py +2 -4
- gitcode_api-1.2.9/gitcode_api/llm/jiuwen.py +97 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/llm/mcp.py +2 -6
- gitcode_api-1.2.9/gitcode_api/run_mcp.py +6 -0
- gitcode_api-1.2.9/gitcode_api/version.txt +1 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api.egg-info/PKG-INFO +33 -9
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api.egg-info/SOURCES.txt +3 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/pyproject.toml +6 -3
- gitcode_api-1.2.9/tests/test_build_manifest.py +94 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/tests/test_llm_tools.py +60 -6
- gitcode_api-1.2.7/gitcode_api/version.txt +0 -1
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/LICENSE +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/__init__.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/__main__.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/_base_client.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/_base_resource.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/_cli_banner.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/_client.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/_exceptions.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/_models.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/llm/openai.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/py.typed +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/resources/__init__.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/resources/_shared.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/resources/account.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/resources/collaboration.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/resources/misc.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api/resources/repositories.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api.egg-info/dependency_links.txt +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api.egg-info/entry_points.txt +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api.egg-info/requires.txt +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/gitcode_api.egg-info/top_level.txt +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/setup.cfg +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/tests/test_base_client.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/tests/test_cli.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/tests/test_client.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/tests/test_models.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/tests/test_resources_account.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/tests/test_resources_collaboration.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/tests/test_resources_misc.py +0 -0
- {gitcode_api-1.2.7 → gitcode_api-1.2.9}/tests/test_resources_repositories.py +0 -0
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitcode-api
|
|
3
|
-
Version: 1.2.
|
|
4
|
-
Summary: Easy to use Python SDK for the GitCode REST API. Providing builtin CLI tool, and optional LLM integration (MCP and
|
|
3
|
+
Version: 1.2.9
|
|
4
|
+
Summary: Easy to use Python SDK for the GitCode REST API. Providing builtin CLI tool, and optional LLM integration (MCP, OpenAI tool, and openJiuwen tool) for agents. Community-maintained.
|
|
5
5
|
Author-email: Hugo Huang <hugo@hugohuang.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: changelog, https://gitcode-api.readthedocs.io/en/latest/changelog.html
|
|
8
|
+
Project-URL: issues, https://github.com/Trenza1ore/GitCode-API/issues
|
|
8
9
|
Project-URL: documentation, https://gitcode-api.readthedocs.io
|
|
9
10
|
Project-URL: gitcode, https://gitcode.com/SushiNinja/GitCode-API
|
|
10
11
|
Project-URL: github, https://github.com/Trenza1ore/GitCode-API
|
|
11
|
-
|
|
12
|
+
Project-URL: homepage, https://linktr.ee/Hugoooo
|
|
13
|
+
Project-URL: author, https://hugohuang.com
|
|
14
|
+
Keywords: gitcode,git,devops,api,sdk,python,httpx,client,mcp,agent,fastmcp,llm,openjiuwen,mcp client,mcp server,model context protocol
|
|
12
15
|
Classifier: Development Status :: 4 - Beta
|
|
13
16
|
Classifier: Programming Language :: Python
|
|
14
17
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
@@ -35,12 +38,12 @@ Dynamic: license-file
|
|
|
35
38
|
# GitCode-API
|
|
36
39
|
|
|
37
40
|
[](https://pypi.org/project/gitcode-api) [](https://pepy.tech/projects/gitcode-api) [](https://www.codefactor.io/repository/github/trenza1ore/gitcode-api)
|
|
38
|
-
[](https://cursor.com/en/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19) [](https://vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
39
42
|
[](https://github.com/Trenza1ore/GitCode-API) [](https://gitcode.com/SushiNinja/GitCode-API)
|
|
40
43
|
|
|
41
44
|
[](https://gitcode-api.readthedocs.io) [](README.zh.md)
|
|
42
45
|
|
|
43
|
-
`gitcode-api` is a community-maintained Python SDK for the GitCode REST API. It provides easy-to-use synchronous and asynchronous clients, repository-scoped helpers, and lightweight response models so you can work with GitCode from Python without hand-writing raw HTTP requests. The `gitcode_api.llm` module adds an OpenAI-style function tool
|
|
46
|
+
`gitcode-api` is a community-maintained Python SDK for the GitCode REST API. It provides easy-to-use synchronous and asynchronous clients, repository-scoped helpers, and lightweight response models so you can work with GitCode from Python without hand-writing raw HTTP requests. The `gitcode_api.llm` module adds an OpenAI-style function tool, an MCP service, and an [openJiuwen](https://openjiuwen.com) tool integration so agents can reuse the same resource-oriented API.
|
|
44
47
|
|
|
45
48
|
## Why This Project
|
|
46
49
|
|
|
@@ -49,8 +52,9 @@ Dynamic: license-file
|
|
|
49
52
|
- Resource groups such as `client.repos`, `client.pulls`, and `client.users`.
|
|
50
53
|
- Repository defaults via `owner=` and `repo=` on the client.
|
|
51
54
|
- Sphinx docs plus a mirrored GitCode REST API reference in `docs/`.
|
|
52
|
-
- Provides MCP server
|
|
55
|
+
- Provides MCP server, OpenAI tool, and [openJiuwen](https://openjiuwen.com) tool for LLM agent usage.
|
|
53
56
|
- Provide MCP service that directly installs to your IDE of choice, such as Cursor and VS Code!
|
|
57
|
+
- Provides an [mcpb bundle](https://www.anthropic.com/engineering/desktop-extensions) you can install directly in the Claude desktop app; download it from [Release](https://github.com/Trenza1ore/GitCode-API/releases/latest).
|
|
54
58
|
|
|
55
59
|
## Installation
|
|
56
60
|
|
|
@@ -61,11 +65,11 @@ pip install -U gitcode-api
|
|
|
61
65
|
```
|
|
62
66
|
|
|
63
67
|
Install the MCP server to your AI-powered IDE of choice:
|
|
68
|
+
|
|
64
69
|
[](https://cursor.com/en/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19)
|
|
65
70
|
[](https://vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
66
71
|
[](https://insiders.vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D&quality=insiders)
|
|
67
72
|
[](https://vs-open.link/mcp-install?%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
68
|
-
[](https://block.github.io/goose/extension?cmd=uvx&arg=--from%2520gitcode-api%5Bmcp%5D%2520gitcode-api%2520serve&id=GitCode%20API&name=GitCode%20API&description=MCP%20Server%20for%20GitCode%20API)
|
|
69
73
|
[](https://lmstudio.ai/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19)
|
|
70
74
|
|
|
71
75
|
For detailed setup (including installing to services like Claude Code / Codex): see [install_mcp_server.md](install_mcp_server.md).
|
|
@@ -225,7 +229,7 @@ Both `GitCode` and `AsyncGitCode` expose:
|
|
|
225
229
|
|
|
226
230
|
Every resource group inherits a cached `methods` property from the shared resource base: a `tuple` of public callable names in stable SDK order (underscore-segment sort key, not plain A–Z on the full identifier). Private names and the introspection helpers `methods` and `method_signature` are omitted. For example, `client.pulls.methods` helps with discovery or tooling without reading the full manual list. For one method’s parameters and return type, call `client.pulls.method_signature("list_issues")` (a cached string from `inspect.signature`, with `gitcode_api._models.` stripped from annotations).
|
|
227
231
|
|
|
228
|
-
## LLM tools and
|
|
232
|
+
## LLM tools, MCP, and openJiuwen
|
|
229
233
|
|
|
230
234
|
The `gitcode_api.llm` module exposes a single logical tool, **`gitcode_api_tool`**, that routes calls to sync or async SDK resources. Model-facing parameters match the JSON schema used by OpenAI-style function tools:
|
|
231
235
|
|
|
@@ -312,6 +316,26 @@ The same server is available from the CLI as `gitcode-api serve` (see the [CLI](
|
|
|
312
316
|
|
|
313
317
|
To share auth or clients across tools, build `GitCodeLLMTool` once (`from gitcode_api.llm._tool import GitCodeLLMTool`) and pass it as `tool=` into `GitCodeMCP`, `create_mcp_server`, `register_mcp_gitcode_api_tool`, or `create_mcp_gitcode_api_tool`.
|
|
314
318
|
|
|
319
|
+
### openJiuwen (`LocalFunction`)
|
|
320
|
+
|
|
321
|
+
[openJiuwen](https://openjiuwen.com) is an open agent platform. With the separate `openjiuwen` package installed (**Python 3.11+**), `create_openjiuwen_gitcode_api_tool` returns an openJiuwen `LocalFunction` that uses the same `op_type` / `action` / `params` / `help` arguments as the OpenAI adapter. Invocation is async-only (`await jiuwen_tool.invoke({...})`).
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
pip install openjiuwen
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
from gitcode_api.llm import create_openjiuwen_gitcode_api_tool
|
|
329
|
+
|
|
330
|
+
jiuwen_tool = create_openjiuwen_gitcode_api_tool(owner="SushiNinja", repo="GitCode-API")
|
|
331
|
+
# jiuwen_tool.card — name, description, input_params
|
|
332
|
+
# await jiuwen_tool.invoke({"op_type": "repos", "action": "get", "params": {}})
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Optional `name=` and `description=` override the default tool card. Constructor options otherwise mirror `GitCode` / `AsyncGitCode` (`client=`, `async_client=`, `api_key=`, `owner=`, `repo=`, `base_url=`, `timeout=`, `decrypt=`).
|
|
336
|
+
|
|
337
|
+
**Claude Desktop (MCPB):** published GitHub Releases include a `gitcode-<version>.mcpb` bundle for one-click installation as a Claude Desktop extension; see Anthropic’s guide, [Build a desktop extension with MCPB](https://claude.com/docs/connectors/building/mcpb). From a checkout you can run `make mcpb` (requires the [`@anthropic-ai/mcpb`](https://www.npmjs.com/package/@anthropic-ai/mcpb) CLI on your `PATH`).
|
|
338
|
+
|
|
315
339
|
## Examples
|
|
316
340
|
|
|
317
341
|
Runnable examples live in `examples/`:
|
|
@@ -373,7 +397,7 @@ with GitCode(
|
|
|
373
397
|
|
|
374
398
|
Use `httpx.AsyncClient(verify=...)` with `AsyncGitCode` for async code.
|
|
375
399
|
|
|
376
|
-
The OpenAI tool (`GitCodeOpenAITool`)
|
|
400
|
+
The OpenAI tool (`GitCodeOpenAITool`), MCP helpers, and `create_openjiuwen_gitcode_api_tool` accept the same `client=` / `async_client=` arguments (OpenAI and MCP also accept a shared `GitCodeLLMTool` via `tool=`). Build `GitCode` / `AsyncGitCode` with your custom `http_client` once and pass it through so LLM tool calls reuse the same TLS settings.
|
|
377
401
|
|
|
378
402
|
## Project Status
|
|
379
403
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# GitCode-API
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/gitcode-api) [](https://pepy.tech/projects/gitcode-api) [](https://www.codefactor.io/repository/github/trenza1ore/gitcode-api)
|
|
4
|
-
[](https://cursor.com/en/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19) [](https://vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
5
5
|
[](https://github.com/Trenza1ore/GitCode-API) [](https://gitcode.com/SushiNinja/GitCode-API)
|
|
6
6
|
|
|
7
7
|
[](https://gitcode-api.readthedocs.io) [](README.zh.md)
|
|
8
8
|
|
|
9
|
-
`gitcode-api` is a community-maintained Python SDK for the GitCode REST API. It provides easy-to-use synchronous and asynchronous clients, repository-scoped helpers, and lightweight response models so you can work with GitCode from Python without hand-writing raw HTTP requests. The `gitcode_api.llm` module adds an OpenAI-style function tool
|
|
9
|
+
`gitcode-api` is a community-maintained Python SDK for the GitCode REST API. It provides easy-to-use synchronous and asynchronous clients, repository-scoped helpers, and lightweight response models so you can work with GitCode from Python without hand-writing raw HTTP requests. The `gitcode_api.llm` module adds an OpenAI-style function tool, an MCP service, and an [openJiuwen](https://openjiuwen.com) tool integration so agents can reuse the same resource-oriented API.
|
|
10
10
|
|
|
11
11
|
## Why This Project
|
|
12
12
|
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
- Resource groups such as `client.repos`, `client.pulls`, and `client.users`.
|
|
16
16
|
- Repository defaults via `owner=` and `repo=` on the client.
|
|
17
17
|
- Sphinx docs plus a mirrored GitCode REST API reference in `docs/`.
|
|
18
|
-
- Provides MCP server
|
|
18
|
+
- Provides MCP server, OpenAI tool, and [openJiuwen](https://openjiuwen.com) tool for LLM agent usage.
|
|
19
19
|
- Provide MCP service that directly installs to your IDE of choice, such as Cursor and VS Code!
|
|
20
|
+
- Provides an [mcpb bundle](https://www.anthropic.com/engineering/desktop-extensions) you can install directly in the Claude desktop app; download it from [Release](https://github.com/Trenza1ore/GitCode-API/releases/latest).
|
|
20
21
|
|
|
21
22
|
## Installation
|
|
22
23
|
|
|
@@ -27,11 +28,11 @@ pip install -U gitcode-api
|
|
|
27
28
|
```
|
|
28
29
|
|
|
29
30
|
Install the MCP server to your AI-powered IDE of choice:
|
|
31
|
+
|
|
30
32
|
[](https://cursor.com/en/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19)
|
|
31
33
|
[](https://vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
32
34
|
[](https://insiders.vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D&quality=insiders)
|
|
33
35
|
[](https://vs-open.link/mcp-install?%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
34
|
-
[](https://block.github.io/goose/extension?cmd=uvx&arg=--from%2520gitcode-api%5Bmcp%5D%2520gitcode-api%2520serve&id=GitCode%20API&name=GitCode%20API&description=MCP%20Server%20for%20GitCode%20API)
|
|
35
36
|
[](https://lmstudio.ai/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19)
|
|
36
37
|
|
|
37
38
|
For detailed setup (including installing to services like Claude Code / Codex): see [install_mcp_server.md](install_mcp_server.md).
|
|
@@ -191,7 +192,7 @@ Both `GitCode` and `AsyncGitCode` expose:
|
|
|
191
192
|
|
|
192
193
|
Every resource group inherits a cached `methods` property from the shared resource base: a `tuple` of public callable names in stable SDK order (underscore-segment sort key, not plain A–Z on the full identifier). Private names and the introspection helpers `methods` and `method_signature` are omitted. For example, `client.pulls.methods` helps with discovery or tooling without reading the full manual list. For one method’s parameters and return type, call `client.pulls.method_signature("list_issues")` (a cached string from `inspect.signature`, with `gitcode_api._models.` stripped from annotations).
|
|
193
194
|
|
|
194
|
-
## LLM tools and
|
|
195
|
+
## LLM tools, MCP, and openJiuwen
|
|
195
196
|
|
|
196
197
|
The `gitcode_api.llm` module exposes a single logical tool, **`gitcode_api_tool`**, that routes calls to sync or async SDK resources. Model-facing parameters match the JSON schema used by OpenAI-style function tools:
|
|
197
198
|
|
|
@@ -278,6 +279,26 @@ The same server is available from the CLI as `gitcode-api serve` (see the [CLI](
|
|
|
278
279
|
|
|
279
280
|
To share auth or clients across tools, build `GitCodeLLMTool` once (`from gitcode_api.llm._tool import GitCodeLLMTool`) and pass it as `tool=` into `GitCodeMCP`, `create_mcp_server`, `register_mcp_gitcode_api_tool`, or `create_mcp_gitcode_api_tool`.
|
|
280
281
|
|
|
282
|
+
### openJiuwen (`LocalFunction`)
|
|
283
|
+
|
|
284
|
+
[openJiuwen](https://openjiuwen.com) is an open agent platform. With the separate `openjiuwen` package installed (**Python 3.11+**), `create_openjiuwen_gitcode_api_tool` returns an openJiuwen `LocalFunction` that uses the same `op_type` / `action` / `params` / `help` arguments as the OpenAI adapter. Invocation is async-only (`await jiuwen_tool.invoke({...})`).
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
pip install openjiuwen
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
from gitcode_api.llm import create_openjiuwen_gitcode_api_tool
|
|
292
|
+
|
|
293
|
+
jiuwen_tool = create_openjiuwen_gitcode_api_tool(owner="SushiNinja", repo="GitCode-API")
|
|
294
|
+
# jiuwen_tool.card — name, description, input_params
|
|
295
|
+
# await jiuwen_tool.invoke({"op_type": "repos", "action": "get", "params": {}})
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Optional `name=` and `description=` override the default tool card. Constructor options otherwise mirror `GitCode` / `AsyncGitCode` (`client=`, `async_client=`, `api_key=`, `owner=`, `repo=`, `base_url=`, `timeout=`, `decrypt=`).
|
|
299
|
+
|
|
300
|
+
**Claude Desktop (MCPB):** published GitHub Releases include a `gitcode-<version>.mcpb` bundle for one-click installation as a Claude Desktop extension; see Anthropic’s guide, [Build a desktop extension with MCPB](https://claude.com/docs/connectors/building/mcpb). From a checkout you can run `make mcpb` (requires the [`@anthropic-ai/mcpb`](https://www.npmjs.com/package/@anthropic-ai/mcpb) CLI on your `PATH`).
|
|
301
|
+
|
|
281
302
|
## Examples
|
|
282
303
|
|
|
283
304
|
Runnable examples live in `examples/`:
|
|
@@ -339,7 +360,7 @@ with GitCode(
|
|
|
339
360
|
|
|
340
361
|
Use `httpx.AsyncClient(verify=...)` with `AsyncGitCode` for async code.
|
|
341
362
|
|
|
342
|
-
The OpenAI tool (`GitCodeOpenAITool`)
|
|
363
|
+
The OpenAI tool (`GitCodeOpenAITool`), MCP helpers, and `create_openjiuwen_gitcode_api_tool` accept the same `client=` / `async_client=` arguments (OpenAI and MCP also accept a shared `GitCodeLLMTool` via `tool=`). Build `GitCode` / `AsyncGitCode` with your custom `http_client` once and pass it through so LLM tool calls reuse the same TLS settings.
|
|
343
364
|
|
|
344
365
|
## Project Status
|
|
345
366
|
|
|
@@ -4,6 +4,7 @@ from importlib import import_module
|
|
|
4
4
|
from typing import TYPE_CHECKING, Any, Dict
|
|
5
5
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
|
+
from .jiuwen import create_openjiuwen_gitcode_api_tool
|
|
7
8
|
from .mcp import (
|
|
8
9
|
GitCodeMCP,
|
|
9
10
|
create_mcp_gitcode_api_tool,
|
|
@@ -21,6 +22,7 @@ _IMPORT_MAP = {
|
|
|
21
22
|
"register_mcp_gitcode_api_tool": ".mcp",
|
|
22
23
|
"register_mcp_help_resources": ".mcp",
|
|
23
24
|
"GitCodeOpenAITool": ".openai",
|
|
25
|
+
"create_openjiuwen_gitcode_api_tool": ".jiuwen",
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
_IMPORT_CACHE: Dict[str, Any] = {}
|
|
@@ -54,4 +56,5 @@ __all__ = [
|
|
|
54
56
|
"create_mcp_server",
|
|
55
57
|
"register_mcp_gitcode_api_tool",
|
|
56
58
|
"register_mcp_help_resources",
|
|
59
|
+
"create_openjiuwen_gitcode_api_tool",
|
|
57
60
|
]
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
import base64
|
|
4
4
|
import inspect
|
|
5
5
|
import logging
|
|
6
|
+
import os
|
|
6
7
|
from collections.abc import Mapping
|
|
7
8
|
from functools import lru_cache
|
|
8
|
-
import os
|
|
9
9
|
from typing import Any, Callable, Dict, Optional, Tuple
|
|
10
10
|
|
|
11
11
|
from gitcode_api import (
|
|
@@ -38,9 +38,7 @@ MCP_SERVER_INSTRUCTIONS = (
|
|
|
38
38
|
"Successful results are JSON-serializable. Raw bytes from endpoints such as contents.get_raw are "
|
|
39
39
|
'returned as {"encoding": "base64", "data": "<ascii>"}.\n'
|
|
40
40
|
'Failures are objects with "error": true and a "message" string.\n\n'
|
|
41
|
-
"Valid op_type values for this client version:\n- "
|
|
42
|
-
+ "\n- ".join(OP_TYPE_ENUM)
|
|
43
|
-
+ "\n\n"
|
|
41
|
+
"Valid op_type values for this client version:\n- " + "\n- ".join(OP_TYPE_ENUM) + "\n\n"
|
|
44
42
|
"Optional MCP resources (read without calling the tool):\n"
|
|
45
43
|
"- gitcode-api://help — markdown index of help URIs\n"
|
|
46
44
|
"- gitcode-api://help/{op_type} — plain-text method list for that client resource\n"
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""openJiuwen ``LocalFunction`` adapter for the GitCode LLM tool."""
|
|
2
|
+
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Callable, Dict, Optional
|
|
5
|
+
|
|
6
|
+
from gitcode_api import AsyncGitCode, GitCode
|
|
7
|
+
from gitcode_api._base_client import DEFAULT_BASE_URL
|
|
8
|
+
|
|
9
|
+
from ._tool import TOOL_DESCRIPTION, TOOL_NAME, TOOL_PARAMETERS, GitCodeLLMTool
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from openjiuwen.core.foundation.tool import LocalFunction
|
|
13
|
+
|
|
14
|
+
def _missing_openjiuwen_error() -> ImportError:
|
|
15
|
+
return ImportError(
|
|
16
|
+
"The openJiuwen tool support requires the optional dependency: pip install openjiuwen. "
|
|
17
|
+
"Note: Python 3.11+ is required for openjiuwen."
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _openjiuwen_tool_decorator() -> Callable[..., Any]:
|
|
22
|
+
try:
|
|
23
|
+
mod = import_module("openjiuwen.core.foundation.tool")
|
|
24
|
+
except ImportError as exc:
|
|
25
|
+
raise _missing_openjiuwen_error() from exc
|
|
26
|
+
return getattr(mod, "tool") # type: ignore[no-any-return]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class _GitCodeJiuwenTool(GitCodeLLMTool):
|
|
30
|
+
"""Build an openJiuwen ``LocalFunction`` bound to :class:`GitCodeLLMTool` (async invoke only)."""
|
|
31
|
+
|
|
32
|
+
def __init__(self, *, name: Optional[str] = None, description: Optional[str] = None, **kwargs) -> None:
|
|
33
|
+
super().__init__(**kwargs)
|
|
34
|
+
tool_name = name if name is not None else TOOL_NAME
|
|
35
|
+
tool_description = description if description is not None else TOOL_DESCRIPTION
|
|
36
|
+
oj_tool = _openjiuwen_tool_decorator()
|
|
37
|
+
|
|
38
|
+
async def _async_impl(
|
|
39
|
+
op_type: str,
|
|
40
|
+
action: str = "",
|
|
41
|
+
params: Optional[Dict[str, Any]] = None,
|
|
42
|
+
help: bool = False,
|
|
43
|
+
) -> Any:
|
|
44
|
+
return await self.__async_call__(op_type=op_type, action=action, params=params, help=help)
|
|
45
|
+
|
|
46
|
+
self.local_function = oj_tool(
|
|
47
|
+
_async_impl,
|
|
48
|
+
name=tool_name,
|
|
49
|
+
description=tool_description,
|
|
50
|
+
input_params=TOOL_PARAMETERS,
|
|
51
|
+
auto_extract=False,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def create_openjiuwen_gitcode_api_tool(
|
|
56
|
+
name: Optional[str] = None,
|
|
57
|
+
description: Optional[str] = None,
|
|
58
|
+
*,
|
|
59
|
+
client: Optional[GitCode] = None,
|
|
60
|
+
async_client: Optional[AsyncGitCode] = None,
|
|
61
|
+
api_key: Optional[str] = None,
|
|
62
|
+
owner: Optional[str] = None,
|
|
63
|
+
repo: Optional[str] = None,
|
|
64
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
65
|
+
timeout: Optional[float] = None,
|
|
66
|
+
decrypt: Optional[Callable[..., Any]] = None,
|
|
67
|
+
) -> "LocalFunction":
|
|
68
|
+
"""Create an openJiuwen ``LocalFunction`` for the GitCode API tool.
|
|
69
|
+
|
|
70
|
+
:param name: Tool name on the ``LocalFunction`` card; defaults to ``gitcode_api_tool``.
|
|
71
|
+
:param description: Tool description on the card; defaults to the shared GitCode tool description.
|
|
72
|
+
:param client: Optional synchronous GitCode client.
|
|
73
|
+
:param async_client: Optional asynchronous GitCode client.
|
|
74
|
+
:param api_key: Personal access token when clients are not supplied.
|
|
75
|
+
:param owner: Default repository owner for generated clients.
|
|
76
|
+
:param repo: Default repository name for generated clients.
|
|
77
|
+
:param base_url: Base URL for generated clients.
|
|
78
|
+
:param timeout: Request timeout for generated clients.
|
|
79
|
+
:param decrypt: Optional decryption function for encrypted access tokens.
|
|
80
|
+
:returns: openJiuwen ``LocalFunction`` with the standard parameter schema.
|
|
81
|
+
"""
|
|
82
|
+
adapter = _GitCodeJiuwenTool(
|
|
83
|
+
client=client,
|
|
84
|
+
async_client=async_client,
|
|
85
|
+
api_key=api_key,
|
|
86
|
+
owner=owner,
|
|
87
|
+
repo=repo,
|
|
88
|
+
base_url=base_url,
|
|
89
|
+
timeout=timeout,
|
|
90
|
+
decrypt=decrypt,
|
|
91
|
+
name=name,
|
|
92
|
+
description=description,
|
|
93
|
+
)
|
|
94
|
+
return adapter.local_function
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
__all__ = ["create_openjiuwen_gitcode_api_tool"]
|
|
@@ -89,9 +89,7 @@ def register_mcp_help_resources(mcp: Union["FastMCP", Any]) -> None:
|
|
|
89
89
|
@mcp.resource(
|
|
90
90
|
"gitcode-api://help/{op_type}",
|
|
91
91
|
name="gitcode_api_op_type_help",
|
|
92
|
-
description=(
|
|
93
|
-
"Method list for one op_type (same as gitcode_api_tool with help=true and empty action)."
|
|
94
|
-
),
|
|
92
|
+
description=("Method list for one op_type (same as gitcode_api_tool with help=true and empty action)."),
|
|
95
93
|
mime_type="text/plain",
|
|
96
94
|
)
|
|
97
95
|
async def _op_type_help_resource(op_type: str) -> str:
|
|
@@ -132,9 +130,7 @@ class GitCodeMCP:
|
|
|
132
130
|
return getattr(self.mcp, name)
|
|
133
131
|
|
|
134
132
|
|
|
135
|
-
def create_mcp_server(
|
|
136
|
-
name: str = "GitCode API", tool: Optional[GitCodeLLMTool] = None, **kwargs: Any
|
|
137
|
-
) -> "FastMCP":
|
|
133
|
+
def create_mcp_server(name: str = "GitCode API", tool: Optional[GitCodeLLMTool] = None, **kwargs: Any) -> "FastMCP":
|
|
138
134
|
"""Create a FastMCP server with the GitCode API tool already registered.
|
|
139
135
|
|
|
140
136
|
:param name: MCP server display name.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.2.9
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitcode-api
|
|
3
|
-
Version: 1.2.
|
|
4
|
-
Summary: Easy to use Python SDK for the GitCode REST API. Providing builtin CLI tool, and optional LLM integration (MCP and
|
|
3
|
+
Version: 1.2.9
|
|
4
|
+
Summary: Easy to use Python SDK for the GitCode REST API. Providing builtin CLI tool, and optional LLM integration (MCP, OpenAI tool, and openJiuwen tool) for agents. Community-maintained.
|
|
5
5
|
Author-email: Hugo Huang <hugo@hugohuang.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: changelog, https://gitcode-api.readthedocs.io/en/latest/changelog.html
|
|
8
|
+
Project-URL: issues, https://github.com/Trenza1ore/GitCode-API/issues
|
|
8
9
|
Project-URL: documentation, https://gitcode-api.readthedocs.io
|
|
9
10
|
Project-URL: gitcode, https://gitcode.com/SushiNinja/GitCode-API
|
|
10
11
|
Project-URL: github, https://github.com/Trenza1ore/GitCode-API
|
|
11
|
-
|
|
12
|
+
Project-URL: homepage, https://linktr.ee/Hugoooo
|
|
13
|
+
Project-URL: author, https://hugohuang.com
|
|
14
|
+
Keywords: gitcode,git,devops,api,sdk,python,httpx,client,mcp,agent,fastmcp,llm,openjiuwen,mcp client,mcp server,model context protocol
|
|
12
15
|
Classifier: Development Status :: 4 - Beta
|
|
13
16
|
Classifier: Programming Language :: Python
|
|
14
17
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
@@ -35,12 +38,12 @@ Dynamic: license-file
|
|
|
35
38
|
# GitCode-API
|
|
36
39
|
|
|
37
40
|
[](https://pypi.org/project/gitcode-api) [](https://pepy.tech/projects/gitcode-api) [](https://www.codefactor.io/repository/github/trenza1ore/gitcode-api)
|
|
38
|
-
[](https://cursor.com/en/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19) [](https://vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
39
42
|
[](https://github.com/Trenza1ore/GitCode-API) [](https://gitcode.com/SushiNinja/GitCode-API)
|
|
40
43
|
|
|
41
44
|
[](https://gitcode-api.readthedocs.io) [](README.zh.md)
|
|
42
45
|
|
|
43
|
-
`gitcode-api` is a community-maintained Python SDK for the GitCode REST API. It provides easy-to-use synchronous and asynchronous clients, repository-scoped helpers, and lightweight response models so you can work with GitCode from Python without hand-writing raw HTTP requests. The `gitcode_api.llm` module adds an OpenAI-style function tool
|
|
46
|
+
`gitcode-api` is a community-maintained Python SDK for the GitCode REST API. It provides easy-to-use synchronous and asynchronous clients, repository-scoped helpers, and lightweight response models so you can work with GitCode from Python without hand-writing raw HTTP requests. The `gitcode_api.llm` module adds an OpenAI-style function tool, an MCP service, and an [openJiuwen](https://openjiuwen.com) tool integration so agents can reuse the same resource-oriented API.
|
|
44
47
|
|
|
45
48
|
## Why This Project
|
|
46
49
|
|
|
@@ -49,8 +52,9 @@ Dynamic: license-file
|
|
|
49
52
|
- Resource groups such as `client.repos`, `client.pulls`, and `client.users`.
|
|
50
53
|
- Repository defaults via `owner=` and `repo=` on the client.
|
|
51
54
|
- Sphinx docs plus a mirrored GitCode REST API reference in `docs/`.
|
|
52
|
-
- Provides MCP server
|
|
55
|
+
- Provides MCP server, OpenAI tool, and [openJiuwen](https://openjiuwen.com) tool for LLM agent usage.
|
|
53
56
|
- Provide MCP service that directly installs to your IDE of choice, such as Cursor and VS Code!
|
|
57
|
+
- Provides an [mcpb bundle](https://www.anthropic.com/engineering/desktop-extensions) you can install directly in the Claude desktop app; download it from [Release](https://github.com/Trenza1ore/GitCode-API/releases/latest).
|
|
54
58
|
|
|
55
59
|
## Installation
|
|
56
60
|
|
|
@@ -61,11 +65,11 @@ pip install -U gitcode-api
|
|
|
61
65
|
```
|
|
62
66
|
|
|
63
67
|
Install the MCP server to your AI-powered IDE of choice:
|
|
68
|
+
|
|
64
69
|
[](https://cursor.com/en/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19)
|
|
65
70
|
[](https://vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
66
71
|
[](https://insiders.vscode.dev/redirect/mcp/install?name=GitCode%20API&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D&quality=insiders)
|
|
67
72
|
[](https://vs-open.link/mcp-install?%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22gitcode-api%5Bmcp%5D%22%2C%22gitcode-api%22%2C%22serve%22%5D%2C%22env%22%3A%7B%22GITCODE_ACCESS_TOKEN%22%3A%22%24%7Binput%3Agitcode_access_token%7D%22%7D%2C%22inputs%22%3A%5B%7B%22id%22%3A%22gitcode_access_token%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Enter%20GITCODE_ACCESS_TOKEN%22%2C%22password%22%3Atrue%7D%5D%7D)
|
|
68
|
-
[](https://block.github.io/goose/extension?cmd=uvx&arg=--from%2520gitcode-api%5Bmcp%5D%2520gitcode-api%2520serve&id=GitCode%20API&name=GitCode%20API&description=MCP%20Server%20for%20GitCode%20API)
|
|
69
73
|
[](https://lmstudio.ai/install-mcp?name=GitCode%20API&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnaXRjb2RlLWFwaVttY3BdIiwiZ2l0Y29kZS1hcGkiLCJzZXJ2ZSJdLCJlbnYiOnsiR0lUQ09ERV9BQ0NFU1NfVE9LRU4iOiIke2lucHV0OmdpdGNvZGVfYWNjZXNzX3Rva2VufSJ9LCJpbnB1dHMiOlt7ImlkIjoiZ2l0Y29kZV9hY2Nlc3NfdG9rZW4iLCJ0eXBlIjoicHJvbXB0U3RyaW5nIiwiZGVzY3JpcHRpb24iOiJFbnRlciBHSVRDT0RFX0FDQ0VTU19UT0tFTiIsInBhc3N3b3JkIjp0cnVlfV19)
|
|
70
74
|
|
|
71
75
|
For detailed setup (including installing to services like Claude Code / Codex): see [install_mcp_server.md](install_mcp_server.md).
|
|
@@ -225,7 +229,7 @@ Both `GitCode` and `AsyncGitCode` expose:
|
|
|
225
229
|
|
|
226
230
|
Every resource group inherits a cached `methods` property from the shared resource base: a `tuple` of public callable names in stable SDK order (underscore-segment sort key, not plain A–Z on the full identifier). Private names and the introspection helpers `methods` and `method_signature` are omitted. For example, `client.pulls.methods` helps with discovery or tooling without reading the full manual list. For one method’s parameters and return type, call `client.pulls.method_signature("list_issues")` (a cached string from `inspect.signature`, with `gitcode_api._models.` stripped from annotations).
|
|
227
231
|
|
|
228
|
-
## LLM tools and
|
|
232
|
+
## LLM tools, MCP, and openJiuwen
|
|
229
233
|
|
|
230
234
|
The `gitcode_api.llm` module exposes a single logical tool, **`gitcode_api_tool`**, that routes calls to sync or async SDK resources. Model-facing parameters match the JSON schema used by OpenAI-style function tools:
|
|
231
235
|
|
|
@@ -312,6 +316,26 @@ The same server is available from the CLI as `gitcode-api serve` (see the [CLI](
|
|
|
312
316
|
|
|
313
317
|
To share auth or clients across tools, build `GitCodeLLMTool` once (`from gitcode_api.llm._tool import GitCodeLLMTool`) and pass it as `tool=` into `GitCodeMCP`, `create_mcp_server`, `register_mcp_gitcode_api_tool`, or `create_mcp_gitcode_api_tool`.
|
|
314
318
|
|
|
319
|
+
### openJiuwen (`LocalFunction`)
|
|
320
|
+
|
|
321
|
+
[openJiuwen](https://openjiuwen.com) is an open agent platform. With the separate `openjiuwen` package installed (**Python 3.11+**), `create_openjiuwen_gitcode_api_tool` returns an openJiuwen `LocalFunction` that uses the same `op_type` / `action` / `params` / `help` arguments as the OpenAI adapter. Invocation is async-only (`await jiuwen_tool.invoke({...})`).
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
pip install openjiuwen
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
from gitcode_api.llm import create_openjiuwen_gitcode_api_tool
|
|
329
|
+
|
|
330
|
+
jiuwen_tool = create_openjiuwen_gitcode_api_tool(owner="SushiNinja", repo="GitCode-API")
|
|
331
|
+
# jiuwen_tool.card — name, description, input_params
|
|
332
|
+
# await jiuwen_tool.invoke({"op_type": "repos", "action": "get", "params": {}})
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Optional `name=` and `description=` override the default tool card. Constructor options otherwise mirror `GitCode` / `AsyncGitCode` (`client=`, `async_client=`, `api_key=`, `owner=`, `repo=`, `base_url=`, `timeout=`, `decrypt=`).
|
|
336
|
+
|
|
337
|
+
**Claude Desktop (MCPB):** published GitHub Releases include a `gitcode-<version>.mcpb` bundle for one-click installation as a Claude Desktop extension; see Anthropic’s guide, [Build a desktop extension with MCPB](https://claude.com/docs/connectors/building/mcpb). From a checkout you can run `make mcpb` (requires the [`@anthropic-ai/mcpb`](https://www.npmjs.com/package/@anthropic-ai/mcpb) CLI on your `PATH`).
|
|
338
|
+
|
|
315
339
|
## Examples
|
|
316
340
|
|
|
317
341
|
Runnable examples live in `examples/`:
|
|
@@ -373,7 +397,7 @@ with GitCode(
|
|
|
373
397
|
|
|
374
398
|
Use `httpx.AsyncClient(verify=...)` with `AsyncGitCode` for async code.
|
|
375
399
|
|
|
376
|
-
The OpenAI tool (`GitCodeOpenAITool`)
|
|
400
|
+
The OpenAI tool (`GitCodeOpenAITool`), MCP helpers, and `create_openjiuwen_gitcode_api_tool` accept the same `client=` / `async_client=` arguments (OpenAI and MCP also accept a shared `GitCodeLLMTool` via `tool=`). Build `GitCode` / `AsyncGitCode` with your custom `http_client` once and pass it through so LLM tool calls reuse the same TLS settings.
|
|
377
401
|
|
|
378
402
|
## Project Status
|
|
379
403
|
|
|
@@ -11,6 +11,7 @@ gitcode_api/_exceptions.py
|
|
|
11
11
|
gitcode_api/_models.py
|
|
12
12
|
gitcode_api/cli.py
|
|
13
13
|
gitcode_api/py.typed
|
|
14
|
+
gitcode_api/run_mcp.py
|
|
14
15
|
gitcode_api/version.txt
|
|
15
16
|
gitcode_api.egg-info/PKG-INFO
|
|
16
17
|
gitcode_api.egg-info/SOURCES.txt
|
|
@@ -20,6 +21,7 @@ gitcode_api.egg-info/requires.txt
|
|
|
20
21
|
gitcode_api.egg-info/top_level.txt
|
|
21
22
|
gitcode_api/llm/__init__.py
|
|
22
23
|
gitcode_api/llm/_tool.py
|
|
24
|
+
gitcode_api/llm/jiuwen.py
|
|
23
25
|
gitcode_api/llm/mcp.py
|
|
24
26
|
gitcode_api/llm/openai.py
|
|
25
27
|
gitcode_api/resources/__init__.py
|
|
@@ -29,6 +31,7 @@ gitcode_api/resources/collaboration.py
|
|
|
29
31
|
gitcode_api/resources/misc.py
|
|
30
32
|
gitcode_api/resources/repositories.py
|
|
31
33
|
tests/test_base_client.py
|
|
34
|
+
tests/test_build_manifest.py
|
|
32
35
|
tests/test_cli.py
|
|
33
36
|
tests/test_client.py
|
|
34
37
|
tests/test_llm_tools.py
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "gitcode-api"
|
|
3
|
-
version = "1.2.
|
|
4
|
-
description = "Easy to use Python SDK for the GitCode REST API. Providing builtin CLI tool, and optional LLM integration (MCP and
|
|
3
|
+
version = "1.2.9"
|
|
4
|
+
description = "Easy to use Python SDK for the GitCode REST API. Providing builtin CLI tool, and optional LLM integration (MCP, OpenAI tool, and openJiuwen tool) for agents. Community-maintained."
|
|
5
5
|
keywords = [
|
|
6
6
|
"gitcode", "git", "devops", "api", "sdk", "python", "httpx", "client",
|
|
7
|
-
"mcp", "agent", "fastmcp", "llm", "mcp client", "mcp server", "model context protocol",
|
|
7
|
+
"mcp", "agent", "fastmcp", "llm", "openjiuwen", "mcp client", "mcp server", "model context protocol",
|
|
8
8
|
]
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9,<4"
|
|
@@ -72,9 +72,12 @@ dev = [{ include-group = "test" }, { include-group = "format" }, { include-group
|
|
|
72
72
|
|
|
73
73
|
[project.urls]
|
|
74
74
|
changelog = "https://gitcode-api.readthedocs.io/en/latest/changelog.html"
|
|
75
|
+
issues = "https://github.com/Trenza1ore/GitCode-API/issues"
|
|
75
76
|
documentation = "https://gitcode-api.readthedocs.io"
|
|
76
77
|
gitcode = "https://gitcode.com/SushiNinja/GitCode-API"
|
|
77
78
|
github = "https://github.com/Trenza1ore/GitCode-API"
|
|
79
|
+
homepage = "https://linktr.ee/Hugoooo"
|
|
80
|
+
author = "https://hugohuang.com"
|
|
78
81
|
|
|
79
82
|
[project.scripts]
|
|
80
83
|
gitcode-api = "gitcode_api.cli:main"
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Offline tests for ``scripts/build_manifest.py``."""
|
|
2
|
+
|
|
3
|
+
import importlib.util
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
10
|
+
_BUILD_MANIFEST_PATH = ROOT / "scripts" / "build_manifest.py"
|
|
11
|
+
_spec = importlib.util.spec_from_file_location("build_manifest", _BUILD_MANIFEST_PATH)
|
|
12
|
+
assert _spec and _spec.loader
|
|
13
|
+
_build_manifest = importlib.util.module_from_spec(_spec)
|
|
14
|
+
_spec.loader.exec_module(_build_manifest)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
MINIMAL_PYPROJECT = b"""\
|
|
18
|
+
[project]
|
|
19
|
+
name = "demo-pkg"
|
|
20
|
+
version = "9.8.7"
|
|
21
|
+
description = "Demo description line."
|
|
22
|
+
keywords = ["alpha", "beta"]
|
|
23
|
+
license = "MIT"
|
|
24
|
+
authors = [{ name = "Alice Example", email = "alice@example.com" }]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
homepage = "https://example.com/home"
|
|
28
|
+
documentation = "https://example.com/docs"
|
|
29
|
+
github = "https://github.com/org/demo"
|
|
30
|
+
author = "https://example.com/~alice"
|
|
31
|
+
issues = "https://github.com/org/demo/issues"
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
MINIMAL_TEMPLATE = {
|
|
35
|
+
"version": "{{VERSION}}",
|
|
36
|
+
"description": "Static manifest description (not from pyproject placeholders).",
|
|
37
|
+
"author": {
|
|
38
|
+
"name": "{{AUTHOR_NAME}}",
|
|
39
|
+
"email": "{{AUTHOR_EMAIL}}",
|
|
40
|
+
"url": "{{AUTHOR_URL}}",
|
|
41
|
+
},
|
|
42
|
+
"homepage": "{{HOMEPAGE}}",
|
|
43
|
+
"documentation": "{{DOCUMENTATION}}",
|
|
44
|
+
"support": "{{SUPPORT}}",
|
|
45
|
+
"repository": {"type": "git", "url": "{{REPOSITORY_URL}}"},
|
|
46
|
+
"keywords": [],
|
|
47
|
+
"license": "",
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_build_manifest_dict_substitutes_and_lists(tmp_path: Path) -> None:
|
|
52
|
+
pyproject_path = tmp_path / "pyproject.toml"
|
|
53
|
+
pyproject_path.write_bytes(MINIMAL_PYPROJECT)
|
|
54
|
+
template_path = tmp_path / "manifest.in.json"
|
|
55
|
+
template_path.write_text(json.dumps(MINIMAL_TEMPLATE), encoding="utf-8")
|
|
56
|
+
|
|
57
|
+
manifest = _build_manifest.build_manifest_dict(pyproject_path, template_path)
|
|
58
|
+
|
|
59
|
+
assert manifest["version"] == "9.8.7"
|
|
60
|
+
assert manifest["description"] == "Static manifest description (not from pyproject placeholders)."
|
|
61
|
+
assert manifest["author"]["name"] == "Alice Example"
|
|
62
|
+
assert manifest["author"]["email"] == "alice@example.com"
|
|
63
|
+
assert manifest["author"]["url"] == "https://example.com/~alice"
|
|
64
|
+
assert manifest["homepage"] == "https://example.com/home"
|
|
65
|
+
assert manifest["documentation"] == "https://example.com/docs"
|
|
66
|
+
assert manifest["support"] == "https://github.com/org/demo/issues"
|
|
67
|
+
assert manifest["repository"]["url"] == "https://github.com/org/demo"
|
|
68
|
+
assert manifest["keywords"] == ["alpha", "beta"]
|
|
69
|
+
assert manifest["license"] == "MIT"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_write_manifest_ensure_ascii_utf8(tmp_path: Path) -> None:
|
|
73
|
+
out = tmp_path / "out.json"
|
|
74
|
+
_build_manifest.write_manifest({"note": "café"}, out)
|
|
75
|
+
text = out.read_text(encoding="utf-8")
|
|
76
|
+
assert "café" in text
|
|
77
|
+
assert text.endswith("\n")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_missing_github_raises(tmp_path: Path) -> None:
|
|
81
|
+
bad = b"""\
|
|
82
|
+
[project]
|
|
83
|
+
name = "x"
|
|
84
|
+
version = "1"
|
|
85
|
+
description = "d"
|
|
86
|
+
authors = [{ name = "A", email = "a@b.c" }]
|
|
87
|
+
"""
|
|
88
|
+
pyproject_path = tmp_path / "pyproject.toml"
|
|
89
|
+
pyproject_path.write_bytes(bad)
|
|
90
|
+
template_path = tmp_path / "manifest.in.json"
|
|
91
|
+
template_path.write_text(json.dumps(MINIMAL_TEMPLATE), encoding="utf-8")
|
|
92
|
+
|
|
93
|
+
with pytest.raises(ValueError, match="github"):
|
|
94
|
+
_build_manifest.build_manifest_dict(pyproject_path, template_path)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import importlib.util
|
|
1
2
|
from typing import Any, Dict
|
|
2
3
|
|
|
3
4
|
import httpx
|
|
@@ -7,12 +8,13 @@ from gitcode_api.llm import (
|
|
|
7
8
|
GitCodeOpenAITool,
|
|
8
9
|
create_mcp_gitcode_api_tool,
|
|
9
10
|
create_mcp_server,
|
|
11
|
+
create_openjiuwen_gitcode_api_tool,
|
|
10
12
|
register_mcp_gitcode_api_tool,
|
|
11
13
|
)
|
|
12
14
|
from gitcode_api.llm._tool import (
|
|
13
|
-
GitCodeLLMTool,
|
|
14
15
|
MCP_SERVER_INSTRUCTIONS,
|
|
15
16
|
OP_TYPE_ENUM,
|
|
17
|
+
GitCodeLLMTool,
|
|
16
18
|
help_resource_index_body,
|
|
17
19
|
op_type_help_resource_body,
|
|
18
20
|
)
|
|
@@ -130,12 +132,14 @@ def test_help_resource_index_body() -> None:
|
|
|
130
132
|
@pytest.mark.asyncio
|
|
131
133
|
async def test_create_mcp_server_registers_help_resources() -> None:
|
|
132
134
|
mcp = create_mcp_server()
|
|
133
|
-
static = await mcp.
|
|
134
|
-
templates = await mcp.
|
|
135
|
+
static = await mcp._list_resources_mcp()
|
|
136
|
+
templates = await mcp._list_resource_templates_mcp()
|
|
135
137
|
assert any(str(r.uri) == "gitcode-api://help" for r in static)
|
|
136
|
-
assert any(
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
assert any(
|
|
139
|
+
"{op_type}" in str(getattr(t, "uri_template", None) or getattr(t, "uriTemplate", None)) for t in templates
|
|
140
|
+
)
|
|
141
|
+
read = await mcp._read_resource_mcp("gitcode-api://help/pulls")
|
|
142
|
+
payload = read[0].content
|
|
139
143
|
assert "Resource: pulls" in payload
|
|
140
144
|
|
|
141
145
|
|
|
@@ -156,3 +160,53 @@ def test_mcp_registers_with_existing_server() -> None:
|
|
|
156
160
|
|
|
157
161
|
assert registered.__name__ == "gitcode_api_tool"
|
|
158
162
|
assert server.registered[0]["name"] == "gitcode_api_tool"
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@pytest.mark.skipif(importlib.util.find_spec("openjiuwen") is not None, reason="openjiuwen is installed")
|
|
166
|
+
def test_create_openjiuwen_gitcode_api_tool_raises_when_openjiuwen_missing() -> None:
|
|
167
|
+
with pytest.raises(ImportError, match="openjiuwen|openJiuwen"):
|
|
168
|
+
create_openjiuwen_gitcode_api_tool(api_key="test-token")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@pytest.mark.skipif(importlib.util.find_spec("openjiuwen") is None, reason="openjiuwen not installed")
|
|
172
|
+
def test_create_openjiuwen_gitcode_api_tool_exposes_tool_card() -> None:
|
|
173
|
+
jiuwen_tool = create_openjiuwen_gitcode_api_tool(api_key="test-token")
|
|
174
|
+
assert jiuwen_tool.card.name == "gitcode_api_tool"
|
|
175
|
+
assert "op_type" in jiuwen_tool.card.input_params.get("properties", {})
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@pytest.mark.skipif(importlib.util.find_spec("openjiuwen") is None, reason="openjiuwen not installed")
|
|
179
|
+
def test_create_openjiuwen_gitcode_api_tool_custom_name_and_description() -> None:
|
|
180
|
+
jiuwen_tool = create_openjiuwen_gitcode_api_tool(
|
|
181
|
+
api_key="test-token",
|
|
182
|
+
name="my_gitcode",
|
|
183
|
+
description="Custom GitCode tool copy.",
|
|
184
|
+
)
|
|
185
|
+
assert jiuwen_tool.card.name == "my_gitcode"
|
|
186
|
+
assert jiuwen_tool.card.description == "Custom GitCode tool copy."
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@pytest.mark.skipif(importlib.util.find_spec("openjiuwen") is None, reason="openjiuwen not installed")
|
|
190
|
+
@pytest.mark.asyncio
|
|
191
|
+
async def test_create_openjiuwen_gitcode_api_tool_invoke(async_client_factory: Any) -> None:
|
|
192
|
+
captured: Dict[str, Any] = {}
|
|
193
|
+
|
|
194
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
195
|
+
captured["url"] = str(request.url)
|
|
196
|
+
return httpx.Response(200, json={"full_name": "SushiNinja/GitCode-API"})
|
|
197
|
+
|
|
198
|
+
client, http_client = async_client_factory(handler)
|
|
199
|
+
try:
|
|
200
|
+
jiuwen_tool = create_openjiuwen_gitcode_api_tool(async_client=client)
|
|
201
|
+
result = await jiuwen_tool.invoke(
|
|
202
|
+
{
|
|
203
|
+
"op_type": "repos",
|
|
204
|
+
"action": "get",
|
|
205
|
+
"params": {"owner": "SushiNinja", "repo": "GitCode-API"},
|
|
206
|
+
}
|
|
207
|
+
)
|
|
208
|
+
finally:
|
|
209
|
+
await http_client.aclose()
|
|
210
|
+
|
|
211
|
+
assert "/repos/SushiNinja/GitCode-API" in captured["url"]
|
|
212
|
+
assert result == {"full_name": "SushiNinja/GitCode-API"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.2.7
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|