Metadata-Version: 2.5
Name: prcpy-erlc
Version: 0.1.1
Summary: A typed Python client for the ER:LC Private Server API.
Project-URL: Documentation, https://apidocs.erlc.gg/
Project-URL: Repository, https://github.com/Metolix/erlcpy
Project-URL: Issues, https://github.com/Metolix/erlcpy/issues
Author: Sidhak Singh
License: MIT License
        
        Copyright (c) 2026 Sidhak Singh
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: api,erlc,private-server,python,roblox
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx<1,>=0.27
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: cryptography>=42; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: webhooks
Requires-Dist: cryptography>=42; extra == 'webhooks'
Description-Content-Type: text/markdown

# prcpy

A typed Python client for the ER:LC Private Server API.

prcpy provides synchronous and asynchronous clients, typed response models, rate-limit metadata, structured exceptions, webhook helpers, and a low-level request interface for endpoints that are added to the API later.

> prcpy is an independent open-source project and is not affiliated with or endorsed by ER:LC or PRC.

## Requirements

- Python 3.10+
- An ER:LC private server with API access
- A server key from the server's API settings

## Installation

```bash
pip install prcpy-erlc
```

For webhook signature verification:

```bash
pip install "prcpy-erlc[webhooks]"
```

## Quick start

```python
from prcpy import Client

with Client("your-server-key") as client:
    server = client.get_server(players=True)

    print(server.name)
    print(f"{server.current_players}/{server.max_players}")

    for player in server.players or []:
        print(player.username, player.team)
```

## Async

```python
from prcpy import AsyncClient

async with AsyncClient("your-server-key") as client:
    server = await client.get_server(players=True)
    print(server.name)
```

## Available server data

The v2 server endpoint supports these optional resources:

- `players`
- `staff`
- `join_logs`
- `queue`
- `kill_logs`
- `command_logs`
- `mod_calls`
- `emergency_calls`
- `vehicles`

Only request the data an application needs.

```python
server = client.get_server(
    players=True,
    staff=True,
    vehicles=True,
    emergency_calls=True,
)
```

## Convenience methods

```python
players = client.get_players()
staff = client.get_staff()
join_logs = client.get_join_logs()
queue = client.get_queue()
kill_logs = client.get_kill_logs()
command_logs = client.get_command_logs()
mod_calls = client.get_mod_calls()
vehicles = client.get_vehicles()
bans = client.get_bans()
```

## Commands

```python
result = client.send_command(":h Hello from prcpy")
print(result.message)
```

The API documents a `commandId` on command failures. prcpy exposes it as `CommandError.command_id` or `ServerOfflineError.command_id` when supplied by the API.

## Authentication

All API requests use the `server-key` header.

Public applications may also provide a global API key:

```python
client = Client(
    "server-key",
    global_api_key="global-api-key",
)
```

Environment variables are supported:

```text
ERLC_SERVER_KEY=...
ERLC_GLOBAL_API_KEY=...
```

```python
client = Client.from_env()
```

Never commit keys to source control.

## Rate limits

The client reads the API's `X-RateLimit-Bucket`, `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` response headers.

```python
client.get_server()
print(client.rate_limit)
```

A 429 response raises `RateLimitError` with `retry_after` when the server provides a `Retry-After` header.

prcpy does not silently retry commands. This avoids accidentally executing an in-game command more than once.

## Raw API access

The typed methods cover the documented API, but the API can grow independently of this package.

```python
data = client.request("GET", "/v2/server", params={"Players": "true"})
```

## Webhooks

prcpy includes a small helper for Ed25519 webhook verification:

```python
from prcpy.webhooks import verify_signature

verify_signature(
    timestamp=request.headers["X-Signature-Timestamp"],
    signature=request.headers["X-Signature-Ed25519"],
    body=raw_request_body,
    public_key="your-webhook-public-key",
)
```

Always verify the raw request body before parsing JSON.

## Development

```bash
python -m pip install -e ".[dev]"
ruff check .
pytest
```

## Project structure

```text
prcpy/
├── docs/
├── examples/
├── src/prcpy/
│   ├── client.py
│   ├── errors.py
│   ├── models.py
│   ├── rate_limits.py
│   └── webhooks.py
├── tests/
├── .github/workflows/
├── CONTRIBUTING.md
├── LICENSE
├── pyproject.toml
└── README.md
```

## License

MIT

## Thanks
Thanks to Copilot for fixing the CI (and writing the MD files...)