METADATA 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. Metadata-Version: 2.4
  2. Name: chattolib
  3. Version: 0.5.0b4
  4. Summary: Async Python client library for the Chatto webchat Connect API
  5. Author-email: Felix <chatto@f3l1x.it>
  6. License-Expression: MPL-2.0 AND Apache-2.0
  7. Project-URL: Homepage, https://chat.chatto.run
  8. Keywords: chatto,connect,connectrpc,async,webchat,client
  9. Classifier: Development Status :: 3 - Alpha
  10. Classifier: Intended Audience :: Developers
  11. Classifier: Programming Language :: Python :: 3
  12. Classifier: Programming Language :: Python :: 3.11
  13. Classifier: Programming Language :: Python :: 3.12
  14. Classifier: Programming Language :: Python :: 3.13
  15. Classifier: Topic :: Communications :: Chat
  16. Classifier: Framework :: AsyncIO
  17. Requires-Python: >=3.11
  18. Description-Content-Type: text/markdown
  19. License-File: LICENSE
  20. License-File: LICENSES/Apache-2.0.txt
  21. License-File: LICENSES/MPL-2.0.txt
  22. Requires-Dist: protobuf>=5.28
  23. Requires-Dist: httpx>=0.27
  24. Provides-Extra: realtime
  25. Requires-Dist: websockets>=13.0; extra == "realtime"
  26. Provides-Extra: dev
  27. Requires-Dist: pytest>=8.0; extra == "dev"
  28. Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
  29. Requires-Dist: respx>=0.22; extra == "dev"
  30. Requires-Dist: ruff>=0.8; extra == "dev"
  31. Requires-Dist: mypy>=1.13; extra == "dev"
  32. Dynamic: license-file
  33. # chattolib
  34. **Unofficial** async Python client library for the [Chatto](https://chat.chatto.run) webchat API.
  35. > Chattolib versions track the Chatto server version they target. The current
  36. > release targets Chatto's ConnectRPC API. Request/response traffic uses the
  37. > official [`connectrpc`](https://pypi.org/project/connectrpc/) Python
  38. > package; the realtime channel is a binary protobuf WebSocket at
  39. > `/api/realtime` (needs the ``[realtime]`` extra).
  40. >
  41. > **chattolib is a bot library.** It drives *bot* accounts, which
  42. > authenticate with a key used directly as a bearer token (no password,
  43. > no `/auth/login` round-trip). Normal humans use the Chatto web app; you
  44. > reach the API here as a bot. See the [bot guide](docs/bots.md).
  45. ## Install
  46. ```bash
  47. pip install chattolib
  48. ```
  49. ## Quick start
  50. ```python
  51. import asyncio
  52. from chattolib import ChattoClient
  53. async def main():
  54. # Public discovery — no auth required
  55. async with ChattoClient() as anon:
  56. profile, login = await anon.get_server()
  57. print(f"Chatto {profile.version}: {profile.name}")
  58. # Authenticated calls — a bot key is used directly as a bearer token
  59. async with ChattoClient(token="cht_BK_...") as client:
  60. me = await client.me()
  61. print(f"Authenticated as {me.display_name}")
  62. for entry in await client.list_rooms():
  63. if entry.room:
  64. print(f" - {entry.room.name}")
  65. asyncio.run(main())
  66. ```
  67. For a full bot (event handlers, `say`/`reply`/`react`, presence, auto-join),
  68. use the higher-level :class:`~chattolib.bot.Bot` facade — see
  69. [docs/bots.md](docs/bots.md).
  70. ## Realtime
  71. Install with the extra:
  72. ```bash
  73. pip install 'chattolib[realtime]'
  74. ```
  75. Then stream live events:
  76. ```python
  77. from chattolib import stream_events
  78. async with ChattoClient(token="cht_BK_...") as client:
  79. async for event in stream_events(client):
  80. print(event.kind, event.actor_id, event.payload)
  81. ```
  82. `event.kind` names the protobuf ``oneof`` case (`message_posted`,
  83. `reaction_added`, `presence_changed`, `notification_created`, …).
  84. `event.payload` is the concrete protobuf sub-message — access its fields
  85. directly (e.g. `event.payload.room_id`). Realtime events are invalidation
  86. signals; use the corresponding Connect RPC (`GetRoomEventsAround`,
  87. `GetNotification`, `GetUser`, …) to hydrate the referenced resource.
  88. ## Escape hatch
  89. `ChattoClient.services` exposes the underlying `connectrpc` service clients
  90. directly (one per Chatto service), for anything the Pythonic wrappers don't
  91. yet cover. For example:
  92. ```python
  93. from chattolib._pb.chatto.api.v1 import messages_pb2
  94. resp = await client.services.messages.get_message(
  95. messages_pb2.GetMessageRequest(room_id=..., event_id=...)
  96. )
  97. ```
  98. ## License
  99. - chattolib's own code is licensed under **MPL-2.0** (Mozilla Public License
  100. 2.0) — a weak, file-level copyleft. You can use, distribute, and embed
  101. chattolib in commercial or proprietary software; modifications to the
  102. library's own files must be released under MPL-2.0.
  103. - Vendored Chatto protobuf definitions under `proto/chatto/**` and the
  104. generated bindings under `src/chattolib/_pb/chatto/**` are **Apache-2.0**,
  105. matching upstream [`chattocorp/chatto`](https://github.com/chattocorp/chatto).
  106. - Vendored `buf.validate` material is Apache-2.0 (from
  107. [`bufbuild/protovalidate`](https://github.com/bufbuild/protovalidate)).
  108. See [LICENSING.md](LICENSING.md) for the full picture and
  109. [REUSE.toml](REUSE.toml) for the machine-readable licence map.
  110. Note: chattolib versions **0.0.1 through 0.4.9** were released under **MIT**.
  111. Those releases remain MIT-licensed forever on PyPI; the MPL-2.0 relicence
  112. applies to newly published releases only.