byteforge-telegram 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.
- byteforge_telegram-0.1.0/.claude/settings.local.json +10 -0
- byteforge_telegram-0.1.0/.gitignore +81 -0
- byteforge_telegram-0.1.0/CLAUDE.md +213 -0
- byteforge_telegram-0.1.0/LICENSE +21 -0
- byteforge_telegram-0.1.0/MANIFEST.in +4 -0
- byteforge_telegram-0.1.0/PKG-INFO +408 -0
- byteforge_telegram-0.1.0/README.md +374 -0
- byteforge_telegram-0.1.0/build-publish.sh +15 -0
- byteforge_telegram-0.1.0/dev-requirements.txt +8 -0
- byteforge_telegram-0.1.0/pyproject.toml +64 -0
- byteforge_telegram-0.1.0/pytest.ini +6 -0
- byteforge_telegram-0.1.0/requirements.txt +2 -0
- byteforge_telegram-0.1.0/src/byteforge_telegram/__init__.py +22 -0
- byteforge_telegram-0.1.0/src/byteforge_telegram/cli.py +125 -0
- byteforge_telegram-0.1.0/src/byteforge_telegram/models.py +49 -0
- byteforge_telegram-0.1.0/src/byteforge_telegram/notifier.py +207 -0
- byteforge_telegram-0.1.0/src/byteforge_telegram/webhook.py +140 -0
- byteforge_telegram-0.1.0/tests/__init__.py +3 -0
- byteforge_telegram-0.1.0/tests/test_cli.py +238 -0
- byteforge_telegram-0.1.0/tests/test_models.py +166 -0
- byteforge_telegram-0.1.0/tests/test_notifier.py +320 -0
- byteforge_telegram-0.1.0/tests/test_webhook.py +236 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# venv stuff
|
|
2
|
+
pyvenv.cfg
|
|
3
|
+
bin/
|
|
4
|
+
|
|
5
|
+
# Byte-compiled / optimized / DLL files
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
|
|
10
|
+
# C extensions
|
|
11
|
+
*.so
|
|
12
|
+
|
|
13
|
+
# Distribution / packaging
|
|
14
|
+
.Python
|
|
15
|
+
build/
|
|
16
|
+
develop-eggs/
|
|
17
|
+
dist/
|
|
18
|
+
downloads/
|
|
19
|
+
eggs/
|
|
20
|
+
.eggs/
|
|
21
|
+
lib/
|
|
22
|
+
lib64/
|
|
23
|
+
parts/
|
|
24
|
+
sdist/
|
|
25
|
+
var/
|
|
26
|
+
wheels/
|
|
27
|
+
share/python-wheels/
|
|
28
|
+
*.egg-info/
|
|
29
|
+
.installed.cfg
|
|
30
|
+
*.egg
|
|
31
|
+
MANIFEST
|
|
32
|
+
|
|
33
|
+
# PyInstaller
|
|
34
|
+
*.manifest
|
|
35
|
+
*.spec
|
|
36
|
+
|
|
37
|
+
# Unit test / coverage reports
|
|
38
|
+
htmlcov/
|
|
39
|
+
.tox/
|
|
40
|
+
.nox/
|
|
41
|
+
.coverage
|
|
42
|
+
.coverage.*
|
|
43
|
+
.cache
|
|
44
|
+
nosetests.xml
|
|
45
|
+
coverage.xml
|
|
46
|
+
*.cover
|
|
47
|
+
*.py,cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
cover/
|
|
51
|
+
|
|
52
|
+
# Environments
|
|
53
|
+
.env
|
|
54
|
+
.venv
|
|
55
|
+
env/
|
|
56
|
+
venv/
|
|
57
|
+
ENV/
|
|
58
|
+
env.bak/
|
|
59
|
+
venv.bak/
|
|
60
|
+
|
|
61
|
+
# IDEs
|
|
62
|
+
.vscode/
|
|
63
|
+
.idea/
|
|
64
|
+
*.swp
|
|
65
|
+
*.swo
|
|
66
|
+
*~
|
|
67
|
+
|
|
68
|
+
# OS
|
|
69
|
+
.DS_Store
|
|
70
|
+
Thumbs.db
|
|
71
|
+
|
|
72
|
+
# mypy
|
|
73
|
+
.mypy_cache/
|
|
74
|
+
.dmypy.json
|
|
75
|
+
dmypy.json
|
|
76
|
+
|
|
77
|
+
# Pyre type checker
|
|
78
|
+
.pyre/
|
|
79
|
+
|
|
80
|
+
# pytype static type analyzer
|
|
81
|
+
.pytype/
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
`byteforge-telegram` is a reusable Python library for Telegram bot notifications and webhook management. It provides both synchronous and asynchronous APIs for sending Telegram messages and managing webhooks.
|
|
8
|
+
|
|
9
|
+
## Development Commands
|
|
10
|
+
|
|
11
|
+
**CRITICAL**: This project uses a virtual environment. ALWAYS use `source bin/activate && python` and `source bin/activate && pip`. NEVER use `python3` or `pip3` directly - these are system executables and we always use the virtual environment.
|
|
12
|
+
|
|
13
|
+
### Environment Setup
|
|
14
|
+
```bash
|
|
15
|
+
# Virtual environment is already set up in this project
|
|
16
|
+
|
|
17
|
+
# Option 1: Install from requirements files
|
|
18
|
+
source bin/activate && pip install -r requirements.txt
|
|
19
|
+
source bin/activate && pip install -r dev-requirements.txt
|
|
20
|
+
|
|
21
|
+
# Option 2: Install in development mode (includes all dependencies)
|
|
22
|
+
source bin/activate && pip install -e ".[dev]"
|
|
23
|
+
|
|
24
|
+
# Note: requirements.txt includes mazza-base from private GitHub repo
|
|
25
|
+
# This requires CR_PAT environment variable to be set
|
|
26
|
+
# export CR_PAT=your_github_token
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Running Tests
|
|
30
|
+
```bash
|
|
31
|
+
# Run all tests
|
|
32
|
+
source bin/activate && python -m pytest
|
|
33
|
+
|
|
34
|
+
# Run with coverage
|
|
35
|
+
source bin/activate && python -m pytest --cov=byteforge_telegram
|
|
36
|
+
|
|
37
|
+
# Run a single test file
|
|
38
|
+
source bin/activate && python -m pytest tests/test_notifier.py
|
|
39
|
+
|
|
40
|
+
# Run a specific test
|
|
41
|
+
source bin/activate && python -m pytest tests/test_notifier.py::test_send_message
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Code Formatting
|
|
45
|
+
```bash
|
|
46
|
+
# Format code with Black (line length: 100)
|
|
47
|
+
source bin/activate && python -m black src/
|
|
48
|
+
|
|
49
|
+
# Check formatting without making changes
|
|
50
|
+
source bin/activate && python -m black --check src/
|
|
51
|
+
|
|
52
|
+
# Sort imports with isort
|
|
53
|
+
source bin/activate && python -m isort src/
|
|
54
|
+
|
|
55
|
+
# Check import sorting without making changes
|
|
56
|
+
source bin/activate && python -m isort --check-only src/
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Type Checking
|
|
60
|
+
```bash
|
|
61
|
+
# Run mypy type checker
|
|
62
|
+
source bin/activate && python -m mypy src/
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Building and Publishing
|
|
66
|
+
```bash
|
|
67
|
+
# Build package
|
|
68
|
+
source bin/activate && python -m build
|
|
69
|
+
|
|
70
|
+
# Publish to PyPI (requires credentials)
|
|
71
|
+
source bin/activate && python -m twine upload dist/*
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Testing CLI Tool Locally
|
|
75
|
+
```bash
|
|
76
|
+
# After installing in development mode, the CLI is available
|
|
77
|
+
source bin/activate && setup-telegram-webhook --help
|
|
78
|
+
source bin/activate && setup-telegram-webhook --token YOUR_TOKEN --info
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Architecture
|
|
82
|
+
|
|
83
|
+
### Core Components
|
|
84
|
+
|
|
85
|
+
**TelegramBotController** (`src/byteforge_telegram/notifier.py`)
|
|
86
|
+
- Main class for sending Telegram notifications
|
|
87
|
+
- Supports both sync (`send_message_sync`, `send_formatted_sync`) and async (`send_message`, `send_formatted`) methods
|
|
88
|
+
- Creates fresh Bot instances per call to avoid event loop conflicts
|
|
89
|
+
- Handles automatic session cleanup to prevent connection leaks
|
|
90
|
+
- Key design: Uses `_send_with_new_bot()` pattern to create disposable Bot instances
|
|
91
|
+
|
|
92
|
+
**WebhookManager** (`src/byteforge_telegram/webhook.py`)
|
|
93
|
+
- Manages Telegram webhook configuration via REST API
|
|
94
|
+
- Methods: `set_webhook()`, `get_webhook_info()`, `delete_webhook()`
|
|
95
|
+
- Uses synchronous `requests` library
|
|
96
|
+
- Validates HTTPS requirement for webhook URLs
|
|
97
|
+
|
|
98
|
+
**CLI Tool** (`src/byteforge_telegram/cli.py`)
|
|
99
|
+
- Command-line interface: `setup-telegram-webhook`
|
|
100
|
+
- Supports setting, viewing, and deleting webhooks
|
|
101
|
+
- Can use `--token` flag or `TELEGRAM_BOT_TOKEN` environment variable
|
|
102
|
+
|
|
103
|
+
**TelegramResponse** (`src/byteforge_telegram/models.py`)
|
|
104
|
+
- Dataclass for type-safe webhook response construction
|
|
105
|
+
- Used when handling webhook updates to return responses to Telegram
|
|
106
|
+
- Primary method: `to_dict()` - converts to dict for JSON serialization
|
|
107
|
+
- Supports reply_markup for inline keyboards and other Telegram features
|
|
108
|
+
- Default parse_mode is HTML
|
|
109
|
+
|
|
110
|
+
### Sync/Async Design Pattern
|
|
111
|
+
|
|
112
|
+
The library handles both sync and async contexts by:
|
|
113
|
+
1. Detecting running event loops with `asyncio.get_running_loop()`
|
|
114
|
+
2. Creating tasks in existing loops OR running new loops with `asyncio.run()`
|
|
115
|
+
3. Creating fresh Bot instances per message to avoid cross-loop contamination
|
|
116
|
+
4. Cleaning up HTTP sessions in `finally` blocks
|
|
117
|
+
|
|
118
|
+
**CRITICAL**: When modifying async code:
|
|
119
|
+
- Never reuse Bot instances across async calls - always create new ones
|
|
120
|
+
- Always clean up sessions in `finally` blocks using dynamic attribute detection
|
|
121
|
+
- The `*_sync()` methods must handle both running and non-running event loop scenarios
|
|
122
|
+
- Use `try/except RuntimeError` to detect if an event loop is already running
|
|
123
|
+
|
|
124
|
+
### Message Formatting
|
|
125
|
+
|
|
126
|
+
- Default parse mode: `ParseMode.HTML`
|
|
127
|
+
- `send_formatted()` builds HTML-formatted messages with title, key-value fields, optional emoji, and footer
|
|
128
|
+
- All formatting is HTML-based (bold with `<b>`, italic with `<i>`)
|
|
129
|
+
|
|
130
|
+
## Important Patterns
|
|
131
|
+
|
|
132
|
+
### Error Handling
|
|
133
|
+
- Methods return `Dict[str, bool]` mapping chat_id to success status
|
|
134
|
+
- Failures are logged but don't raise exceptions
|
|
135
|
+
- Network errors caught via `TelegramError` and general `Exception`
|
|
136
|
+
|
|
137
|
+
### Session Management
|
|
138
|
+
- Each message send creates a new Bot instance
|
|
139
|
+
- Sessions are explicitly closed in `finally` blocks
|
|
140
|
+
- Uses dynamic attribute detection (`getattr`) to handle different session types
|
|
141
|
+
|
|
142
|
+
### Type Hints
|
|
143
|
+
- All public methods include type hints for parameters and return types
|
|
144
|
+
- Uses `Optional`, `List`, `Dict`, `Any` from typing module
|
|
145
|
+
- Return types are explicit (e.g., `Dict[str, bool]`, `Optional[Dict[str, Any]]`)
|
|
146
|
+
|
|
147
|
+
### Webhook Response Pattern
|
|
148
|
+
|
|
149
|
+
There are **two patterns** for handling Telegram webhooks:
|
|
150
|
+
|
|
151
|
+
**Pattern 1: Simple (using TelegramBotController)**
|
|
152
|
+
- Process the webhook update
|
|
153
|
+
- Use `TelegramBotController.send_message_sync()` to send responses
|
|
154
|
+
- Return `{'ok': True}` to acknowledge webhook
|
|
155
|
+
- Good for simple bots and async processing
|
|
156
|
+
|
|
157
|
+
**Pattern 2: Advanced (using TelegramResponse)**
|
|
158
|
+
- Process the webhook update
|
|
159
|
+
- Create `TelegramResponse` object
|
|
160
|
+
- Return `response.to_dict()` directly in webhook response
|
|
161
|
+
- Telegram processes the response inline
|
|
162
|
+
- More efficient, no separate API call
|
|
163
|
+
- Typical pattern:
|
|
164
|
+
```python
|
|
165
|
+
response = TelegramResponse(
|
|
166
|
+
method='sendMessage',
|
|
167
|
+
chat_id=chat_id,
|
|
168
|
+
text='<b>Response text</b>',
|
|
169
|
+
parse_mode='HTML'
|
|
170
|
+
)
|
|
171
|
+
return jsonify(response.to_dict()), 200
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Project Structure
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
src/byteforge_telegram/
|
|
178
|
+
├── __init__.py # Package exports
|
|
179
|
+
├── notifier.py # TelegramBotController and ParseMode
|
|
180
|
+
├── webhook.py # WebhookManager
|
|
181
|
+
├── models.py # TelegramResponse dataclass
|
|
182
|
+
└── cli.py # CLI entry point
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Dependencies
|
|
186
|
+
|
|
187
|
+
**Production (requirements.txt):**
|
|
188
|
+
- `python-telegram-bot` - Core Telegram API wrapper
|
|
189
|
+
- `mazza-base` - Mazza base library from private GitHub repo (requires CR_PAT env var)
|
|
190
|
+
|
|
191
|
+
**Development (dev-requirements.txt):**
|
|
192
|
+
- `mypy` - Type checking
|
|
193
|
+
- `black` - Code formatting
|
|
194
|
+
- `isort` - Import sorting
|
|
195
|
+
|
|
196
|
+
**Additional from pyproject.toml:**
|
|
197
|
+
- `requests>=2.31.0` - HTTP client for webhook management
|
|
198
|
+
- Dev: `pytest`, `pytest-asyncio`
|
|
199
|
+
|
|
200
|
+
## Testing Notes
|
|
201
|
+
|
|
202
|
+
- No test files exist yet in the repository
|
|
203
|
+
- When adding tests, use `pytest-asyncio` for async test support
|
|
204
|
+
- Test both sync and async methods
|
|
205
|
+
- Mock Telegram API calls to avoid real API usage
|
|
206
|
+
- **CRITICAL**: After making changes, always run `source bin/activate && python -m pytest` BEFORE committing code
|
|
207
|
+
- Remember: NEVER use `python3` - always use the venv with `source bin/activate && python`
|
|
208
|
+
|
|
209
|
+
## Version Management
|
|
210
|
+
|
|
211
|
+
- Version is defined in `pyproject.toml` (currently 0.1.0)
|
|
212
|
+
- Version must also be updated in `src/byteforge_telegram/__init__.py`
|
|
213
|
+
- When bumping version, update both files to keep them in sync
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Jason Byteforge
|
|
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.
|