- Python 100%
| pyforgejo | add activitypub endpoints following #2 | |
| .gitignore | add org files to .gitignore | |
| config.yaml | initial commit | |
| LICENSE | add MIT license | |
| pyproject.toml | increment version and publish on pypi | |
| README.md | add advice about harabat/openapi-python-client fork for development | |
pyforgejo
A client library for accessing the Forgejo API.
Usage
Create a client:
from pyforgejo import AuthenticatedClient
client = AuthenticatedClient(base_url='https://codeberg.org/api/v1', token='API_TOKEN')
Call an endpoint:
from pyforgejo.api.user import user_get_current
response = user_get_current.sync_detailed(client=client)
# async version
response_async = user_get_current.asyncio_detailed(client=client)
response = await response_async
print(response)
Installation
pip install pyforgejo
Forgejo API
Resources:
- API Usage | Forgejo – Beyond coding. We forge.: user guide for the Forgejo API
- Forgejo API | Codeberg: API reference for Codeberg
- Forgejo API Swagger spec | Codeberg: Codeberg's Forgejo API Swagger spec
- openapi-generators/openapi-python-client: repo for the generator library that was used to generate
pyforgejo - About Swagger Specification | Documentation | Swagger: docs for Swagger spec
- The OpenAPI Specification Explained | OpenAPI Documentation: docs for OpenAPI spec
The structure of the import statement for interacting with a specific endpoint follows this pattern:
from pyforgejo.api.<root_path> import <operation_id>
Here, <tag> is the root path or tag for the endpoint in the Swagger spec, and <operation_id> is the operationId for the specific function you want to call, converted to snake case.
For example, for the endpoint /repos/search, the Swagger spec is:
"/repos/search": {
"tags": ["repository"],
"operationId": "repoSearch",
...
}
So to hit that endpoint, the import statement will be:
from pyforgejo.api.repository import repo_search
Every path/operation combo becomes a Python module with four functions:
sync: Blocking request that returns parsed data (if successful) orNonesync_detailed: Blocking request that always returns aRequest, optionally withparsedset if the request was successfulasyncio: Likesyncbut async instead of blockingasyncio_detailed: Likesync_detailedbut async instead of blocking
Currently, Forgejo's API spec does not provide the response schemas for every endpoints, so most endpoints will not return parsed data and only have a detailed method.
All path/query parameters and bodies become method arguments.
Development
openapi-python-client
pyforgejo is generated with openapi-python-client, with as of now very little modification.
If you run into any issues, please create an issue in this repo.
If you want to work on a PR, please consider making a PR to openapi-python-client rather than to this repo.
openapi-python-client was chosen to generate this client over openapi-generator and fern because of the following reasons:
openapi-python-clientis Python-specific, which allows it to leverage specific language features, have a clearer code, and offer a better developer experience, compared toopenapi-generator's one-size-fits-all approachopenapi-python-clientis written in Python, so users ofpyforgejowill be more likely to be able to make contributions and fix bugs in the generator's code itself, whileopenapi-generatoris written in Java, which represents a higher barrier to contributionsopenapi-python-clientsupports more authentication options, including access tokens, thanfern- the documentation is limited, but clearer than for
openapi-generator
Generating the client with openapi-python-client
- Convert Forgejo's Swagger spec to OpenAPI with swagger-converter, as Swagger is not supported by
openapi-python-client. - Install openapi-python-client:
pip install openapi-python-client - Create a
config.yamlfile with the following content:project_name_override:"pyforgejo" - Generate the client (this will create a
pyforgejo/dir):openapi-python-client generate --path /path/to/forgejo_openapi.json --config /path/to/config.yaml - Alternatively, update the client:
git clone https://codeberg.org/harabat/pyforgejo openapi-python-client update --path /path/to/forgejo_openapi.json --config ./pyforgejo/config.yaml - Navigate to the
pyforgejo/dir and call the API:from pyforgejo.client import AuthenticatedClient from pyforgejo.api.user import user_get_current client = AuthenticatedClient(base_url='FORGEJO_URL' + '/api/v1', token='ACCESS_TOKEN') response = user_get_current.sync_detailed(client=client) print(response) # Response(status_code=<HTTPStatus.OK: 200>, ...)
Because merging of PRs on openapi-python-client can be slow, the fork at https://github.com/harabat/openapi-python-client, which is where I work on pyforgejo-related PRs to openapi-python-client, might be more up-to-date. In this case, replace step 1 above with the following:
git clone https://github.com/harabat/openapi-python-client.git
pip install ./openapi-python-client --upgrade
Modifying openapi-python-client
- Clone and modify
openapi-python-clientgit clone https://github.com/openapi-generators/openapi-python-client.git nvim openapi-python-client/openapi_python_client/parser/openapi.py # make your changes - Create and activate new env
- Install (or upgrade) modified local package
pip install ./openapi-python-client # pip install ./openapi-python-client --upgrade # after making further changes - Generate a new client the regular way
openapi-python-client generate --path /path/to/forgejo_openapi.json --config /path/to/config.yaml