Skip to content

Repository files navigation

telegram-init-data

PyPI versionPython versionsPyPI DownloadsLicense: 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

fromtelegram_init_dataimportvalidate, parsebot_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"])
exceptExceptionase:
print(f"Validation failed: {e}")

FastAPI

fromfastapiimportFastAPI, Depends, HTTPExceptionfromtelegram_init_dataimportvalidate, parseapp=FastAPI()
defverify_init_data(init_data: str) ->dict:
bot_token="YOUR_BOT_TOKEN"try:
validate(init_data, bot_token)
returnparse(init_data)
exceptExceptionase:
raiseHTTPException(status_code=401, detail=str(e))
@app.post("/user/profile")asyncdefget_profile(init_data: dict=Depends(verify_init_data)):
user=init_data.get("user")
ifnotuser:
raiseHTTPException(status_code=400, detail="User data not found")
return {"user_id": user["id"], "name": user["first_name"]}

Signing (tests / development)

fromtelegram_init_dataimportsign, is_validfromdatetimeimportdatetimebot_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())
ifis_valid(signed_data, bot_token):
print("Valid")

API Reference

validate(value, token, options=None)

Validate Telegram Mini App init data.

ParameterTypeDescription
value`strdict`
tokenstrBot token from @BotFather
optionsdict, optionalexpires_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

classInitData(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: inthash: strsignature: Optional[str]
classUser(TypedDict):
id: intfirst_name: strlast_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]
classChat(TypedDict):
id: inttype: ChatTypetitle: Optional[str]
username: Optional[str]
photo_url: Optional[str]
classChatType(str, Enum):
SENDER="sender"PRIVATE="private"GROUP="group"SUPERGROUP="supergroup"CHANNEL="channel"

Exceptions

ExceptionWhen
TelegramInitDataErrorBase class
AuthDateInvalidErrorInvalid or missing auth_date
SignatureInvalidErrorSignature mismatch
SignatureMissingErrorMissing hash / signature
ExpiredErrorInit data expired

Options

# Custom TTL (1 hour)validate(init_data, bot_token, {"expires_in": 3600})
# Disable expiration checkvalidate(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

fromfastapiimportFastAPI, Depends, HTTPException, Headerfromtelegram_init_dataimportparse, is_validapp=FastAPI()
defget_init_data(authorization: str=Header(None)):
ifnotauthorization:
raiseHTTPException(status_code=401, detail="Authorization header missing")
ifnotauthorization.startswith("tma "):
raiseHTTPException(status_code=401, detail="Invalid authorization format")
init_data=authorization[4:]
bot_token="YOUR_BOT_TOKEN"ifnotis_valid(init_data, bot_token):
raiseHTTPException(status_code=401, detail="Invalid init data")
returnparse(init_data)
@app.get("/me")asyncdefget_current_user(init_data: dict=Depends(get_init_data)):
user=init_data.get("user")
ifnotuser:
raiseHTTPException(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

Stars

16 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages