Python library for working with Telegram Mini Apps initialization data
Project description
Telegram Init Data Python
A Python library for working with Telegram Mini Apps initialization data. This library provides utilities to parse, validate, and sign init data on the server side, similar to the official @telegram-apps/init-data-node package.
Features
- 🔐 Validate init data - Verify signature and expiration of Telegram Mini App init data
- 📝 Parse init data - Convert URL-encoded init data to structured Python objects
- ✍️ Sign init data - Create signed init data for testing and development
- 🔍 Type safety - Full type hints and validation
- 🚀 FastAPI integration - Ready-to-use middleware for FastAPI applications
- 🌐 3rd party validation - Support for validating data signed by Telegram directly
Installation
pip install telegram-init-data
For FastAPI integration:
pip install telegram-init-data[fastapi]
Quick Start
Basic Validation
from telegram_init_data import validate, parse
# Your bot token from @BotFather
bot_token = "YOUR_BOT_TOKEN"
# Init data string from Telegram Mini App
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 the init data
validate(init_data, bot_token)
print("✅ Init data is valid!")
# Parse the init data
parsed_data = parse(init_data)
print(f"User: {parsed_data['user']['first_name']}")
except Exception as e:
print(f"❌ Validation failed: {e}")
Using with FastAPI
from fastapi import FastAPI, Depends, HTTPException
from telegram_init_data import validate, parse
app = FastAPI()
def verify_init_data(init_data: str) -> dict:
"""Dependency to verify and parse init data"""
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"]}
Advanced Usage
from telegram_init_data import sign, is_valid
from datetime import datetime
# Create test init data
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()
}
# Sign the data
signed_data = sign(test_data, bot_token, datetime.now())
print(f"Signed data: {signed_data}")
# Check if data is valid (returns boolean)
if is_valid(signed_data, bot_token):
print("✅ Data is valid")
else:
print("❌ Data is invalid")
API Reference
Core Functions
validate(value, token, options=None)
Validates Telegram Mini App init data.
Parameters:
value(str | dict): Init data to validatetoken(str): Bot token from @BotFatheroptions(dict, optional): Validation optionsexpires_in(int): Expiration time in seconds (default: 86400)
Raises:
SignatureMissingError: When hash parameter is missingAuthDateInvalidError: When auth_date is invalid or missingExpiredError: When init data has expiredSignatureInvalidError: When signature verification fails
is_valid(value, token, options=None)
Checks if init data is valid without raising exceptions.
Returns: bool - True if valid, False otherwise
parse(value)
Parses init data string into structured Python object.
Parameters:
value(str | dict): Init data to parse
Returns: InitData - Parsed init data object
sign(data, token, auth_date, options=None)
Signs init data for testing/development.
Parameters:
data(dict): Data to signtoken(str): Bot tokenauth_date(datetime): Authentication dateoptions(dict, optional): Signing options
Returns: str - Signed init data as URL-encoded string
Data Types
InitData
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]
User
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]
Chat
class Chat(TypedDict):
id: int
type: ChatType
title: Optional[str]
username: Optional[str]
photo_url: Optional[str]
ChatType
class ChatType(str, Enum):
SENDER = "sender"
PRIVATE = "private"
GROUP = "group"
SUPERGROUP = "supergroup"
CHANNEL = "channel"
Exception Classes
TelegramInitDataError: Base exception classAuthDateInvalidError: Invalid or missing auth_dateSignatureInvalidError: Invalid signatureSignatureMissingError: Missing signature/hashExpiredError: Init data has expired
Configuration Options
Validation Options
options = {
"expires_in": 3600, # 1 hour expiration instead of default 24 hours
}
validate(init_data, bot_token, options)
Disable Expiration Check
options = {
"expires_in": 0, # Disable expiration check
}
validate(init_data, bot_token, options)
Testing
Run tests with pytest:
# Install development dependencies
pip install -e .[dev]
# Run tests
pytest
# Run with coverage
pytest --cov=telegram_init_data --cov-report=html
Examples
Complete FastAPI Application
from fastapi import FastAPI, Depends, HTTPException, Header
from telegram_init_data import validate, parse, is_valid
app = FastAPI()
def get_init_data(authorization: str = Header(None)):
"""Extract and validate init data from Authorization header"""
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:] # Remove "tma " prefix
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)):
"""Get current user info"""
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)
}
@app.post("/settings")
async def update_settings(
settings: dict,
init_data: dict = Depends(get_init_data)
):
"""Update user settings"""
user = init_data.get("user")
# Save settings for user["id"]
return {"status": "success"}
Development
Setup Development Environment
# Clone the repository
git clone https://github.com/telegram-init-data/telegram-init-data-python.git
cd telegram-init-data-python
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e .[dev]
# Run tests
pytest
# Format code
black telegram_init_data tests
isort telegram_init_data tests
# Type checking
mypy telegram_init_data
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License. See LICENSE for details.
Related Projects
- @telegram-apps/init-data-node - Official Node.js implementation
- Telegram Mini Apps Documentation - Official documentation
Changelog
See CHANGELOG.md for details about changes in each version.
Support
If you have questions or need help:
- Check the documentation
- Look at the examples
- Open an issue
Developed with ❤️ by Imran Gadzhiev to support Telegram Mini Apps developers.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file telegram_init_data-1.0.2.tar.gz.
File metadata
- Download URL: telegram_init_data-1.0.2.tar.gz
- Upload date:
- Size: 19.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15b3f6a51c163f62fd673c67f97636e8af65fa1409eb0782336736f3c90f7b84
|
|
| MD5 |
e6071c113b020eb09eb4272f1f159772
|
|
| BLAKE2b-256 |
9555c7e20114ca31bbf2c1448764dacb09188c6d997743c63cf0226da4a82944
|
File details
Details for the file telegram_init_data-1.0.2-py3-none-any.whl.
File metadata
- Download URL: telegram_init_data-1.0.2-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb15c6bc9f2407130b1b215980d1b30dcb8a38b2c85168b08c33b6270a42cce3
|
|
| MD5 |
6aef08ac2ec860171143c727d2495fce
|
|
| BLAKE2b-256 |
8bd7445f3a65a33575386df2f5442c2fdfe94571cf12654c447f3e0941f78dbe
|