telegram-init-data
Python library for parsing, validating, and signing Telegram Mini Apps initialization data on the server side. API-compatible in spirit with @tma.js/init-data-node.
Features
- Validate init data signature and expiration
- Parse URL-encoded init data into typed Python objects
- Sign init data for testing and development
- Full type hints
- Optional FastAPI integration
- Third-party validation (data signed by Telegram directly)
Installation
pip install telegram-init-data
With FastAPI support:
pip install telegram-init-data[fastapi]
Quick Start
Validation
from telegram_init_data import validate, parse
bot_token = "YOUR_BOT_TOKEN"
init_data = "query_id=AAHdF6IQAAAAAN0XohDhrOrc&user=%7B%22id%22%3A279058397%2C%22first_name%22%3A%22Vladislav%22%2C%22last_name%22%3A%22Kibenko%22%2C%22username%22%3A%22vdkfrost%22%2C%22language_code%22%3A%22ru%22%2C%22is_premium%22%3Atrue%7D&auth_date=1662771648&hash=c501b71e775f74ce10e377dea85a7ea24ecd640b223ea86dfe453e0eaed2e2b2"
try:
validate(init_data, bot_token)
parsed = parse(init_data)
print(parsed["user"]["first_name"])
except Exception as e:
print(f"Validation failed: {e}")
FastAPI
from fastapi import FastAPI, Depends, HTTPException
from telegram_init_data import validate, parse
app = FastAPI()
def verify_init_data(init_data: str) -> dict:
bot_token = "YOUR_BOT_TOKEN"
try:
validate(init_data, bot_token)
return parse(init_data)
except Exception as e:
raise HTTPException(status_code=401, detail=str(e))
@app.post("/user/profile")
async def get_profile(init_data: dict = Depends(verify_init_data)):
user = init_data.get("user")
if not user:
raise HTTPException(status_code=400, detail="User data not found")
return {"user_id": user["id"], "name": user["first_name"]}
Signing (tests / development)
from telegram_init_data import sign, is_valid
from datetime import datetime
bot_token = "YOUR_BOT_TOKEN"
test_data = {
"query_id": "test_query_id",
"user": {
"id": 123456789,
"first_name": "John",
"last_name": "Doe",
"username": "johndoe",
"language_code": "en",
},
"auth_date": datetime.now(),
}
signed_data = sign(test_data, bot_token, datetime.now())
if is_valid(signed_data, bot_token):
print("Valid")
API Reference
validate(value, token, options=None)
Validate Telegram Mini App init data.
| Parameter | Type | Description |
|---|---|---|
value |
`str | dict` |
token |
str |
Bot token from @BotFather |
options |
dict, optional |
expires_in (seconds, default 86400) |
Raises: SignatureMissingError, AuthDateInvalidError, ExpiredError, SignatureInvalidError
is_valid(value, token, options=None)
Same checks as validate, returns bool instead of raising.
parse(value)
Parse init data into a structured object. Returns InitData.
sign(data, token, auth_date, options=None)
Sign init data for testing. Returns a URL-encoded string.
Types
class InitData(TypedDict):
query_id: Optional[str]
user: Optional[User]
receiver: Optional[User]
chat: Optional[Chat]
chat_type: Optional[ChatType]
chat_instance: Optional[str]
start_param: Optional[str]
can_send_after: Optional[int]
auth_date: int
hash: str
signature: Optional[str]
class User(TypedDict):
id: int
first_name: str
last_name: Optional[str]
username: Optional[str]
language_code: Optional[str]
is_bot: Optional[bool]
is_premium: Optional[bool]
added_to_attachment_menu: Optional[bool]
allows_write_to_pm: Optional[bool]
photo_url: Optional[str]
class Chat(TypedDict):
id: int
type: ChatType
title: Optional[str]
username: Optional[str]
photo_url: Optional[str]
class ChatType(str, Enum):
SENDER = "sender"
PRIVATE = "private"
GROUP = "group"
SUPERGROUP = "supergroup"
CHANNEL = "channel"
Exceptions
| Exception | When |
|---|---|
TelegramInitDataError |
Base class |
AuthDateInvalidError |
Invalid or missing auth_date |
SignatureInvalidError |
Signature mismatch |
SignatureMissingError |
Missing hash / signature |
ExpiredError |
Init data expired |
Options
# Custom TTL (1 hour)
validate(init_data, bot_token, {"expires_in": 3600})
# Disable expiration check
validate(init_data, bot_token, {"expires_in": 0})
Testing
pip install -e ".[dev]"
pytest
pytest --cov=telegram_init_data --cov-report=html
Examples
See [examples/](examples/) for basic usage and a FastAPI app.
FastAPI with Authorization header
from fastapi import FastAPI, Depends, HTTPException, Header
from telegram_init_data import parse, is_valid
app = FastAPI()
def get_init_data(authorization: str = Header(None)):
if not authorization:
raise HTTPException(status_code=401, detail="Authorization header missing")
if not authorization.startswith("tma "):
raise HTTPException(status_code=401, detail="Invalid authorization format")
init_data = authorization[4:]
bot_token = "YOUR_BOT_TOKEN"
if not is_valid(init_data, bot_token):
raise HTTPException(status_code=401, detail="Invalid init data")
return parse(init_data)
@app.get("/me")
async def get_current_user(init_data: dict = Depends(get_init_data)):
user = init_data.get("user")
if not user:
raise HTTPException(status_code=400, detail="User data not found")
return {
"id": user["id"],
"name": user.get("first_name", ""),
"username": user.get("username"),
"is_premium": user.get("is_premium", False),
}
Development
git clone https://github.com/iCodeCraft/telegram-init-data.git
cd telegram-init-data
python -m venv venv
source venv/bin/activate
pip install -e ".[dev]"
pytest
black telegram_init_data tests
isort telegram_init_data tests
mypy telegram_init_data
License
MIT. See LICENSE.
Related
- @tma.js/init-data-node — Node.js counterpart
- Telegram Mini Apps documentation
- Download stats (pepy.tech)
Changelog
See CHANGELOG.md.
Metadata
Release files for telegram-init-data 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| telegram_init_data-1.1.0.tar.gz | 16.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| telegram_init_data-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.3 kB
Release files / telegram_init_data-1.1.0.tar.gz
| Download URL | telegram_init_data-1.1.0.tar.gz |
|---|---|
| Size | 16.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a42e66e422145b70ef90dd172f2b82c221acf7f5c4f754e0be7ecf9bdd170bff
|
|
BLAKE2b-256 checksum How to use checksums |
99666261f370cde758539eb21c7fb6c868946babba5c741262dbb7b3712158a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.0
|
Release files / telegram_init_data-1.1.0-py3-none-any.whl
| Download URL | telegram_init_data-1.1.0-py3-none-any.whl |
|---|---|
| Size | 15.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
17494c62a3f85bade8ddeea3c5e1f89cfd46d632b2c0ff226adcac78ef22a598
|
|
BLAKE2b-256 checksum How to use checksums |
55391b22839b2d26664b25027d320bc0336b8171ebc77462a5015d6e575cf417
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.0
|