Skip to main content

Python library for working with Telegram Mini Apps initialization data

Project description

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.

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.1.0.tar.gz (16.5 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.1.0-py3-none-any.whl (15.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: telegram_init_data-1.1.0.tar.gz
  • Upload date:
  • Size: 16.5 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.1.0.tar.gz
Algorithm Hash digest
SHA256 a42e66e422145b70ef90dd172f2b82c221acf7f5c4f754e0be7ecf9bdd170bff
MD5 20fa1407aab93bd02b9919300aefc1dd
BLAKE2b-256 99666261f370cde758539eb21c7fb6c868946babba5c741262dbb7b3712158a7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for telegram_init_data-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 17494c62a3f85bade8ddeea3c5e1f89cfd46d632b2c0ff226adcac78ef22a598
MD5 bb852172e0bb8f45681cc6c7a650dcbe
BLAKE2b-256 55391b22839b2d26664b25027d320bc0336b8171ebc77462a5015d6e575cf417

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