rootpy-client 1.31.1__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.
- rootpy_client-1.31.1/LICENSE +21 -0
- rootpy_client-1.31.1/MANIFEST.in +19 -0
- rootpy_client-1.31.1/PKG-INFO +157 -0
- rootpy_client-1.31.1/README.md +113 -0
- rootpy_client-1.31.1/pyproject.toml +90 -0
- rootpy_client-1.31.1/rootpy/__init__.py +393 -0
- rootpy_client-1.31.1/rootpy/_registry_loader.py +122 -0
- rootpy_client-1.31.1/rootpy/accounts.py +554 -0
- rootpy_client-1.31.1/rootpy/attach.py +243 -0
- rootpy_client-1.31.1/rootpy/auth.py +310 -0
- rootpy_client-1.31.1/rootpy/cache.py +190 -0
- rootpy_client-1.31.1/rootpy/client.py +1702 -0
- rootpy_client-1.31.1/rootpy/commands.py +444 -0
- rootpy_client-1.31.1/rootpy/data/enums.json +1 -0
- rootpy_client-1.31.1/rootpy/data/message_schemas.json +1 -0
- rootpy_client-1.31.1/rootpy/data/messages.json +1 -0
- rootpy_client-1.31.1/rootpy/data/rpc_services.json +1 -0
- rootpy_client-1.31.1/rootpy/data/services.json +1 -0
- rootpy_client-1.31.1/rootpy/discovery.py +578 -0
- rootpy_client-1.31.1/rootpy/dm_member.py +305 -0
- rootpy_client-1.31.1/rootpy/domain_managers.py +677 -0
- rootpy_client-1.31.1/rootpy/emoji.py +129 -0
- rootpy_client-1.31.1/rootpy/enums.py +315 -0
- rootpy_client-1.31.1/rootpy/events.py +153 -0
- rootpy_client-1.31.1/rootpy/exceptions.py +687 -0
- rootpy_client-1.31.1/rootpy/features.py +949 -0
- rootpy_client-1.31.1/rootpy/gateway.py +1477 -0
- rootpy_client-1.31.1/rootpy/generated_rpc_registry.py +18 -0
- rootpy_client-1.31.1/rootpy/highlevel.py +1472 -0
- rootpy_client-1.31.1/rootpy/host.py +594 -0
- rootpy_client-1.31.1/rootpy/identifiers.py +119 -0
- rootpy_client-1.31.1/rootpy/media.py +43 -0
- rootpy_client-1.31.1/rootpy/media_bootstrap.py +111 -0
- rootpy_client-1.31.1/rootpy/models.py +944 -0
- rootpy_client-1.31.1/rootpy/object_api.py +606 -0
- rootpy_client-1.31.1/rootpy/packet_schemas.py +181 -0
- rootpy_client-1.31.1/rootpy/packets.py +176 -0
- rootpy_client-1.31.1/rootpy/pagination.py +31 -0
- rootpy_client-1.31.1/rootpy/permissions.py +237 -0
- rootpy_client-1.31.1/rootpy/presence.py +173 -0
- rootpy_client-1.31.1/rootpy/protocol.py +164 -0
- rootpy_client-1.31.1/rootpy/py.typed +0 -0
- rootpy_client-1.31.1/rootpy/raw_api.py +244 -0
- rootpy_client-1.31.1/rootpy/responses.py +110 -0
- rootpy_client-1.31.1/rootpy/root_exception.py +306 -0
- rootpy_client-1.31.1/rootpy/service_facade.py +32 -0
- rootpy_client-1.31.1/rootpy/services/__init__.py +27 -0
- rootpy_client-1.31.1/rootpy/services/assets.py +503 -0
- rootpy_client-1.31.1/rootpy/services/calls.py +1411 -0
- rootpy_client-1.31.1/rootpy/services/communities.py +735 -0
- rootpy_client-1.31.1/rootpy/services/community_admin.py +1036 -0
- rootpy_client-1.31.1/rootpy/services/direct_messages.py +524 -0
- rootpy_client-1.31.1/rootpy/services/discovery.py +204 -0
- rootpy_client-1.31.1/rootpy/services/messages.py +811 -0
- rootpy_client-1.31.1/rootpy/services/users.py +440 -0
- rootpy_client-1.31.1/rootpy/stats.py +208 -0
- rootpy_client-1.31.1/rootpy/structured_api.py +956 -0
- rootpy_client-1.31.1/rootpy/structured_registry.py +61 -0
- rootpy_client-1.31.1/rootpy/transport.py +403 -0
- rootpy_client-1.31.1/rootpy/typed_events.py +496 -0
- rootpy_client-1.31.1/rootpy/unread.py +546 -0
- rootpy_client-1.31.1/rootpy/users.py +187 -0
- rootpy_client-1.31.1/rootpy/validation.py +145 -0
- rootpy_client-1.31.1/rootpy_client.egg-info/PKG-INFO +157 -0
- rootpy_client-1.31.1/rootpy_client.egg-info/SOURCES.txt +67 -0
- rootpy_client-1.31.1/rootpy_client.egg-info/dependency_links.txt +1 -0
- rootpy_client-1.31.1/rootpy_client.egg-info/requires.txt +14 -0
- rootpy_client-1.31.1/rootpy_client.egg-info/top_level.txt +1 -0
- rootpy_client-1.31.1/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 solluws
|
|
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,19 @@
|
|
|
1
|
+
# The sdist is the library plus the two documents a reader needs offline.
|
|
2
|
+
# Everything else in this repository -- the test suite, the examples and the
|
|
3
|
+
# CI configuration -- is repository material and is deliberately left out of
|
|
4
|
+
# the distribution.
|
|
5
|
+
include LICENSE README.md
|
|
6
|
+
|
|
7
|
+
# The protocol registries. Without them the package installs and every schema
|
|
8
|
+
# lookup raises, so this line is load-bearing in the sdist exactly as
|
|
9
|
+
# [tool.setuptools.package-data] is in the wheel.
|
|
10
|
+
recursive-include rootpy/data *.json
|
|
11
|
+
|
|
12
|
+
# PEP 561 marker for the "Typing :: Typed" classifier.
|
|
13
|
+
include rootpy/py.typed
|
|
14
|
+
|
|
15
|
+
prune tests
|
|
16
|
+
prune examples
|
|
17
|
+
prune .github
|
|
18
|
+
|
|
19
|
+
global-exclude *.py[cod] __pycache__/* *.log tokens*.txt *.token .env
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rootpy-client
|
|
3
|
+
Version: 1.31.1
|
|
4
|
+
Summary: Async Python client for the Root chat platform
|
|
5
|
+
Author: solluws
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://rootpy.gay
|
|
8
|
+
Project-URL: Documentation, https://rootpy.gay
|
|
9
|
+
Project-URL: Repository, https://github.com/solluws/rap-p-ers
|
|
10
|
+
Project-URL: Issues, https://github.com/solluws/rap-p-ers/issues
|
|
11
|
+
Keywords: root,rootapp,chat,async,asyncio,grpc-web,websocket,bot,api-client
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Framework :: AsyncIO
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
|
+
Classifier: Topic :: Communications :: Chat
|
|
25
|
+
Classifier: Topic :: Internet
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: httpx[http2]>=0.27
|
|
32
|
+
Requires-Dist: websockets>=12.0
|
|
33
|
+
Requires-Dist: emoji>=2.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-asyncio>=0.26; extra == "dev"
|
|
37
|
+
Requires-Dist: httpx[socks]>=0.27; extra == "dev"
|
|
38
|
+
Provides-Extra: voice
|
|
39
|
+
Requires-Dist: av>=15.1; extra == "voice"
|
|
40
|
+
Requires-Dist: aiortc>=1.13; extra == "voice"
|
|
41
|
+
Requires-Dist: imageio-ffmpeg<1,>=0.5; extra == "voice"
|
|
42
|
+
Requires-Dist: playwright>=1.44; extra == "voice"
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
# rootpy-client
|
|
46
|
+
|
|
47
|
+
[](https://github.com/solluws/rap-p-ers/actions/workflows/tests.yml)
|
|
48
|
+
[](https://pypi.org/project/rootpy-client/)
|
|
49
|
+
[](https://github.com/solluws/rap-p-ers/blob/main/LICENSE)
|
|
50
|
+
|
|
51
|
+
An async Python client for the [Root](https://rootapp.com) chat platform. It
|
|
52
|
+
drives one account — yours — from a script or a bot, and covers messaging,
|
|
53
|
+
communities, channels, roles, direct messages, friends, presence, voice
|
|
54
|
+
signalling and the real-time gateway.
|
|
55
|
+
|
|
56
|
+
Unofficial. Not affiliated with Root, and not endorsed by them.
|
|
57
|
+
|
|
58
|
+
**Guides, examples and the full API reference: <https://rootpy.gay>**
|
|
59
|
+
|
|
60
|
+
## Install
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install rootpy-client
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
You install `rootpy-client` and you import `rootpy`. The two names differ
|
|
67
|
+
because an unrelated project already holds `rootpy` on PyPI. This is not that
|
|
68
|
+
project.
|
|
69
|
+
|
|
70
|
+
Python 3.10 or later. Playing audio into a voice call needs an opt-in extra:
|
|
71
|
+
`pip install "rootpy-client[voice]"`.
|
|
72
|
+
|
|
73
|
+
## Use it
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import asyncio
|
|
77
|
+
import os
|
|
78
|
+
|
|
79
|
+
from rootpy import RootClient
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
async def main():
|
|
83
|
+
client = RootClient(token=os.environ["ROOT_TOKEN"])
|
|
84
|
+
await client.login_token()
|
|
85
|
+
|
|
86
|
+
await client.messages.send(CHANNEL_ID, "hello", community_id=COMMUNITY_ID)
|
|
87
|
+
|
|
88
|
+
await client.close()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
asyncio.run(main())
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Receiving needs the gateway, and a community delivers nothing until you attach
|
|
95
|
+
to it:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
@client.event
|
|
99
|
+
async def on_message(event):
|
|
100
|
+
print(event.message.content)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
async with client.community.held(COMMUNITY_ID):
|
|
104
|
+
await client.connect()
|
|
105
|
+
await client.wait_until_ready()
|
|
106
|
+
await asyncio.sleep(3600)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## What is in it
|
|
110
|
+
|
|
111
|
+
- **Messages** — send, reply in a thread, edit, delete, react, pin, and
|
|
112
|
+
paginated history.
|
|
113
|
+
- **Communities** — create, join by invite, channels and channel groups, roles
|
|
114
|
+
and permissions, members, invites, emoji and assets.
|
|
115
|
+
- **Discovery** — search the public directory, and list your own community.
|
|
116
|
+
- **Direct messages** — conversations, group conversations, friends and blocks.
|
|
117
|
+
- **Gateway** — a websocket connection with typed events, `wait_for()` and
|
|
118
|
+
reconnection.
|
|
119
|
+
- **Voice** — call signalling, mute and deafen, and audio playback behind the
|
|
120
|
+
`[voice]` extra.
|
|
121
|
+
- **Auth** — token login, email and password login, and signup.
|
|
122
|
+
|
|
123
|
+
## Notes worth knowing before you start
|
|
124
|
+
|
|
125
|
+
- **Membership is not a subscription.** Until you call
|
|
126
|
+
`client.community.attach(id)`, the hub sends no packet for that community at
|
|
127
|
+
all, while direct messages and mentions keep arriving on the same socket.
|
|
128
|
+
That asymmetry is what a broken listener looks like.
|
|
129
|
+
- **The gateway is a resync cycle, not a persistent stream.** The hub sends a
|
|
130
|
+
batch, closes with code 1000, and expects a reconnect. That is normal. An
|
|
131
|
+
attach does not survive it, so hold it with `client.community.held(id)`.
|
|
132
|
+
- **Presence is two calls, and the lower one wins.** Others see
|
|
133
|
+
`min(ceiling, device)`. Both halves succeed on their own, so setting only the
|
|
134
|
+
ceiling leaves your account invisible to everybody and reports success.
|
|
135
|
+
`client.set_presence(...)` sets both.
|
|
136
|
+
|
|
137
|
+
## Develop
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
git clone https://github.com/solluws/rap-p-ers
|
|
141
|
+
cd rap-p-ers
|
|
142
|
+
pip install -e ".[dev]"
|
|
143
|
+
python -m pytest -q
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The suite is offline. It pins the wire format, so a change to an endpoint, a
|
|
147
|
+
field number or a default fails a test rather than a live request.
|
|
148
|
+
|
|
149
|
+
Pull requests are welcome. Keep the tests green, and add one for whatever you
|
|
150
|
+
change.
|
|
151
|
+
|
|
152
|
+
## Licence
|
|
153
|
+
|
|
154
|
+
MIT. See [LICENSE](https://github.com/solluws/rap-p-ers/blob/main/LICENSE).
|
|
155
|
+
|
|
156
|
+
Use this on accounts you control, and read Root's terms before you automate
|
|
157
|
+
anything on their service.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# rootpy-client
|
|
2
|
+
|
|
3
|
+
[](https://github.com/solluws/rap-p-ers/actions/workflows/tests.yml)
|
|
4
|
+
[](https://pypi.org/project/rootpy-client/)
|
|
5
|
+
[](https://github.com/solluws/rap-p-ers/blob/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
An async Python client for the [Root](https://rootapp.com) chat platform. It
|
|
8
|
+
drives one account — yours — from a script or a bot, and covers messaging,
|
|
9
|
+
communities, channels, roles, direct messages, friends, presence, voice
|
|
10
|
+
signalling and the real-time gateway.
|
|
11
|
+
|
|
12
|
+
Unofficial. Not affiliated with Root, and not endorsed by them.
|
|
13
|
+
|
|
14
|
+
**Guides, examples and the full API reference: <https://rootpy.gay>**
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install rootpy-client
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
You install `rootpy-client` and you import `rootpy`. The two names differ
|
|
23
|
+
because an unrelated project already holds `rootpy` on PyPI. This is not that
|
|
24
|
+
project.
|
|
25
|
+
|
|
26
|
+
Python 3.10 or later. Playing audio into a voice call needs an opt-in extra:
|
|
27
|
+
`pip install "rootpy-client[voice]"`.
|
|
28
|
+
|
|
29
|
+
## Use it
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
import asyncio
|
|
33
|
+
import os
|
|
34
|
+
|
|
35
|
+
from rootpy import RootClient
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
async def main():
|
|
39
|
+
client = RootClient(token=os.environ["ROOT_TOKEN"])
|
|
40
|
+
await client.login_token()
|
|
41
|
+
|
|
42
|
+
await client.messages.send(CHANNEL_ID, "hello", community_id=COMMUNITY_ID)
|
|
43
|
+
|
|
44
|
+
await client.close()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
asyncio.run(main())
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Receiving needs the gateway, and a community delivers nothing until you attach
|
|
51
|
+
to it:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
@client.event
|
|
55
|
+
async def on_message(event):
|
|
56
|
+
print(event.message.content)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
async with client.community.held(COMMUNITY_ID):
|
|
60
|
+
await client.connect()
|
|
61
|
+
await client.wait_until_ready()
|
|
62
|
+
await asyncio.sleep(3600)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## What is in it
|
|
66
|
+
|
|
67
|
+
- **Messages** — send, reply in a thread, edit, delete, react, pin, and
|
|
68
|
+
paginated history.
|
|
69
|
+
- **Communities** — create, join by invite, channels and channel groups, roles
|
|
70
|
+
and permissions, members, invites, emoji and assets.
|
|
71
|
+
- **Discovery** — search the public directory, and list your own community.
|
|
72
|
+
- **Direct messages** — conversations, group conversations, friends and blocks.
|
|
73
|
+
- **Gateway** — a websocket connection with typed events, `wait_for()` and
|
|
74
|
+
reconnection.
|
|
75
|
+
- **Voice** — call signalling, mute and deafen, and audio playback behind the
|
|
76
|
+
`[voice]` extra.
|
|
77
|
+
- **Auth** — token login, email and password login, and signup.
|
|
78
|
+
|
|
79
|
+
## Notes worth knowing before you start
|
|
80
|
+
|
|
81
|
+
- **Membership is not a subscription.** Until you call
|
|
82
|
+
`client.community.attach(id)`, the hub sends no packet for that community at
|
|
83
|
+
all, while direct messages and mentions keep arriving on the same socket.
|
|
84
|
+
That asymmetry is what a broken listener looks like.
|
|
85
|
+
- **The gateway is a resync cycle, not a persistent stream.** The hub sends a
|
|
86
|
+
batch, closes with code 1000, and expects a reconnect. That is normal. An
|
|
87
|
+
attach does not survive it, so hold it with `client.community.held(id)`.
|
|
88
|
+
- **Presence is two calls, and the lower one wins.** Others see
|
|
89
|
+
`min(ceiling, device)`. Both halves succeed on their own, so setting only the
|
|
90
|
+
ceiling leaves your account invisible to everybody and reports success.
|
|
91
|
+
`client.set_presence(...)` sets both.
|
|
92
|
+
|
|
93
|
+
## Develop
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
git clone https://github.com/solluws/rap-p-ers
|
|
97
|
+
cd rap-p-ers
|
|
98
|
+
pip install -e ".[dev]"
|
|
99
|
+
python -m pytest -q
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The suite is offline. It pins the wire format, so a change to an endpoint, a
|
|
103
|
+
field number or a default fails a test rather than a live request.
|
|
104
|
+
|
|
105
|
+
Pull requests are welcome. Keep the tests green, and add one for whatever you
|
|
106
|
+
change.
|
|
107
|
+
|
|
108
|
+
## Licence
|
|
109
|
+
|
|
110
|
+
MIT. See [LICENSE](https://github.com/solluws/rap-p-ers/blob/main/LICENSE).
|
|
111
|
+
|
|
112
|
+
Use this on accounts you control, and read Root's terms before you automate
|
|
113
|
+
anything on their service.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "rootpy-client"
|
|
7
|
+
version = "1.31.1"
|
|
8
|
+
description = "Async Python client for the Root chat platform"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [{ name = "solluws" }]
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
keywords = [
|
|
15
|
+
"root",
|
|
16
|
+
"rootapp",
|
|
17
|
+
"chat",
|
|
18
|
+
"async",
|
|
19
|
+
"asyncio",
|
|
20
|
+
"grpc-web",
|
|
21
|
+
"websocket",
|
|
22
|
+
"bot",
|
|
23
|
+
"api-client",
|
|
24
|
+
]
|
|
25
|
+
classifiers = [
|
|
26
|
+
"Development Status :: 4 - Beta",
|
|
27
|
+
"Framework :: AsyncIO",
|
|
28
|
+
"Intended Audience :: Developers",
|
|
29
|
+
"Operating System :: OS Independent",
|
|
30
|
+
"Programming Language :: Python",
|
|
31
|
+
"Programming Language :: Python :: 3",
|
|
32
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
33
|
+
"Programming Language :: Python :: 3.10",
|
|
34
|
+
"Programming Language :: Python :: 3.11",
|
|
35
|
+
"Programming Language :: Python :: 3.12",
|
|
36
|
+
"Programming Language :: Python :: 3.13",
|
|
37
|
+
"Programming Language :: Python :: 3.14",
|
|
38
|
+
"Topic :: Communications :: Chat",
|
|
39
|
+
"Topic :: Internet",
|
|
40
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
41
|
+
"Typing :: Typed",
|
|
42
|
+
]
|
|
43
|
+
dependencies = [
|
|
44
|
+
"httpx[http2]>=0.27",
|
|
45
|
+
"websockets>=12.0",
|
|
46
|
+
# Reactions are a core verb, and Root addresses every reaction by
|
|
47
|
+
# shortcode. Without this, rootpy/emoji.py falls back to a 20-entry table
|
|
48
|
+
# and refuses ordinary emoji -- a rocket and a pair of eyes both raised
|
|
49
|
+
# ValueError on a stock install. Pure Python, no transitive dependencies.
|
|
50
|
+
"emoji>=2.0",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[project.urls]
|
|
54
|
+
Homepage = "https://rootpy.gay"
|
|
55
|
+
Documentation = "https://rootpy.gay"
|
|
56
|
+
Repository = "https://github.com/solluws/rap-p-ers"
|
|
57
|
+
Issues = "https://github.com/solluws/rap-p-ers/issues"
|
|
58
|
+
|
|
59
|
+
[project.optional-dependencies]
|
|
60
|
+
# httpx[socks] is a test requirement, not a runtime one. SOCKS support stays
|
|
61
|
+
# optional for users. The proxy tests build a real httpx.AsyncClient with a
|
|
62
|
+
# socks5h:// URL, and httpx needs socksio for that scheme.
|
|
63
|
+
dev = ["pytest>=8.0", "pytest-asyncio>=0.26", "httpx[socks]>=0.27"]
|
|
64
|
+
# Voice / WebRTC. Never installed automatically -- rootpy raises
|
|
65
|
+
# MediaDependencyMissing naming this extra instead of shelling out to pip.
|
|
66
|
+
voice = [
|
|
67
|
+
"av>=15.1",
|
|
68
|
+
"aiortc>=1.13",
|
|
69
|
+
"imageio-ffmpeg>=0.5,<1",
|
|
70
|
+
"playwright>=1.44",
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
[tool.setuptools.packages.find]
|
|
74
|
+
include = ["rootpy*"]
|
|
75
|
+
# examples/ lives at the repo root; it is documentation, not shipped code.
|
|
76
|
+
exclude = ["rootpy.examples*", "tests*"]
|
|
77
|
+
|
|
78
|
+
[tool.setuptools.package-data]
|
|
79
|
+
# The protocol registries and the PEP 561 marker. Without the JSON the wheel
|
|
80
|
+
# installs but every schema lookup raises at runtime.
|
|
81
|
+
rootpy = ["data/*.json", "py.typed"]
|
|
82
|
+
|
|
83
|
+
[tool.pytest.ini_options]
|
|
84
|
+
testpaths = ["tests"]
|
|
85
|
+
asyncio_mode = "auto"
|
|
86
|
+
# Session-scoped async fixtures and tests must share one event loop; with the
|
|
87
|
+
# default function scope the first test to finish closes the loop the fixtures
|
|
88
|
+
# were created on.
|
|
89
|
+
asyncio_default_fixture_loop_scope = "session"
|
|
90
|
+
asyncio_default_test_loop_scope = "session"
|