moonlygram 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.
- moonlygram-0.1.0/.github/workflows/ci.yml +43 -0
- moonlygram-0.1.0/.github/workflows/docs.yml +21 -0
- moonlygram-0.1.0/.github/workflows/release.yml +40 -0
- moonlygram-0.1.0/.gitignore +26 -0
- moonlygram-0.1.0/CHANGELOG.md +26 -0
- moonlygram-0.1.0/CONTRIBUTING.md +63 -0
- moonlygram-0.1.0/LICENSE +21 -0
- moonlygram-0.1.0/PKG-INFO +128 -0
- moonlygram-0.1.0/README.md +93 -0
- moonlygram-0.1.0/SECURITY.md +32 -0
- moonlygram-0.1.0/codegen/api.json +27432 -0
- moonlygram-0.1.0/codegen/gen_types.py +279 -0
- moonlygram-0.1.0/codegen/overrides.py +118 -0
- moonlygram-0.1.0/codegen/refresh.py +36 -0
- moonlygram-0.1.0/docs/api/bot.md +3 -0
- moonlygram-0.1.0/docs/api/errors.md +6 -0
- moonlygram-0.1.0/docs/api/ext.md +37 -0
- moonlygram-0.1.0/docs/api/filters.md +3 -0
- moonlygram-0.1.0/docs/api/rich.md +6 -0
- moonlygram-0.1.0/docs/api/types.md +9 -0
- moonlygram-0.1.0/docs/conversations.md +56 -0
- moonlygram-0.1.0/docs/handlers.md +61 -0
- moonlygram-0.1.0/docs/index.md +44 -0
- moonlygram-0.1.0/docs/migrating.md +126 -0
- moonlygram-0.1.0/docs/performance.md +58 -0
- moonlygram-0.1.0/docs/persistence.md +34 -0
- moonlygram-0.1.0/docs/quickstart.md +67 -0
- moonlygram-0.1.0/docs/rich-messages.md +40 -0
- moonlygram-0.1.0/docs/scheduling.md +28 -0
- moonlygram-0.1.0/examples/conversationbot.py +56 -0
- moonlygram-0.1.0/examples/echobot.py +28 -0
- moonlygram-0.1.0/examples/inlinebot.py +37 -0
- moonlygram-0.1.0/examples/richbot.py +31 -0
- moonlygram-0.1.0/mkdocs.yml +88 -0
- moonlygram-0.1.0/pyproject.toml +56 -0
- moonlygram-0.1.0/src/moonlygram/__init__.py +196 -0
- moonlygram-0.1.0/src/moonlygram/_types_generated.py +1010 -0
- moonlygram-0.1.0/src/moonlygram/bot.py +1649 -0
- moonlygram-0.1.0/src/moonlygram/defaults.py +18 -0
- moonlygram-0.1.0/src/moonlygram/errors.py +140 -0
- moonlygram-0.1.0/src/moonlygram/ext/__init__.py +66 -0
- moonlygram-0.1.0/src/moonlygram/ext/application.py +680 -0
- moonlygram-0.1.0/src/moonlygram/ext/callbackdata.py +82 -0
- moonlygram-0.1.0/src/moonlygram/ext/context.py +74 -0
- moonlygram-0.1.0/src/moonlygram/ext/filters.py +242 -0
- moonlygram-0.1.0/src/moonlygram/ext/handlers.py +449 -0
- moonlygram-0.1.0/src/moonlygram/ext/jobqueue.py +332 -0
- moonlygram-0.1.0/src/moonlygram/ext/persistence.py +132 -0
- moonlygram-0.1.0/src/moonlygram/ext/ratelimiter.py +124 -0
- moonlygram-0.1.0/src/moonlygram/helpers.py +111 -0
- moonlygram-0.1.0/src/moonlygram/py.typed +0 -0
- moonlygram-0.1.0/src/moonlygram/rich/__init__.py +45 -0
- moonlygram-0.1.0/src/moonlygram/rich/builder.py +199 -0
- moonlygram-0.1.0/src/moonlygram/rich/markdown.py +156 -0
- moonlygram-0.1.0/src/moonlygram/session.py +97 -0
- moonlygram-0.1.0/src/moonlygram/types.py +1358 -0
- moonlygram-0.1.0/tests/conftest.py +122 -0
- moonlygram-0.1.0/tests/test_application.py +304 -0
- moonlygram-0.1.0/tests/test_bot.py +189 -0
- moonlygram-0.1.0/tests/test_bound.py +96 -0
- moonlygram-0.1.0/tests/test_callbackdata.py +112 -0
- moonlygram-0.1.0/tests/test_chat_admin.py +268 -0
- moonlygram-0.1.0/tests/test_codegen.py +51 -0
- moonlygram-0.1.0/tests/test_content.py +117 -0
- moonlygram-0.1.0/tests/test_context.py +62 -0
- moonlygram-0.1.0/tests/test_conversationhandler.py +326 -0
- moonlygram-0.1.0/tests/test_errors.py +92 -0
- moonlygram-0.1.0/tests/test_filters.py +133 -0
- moonlygram-0.1.0/tests/test_forum.py +49 -0
- moonlygram-0.1.0/tests/test_handlers.py +171 -0
- moonlygram-0.1.0/tests/test_helpers.py +57 -0
- moonlygram-0.1.0/tests/test_inline.py +147 -0
- moonlygram-0.1.0/tests/test_jobqueue.py +165 -0
- moonlygram-0.1.0/tests/test_media.py +120 -0
- moonlygram-0.1.0/tests/test_persistence.py +107 -0
- moonlygram-0.1.0/tests/test_ratelimiter.py +132 -0
- moonlygram-0.1.0/tests/test_rich.py +155 -0
- moonlygram-0.1.0/tests/test_stickers.py +131 -0
- moonlygram-0.1.0/tests/test_types.py +137 -0
- moonlygram-0.1.0/tests/test_updates.py +243 -0
- moonlygram-0.1.0/tests/test_webhooks.py +94 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
- name: Install
|
|
21
|
+
run: python -m pip install -e ".[dev]"
|
|
22
|
+
- name: Lint
|
|
23
|
+
run: ruff check src tests codegen
|
|
24
|
+
- name: Type-check
|
|
25
|
+
run: mypy
|
|
26
|
+
- name: Test
|
|
27
|
+
run: pytest -q
|
|
28
|
+
|
|
29
|
+
codegen-fresh:
|
|
30
|
+
# Fails if _types_generated.py was hand-edited or left stale after a spec or
|
|
31
|
+
# overrides change — the generator output must always be committed.
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
- uses: actions/setup-python@v5
|
|
36
|
+
with:
|
|
37
|
+
python-version: "3.12"
|
|
38
|
+
- name: Install
|
|
39
|
+
run: python -m pip install -e ".[dev]"
|
|
40
|
+
- name: Regenerate types
|
|
41
|
+
run: python codegen/gen_types.py
|
|
42
|
+
- name: Verify no drift
|
|
43
|
+
run: git diff --exit-code -- src/moonlygram/_types_generated.py
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
deploy:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- name: Install
|
|
19
|
+
run: pip install -e ".[docs]"
|
|
20
|
+
- name: Build and deploy
|
|
21
|
+
run: mkdocs gh-deploy --force --strict
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI when a version tag is pushed. Uses PyPI trusted publishing
|
|
4
|
+
# (OIDC) — no API token needed once the project is configured on PyPI; see
|
|
5
|
+
# https://docs.pypi.org/trusted-publishers/. Configure the publisher to point at
|
|
6
|
+
# this repository and the "pypi" environment below.
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
tags: ["v*"]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
- name: Build sdist and wheel
|
|
21
|
+
run: |
|
|
22
|
+
python -m pip install build
|
|
23
|
+
python -m build
|
|
24
|
+
- uses: actions/upload-artifact@v4
|
|
25
|
+
with:
|
|
26
|
+
name: dist
|
|
27
|
+
path: dist/
|
|
28
|
+
|
|
29
|
+
publish:
|
|
30
|
+
needs: build
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
environment: pypi
|
|
33
|
+
permissions:
|
|
34
|
+
id-token: write # required for trusted publishing
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/download-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: dist
|
|
39
|
+
path: dist/
|
|
40
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
.env
|
|
10
|
+
|
|
11
|
+
# Tooling
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
|
|
16
|
+
# Docs build
|
|
17
|
+
site/
|
|
18
|
+
|
|
19
|
+
# Editor / tooling local settings
|
|
20
|
+
.claude/settings.local.json
|
|
21
|
+
.vscode/
|
|
22
|
+
.idea/
|
|
23
|
+
|
|
24
|
+
# OS
|
|
25
|
+
.DS_Store
|
|
26
|
+
Thumbs.db
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
|
+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0]
|
|
10
|
+
|
|
11
|
+
First public release.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- Async `Bot` covering the common Bot API surface: messaging and editing,
|
|
15
|
+
media, chat and member management, bot configuration, forum topics, stickers,
|
|
16
|
+
inline mode, and the remaining update types.
|
|
17
|
+
- `moonlygram.ext`: `Application` + `ApplicationBuilder`, handler groups,
|
|
18
|
+
filters, `ConversationHandler` (timeouts, nesting, persistence), `JobQueue`,
|
|
19
|
+
rate limiting, arbitrary callback data, and concurrent dispatch.
|
|
20
|
+
- Rich messages (Bot API 10.1): the `RichMessage` builder, inline helpers, and
|
|
21
|
+
`markdown_to_rich`.
|
|
22
|
+
- A typed error hierarchy, builder lifecycle hooks, a `helpers` module, and
|
|
23
|
+
`ContextTypes`.
|
|
24
|
+
- Spec-driven type generation (`codegen/`) producing the received data types
|
|
25
|
+
with full field coverage, guarded by drift tests.
|
|
26
|
+
- `py.typed`: the package ships type information and passes `mypy --strict`.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in Moonlygram. This guide covers the local workflow and
|
|
4
|
+
the one piece that is unusual: the type generator.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pip install -e ".[dev]"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Run the checks the way CI does:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
ruff check src tests codegen
|
|
16
|
+
mypy
|
|
17
|
+
pytest -q
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
All three must pass. Tests are offline (no network, no real bot token).
|
|
21
|
+
|
|
22
|
+
## House style
|
|
23
|
+
|
|
24
|
+
- Docstrings and comments are **plain prose** — no Sphinx cross-references
|
|
25
|
+
(`:class:`, `:meth:`), and no formal Args/Returns blocks beyond the few that
|
|
26
|
+
already exist. Explain the *why* of a non-obvious choice in a short comment.
|
|
27
|
+
- Public API is re-exported through the package `__init__` files, each with an
|
|
28
|
+
explicit `__all__`.
|
|
29
|
+
- The package ships `py.typed` and must stay `mypy --strict` clean.
|
|
30
|
+
|
|
31
|
+
## The type generator (important)
|
|
32
|
+
|
|
33
|
+
The data-only Bot API *received* types in `src/moonlygram/_types_generated.py`
|
|
34
|
+
are **generated** from a vendored copy of the Bot API spec. **Do not edit that
|
|
35
|
+
file by hand** — CI regenerates it and fails if it differs.
|
|
36
|
+
|
|
37
|
+
To change what is modelled:
|
|
38
|
+
|
|
39
|
+
1. Edit `codegen/overrides.py` (the allowlist, flat unions, and per-field
|
|
40
|
+
overrides) — and, for a new API version, refresh the spec:
|
|
41
|
+
```bash
|
|
42
|
+
python codegen/refresh.py
|
|
43
|
+
```
|
|
44
|
+
2. Regenerate:
|
|
45
|
+
```bash
|
|
46
|
+
python codegen/gen_types.py
|
|
47
|
+
```
|
|
48
|
+
3. Run the suite. The drift guards in `tests/test_codegen.py` check that every
|
|
49
|
+
generated type matches the spec and that the file is up to date.
|
|
50
|
+
|
|
51
|
+
Behavior-bearing types (those with shortcut methods or custom binding, such as
|
|
52
|
+
`Message`, `Chat`, `User`) and the *sent* types (keyboards, input media, inline
|
|
53
|
+
query results) stay hand-written in `src/moonlygram/types.py`.
|
|
54
|
+
|
|
55
|
+
## Docs
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install -e ".[docs]"
|
|
59
|
+
mkdocs serve
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The API reference is generated from docstrings by `mkdocstrings`, so keeping
|
|
63
|
+
docstrings accurate keeps the docs accurate.
|
moonlygram-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AtarixiaFamine
|
|
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,128 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: moonlygram
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: An async Telegram Bot API client with built-in rich-message support.
|
|
5
|
+
Project-URL: Homepage, https://github.com/AtarixiaFamine/Moonlygram
|
|
6
|
+
Project-URL: Repository, https://github.com/AtarixiaFamine/Moonlygram
|
|
7
|
+
Project-URL: Issues, https://github.com/AtarixiaFamine/Moonlygram/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/AtarixiaFamine/Moonlygram/blob/main/CHANGELOG.md
|
|
9
|
+
Author: AtarixiaFamine
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: async,bot,bot-api,rich-messages,telegram
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Communications :: Chat
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: httpx>=0.27
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.11; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
31
|
+
Provides-Extra: docs
|
|
32
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
33
|
+
Requires-Dist: mkdocstrings[python]>=0.26; extra == 'docs'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
<h1 align="center">Moonlygram</h1>
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<b>A modern, async Python framework for the Telegram Bot API, with built-in rich messages.</b>
|
|
40
|
+
<br>
|
|
41
|
+
Pure HTTP. No MTProto. No native dependencies.
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<a href="https://pypi.org/project/moonlygram/"><img src="https://img.shields.io/pypi/v/moonlygram.svg" alt="PyPI"></a>
|
|
46
|
+
<img src="https://img.shields.io/pypi/pyversions/moonlygram.svg" alt="Python versions">
|
|
47
|
+
<img src="https://img.shields.io/badge/mypy-strict-blue.svg" alt="mypy strict">
|
|
48
|
+
<img src="https://img.shields.io/badge/Bot%20API-10.1-2CA5E0.svg" alt="Bot API 10.1">
|
|
49
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Description
|
|
55
|
+
|
|
56
|
+
**Moonlygram** is an asynchronous framework for the Telegram **Bot API**. A `Bot` holds the API
|
|
57
|
+
methods and an `Application` (`moonlygram.ext`) registers handlers and runs the update loop, so
|
|
58
|
+
the shape feels familiar if you have used [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot).
|
|
59
|
+
On top of that, it adds something no other library has: **rich messages** (Bot API 10.1).
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install moonlygram
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Requires Python 3.10 or newer.
|
|
68
|
+
|
|
69
|
+
## Usage
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from moonlygram import InlineKeyboardButton, InlineKeyboardMarkup
|
|
73
|
+
from moonlygram.ext import Application, CallbackQueryHandler, CommandHandler
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
async def start(update, context):
|
|
77
|
+
keyboard = InlineKeyboardMarkup([[InlineKeyboardButton("Tap me", callback_data="tapped")]])
|
|
78
|
+
await update.message.reply_text("Hello from Moonlygram!", reply_markup=keyboard)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
async def on_tap(update, context):
|
|
82
|
+
await update.callback_query.answer("You tapped it!")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
app = Application.builder().token("YOUR_BOT_TOKEN").build()
|
|
86
|
+
app.add_handler(CommandHandler("start", start))
|
|
87
|
+
app.add_handler(CallbackQueryHandler(on_tap, pattern="^tapped$"))
|
|
88
|
+
app.run_polling()
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Features
|
|
92
|
+
|
|
93
|
+
- **Familiar:** a python-telegram-bot-style API: `Application`, handlers, filters, and
|
|
94
|
+
`(update, context)` callbacks. Existing bots port with little more than renamed imports.
|
|
95
|
+
- **Async:** receiving and dispatch run concurrently, so a slow handler never stalls the next
|
|
96
|
+
update.
|
|
97
|
+
- **Performant:** a non-blocking poll loop, optional parallel dispatch, a built-in rate limiter,
|
|
98
|
+
and a dependency-free `JobQueue`.
|
|
99
|
+
- **Rich:** send Bot API 10.1 rich messages (headings, tables, collapsibles, math) with a
|
|
100
|
+
composable, auto-escaping builder, or convert Markdown in one call. No other library has this.
|
|
101
|
+
- **Type-hinted:** ships `py.typed` and passes `mypy --strict`. The received types are generated
|
|
102
|
+
from the Bot API schema, so they cannot silently drift.
|
|
103
|
+
- **Lightweight:** one dependency (`httpx`). Pure HTTP, with no MTProto, no `api_id`/`api_hash`,
|
|
104
|
+
and no C extensions.
|
|
105
|
+
- **Batteries included:** conversations, persistence, scheduled jobs, arbitrary callback data,
|
|
106
|
+
and both polling and webhooks.
|
|
107
|
+
|
|
108
|
+
## Resources
|
|
109
|
+
|
|
110
|
+
- **Documentation:** https://atarixiafamine.github.io/Moonlygram/
|
|
111
|
+
- **Migrating from python-telegram-bot:** https://atarixiafamine.github.io/Moonlygram/migrating/
|
|
112
|
+
- **Examples:** [`examples/`](examples/)
|
|
113
|
+
- **Changelog:** [`CHANGELOG.md`](CHANGELOG.md)
|
|
114
|
+
|
|
115
|
+
## Roadmap
|
|
116
|
+
|
|
117
|
+
Core messaging, media, chat and member administration, bot configuration, forum topics,
|
|
118
|
+
stickers, and inline mode are all covered. Still in progress: the niche Bot API domains of
|
|
119
|
+
payments / Telegram Stars, business accounts, games, and passport / giveaways / paid media.
|
|
120
|
+
|
|
121
|
+
## Contributing
|
|
122
|
+
|
|
123
|
+
Contributions are welcome. See [`CONTRIBUTING.md`](CONTRIBUTING.md); it covers the spec-driven
|
|
124
|
+
codegen workflow for data types (edit the spec or overrides, regenerate, then test).
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
Released under the **MIT License**. See [`LICENSE`](LICENSE). Copyright © 2026 AtarixiaFamine.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<h1 align="center">Moonlygram</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<b>A modern, async Python framework for the Telegram Bot API, with built-in rich messages.</b>
|
|
5
|
+
<br>
|
|
6
|
+
Pure HTTP. No MTProto. No native dependencies.
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://pypi.org/project/moonlygram/"><img src="https://img.shields.io/pypi/v/moonlygram.svg" alt="PyPI"></a>
|
|
11
|
+
<img src="https://img.shields.io/pypi/pyversions/moonlygram.svg" alt="Python versions">
|
|
12
|
+
<img src="https://img.shields.io/badge/mypy-strict-blue.svg" alt="mypy strict">
|
|
13
|
+
<img src="https://img.shields.io/badge/Bot%20API-10.1-2CA5E0.svg" alt="Bot API 10.1">
|
|
14
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Description
|
|
20
|
+
|
|
21
|
+
**Moonlygram** is an asynchronous framework for the Telegram **Bot API**. A `Bot` holds the API
|
|
22
|
+
methods and an `Application` (`moonlygram.ext`) registers handlers and runs the update loop, so
|
|
23
|
+
the shape feels familiar if you have used [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot).
|
|
24
|
+
On top of that, it adds something no other library has: **rich messages** (Bot API 10.1).
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install moonlygram
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Requires Python 3.10 or newer.
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from moonlygram import InlineKeyboardButton, InlineKeyboardMarkup
|
|
38
|
+
from moonlygram.ext import Application, CallbackQueryHandler, CommandHandler
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
async def start(update, context):
|
|
42
|
+
keyboard = InlineKeyboardMarkup([[InlineKeyboardButton("Tap me", callback_data="tapped")]])
|
|
43
|
+
await update.message.reply_text("Hello from Moonlygram!", reply_markup=keyboard)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
async def on_tap(update, context):
|
|
47
|
+
await update.callback_query.answer("You tapped it!")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
app = Application.builder().token("YOUR_BOT_TOKEN").build()
|
|
51
|
+
app.add_handler(CommandHandler("start", start))
|
|
52
|
+
app.add_handler(CallbackQueryHandler(on_tap, pattern="^tapped$"))
|
|
53
|
+
app.run_polling()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Features
|
|
57
|
+
|
|
58
|
+
- **Familiar:** a python-telegram-bot-style API: `Application`, handlers, filters, and
|
|
59
|
+
`(update, context)` callbacks. Existing bots port with little more than renamed imports.
|
|
60
|
+
- **Async:** receiving and dispatch run concurrently, so a slow handler never stalls the next
|
|
61
|
+
update.
|
|
62
|
+
- **Performant:** a non-blocking poll loop, optional parallel dispatch, a built-in rate limiter,
|
|
63
|
+
and a dependency-free `JobQueue`.
|
|
64
|
+
- **Rich:** send Bot API 10.1 rich messages (headings, tables, collapsibles, math) with a
|
|
65
|
+
composable, auto-escaping builder, or convert Markdown in one call. No other library has this.
|
|
66
|
+
- **Type-hinted:** ships `py.typed` and passes `mypy --strict`. The received types are generated
|
|
67
|
+
from the Bot API schema, so they cannot silently drift.
|
|
68
|
+
- **Lightweight:** one dependency (`httpx`). Pure HTTP, with no MTProto, no `api_id`/`api_hash`,
|
|
69
|
+
and no C extensions.
|
|
70
|
+
- **Batteries included:** conversations, persistence, scheduled jobs, arbitrary callback data,
|
|
71
|
+
and both polling and webhooks.
|
|
72
|
+
|
|
73
|
+
## Resources
|
|
74
|
+
|
|
75
|
+
- **Documentation:** https://atarixiafamine.github.io/Moonlygram/
|
|
76
|
+
- **Migrating from python-telegram-bot:** https://atarixiafamine.github.io/Moonlygram/migrating/
|
|
77
|
+
- **Examples:** [`examples/`](examples/)
|
|
78
|
+
- **Changelog:** [`CHANGELOG.md`](CHANGELOG.md)
|
|
79
|
+
|
|
80
|
+
## Roadmap
|
|
81
|
+
|
|
82
|
+
Core messaging, media, chat and member administration, bot configuration, forum topics,
|
|
83
|
+
stickers, and inline mode are all covered. Still in progress: the niche Bot API domains of
|
|
84
|
+
payments / Telegram Stars, business accounts, games, and passport / giveaways / paid media.
|
|
85
|
+
|
|
86
|
+
## Contributing
|
|
87
|
+
|
|
88
|
+
Contributions are welcome. See [`CONTRIBUTING.md`](CONTRIBUTING.md); it covers the spec-driven
|
|
89
|
+
codegen workflow for data types (edit the spec or overrides, regenerate, then test).
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
Released under the **MIT License**. See [`LICENSE`](LICENSE). Copyright © 2026 AtarixiaFamine.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Moonlygram is pre-1.0; security fixes are released against the latest version only.
|
|
6
|
+
|
|
7
|
+
| Version | Supported |
|
|
8
|
+
| ---------- | --------- |
|
|
9
|
+
| latest 0.x | ✅ |
|
|
10
|
+
| older | ❌ |
|
|
11
|
+
|
|
12
|
+
## Reporting a Vulnerability
|
|
13
|
+
|
|
14
|
+
Please **do not open a public issue** for security vulnerabilities.
|
|
15
|
+
|
|
16
|
+
Report privately through GitHub's [private vulnerability reporting](https://github.com/AtarixiaFamine/Moonlygram/security/advisories/new)
|
|
17
|
+
(the repo's **Security → Report a vulnerability** button). Include:
|
|
18
|
+
|
|
19
|
+
- a description of the issue and its impact,
|
|
20
|
+
- steps to reproduce (a minimal proof of concept if possible),
|
|
21
|
+
- the affected version(s).
|
|
22
|
+
|
|
23
|
+
Expect an acknowledgement within a few days. Once confirmed, I'll prepare and
|
|
24
|
+
release a fix and credit you in the advisory unless you'd rather stay anonymous.
|
|
25
|
+
Please allow a reasonable window before any public disclosure.
|
|
26
|
+
|
|
27
|
+
## Scope
|
|
28
|
+
|
|
29
|
+
Moonlygram is an HTTP client for the Telegram Bot API. Your **bot token is a
|
|
30
|
+
secret**: keep it out of source control and logs, and set the `secret_token`
|
|
31
|
+
option on webhooks so you can verify requests really come from Telegram. Token
|
|
32
|
+
leakage in your own code is outside this project's scope.
|