Skip to main content

Python library for working with Telegram Mini Apps initialization data

Project description

Telegram Init Data Python

PyPI version Python versions License: MIT

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 validate
  • token (str): Bot token from @BotFather
  • options (dict, optional): Validation options
    • expires_in (int): Expiration time in seconds (default: 86400)

Raises:

  • SignatureMissingError: When hash parameter is missing
  • AuthDateInvalidError: When auth_date is invalid or missing
  • ExpiredError: When init data has expired
  • SignatureInvalidError: 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 sign
  • token (str): Bot token
  • auth_date (datetime): Authentication date
  • options (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]

Exception Classes

  • TelegramInitDataError: Base exception class
  • AuthDateInvalidError: Invalid or missing auth_date
  • SignatureInvalidError: Invalid signature
  • SignatureMissingError: Missing signature/hash
  • ExpiredError: 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

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

License

MIT License. See LICENSE for details.

Related Projects

Changelog

See CHANGELOG.md for details about changes in each version.

Support

If you have questions or need help:

  1. Check the documentation
  2. Look at the examples
  3. Open an issue

Made with ❤️ for the Telegram Mini Apps community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

telegram_init_data-1.0.0.tar.gz (19.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

telegram_init_data-1.0.0-py3-none-any.whl (18.6 kB view details)

Uploaded Python 3

File details

Details for the file telegram_init_data-1.0.0.tar.gz.

File metadata

  • Download URL: telegram_init_data-1.0.0.tar.gz
  • Upload date:
  • Size: 19.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.0

File hashes

Hashes for telegram_init_data-1.0.0.tar.gz
Algorithm Hash digest
SHA256 be8e418e06dfd8f22713076e3b0785fcddd9ba9272c57ca6b6d320c7d72992f8
MD5 1b6bc711daecdbcc31f7065572999590
BLAKE2b-256 774bcdfc0e91de6db053f3407e1a16e2634c0a3156d644f28cfb7675e27b5e77

See more details on using hashes here.

File details

Details for the file telegram_init_data-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for telegram_init_data-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5e7098288640f8e13cd91d25e58aabea10472e06079e1524fc2167a65c8bd8b8
MD5 4575676c87bfc97d3b2430c1306d8f5e
BLAKE2b-256 cba68d0c8b1642bf4872a4354bb760dff464bc671231ea08fe16eb686cff1d38

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page