| api_spec | ||
| pyforgejo | ||
| tests | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
pyforgejo
A Python client library for accessing the Forgejo API.
⚠️ pyforgejo 2.0 introduces significant changes. If you're using 1.0, you can view docs on the 1.0 branch.
Usage
- Create an
.envfile in your project directory with theBASE_URLand yourAPI_KEY:
BASE_URL=https://codeberg.org/api/v1
API_KEY=your_api_key
- Create a client and call an endpoint:
from pyforgejo import PyforgejoApi
client = PyforgejoApi()
# get a specific repo
repo = client.repository.repo_get(owner='harabat', repo='pyforgejo')
repo
# Repository(allow_fast_forward_only_merge=False, allow_merge_commits=True, allow_rebase=True, ...)
repo.dict()
# {'allow_fast_forward_only_merge': False,
# 'allow_merge_commits': True,
# 'allow_rebase': True,
# ...
# }
# list issues for the repo
issues = client.issue.list_issues(owner=repo.owner.login, repo=repo.name)
[issue.title for issue in issues]
# ['Normalize option model names',
# 'Calling methods from client',
# '`parsed` is None for most methods',
# '`openapi-python-client` does not support `text/plain` requests']
The client follows this pattern for calling endpoints:
client.<resource>.<operation_id>(args)
where:
<resource>: the API resource (e.g.,repository,issue,user)<operation_id>: the specific operation, derived from the OpenAPI spec'soperationId(converted to snake_case)
You can find the resource and operation_id either in the Swagger spec or in the API reference.
Installation
pip install pyforgejo
Forgejo API Resources
- API Usage | Forgejo: user guide for the Forgejo API
- Forgejo API | Codeberg: API reference for Forgejo
- Forgejo API Swagger spec | Codeberg: Forgejo API Swagger spec
- About Swagger Specification | Documentation | Swagger: docs for Swagger spec
- The OpenAPI Specification Explained | OpenAPI Documentation: docs for OpenAPI spec
Development
Using fern
pyforgejo is generated with fern, based on a patched Forgejo OpenAPI spec.
The user experience and code architecture of the fern-generated client follow best practice. As the library is tested by users, we will identify any issues inherent to fern that prove limiting to pyforgejo: if we find such issues and cannot patch them upstream, the current codebase provides a good foundation for further development and any divergence from fern would not affect the vast majority of usecases.
Because the client has to apply to a specific Forgejo release, pyforgejo tracks Codeberg. If you need a client for a different Forgejo release, you can generate your own by following the steps below.
Generating the client with fern
- Download Forgejo's Swagger API spec and convert it to OpenAPI v3 via https://converter.swagger.io/.
mkdir api_spec
wget https://converter.swagger.io/api/convert\?url\=https%3A%2F%2Fcode.forgejo.org%2Fswagger.v1.json --output-document=api_spec/openapi.json
- Edit both
swagger.v1.jsonandopenapi.jsonto keep onlyAuthorizationHeaderTokenin security definitions.
"securityDefinitions": {
"AuthorizationHeaderToken": {
"description": "API tokens must be prepended with \"token\" followed by a space.",
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
},
"security": [
{
"AuthorizationHeaderToken": []
}
]
- Modify endpoints with multiple return types in
openapi.json.
"/repos/{owner}/{repo}/contents/{filepath}": {
"get": {
// ...
"responses": {
"200": {
- "$ref": "#/components/responses/ContentsResponse"
+ "description": "A single file's contents or a directory listing",
+ "content": {
+ "application/json": {
+ "schema": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/ContentsResponse"
+ },
+ {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentsResponse"
+ }
+ }
+ ]
+ }
+ },
+ "text/html": {
+ "schema": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/ContentsResponse"
+ },
+ {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ContentsResponse"
+ }
+ }
+ ]
+ }
+ }
+ }
},
// ...
}
},
},
- Install fern, initialise a new workspace, and specify
pyforgejoas the name of your organisation (= client).
npm install -g fern-api
fern init --openapi api_spec/openapi.json
# Please enter your organization: pyforgejo
- Add the Python SDK generator.
fern add fernapi/fern-python-sdk
- Remove other generators and set the output directory to
pyforgejo.
# yaml-language-server: $schema=https://schema.buildwithfern.dev/generators-yml.json
api:
specs:
- openapi: openapi/openapi.json
default-group: local
groups:
local:
generators:
- - name: fernapi/fern-typescript-sdk
- # ...
- name: fernapi/fern-python-sdk
version: x.x.x
output:
location: local-file-system
- path: ../sdks/python
+ path: ../sdks/pyforgejo
- Generate the client (output will be in
sdks/pyforgejo).
fern generate
# you'll have to login to GitHub
- Create a
.envfile insdks/pyforgejowith yourBASE_URLandAPI_KEY.
BASE_URL=https://codeberg.org/api/v1
API_KEY="token your_api_key"
- Modify the
PyforgejoApiandAsyncPyforgejoApiclasses insdks/pyforgejo/client.pyto use environment variables.
# ...
from .user.client import AsyncUserClient, UserClient
+import os
+from dotenv import load_dotenv
+
+load_dotenv()
+
+BASE_URL = os.getenv("BASE_URL", "")
+API_KEY = os.getenv("API_KEY", "")
class PyforgejoApi:
# ...
base_url : typing.Optional[str]
- The base url to use for requests from the client.
+ The base url to use for requests from the client. Defaults to BASE_URL from .env file.
# ...
- api_key : str
+ api_key : typing.Optional[str]
+ The API key to use for authentication. Defaults to API_KEY from .env file.
# ...
def __init__(
# ...
- api_key: str,
+ api_key: typing.Optional[str] = None,
# ...
):
+ base_url = base_url or BASE_URL
+ api_key = api_key or API_KEY
+
+ if not base_url:
+ raise ValueError("base_url must be provided either as an .env variable or as an argument")
+ if not api_key:
+ raise ValueError("api_key must be provided either as an .env variable or as an argument")
# same for AsyncPyforgejoApi
- Update handling of
api_keyincore/client_wrapper.py.
def get_headers(self) -> typing.Dict[str, str]:
headers: typing.Dict[str, str] = {
"X-Fern-Language": "Python",
}
- headers["Authorization"] = self.api_key
+ headers["Authorization"] = f"token {self.api_key.replace('token ', '')}"
return headers
- Create a virtual environment and install dependencies.
wget https://codeberg.org/harabat/pyforgejo/raw/branch/main/pyproject.toml
uv venv
uv pip install -e '.[dev]'
uv sync --dev
uv run ruff format .
- Use the client as shown in the Usage section.
# uv pip install ipython
# uv run ipython
from pyforgejo import PyforgejoApi
client = PyforgejoApi()
user = client.user.get_current()
- Run tests.
wget https://codeberg.org/harabat/pyforgejo/archive/main:tests.zip
unzip tests.zip
rm tests.zip
uv run pytest -v tests/test_client.py