GitHubKit


NameGitHubKit JSON
Version 0.11.4 PyPI version JSON
download
home_pagehttps://github.com/yanyongyu/githubkit
SummaryGitHub SDK for Python
upload_time2024-04-20 07:51:05
maintainerNone
docs_urlNone
authoryanyongyu
requires_python<4.0,>=3.8
licenseMIT
keywords github octokit
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <!-- markdownlint-disable MD033 MD041 -->
<div align="center">

[![githubkit](https://socialify.git.ci/yanyongyu/githubkit/image?description=1&descriptionEditable=%E2%9C%A8%20GitHub%20SDK%20for%20Python%20%E2%9C%A8&font=Bitter&language=1&pattern=Circuit%20Board&theme=Light)](https://github.com/yanyongyu/githubkit)

</div>

<p align="center">
  <a href="https://raw.githubusercontent.com/yanyongyu/githubkit/master/LICENSE">
    <img src="https://img.shields.io/github/license/yanyongyu/githubkit" alt="license">
  </a>
  <a href="https://pypi.python.org/pypi/githubkit">
    <img src="https://img.shields.io/pypi/v/githubkit?logo=python&logoColor=edb641" alt="pypi">
  </a>
  <img src="https://img.shields.io/badge/python-3.8+-blue?logo=python&logoColor=edb641" alt="python">
  <a href="https://github.com/psf/black">
    <img src="https://img.shields.io/badge/code%20style-black-000000.svg?logo=python&logoColor=edb641" alt="black">
  </a>
  <a href="https://github.com/Microsoft/pyright">
    <img src="https://img.shields.io/badge/types-pyright-797952.svg?logo=python&logoColor=edb641" alt="pyright">
  </a>
  <a href="https://github.com/astral-sh/ruff">
    <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json" alt="ruff">
  </a>
  <a href="https://results.pre-commit.ci/latest/github/yanyongyu/githubkit/master">
    <img src="https://results.pre-commit.ci/badge/github/yanyongyu/githubkit/master.svg" alt="pre-commit" />
  </a>
</p>

<div align="center">

<!-- markdownlint-capture -->
<!-- markdownlint-disable MD036 -->

_✨ The modern, all-batteries-included GitHub SDK for Python ✨_

_✨ Support both **sync** and **async** calls, **fully typed** ✨_

_✨ Always up to date, like octokit ✨_

<!-- markdownlint-restore -->

</div>

## Installation

```bash
pip install githubkit
# or, use poetry
poetry add githubkit
# or, use pdm
pdm add githubkit
```

if you want to auth as github app, extra dependencies are required:

```bash
pip install githubkit[auth-app]
# or, use poetry
poetry add githubkit[auth-app]
# or, use pdm
pdm add githubkit[auth-app]
```

if you want to mix sync and async calls in oauth device callback, extra dependencies are required:

```bash
pip install githubkit[auth-oauth-device]
# or, use poetry
poetry add githubkit[auth-oauth-device]
# or, use pdm
pdm add githubkit[auth-oauth-device]
```

githubkit supports **both pydantic v1 and v2**, but pydantic v2 is recommended. If you have encountered any problems with pydantic v1/v2, please file an issue.

## Usage

### Authentication

Initialize a github client with no authentication:

```python
from githubkit import GitHub, UnauthAuthStrategy

github = GitHub()
# or, use UnauthAuthStrategy
github = GitHub(UnauthAuthStrategy())
```

or using PAT (Token):

```python
from githubkit import GitHub, TokenAuthStrategy

github = GitHub("<your_token_here>")
# or, use TokenAuthStrategy
github = GitHub(TokenAuthStrategy("<your_token_here>"))
```

or using GitHub APP authentication:

```python
from githubkit import GitHub, AppAuthStrategy

github = GitHub(
    AppAuthStrategy(
        "<app_id>", "<private_key>", "<optional_client_id>", "<optional_client_secret>"
    )
)
```

or using GitHub APP Installation authentication:

```python
from githubkit import GitHub, AppInstallationAuthStrategy

github = GitHub(
    AppInstallationAuthStrategy(
        "<app_id>", "<private_key>", installation_id, "<optional_client_id>", "<optional_client_secret>",
    )
)
```

or using OAuth APP authentication:

```python
from githubkit import GitHub, OAuthAppAuthStrategy

github = GitHub(OAuthAppAuthStrategy("<client_id_here>", "<client_secret_here>"))
```

or using GitHub APP / OAuth APP web flow authentication:

```python
from githubkit import GitHub, OAuthWebAuthStrategy

github = GitHub(
    OAuthWebAuthStrategy(
        "<client_id_here>", "<client_secret_here>", "<web_flow_exchange_code_here>"
    )
)
```

or using GitHub Action authentication:

```python
from githubkit import GitHub, ActionAuthStrategy

github = GitHub(ActionAuthStrategy())
```

and add env or input to the step:

```yaml
- name: Some step use githubkit
  with:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Some step use githubkit
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

### Config

githubkit is highly configurable, you can change the default config by passing config options to `GitHub`:

```python
from githubkit import GitHub

github = GitHub(
    base_url="https://api.github.com/",
    accept_format="full+json",
    previews=["starfox"],
    user_agent="GitHubKit/Python",
    follow_redirects=True,
    timeout=None,
    http_cache=True,
    auto_retry=True,
)
```

The `accept_format` and `previews` are used to set the default `Accept` header, you can find more details in [GitHub API docs](https://docs.github.com/en/rest/overview/media-types).

The `http_cache` option enables the http caching feature powered by [Hishel](https://hishel.com/) for HTTPX. GitHub API limits the number of requests that you can make within a specific amount of time. This feature is useful to reduce the number of requests to GitHub API and avoid hitting the rate limit.

The `auto_retry` option enables request retrying when rate limit exceeded and server error encountered. See [Auto Retry](#auto-retry) for more infomation.

### Calling Rest API

> APIs are fully typed. Typing in the following examples is just for reference only.

Simple sync call:

```python
from githubkit import Response
from githubkit.versions.latest.models import FullRepository

resp: Response[FullRepository] = github.rest.repos.get(owner="owner", repo="repo")
repo: FullRepository = resp.parsed_data
```

Simple async call:

```python
from githubkit import Response
from githubkit.versions.latest.models import FullRepository

resp: Response[FullRepository] = await github.rest.repos.async_get(owner="owner", repo="repo")
repo: FullRepository = resp.parsed_data
```

Call API with context (reusing client):

```python
from githubkit import Response
from githubkit.versions.latest.models import FullRepository

with GitHub("<your_token_here>") as github:
    resp: Response[FullRepository] = github.rest.repos.get(owner="owner", repo="repo")
    repo: FullRepository = resp.parsed_data
```

```python
from githubkit import Response
from githubkit.versions.latest.models import FullRepository

async with GitHub("<your_token_here>") as github:
    resp: Response[FullRepository] = await github.rest.repos.async_get(owner="owner", repo="repo")
    repo: FullRepository = resp.parsed_data
```

### Data Validation

As shown above, the response data is parsed and validated by accessing the `response.parsed_data` property. This ensures that the data type returned by the API is as expected and your code is safe to use it (with static type checking). But sometimes you may want to get the raw data returned by the API, such as when the schema is not correct. You can use the `response.text` property or `response.json()` method to get the raw data:

```python
from typing import Any, Dict
from githubkit import Response

resp: Response[FullRepository] = github.rest.repos.get(owner="owner", repo="repo")
repo: Dict[str, Any] = resp.json()
```

### Rest API Versioning

> APIs are fully typed. Different versions of APIs are typed separately.

githubkit supports all versions of GitHub API, you can switch between versions as follows:

```python
github.rest("2022-11-28").repos.get(owner="owner", repo="repo")
```

The models of versions can be imported from `githubkit.versions.<version>.models`, for example:

```python
from githubkit.versions.v2022_11_28.models import FullRepository
```

Specially, the `latest` version is always linked to the latest version of GitHub API:

```python
from githubkit.versions.latest.models import FullRepository
```

> [!NOTE]
> For backward compatibility, the `githubkit.rest` module is linked to the models of `latest` version by default.
>
> ```python
> from githubkit.rest import FullRepository
> ```

You can also get the latest version name of GitHub API and all versions mapping of GitHub API:

```python
from githubkit.versions import LATEST_VERSION, VERSIONS
```

Current supported versions are: (you can find it in the section `[[tool.codegen.descriptions]]` of the `pyproject.toml` file)

- 2022-11-28 (latest)
- ghec-2022-11-28

### Pagination

Pagination type checking is also supported:

> Typing is tested with Pylance (Pyright).

```python
from githubkit.versions.latest.models import Issue

for issue in github.paginate(
    github.rest.issues.list_for_repo, owner="owner", repo="repo", state="open"
):
    issue: Issue
    print(issue.number)
```

```python
from githubkit.versions.latest.models import Issue

async for issue in github.paginate(
    github.rest.issues.async_list_for_repo, owner="owner", repo="repo", state="open"
):
    issue: Issue
    print(issue.number)
```

complex pagination with custom map function (some api returns data in a nested field):

```python
async for accessible_repo in github.paginate(
    github.rest.apps.async_list_installation_repos_for_authenticated_user,
    map_func=lambda r: r.parsed_data.repositories,
    installation_id=1,
):
    accessible_repo: Repository
    print(accessible_repo.full_name)
```

### Calling GraphQL API

Simple sync call:

```python
data: Dict[str, Any] = github.graphql(query, variables={"foo": "bar"})
```

Simple async call:

```python
data: Dict[str, Any] = await github.async_graphql(query, variables={"foo": "bar"})
```

### Auto Retry

By default, githubkit will retry the request when specific exception encountered. When rate limit exceeded, githubkit will retry once after GitHub suggested waiting time. When server error encountered (http status >= 500), githubkit will retry max three times.

You can disable this feature by set the `auto_retry` config to `False`:

```python
github = GitHub(
    ...
    auto_retry=False
)
```

You can also customize the retry decision function by passing a callable:

```python
from datetime import timedelta

from githubkit.retry import RetryOption
from githubkit.exception import GitHubException

def retry_decision_func(exc: GitHubException, retry_count: int) -> RetryOption:
    if retry_count < 1:
        return RetryOption(True, timedelta(seconds=60))
    return RetryOption(False)

github = GitHub(
    ...
    auto_retry=retry_decision_func
)
```

githubkit also provides some builtin retry decision function:

1. Retry when rate limit exceeded:

   ```python
   from githubkit.retry import RETRY_RATE_LIMIT, RetryRateLimit

   # default
   github = GitHub(
      ...
      auto_retry=RETRY_RATE_LIMIT
   )
   # or, custom max retry count
   github = GitHub(
      ...
      auto_retry=RetryRateLimit(max_retry=1)
   )
   ```

2. Retry when server error encountered:

   ```python
   from githubkit.retry import RETRY_SERVER_ERROR, RetryServerError

   # default
   github = GitHub(
      ...
      auto_retry=RETRY_SERVER_ERROR
   )
   # or, custom max retry count
   github = GitHub(
      ...
      auto_retry=RetryServerError(max_retry=1)
   )
   ```

3. Chain retry decision functions:

   ```python
   from githubkit.retry import RETRY_RATE_LIMIT, RETRY_SERVER_ERROR, RetryChainDecision

   github = GitHub(
      ...
      auto_retry=RetryChainDecision(RETRY_RATE_LIMIT, RETRY_SERVER_ERROR)
   )
   ```

### Webhook Verification

> `githubkit.webhooks` module contains some shortcut functions to help you verify and parse webhook payload.

Simple webhook payload verification:

```python
from githubkit.webhooks import verify

valid: bool = verify(secret, request.body, request.headers["X-Hub-Signature-256"])
```

Sign the webhook payload manually:

```python
from githubkit.webhooks import sign

signature: str = sign(secret, payload, method="sha256")
```

### Webhook Parsing

> `githubkit.webhooks` module contains some shortcut functions to help you verify and parse webhook payload.

Parse the payload with event name:

```python
from githubkit.webhooks import parse

event = parse(request.headers["X-GitHub-Event"], request.body)
```

(**NOT RECOMMENDED**) Parse the payload without event name (may cost longer time and more memory):

```python
from githubkit.webhooks import parse_without_name

event = parse_without_name(request.body)
```

> [!WARNING]
> The `parse_without_name` function will try to parse the payload with all supported event names.  
> The behavior of this function is not the same between pydantic v1 and v2.  
> When using pydantic v1, the function will return the first valid event model (known as `left-to-right` mode).  
> When using pydantic v2, the function will return the highest scored valid event model (known as `smart` mode).  
> See: [Union Modes](https://docs.pydantic.dev/latest/concepts/unions/#union-modes).

Parse dict like payload:

```python
from githubkit.webhooks import parse_obj, parse_obj_without_name

event = parse_obj(request.headers["X-GitHub-Event"], request.json())
event = parse_obj_without_name(request.json())  # NOT RECOMMENDED
```

The `parse` and `parse_obj` function supports type overload, if you provide static value for the `event_name` parameter, the return type will be inferred automatically.

Webhook also supports versioning, you can switch between versions as follows:

```python
from githubkit import GitHub

event = GitHub.webhooks("2022-11-28").parse(request.headers["X-GitHub-Event"], request.body)
```

### Switch between AuthStrategy

You can change the auth strategy and get a new client simplely using `with_auth`.

Change from `AppAuthStrategy` to `AppInstallationAuthStrategy`:

```python
from githubkit import GitHub, AppAuthStrategy

github = GitHub(AppAuthStrategy("<app_id>", "<private_key>"))
installation_github = github.with_auth(
    github.auth.as_installation(installation_id)
)
```

Change from `OAuthAppAuthStrategy` to `OAuthWebAuthStrategy`:

```python
from githubkit import GitHub, OAuthAppAuthStrategy

github = GitHub(OAuthAppAuthStrategy("<client_id>", "<client_secret>"))
user_github = github.with_auth(github.auth.as_web_user("<code>"))
```

## Development

Open in Codespaces (Dev Container):

[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=512138996)

Generate latest models and apis:

> [!WARNING]
> This may use about **400M** memory and take a long time.

```bash
./scripts/run-codegen.sh
```

Run tests in dev env:

```bash
./scripts/run-tests.sh
```

Run tests in test envs, for example:

```bash
cd ./envs/pydantic-v2/
poetry run bash ../../scripts/run-tests.sh
```

## Contributors

Thanks to the following people who have contributed to this project:

<a href="https://github.com/yanyongyu/githubkit/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=yanyongyu/githubkit&max=1000" alt="contributors" />
</a>


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/yanyongyu/githubkit",
    "name": "GitHubKit",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.8",
    "maintainer_email": null,
    "keywords": "github, octokit",
    "author": "yanyongyu",
    "author_email": "yyy@yyydl.top",
    "download_url": "https://files.pythonhosted.org/packages/1b/4a/f2d198ed937843d3f401a84d616da3c2170105c02d1531e53bf680fba499/githubkit-0.11.4.tar.gz",
    "platform": null,
    "description": "<!-- markdownlint-disable MD033 MD041 -->\n<div align=\"center\">\n\n[![githubkit](https://socialify.git.ci/yanyongyu/githubkit/image?description=1&descriptionEditable=%E2%9C%A8%20GitHub%20SDK%20for%20Python%20%E2%9C%A8&font=Bitter&language=1&pattern=Circuit%20Board&theme=Light)](https://github.com/yanyongyu/githubkit)\n\n</div>\n\n<p align=\"center\">\n  <a href=\"https://raw.githubusercontent.com/yanyongyu/githubkit/master/LICENSE\">\n    <img src=\"https://img.shields.io/github/license/yanyongyu/githubkit\" alt=\"license\">\n  </a>\n  <a href=\"https://pypi.python.org/pypi/githubkit\">\n    <img src=\"https://img.shields.io/pypi/v/githubkit?logo=python&logoColor=edb641\" alt=\"pypi\">\n  </a>\n  <img src=\"https://img.shields.io/badge/python-3.8+-blue?logo=python&logoColor=edb641\" alt=\"python\">\n  <a href=\"https://github.com/psf/black\">\n    <img src=\"https://img.shields.io/badge/code%20style-black-000000.svg?logo=python&logoColor=edb641\" alt=\"black\">\n  </a>\n  <a href=\"https://github.com/Microsoft/pyright\">\n    <img src=\"https://img.shields.io/badge/types-pyright-797952.svg?logo=python&logoColor=edb641\" alt=\"pyright\">\n  </a>\n  <a href=\"https://github.com/astral-sh/ruff\">\n    <img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json\" alt=\"ruff\">\n  </a>\n  <a href=\"https://results.pre-commit.ci/latest/github/yanyongyu/githubkit/master\">\n    <img src=\"https://results.pre-commit.ci/badge/github/yanyongyu/githubkit/master.svg\" alt=\"pre-commit\" />\n  </a>\n</p>\n\n<div align=\"center\">\n\n<!-- markdownlint-capture -->\n<!-- markdownlint-disable MD036 -->\n\n_\u2728 The modern, all-batteries-included GitHub SDK for Python \u2728_\n\n_\u2728 Support both **sync** and **async** calls, **fully typed** \u2728_\n\n_\u2728 Always up to date, like octokit \u2728_\n\n<!-- markdownlint-restore -->\n\n</div>\n\n## Installation\n\n```bash\npip install githubkit\n# or, use poetry\npoetry add githubkit\n# or, use pdm\npdm add githubkit\n```\n\nif you want to auth as github app, extra dependencies are required:\n\n```bash\npip install githubkit[auth-app]\n# or, use poetry\npoetry add githubkit[auth-app]\n# or, use pdm\npdm add githubkit[auth-app]\n```\n\nif you want to mix sync and async calls in oauth device callback, extra dependencies are required:\n\n```bash\npip install githubkit[auth-oauth-device]\n# or, use poetry\npoetry add githubkit[auth-oauth-device]\n# or, use pdm\npdm add githubkit[auth-oauth-device]\n```\n\ngithubkit supports **both pydantic v1 and v2**, but pydantic v2 is recommended. If you have encountered any problems with pydantic v1/v2, please file an issue.\n\n## Usage\n\n### Authentication\n\nInitialize a github client with no authentication:\n\n```python\nfrom githubkit import GitHub, UnauthAuthStrategy\n\ngithub = GitHub()\n# or, use UnauthAuthStrategy\ngithub = GitHub(UnauthAuthStrategy())\n```\n\nor using PAT (Token):\n\n```python\nfrom githubkit import GitHub, TokenAuthStrategy\n\ngithub = GitHub(\"<your_token_here>\")\n# or, use TokenAuthStrategy\ngithub = GitHub(TokenAuthStrategy(\"<your_token_here>\"))\n```\n\nor using GitHub APP authentication:\n\n```python\nfrom githubkit import GitHub, AppAuthStrategy\n\ngithub = GitHub(\n    AppAuthStrategy(\n        \"<app_id>\", \"<private_key>\", \"<optional_client_id>\", \"<optional_client_secret>\"\n    )\n)\n```\n\nor using GitHub APP Installation authentication:\n\n```python\nfrom githubkit import GitHub, AppInstallationAuthStrategy\n\ngithub = GitHub(\n    AppInstallationAuthStrategy(\n        \"<app_id>\", \"<private_key>\", installation_id, \"<optional_client_id>\", \"<optional_client_secret>\",\n    )\n)\n```\n\nor using OAuth APP authentication:\n\n```python\nfrom githubkit import GitHub, OAuthAppAuthStrategy\n\ngithub = GitHub(OAuthAppAuthStrategy(\"<client_id_here>\", \"<client_secret_here>\"))\n```\n\nor using GitHub APP / OAuth APP web flow authentication:\n\n```python\nfrom githubkit import GitHub, OAuthWebAuthStrategy\n\ngithub = GitHub(\n    OAuthWebAuthStrategy(\n        \"<client_id_here>\", \"<client_secret_here>\", \"<web_flow_exchange_code_here>\"\n    )\n)\n```\n\nor using GitHub Action authentication:\n\n```python\nfrom githubkit import GitHub, ActionAuthStrategy\n\ngithub = GitHub(ActionAuthStrategy())\n```\n\nand add env or input to the step:\n\n```yaml\n- name: Some step use githubkit\n  with:\n    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n- name: Some step use githubkit\n  env:\n    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\n### Config\n\ngithubkit is highly configurable, you can change the default config by passing config options to `GitHub`:\n\n```python\nfrom githubkit import GitHub\n\ngithub = GitHub(\n    base_url=\"https://api.github.com/\",\n    accept_format=\"full+json\",\n    previews=[\"starfox\"],\n    user_agent=\"GitHubKit/Python\",\n    follow_redirects=True,\n    timeout=None,\n    http_cache=True,\n    auto_retry=True,\n)\n```\n\nThe `accept_format` and `previews` are used to set the default `Accept` header, you can find more details in [GitHub API docs](https://docs.github.com/en/rest/overview/media-types).\n\nThe `http_cache` option enables the http caching feature powered by [Hishel](https://hishel.com/) for HTTPX. GitHub API limits the number of requests that you can make within a specific amount of time. This feature is useful to reduce the number of requests to GitHub API and avoid hitting the rate limit.\n\nThe `auto_retry` option enables request retrying when rate limit exceeded and server error encountered. See [Auto Retry](#auto-retry) for more infomation.\n\n### Calling Rest API\n\n> APIs are fully typed. Typing in the following examples is just for reference only.\n\nSimple sync call:\n\n```python\nfrom githubkit import Response\nfrom githubkit.versions.latest.models import FullRepository\n\nresp: Response[FullRepository] = github.rest.repos.get(owner=\"owner\", repo=\"repo\")\nrepo: FullRepository = resp.parsed_data\n```\n\nSimple async call:\n\n```python\nfrom githubkit import Response\nfrom githubkit.versions.latest.models import FullRepository\n\nresp: Response[FullRepository] = await github.rest.repos.async_get(owner=\"owner\", repo=\"repo\")\nrepo: FullRepository = resp.parsed_data\n```\n\nCall API with context (reusing client):\n\n```python\nfrom githubkit import Response\nfrom githubkit.versions.latest.models import FullRepository\n\nwith GitHub(\"<your_token_here>\") as github:\n    resp: Response[FullRepository] = github.rest.repos.get(owner=\"owner\", repo=\"repo\")\n    repo: FullRepository = resp.parsed_data\n```\n\n```python\nfrom githubkit import Response\nfrom githubkit.versions.latest.models import FullRepository\n\nasync with GitHub(\"<your_token_here>\") as github:\n    resp: Response[FullRepository] = await github.rest.repos.async_get(owner=\"owner\", repo=\"repo\")\n    repo: FullRepository = resp.parsed_data\n```\n\n### Data Validation\n\nAs shown above, the response data is parsed and validated by accessing the `response.parsed_data` property. This ensures that the data type returned by the API is as expected and your code is safe to use it (with static type checking). But sometimes you may want to get the raw data returned by the API, such as when the schema is not correct. You can use the `response.text` property or `response.json()` method to get the raw data:\n\n```python\nfrom typing import Any, Dict\nfrom githubkit import Response\n\nresp: Response[FullRepository] = github.rest.repos.get(owner=\"owner\", repo=\"repo\")\nrepo: Dict[str, Any] = resp.json()\n```\n\n### Rest API Versioning\n\n> APIs are fully typed. Different versions of APIs are typed separately.\n\ngithubkit supports all versions of GitHub API, you can switch between versions as follows:\n\n```python\ngithub.rest(\"2022-11-28\").repos.get(owner=\"owner\", repo=\"repo\")\n```\n\nThe models of versions can be imported from `githubkit.versions.<version>.models`, for example:\n\n```python\nfrom githubkit.versions.v2022_11_28.models import FullRepository\n```\n\nSpecially, the `latest` version is always linked to the latest version of GitHub API:\n\n```python\nfrom githubkit.versions.latest.models import FullRepository\n```\n\n> [!NOTE]\n> For backward compatibility, the `githubkit.rest` module is linked to the models of `latest` version by default.\n>\n> ```python\n> from githubkit.rest import FullRepository\n> ```\n\nYou can also get the latest version name of GitHub API and all versions mapping of GitHub API:\n\n```python\nfrom githubkit.versions import LATEST_VERSION, VERSIONS\n```\n\nCurrent supported versions are: (you can find it in the section `[[tool.codegen.descriptions]]` of the `pyproject.toml` file)\n\n- 2022-11-28 (latest)\n- ghec-2022-11-28\n\n### Pagination\n\nPagination type checking is also supported:\n\n> Typing is tested with Pylance (Pyright).\n\n```python\nfrom githubkit.versions.latest.models import Issue\n\nfor issue in github.paginate(\n    github.rest.issues.list_for_repo, owner=\"owner\", repo=\"repo\", state=\"open\"\n):\n    issue: Issue\n    print(issue.number)\n```\n\n```python\nfrom githubkit.versions.latest.models import Issue\n\nasync for issue in github.paginate(\n    github.rest.issues.async_list_for_repo, owner=\"owner\", repo=\"repo\", state=\"open\"\n):\n    issue: Issue\n    print(issue.number)\n```\n\ncomplex pagination with custom map function (some api returns data in a nested field):\n\n```python\nasync for accessible_repo in github.paginate(\n    github.rest.apps.async_list_installation_repos_for_authenticated_user,\n    map_func=lambda r: r.parsed_data.repositories,\n    installation_id=1,\n):\n    accessible_repo: Repository\n    print(accessible_repo.full_name)\n```\n\n### Calling GraphQL API\n\nSimple sync call:\n\n```python\ndata: Dict[str, Any] = github.graphql(query, variables={\"foo\": \"bar\"})\n```\n\nSimple async call:\n\n```python\ndata: Dict[str, Any] = await github.async_graphql(query, variables={\"foo\": \"bar\"})\n```\n\n### Auto Retry\n\nBy default, githubkit will retry the request when specific exception encountered. When rate limit exceeded, githubkit will retry once after GitHub suggested waiting time. When server error encountered (http status >= 500), githubkit will retry max three times.\n\nYou can disable this feature by set the `auto_retry` config to `False`:\n\n```python\ngithub = GitHub(\n    ...\n    auto_retry=False\n)\n```\n\nYou can also customize the retry decision function by passing a callable:\n\n```python\nfrom datetime import timedelta\n\nfrom githubkit.retry import RetryOption\nfrom githubkit.exception import GitHubException\n\ndef retry_decision_func(exc: GitHubException, retry_count: int) -> RetryOption:\n    if retry_count < 1:\n        return RetryOption(True, timedelta(seconds=60))\n    return RetryOption(False)\n\ngithub = GitHub(\n    ...\n    auto_retry=retry_decision_func\n)\n```\n\ngithubkit also provides some builtin retry decision function:\n\n1. Retry when rate limit exceeded:\n\n   ```python\n   from githubkit.retry import RETRY_RATE_LIMIT, RetryRateLimit\n\n   # default\n   github = GitHub(\n      ...\n      auto_retry=RETRY_RATE_LIMIT\n   )\n   # or, custom max retry count\n   github = GitHub(\n      ...\n      auto_retry=RetryRateLimit(max_retry=1)\n   )\n   ```\n\n2. Retry when server error encountered:\n\n   ```python\n   from githubkit.retry import RETRY_SERVER_ERROR, RetryServerError\n\n   # default\n   github = GitHub(\n      ...\n      auto_retry=RETRY_SERVER_ERROR\n   )\n   # or, custom max retry count\n   github = GitHub(\n      ...\n      auto_retry=RetryServerError(max_retry=1)\n   )\n   ```\n\n3. Chain retry decision functions:\n\n   ```python\n   from githubkit.retry import RETRY_RATE_LIMIT, RETRY_SERVER_ERROR, RetryChainDecision\n\n   github = GitHub(\n      ...\n      auto_retry=RetryChainDecision(RETRY_RATE_LIMIT, RETRY_SERVER_ERROR)\n   )\n   ```\n\n### Webhook Verification\n\n> `githubkit.webhooks` module contains some shortcut functions to help you verify and parse webhook payload.\n\nSimple webhook payload verification:\n\n```python\nfrom githubkit.webhooks import verify\n\nvalid: bool = verify(secret, request.body, request.headers[\"X-Hub-Signature-256\"])\n```\n\nSign the webhook payload manually:\n\n```python\nfrom githubkit.webhooks import sign\n\nsignature: str = sign(secret, payload, method=\"sha256\")\n```\n\n### Webhook Parsing\n\n> `githubkit.webhooks` module contains some shortcut functions to help you verify and parse webhook payload.\n\nParse the payload with event name:\n\n```python\nfrom githubkit.webhooks import parse\n\nevent = parse(request.headers[\"X-GitHub-Event\"], request.body)\n```\n\n(**NOT RECOMMENDED**) Parse the payload without event name (may cost longer time and more memory):\n\n```python\nfrom githubkit.webhooks import parse_without_name\n\nevent = parse_without_name(request.body)\n```\n\n> [!WARNING]\n> The `parse_without_name` function will try to parse the payload with all supported event names.  \n> The behavior of this function is not the same between pydantic v1 and v2.  \n> When using pydantic v1, the function will return the first valid event model (known as `left-to-right` mode).  \n> When using pydantic v2, the function will return the highest scored valid event model (known as `smart` mode).  \n> See: [Union Modes](https://docs.pydantic.dev/latest/concepts/unions/#union-modes).\n\nParse dict like payload:\n\n```python\nfrom githubkit.webhooks import parse_obj, parse_obj_without_name\n\nevent = parse_obj(request.headers[\"X-GitHub-Event\"], request.json())\nevent = parse_obj_without_name(request.json())  # NOT RECOMMENDED\n```\n\nThe `parse` and `parse_obj` function supports type overload, if you provide static value for the `event_name` parameter, the return type will be inferred automatically.\n\nWebhook also supports versioning, you can switch between versions as follows:\n\n```python\nfrom githubkit import GitHub\n\nevent = GitHub.webhooks(\"2022-11-28\").parse(request.headers[\"X-GitHub-Event\"], request.body)\n```\n\n### Switch between AuthStrategy\n\nYou can change the auth strategy and get a new client simplely using `with_auth`.\n\nChange from `AppAuthStrategy` to `AppInstallationAuthStrategy`:\n\n```python\nfrom githubkit import GitHub, AppAuthStrategy\n\ngithub = GitHub(AppAuthStrategy(\"<app_id>\", \"<private_key>\"))\ninstallation_github = github.with_auth(\n    github.auth.as_installation(installation_id)\n)\n```\n\nChange from `OAuthAppAuthStrategy` to `OAuthWebAuthStrategy`:\n\n```python\nfrom githubkit import GitHub, OAuthAppAuthStrategy\n\ngithub = GitHub(OAuthAppAuthStrategy(\"<client_id>\", \"<client_secret>\"))\nuser_github = github.with_auth(github.auth.as_web_user(\"<code>\"))\n```\n\n## Development\n\nOpen in Codespaces (Dev Container):\n\n[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=512138996)\n\nGenerate latest models and apis:\n\n> [!WARNING]\n> This may use about **400M** memory and take a long time.\n\n```bash\n./scripts/run-codegen.sh\n```\n\nRun tests in dev env:\n\n```bash\n./scripts/run-tests.sh\n```\n\nRun tests in test envs, for example:\n\n```bash\ncd ./envs/pydantic-v2/\npoetry run bash ../../scripts/run-tests.sh\n```\n\n## Contributors\n\nThanks to the following people who have contributed to this project:\n\n<a href=\"https://github.com/yanyongyu/githubkit/graphs/contributors\">\n  <img src=\"https://contrib.rocks/image?repo=yanyongyu/githubkit&max=1000\" alt=\"contributors\" />\n</a>\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "GitHub SDK for Python",
    "version": "0.11.4",
    "project_urls": {
        "Documentation": "https://github.com/yanyongyu/githubkit",
        "Homepage": "https://github.com/yanyongyu/githubkit",
        "Repository": "https://github.com/yanyongyu/githubkit"
    },
    "split_keywords": [
        "github",
        " octokit"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5942fb193e85ea1c4141b6a9dc8b0b96352edb988ece7cac7a619499a7c86c93",
                "md5": "7a972064090655cecff61a8d75201b5b",
                "sha256": "281af76e9ec24a1f3dc1c99ed4e50785898220d47f84acb2f87be8d7a572769a"
            },
            "downloads": -1,
            "filename": "githubkit-0.11.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7a972064090655cecff61a8d75201b5b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.8",
            "size": 5041441,
            "upload_time": "2024-04-20T07:51:02",
            "upload_time_iso_8601": "2024-04-20T07:51:02.419989Z",
            "url": "https://files.pythonhosted.org/packages/59/42/fb193e85ea1c4141b6a9dc8b0b96352edb988ece7cac7a619499a7c86c93/githubkit-0.11.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1b4af2d198ed937843d3f401a84d616da3c2170105c02d1531e53bf680fba499",
                "md5": "29c0b9e99ae49e7dea446ca885dbb1fb",
                "sha256": "e629d833f98157cb4b1c14b69fdb54f7f960fb0da6906f1fa30fca14c347c0d4"
            },
            "downloads": -1,
            "filename": "githubkit-0.11.4.tar.gz",
            "has_sig": false,
            "md5_digest": "29c0b9e99ae49e7dea446ca885dbb1fb",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.8",
            "size": 1909207,
            "upload_time": "2024-04-20T07:51:05",
            "upload_time_iso_8601": "2024-04-20T07:51:05.301937Z",
            "url": "https://files.pythonhosted.org/packages/1b/4a/f2d198ed937843d3f401a84d616da3c2170105c02d1531e53bf680fba499/githubkit-0.11.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-20 07:51:05",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "yanyongyu",
    "github_project": "githubkit",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "githubkit"
}
        
Elapsed time: 0.23787s