prcpy-erlc 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a reproducible problem
4
+ title: ""
5
+ labels: bug
6
+ assignees: ""
7
+ ---
8
+
9
+ ## Description
10
+
11
+ ## Reproduction
12
+
13
+ ## Expected behavior
14
+
15
+ ## Actual behavior
16
+
17
+ ## Environment
18
+
19
+ - prcpy-erlc version:
20
+ - Python version:
21
+ - OS:
22
+
23
+ Do not include API keys or private server credentials.
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an improvement
4
+ title: ""
5
+ labels: enhancement
6
+ assignees: ""
7
+ ---
8
+
9
+ ## What would you like to add?
10
+
11
+ ## Why is it useful?
12
+
13
+ ## Proposed API
14
+
15
+ ## Additional context
@@ -0,0 +1,12 @@
1
+ ## Summary
2
+
3
+ ## Changes
4
+
5
+ ## Testing
6
+
7
+ - [ ] ruff check .
8
+ - [ ] pytest
9
+
10
+ ## Notes
11
+
12
+ Do not include credentials or private server data.
@@ -0,0 +1,33 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ matrix:
17
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
18
+ steps:
19
+ - uses: actions/checkout@v6
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+ cache: pip
24
+ - name: Install dependencies
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ python -m pip install -e ".[dev]"
28
+ - name: Lint
29
+ run: python -m ruff check .
30
+ - name: Test
31
+ run: python -m pytest
32
+ - name: Build
33
+ run: python -m build
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .pytest_cache/
4
+ .ruff_cache/
5
+ .coverage
6
+ htmlcov/
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+ .venv/
11
+ venv/
12
+ .env
13
+ .env.*
@@ -0,0 +1,144 @@
1
+ # Contributing
2
+
3
+ Thanks for contributing to prcpy.
4
+
5
+ prcpy is a small, typed Python client for the ER:LC Private Server API. The project aims to keep its public API predictable, its dependencies small, and its implementation easy to maintain.
6
+
7
+ ## Before you start
8
+
9
+ For a bug fix, documentation change, or small improvement, open an issue first when the change is likely to affect the public API or overall project direction. For straightforward fixes, you can open a pull request directly.
10
+
11
+ Please search existing issues and pull requests before opening a new one.
12
+
13
+ ## Development setup
14
+
15
+ prcpy supports Python 3.10 and newer.
16
+
17
+ ```bash
18
+ python -m venv .venv
19
+ ```
20
+
21
+ Windows:
22
+ ```powershell
23
+ .venv\Scripts\Activate.ps1
24
+ ```
25
+
26
+ macOS/Linux:
27
+ ```bash
28
+ source .venv/bin/activate
29
+ ```
30
+
31
+ Install development dependencies:
32
+ ```bash
33
+ python -m pip install -e ".[dev]"
34
+ ```
35
+
36
+ ## Running checks
37
+ ```bash
38
+ ruff check .
39
+ pytest
40
+ ```
41
+
42
+ Run both commands before opening a pull request. Changes to webhook verification, HTTP behavior, models, error handling, or other public behavior should include tests.
43
+
44
+ ## Project structure
45
+ ```text
46
+ src/prcpy/ Package source
47
+ tests/ Test suite
48
+ examples/ Usage examples
49
+ docs/ API and design documentation
50
+ .github/ CI and repository templates
51
+ ```
52
+
53
+ Keep implementation code in `src/prcpy`. Avoid adding scripts or files without a clear maintenance or user-facing purpose.
54
+
55
+ ## Code style
56
+ - Follow the existing project structure.
57
+ - Keep functions and classes focused.
58
+ - Prefer explicit, readable code over clever abstractions.
59
+ - Preserve type annotations.
60
+ - Keep the public API small and intentional.
61
+ - Use the standard library where it is sufficient.
62
+ - Avoid unnecessary dependencies.
63
+ - Keep error messages useful without exposing credentials or private data.
64
+ - Do not silently change existing public behavior.
65
+ - Do not add automatic retries to commands unless explicitly designed and documented; repeating a command can have side effects.
66
+
67
+ Ruff is the project's source of truth for linting.
68
+
69
+ ## API changes
70
+
71
+ For public API changes:
72
+ 1. Update the implementation.
73
+ 2. Add or update tests.
74
+ 3. Update documentation.
75
+ 4. Update affected examples.
76
+ 5. Consider backward compatibility.
77
+ 6. Keep the change aligned with the official ER:LC API documentation.
78
+
79
+ If the ER:LC API itself changes, link the relevant official documentation in the pull request description. Do not invent undocumented API behavior when a documented alternative exists.
80
+
81
+ ## Models
82
+
83
+ Keep API models typed and predictable. Match official API fields closely, handle missing optional data safely, preserve useful raw API data where the existing pattern does so, and add tests for new fields.
84
+
85
+ Avoid restrictive enums for API values unless the API guarantees those values are stable.
86
+
87
+ ## HTTP behavior
88
+
89
+ Preserve useful HTTP status information, documented error details, authentication failures, and rate-limit information when changing request handling.
90
+
91
+ Be especially careful with retries: POST requests execute in-game commands and should not be automatically repeated without an explicit design.
92
+
93
+ Never log authenticated request headers.
94
+
95
+ ## Webhooks
96
+
97
+ Webhook changes require tests for valid and invalid signatures.
98
+
99
+ Use synthetic keys and payloads in tests. Never use production webhook credentials.
100
+
101
+ Verify changes against the current ER:LC documentation before submitting them.
102
+
103
+ ## Tests
104
+
105
+ Tests should be deterministic, fast, independent of a live ER:LC server, free of credentials, and focused on observable behavior.
106
+
107
+ Use mocked HTTP responses for API client tests. The normal test suite must not require a real ER:LC private server.
108
+
109
+ ## Documentation
110
+
111
+ Document behavior users can actually rely on. Keep examples short and runnable. When a public API changes, update the README or the appropriate page under `docs/`.
112
+
113
+ ## Commits
114
+
115
+ Use short, descriptive commit messages.
116
+
117
+ ```text
118
+ Add queue endpoint
119
+ Fix rate limit parsing
120
+ Update webhook docs
121
+ Test command errors
122
+ ```
123
+
124
+ Avoid commit messages that contain unnecessary detail or references to tools used to make the change.
125
+
126
+ ## Pull requests
127
+
128
+ A good pull request should explain what changed, why it changed, any public API changes, how it was tested, and compatibility or migration considerations.
129
+
130
+ Keep pull requests focused.
131
+
132
+ Before opening a pull request:
133
+ - [ ] Tests pass.
134
+ - [ ] Ruff passes.
135
+ - [ ] Documentation is updated when needed.
136
+ - [ ] Examples still make sense when affected.
137
+ - [ ] No credentials or private server data are included.
138
+ - [ ] Public API changes are clearly described.
139
+
140
+ ## Security
141
+
142
+ Never include ER:LC server keys, global API keys, webhook secrets, access tokens, or private server data in commits, issues, pull requests, examples, or tests.
143
+
144
+ See [SECURITY.md](SECURITY.md) for vulnerability reporting and security guidance.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sidhak Singh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,248 @@
1
+ Metadata-Version: 2.5
2
+ Name: prcpy-erlc
3
+ Version: 0.1.0
4
+ Summary: A typed Python client for the ER:LC Private Server API.
5
+ Project-URL: Documentation, https://apidocs.erlc.gg/
6
+ Project-URL: Repository, https://github.com/Metolix/erlcpy
7
+ Project-URL: Issues, https://github.com/Metolix/erlcpy/issues
8
+ Author: Sidhak Singh
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 Sidhak Singh
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ Keywords: api,erlc,private-server,python,roblox
32
+ Classifier: Development Status :: 3 - Alpha
33
+ Classifier: Intended Audience :: Developers
34
+ Classifier: License :: OSI Approved :: MIT License
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Programming Language :: Python :: 3 :: Only
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3.13
41
+ Classifier: Typing :: Typed
42
+ Requires-Python: >=3.10
43
+ Requires-Dist: httpx<1,>=0.27
44
+ Provides-Extra: dev
45
+ Requires-Dist: build>=1.2; extra == 'dev'
46
+ Requires-Dist: cryptography>=42; extra == 'dev'
47
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
48
+ Requires-Dist: pytest>=8; extra == 'dev'
49
+ Requires-Dist: respx>=0.21; extra == 'dev'
50
+ Requires-Dist: ruff>=0.6; extra == 'dev'
51
+ Provides-Extra: webhooks
52
+ Requires-Dist: cryptography>=42; extra == 'webhooks'
53
+ Description-Content-Type: text/markdown
54
+
55
+ # prcpy
56
+
57
+ A typed Python client for the ER:LC Private Server API.
58
+
59
+ 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.
60
+
61
+ > prcpy is an independent open-source project and is not affiliated with or endorsed by ER:LC or PRC.
62
+
63
+ ## Requirements
64
+
65
+ - Python 3.10+
66
+ - An ER:LC private server with API access
67
+ - A server key from the server's API settings
68
+
69
+ ## Installation
70
+
71
+ ```bash
72
+ pip install prcpy-erlc
73
+ ```
74
+
75
+ For webhook signature verification:
76
+
77
+ ```bash
78
+ pip install "prcpy-erlc[webhooks]"
79
+ ```
80
+
81
+ ## Quick start
82
+
83
+ ```python
84
+ from prcpy import Client
85
+
86
+ with Client("your-server-key") as client:
87
+ server = client.get_server(players=True)
88
+
89
+ print(server.name)
90
+ print(f"{server.current_players}/{server.max_players}")
91
+
92
+ for player in server.players or []:
93
+ print(player.username, player.team)
94
+ ```
95
+
96
+ ## Async
97
+
98
+ ```python
99
+ from prcpy import AsyncClient
100
+
101
+ async with AsyncClient("your-server-key") as client:
102
+ server = await client.get_server(players=True)
103
+ print(server.name)
104
+ ```
105
+
106
+ ## Available server data
107
+
108
+ The v2 server endpoint supports these optional resources:
109
+
110
+ - `players`
111
+ - `staff`
112
+ - `join_logs`
113
+ - `queue`
114
+ - `kill_logs`
115
+ - `command_logs`
116
+ - `mod_calls`
117
+ - `emergency_calls`
118
+ - `vehicles`
119
+
120
+ Only request the data an application needs.
121
+
122
+ ```python
123
+ server = client.get_server(
124
+ players=True,
125
+ staff=True,
126
+ vehicles=True,
127
+ emergency_calls=True,
128
+ )
129
+ ```
130
+
131
+ ## Convenience methods
132
+
133
+ ```python
134
+ players = client.get_players()
135
+ staff = client.get_staff()
136
+ join_logs = client.get_join_logs()
137
+ queue = client.get_queue()
138
+ kill_logs = client.get_kill_logs()
139
+ command_logs = client.get_command_logs()
140
+ mod_calls = client.get_mod_calls()
141
+ vehicles = client.get_vehicles()
142
+ bans = client.get_bans()
143
+ ```
144
+
145
+ ## Commands
146
+
147
+ ```python
148
+ result = client.send_command(":h Hello from prcpy")
149
+ print(result.message)
150
+ ```
151
+
152
+ The API documents a `commandId` on command failures. prcpy exposes it as `CommandError.command_id` or `ServerOfflineError.command_id` when supplied by the API.
153
+
154
+ ## Authentication
155
+
156
+ All API requests use the `server-key` header.
157
+
158
+ Public applications may also provide a global API key:
159
+
160
+ ```python
161
+ client = Client(
162
+ "server-key",
163
+ global_api_key="global-api-key",
164
+ )
165
+ ```
166
+
167
+ Environment variables are supported:
168
+
169
+ ```text
170
+ ERLC_SERVER_KEY=...
171
+ ERLC_GLOBAL_API_KEY=...
172
+ ```
173
+
174
+ ```python
175
+ client = Client.from_env()
176
+ ```
177
+
178
+ Never commit keys to source control.
179
+
180
+ ## Rate limits
181
+
182
+ The client reads the API's `X-RateLimit-Bucket`, `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` response headers.
183
+
184
+ ```python
185
+ client.get_server()
186
+ print(client.rate_limit)
187
+ ```
188
+
189
+ A 429 response raises `RateLimitError` with `retry_after` when the server provides a `Retry-After` header.
190
+
191
+ prcpy does not silently retry commands. This avoids accidentally executing an in-game command more than once.
192
+
193
+ ## Raw API access
194
+
195
+ The typed methods cover the documented API, but the API can grow independently of this package.
196
+
197
+ ```python
198
+ data = client.request("GET", "/v2/server", params={"Players": "true"})
199
+ ```
200
+
201
+ ## Webhooks
202
+
203
+ prcpy includes a small helper for Ed25519 webhook verification:
204
+
205
+ ```python
206
+ from prcpy.webhooks import verify_signature
207
+
208
+ verify_signature(
209
+ timestamp=request.headers["X-Signature-Timestamp"],
210
+ signature=request.headers["X-Signature-Ed25519"],
211
+ body=raw_request_body,
212
+ public_key="your-webhook-public-key",
213
+ )
214
+ ```
215
+
216
+ Always verify the raw request body before parsing JSON.
217
+
218
+ ## Development
219
+
220
+ ```bash
221
+ python -m pip install -e ".[dev]"
222
+ ruff check .
223
+ pytest
224
+ ```
225
+
226
+ ## Project structure
227
+
228
+ ```text
229
+ prcpy/
230
+ ├── docs/
231
+ ├── examples/
232
+ ├── src/prcpy/
233
+ │ ├── client.py
234
+ │ ├── errors.py
235
+ │ ├── models.py
236
+ │ ├── rate_limits.py
237
+ │ └── webhooks.py
238
+ ├── tests/
239
+ ├── .github/workflows/
240
+ ├── CONTRIBUTING.md
241
+ ├── LICENSE
242
+ ├── pyproject.toml
243
+ └── README.md
244
+ ```
245
+
246
+ ## License
247
+
248
+ MIT
@@ -0,0 +1,194 @@
1
+ # prcpy
2
+
3
+ A typed Python client for the ER:LC Private Server API.
4
+
5
+ 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.
6
+
7
+ > prcpy is an independent open-source project and is not affiliated with or endorsed by ER:LC or PRC.
8
+
9
+ ## Requirements
10
+
11
+ - Python 3.10+
12
+ - An ER:LC private server with API access
13
+ - A server key from the server's API settings
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install prcpy-erlc
19
+ ```
20
+
21
+ For webhook signature verification:
22
+
23
+ ```bash
24
+ pip install "prcpy-erlc[webhooks]"
25
+ ```
26
+
27
+ ## Quick start
28
+
29
+ ```python
30
+ from prcpy import Client
31
+
32
+ with Client("your-server-key") as client:
33
+ server = client.get_server(players=True)
34
+
35
+ print(server.name)
36
+ print(f"{server.current_players}/{server.max_players}")
37
+
38
+ for player in server.players or []:
39
+ print(player.username, player.team)
40
+ ```
41
+
42
+ ## Async
43
+
44
+ ```python
45
+ from prcpy import AsyncClient
46
+
47
+ async with AsyncClient("your-server-key") as client:
48
+ server = await client.get_server(players=True)
49
+ print(server.name)
50
+ ```
51
+
52
+ ## Available server data
53
+
54
+ The v2 server endpoint supports these optional resources:
55
+
56
+ - `players`
57
+ - `staff`
58
+ - `join_logs`
59
+ - `queue`
60
+ - `kill_logs`
61
+ - `command_logs`
62
+ - `mod_calls`
63
+ - `emergency_calls`
64
+ - `vehicles`
65
+
66
+ Only request the data an application needs.
67
+
68
+ ```python
69
+ server = client.get_server(
70
+ players=True,
71
+ staff=True,
72
+ vehicles=True,
73
+ emergency_calls=True,
74
+ )
75
+ ```
76
+
77
+ ## Convenience methods
78
+
79
+ ```python
80
+ players = client.get_players()
81
+ staff = client.get_staff()
82
+ join_logs = client.get_join_logs()
83
+ queue = client.get_queue()
84
+ kill_logs = client.get_kill_logs()
85
+ command_logs = client.get_command_logs()
86
+ mod_calls = client.get_mod_calls()
87
+ vehicles = client.get_vehicles()
88
+ bans = client.get_bans()
89
+ ```
90
+
91
+ ## Commands
92
+
93
+ ```python
94
+ result = client.send_command(":h Hello from prcpy")
95
+ print(result.message)
96
+ ```
97
+
98
+ The API documents a `commandId` on command failures. prcpy exposes it as `CommandError.command_id` or `ServerOfflineError.command_id` when supplied by the API.
99
+
100
+ ## Authentication
101
+
102
+ All API requests use the `server-key` header.
103
+
104
+ Public applications may also provide a global API key:
105
+
106
+ ```python
107
+ client = Client(
108
+ "server-key",
109
+ global_api_key="global-api-key",
110
+ )
111
+ ```
112
+
113
+ Environment variables are supported:
114
+
115
+ ```text
116
+ ERLC_SERVER_KEY=...
117
+ ERLC_GLOBAL_API_KEY=...
118
+ ```
119
+
120
+ ```python
121
+ client = Client.from_env()
122
+ ```
123
+
124
+ Never commit keys to source control.
125
+
126
+ ## Rate limits
127
+
128
+ The client reads the API's `X-RateLimit-Bucket`, `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` response headers.
129
+
130
+ ```python
131
+ client.get_server()
132
+ print(client.rate_limit)
133
+ ```
134
+
135
+ A 429 response raises `RateLimitError` with `retry_after` when the server provides a `Retry-After` header.
136
+
137
+ prcpy does not silently retry commands. This avoids accidentally executing an in-game command more than once.
138
+
139
+ ## Raw API access
140
+
141
+ The typed methods cover the documented API, but the API can grow independently of this package.
142
+
143
+ ```python
144
+ data = client.request("GET", "/v2/server", params={"Players": "true"})
145
+ ```
146
+
147
+ ## Webhooks
148
+
149
+ prcpy includes a small helper for Ed25519 webhook verification:
150
+
151
+ ```python
152
+ from prcpy.webhooks import verify_signature
153
+
154
+ verify_signature(
155
+ timestamp=request.headers["X-Signature-Timestamp"],
156
+ signature=request.headers["X-Signature-Ed25519"],
157
+ body=raw_request_body,
158
+ public_key="your-webhook-public-key",
159
+ )
160
+ ```
161
+
162
+ Always verify the raw request body before parsing JSON.
163
+
164
+ ## Development
165
+
166
+ ```bash
167
+ python -m pip install -e ".[dev]"
168
+ ruff check .
169
+ pytest
170
+ ```
171
+
172
+ ## Project structure
173
+
174
+ ```text
175
+ prcpy/
176
+ ├── docs/
177
+ ├── examples/
178
+ ├── src/prcpy/
179
+ │ ├── client.py
180
+ │ ├── errors.py
181
+ │ ├── models.py
182
+ │ ├── rate_limits.py
183
+ │ └── webhooks.py
184
+ ├── tests/
185
+ ├── .github/workflows/
186
+ ├── CONTRIBUTING.md
187
+ ├── LICENSE
188
+ ├── pyproject.toml
189
+ └── README.md
190
+ ```
191
+
192
+ ## License
193
+
194
+ MIT