Skip to content

iCodeCraft/telegram-init-data

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

telegram-init-data

PyPI version Python versions PyPI Downloads License: MIT

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

Changelog

See CHANGELOG.md.

About

Python library for working with Telegram Mini Apps initialization data. Parse, validate, and sign init data with full type safety and FastAPI integration.

Topics

Resources

License

Stars

15 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages