Initial commit: add Gitea PyPI publish workflow

This commit is contained in:
2026-07-06 11:02:19 -05:00
commit b0d2873cbc
40 changed files with 5831 additions and 0 deletions

184
README.md Normal file
View File

@@ -0,0 +1,184 @@
# conduit-client
A typed Python client for the [Conduit](https://conduit.librewiki.org/doku.php?id=examples) unified API gateway.
## Features
- Synchronous and asynchronous clients (`ConduitClient` and `AsyncConduitClient`).
- Pydantic v2 request/response models.
- Covers every documented Conduit endpoint across gateway, SMS/MMS, media, torrents, wiki, compute, and DNS façades.
- Clean error handling with typed exceptions.
## Installation
```bash
pip install conduit-client
```
## Quick start
```python
from conduit_client import ConduitClient
client = ConduitClient("mega_sk_live_<prefix>_<secret>")
me = client.gateway.me()
print(me.scopes)
```
## Async usage
```python
import asyncio
from conduit_client import AsyncConduitClient
async def main():
async with AsyncConduitClient("mega_sk_live_<prefix>_<secret>") as client:
me = await client.gateway.me()
print(me.scopes)
asyncio.run(main())
```
## Per-façade examples
### Gateway
```python
from conduit_client import ConduitClient
from conduit_client.models.common import CreateKeyRequest
from conduit_client.models.gateway import AuditLogQuery
client = ConduitClient("mega_sk_live_<prefix>_<secret>")
# API keys
keys = client.gateway.list_keys()
new_key = client.gateway.create_key(CreateKeyRequest(display_name="ci", scopes=["sms:send"]))
print(new_key.key) # one-time secret
# Audit log
entries = client.gateway.admin_audit(AuditLogQuery(scope="sms:send", limit=50))
```
### SMS / MMS
```python
from conduit_client.models.sms import SendSmsRequest, SendMmsRequest
sms_id = client.sms.send_sms(SendSmsRequest(did="5550100", dst="5550200", message="hi"))
print(sms_id.id)
mms_id = client.sms.send_mms(
SendMmsRequest(
did="5550100",
dst="5550200",
message="pic",
media1="https://example.com/photo.jpg",
)
)
```
### Media ingestion (MeTube)
```python
from conduit_client.models.media_ingest import CreateIngestJobRequest
job = client.media_ingest.create_job(
CreateIngestJobRequest(url="https://www.youtube.com/watch?v=abc", quality="best")
)
print(job.id, job.status)
```
### Media library (Jellyfin)
```python
from conduit_client.models.media_library import LibraryLoginRequest, LibrarySearchQuery
client.media_library.login(LibraryLoginRequest(username="user", password="pw"))
results = client.media_library.search(LibrarySearchQuery(term="Inception"))
```
### Torrents (Transmission)
```python
from conduit_client.models.torrents import AddTorrentRequest
client.torrents.add(AddTorrentRequest(url="magnet:?xt=urn:btih:...", paused=False))
client.torrents.list(fields=["id", "name"])
```
### Wiki (DokuWiki)
```python
from conduit_client.models.wiki import WriteWikiPageRequest
page = client.wiki.get_raw("namespace:page")
client.wiki.write("namespace:page", WriteWikiPageRequest(text="updated content"))
```
### Compute (Proxmox)
```python
from conduit_client.models.compute import CreateVmRequest, ComputeTicketRequest
ticket = client.compute.auth_ticket(ComputeTicketRequest(username="root", password="pw"))
print(ticket.ticket)
# Create a VM; extra Proxmox fields are forwarded as-is.
client.compute.create_vm(
CreateVmRequest(node="pve", vmid=100, cores=2, memory=2048, storage="local-lvm")
)
client.compute.start_vm(100)
```
### DNS (BIND9)
```python
from conduit_client.models.dns import (
AddZoneRequest,
BatchRecordUpdate,
BatchUpdateRecordsRequest,
)
client.dns.create_zone(AddZoneRequest(zone="example.com", klass="IN"))
client.dns.batch_update_records(
"example.com",
BatchUpdateRecordsRequest(
updates=[
BatchRecordUpdate(op="add", name="www", ttl=300, rtype="A", rdata="1.2.3.4")
]
),
)
client.dns.reload_server("default")
```
## Error handling
```python
from conduit_client import ConduitClient, AuthenticationError, NotFoundError
client = ConduitClient("mega_sk_live_<prefix>_<secret>")
try:
client.sms.delete_sms(999999)
except NotFoundError as exc:
print(exc.status_code, exc.response_body)
except AuthenticationError as exc:
print("Invalid API key", exc.status_code)
```
## Configuration
```python
from conduit_client import ConduitClient
client = ConduitClient(
"mega_sk_live_<prefix>_<secret>",
base_url="https://api.cowtunnel.com",
timeout=60.0,
max_retries=2,
)
```
## License
MIT