init-data-py 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- init_data_py-0.2.0/PKG-INFO +86 -0
- init_data_py-0.2.0/README.md +76 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/pyproject.toml +1 -1
- {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/__init__.py +1 -1
- {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/init_data.py +44 -9
- {init_data_py-0.1.0 → init_data_py-0.2.0}/tests/test_parse.py +2 -2
- {init_data_py-0.1.0 → init_data_py-0.2.0}/tests/test_sign.py +2 -1
- init_data_py-0.2.0/tests/test_to_query_string.py +11 -0
- init_data_py-0.1.0/PKG-INFO +0 -65
- init_data_py-0.1.0/README.md +0 -55
- {init_data_py-0.1.0 → init_data_py-0.2.0}/.github/workflows/publish.yml +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/.gitignore +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/.python-version +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/LICENCE +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/requirements-dev.lock +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/requirements.lock +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/errors/__init__.py +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/errors/errors.py +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/types/__init__.py +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/types/chat.py +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/types/object.py +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/types/user.py +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/tests/__init__.py +0 -0
- {init_data_py-0.1.0 → init_data_py-0.2.0}/tests/test_validate.py +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: init-data-py
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A Python library that provides tools for using and validating Telegram web app init data.
|
|
5
|
+
Author-email: nimaxin <nimaxin@proton.me>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENCE
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# init-data-py
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
A Python library that provides tools for using and validating Telegram web app init data.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
You can install the library using pip:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install init-data-py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
### Parsing
|
|
29
|
+
|
|
30
|
+
To parse the `window.Telegram.WebApp.initData` query string into an `InitData` object for easier access to attributes and validation, you can use the `InitData.parse` method:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from init_data_py import InitData
|
|
34
|
+
|
|
35
|
+
init_data = InitData.parse(query_string)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Validation
|
|
39
|
+
|
|
40
|
+
To validate the init data, you can use the `InitData.validate` method:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
is_valid = init_data.validate(bot_token)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Signing
|
|
47
|
+
|
|
48
|
+
If you need to create and sign your own init data, you can create an `InitData` object and sign it:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from init_data_py import InitData
|
|
52
|
+
from init_data_py.types import User
|
|
53
|
+
|
|
54
|
+
user = User(id=5167898484, first_name="xin")
|
|
55
|
+
init_data = InitData(user=user).sign(bot_token)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Converting InitData to Query String
|
|
59
|
+
|
|
60
|
+
After creating and signing init data, you can convert it to a query sting using the `InitData.to_query_string` method:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
query_string = init_date.to_query_string()
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Real-World Validation Example
|
|
67
|
+
|
|
68
|
+
This example demonstrates how to validate a Telegram Mini App init data. It parses the init data query string into an `InitData` object and validate it using the provided bot token, checking that the data is valid and has not expired:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from init_data_py import InitData
|
|
72
|
+
|
|
73
|
+
bot_token = "7244657541:AAEgqk0HDC3WD5cdbnGMdd6L0TJ74FDp97Y"
|
|
74
|
+
query_string = "query_id=AAF03wc0AgAAAHTfBzROOCVW&user=%7B%22id%22%3A5167898484%2C%22first_name%22%3A%22xin%22%2C%22last_name%22%3A%22%22%2C%22username%22%3A%22pvnimaxin%22%2C%22language_code%22%3A%22en%22%2C%22allows_write_to_pm%22%3Atrue%7D&auth_date=1722938610&hash=8654c8c617c143abf656f4f159be2539880a56f58c2d9be622f90c0346aa162b"
|
|
75
|
+
|
|
76
|
+
init_data = InitData.parse(query_string)
|
|
77
|
+
|
|
78
|
+
is_valid = init_data.validate(
|
|
79
|
+
bot_token=bot_token,
|
|
80
|
+
lifetime=3600,
|
|
81
|
+
)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
This library is licensed under the [MIT License](LICENCE).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# init-data-py
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
A Python library that provides tools for using and validating Telegram web app init data.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
You can install the library using pip:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install init-data-py
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
### Parsing
|
|
19
|
+
|
|
20
|
+
To parse the `window.Telegram.WebApp.initData` query string into an `InitData` object for easier access to attributes and validation, you can use the `InitData.parse` method:
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from init_data_py import InitData
|
|
24
|
+
|
|
25
|
+
init_data = InitData.parse(query_string)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Validation
|
|
29
|
+
|
|
30
|
+
To validate the init data, you can use the `InitData.validate` method:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
is_valid = init_data.validate(bot_token)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Signing
|
|
37
|
+
|
|
38
|
+
If you need to create and sign your own init data, you can create an `InitData` object and sign it:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from init_data_py import InitData
|
|
42
|
+
from init_data_py.types import User
|
|
43
|
+
|
|
44
|
+
user = User(id=5167898484, first_name="xin")
|
|
45
|
+
init_data = InitData(user=user).sign(bot_token)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Converting InitData to Query String
|
|
49
|
+
|
|
50
|
+
After creating and signing init data, you can convert it to a query sting using the `InitData.to_query_string` method:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
query_string = init_date.to_query_string()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Real-World Validation Example
|
|
57
|
+
|
|
58
|
+
This example demonstrates how to validate a Telegram Mini App init data. It parses the init data query string into an `InitData` object and validate it using the provided bot token, checking that the data is valid and has not expired:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from init_data_py import InitData
|
|
62
|
+
|
|
63
|
+
bot_token = "7244657541:AAEgqk0HDC3WD5cdbnGMdd6L0TJ74FDp97Y"
|
|
64
|
+
query_string = "query_id=AAF03wc0AgAAAHTfBzROOCVW&user=%7B%22id%22%3A5167898484%2C%22first_name%22%3A%22xin%22%2C%22last_name%22%3A%22%22%2C%22username%22%3A%22pvnimaxin%22%2C%22language_code%22%3A%22en%22%2C%22allows_write_to_pm%22%3Atrue%7D&auth_date=1722938610&hash=8654c8c617c143abf656f4f159be2539880a56f58c2d9be622f90c0346aa162b"
|
|
65
|
+
|
|
66
|
+
init_data = InitData.parse(query_string)
|
|
67
|
+
|
|
68
|
+
is_valid = init_data.validate(
|
|
69
|
+
bot_token=bot_token,
|
|
70
|
+
lifetime=3600,
|
|
71
|
+
)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
This library is licensed under the [MIT License](LICENCE).
|
|
@@ -3,6 +3,7 @@ import hmac
|
|
|
3
3
|
import json
|
|
4
4
|
import time
|
|
5
5
|
import urllib.parse
|
|
6
|
+
import warnings
|
|
6
7
|
from datetime import datetime, timedelta
|
|
7
8
|
from typing import Literal, Optional
|
|
8
9
|
|
|
@@ -71,7 +72,12 @@ class InitData:
|
|
|
71
72
|
self.auth_date = auth_date
|
|
72
73
|
self.hash = hash
|
|
73
74
|
|
|
74
|
-
def validate(
|
|
75
|
+
def validate(
|
|
76
|
+
self,
|
|
77
|
+
bot_token: str,
|
|
78
|
+
lifetime: Optional[int] = None,
|
|
79
|
+
raise_error: bool = True,
|
|
80
|
+
):
|
|
75
81
|
"""Validates the init data authenticity.
|
|
76
82
|
|
|
77
83
|
Parameters:
|
|
@@ -82,9 +88,12 @@ class InitData:
|
|
|
82
88
|
The maximum validity period of the init data in seconds.
|
|
83
89
|
Recommended for security. Default is `None`.
|
|
84
90
|
|
|
91
|
+
raise_error (`bool`, optional):
|
|
92
|
+
In case True, raises an exception on invalid data, If False, returns False instead of raising an error.
|
|
93
|
+
|
|
85
94
|
Returns:
|
|
86
95
|
`bool`:
|
|
87
|
-
|
|
96
|
+
True if the data is valid; otherwise, returns False.
|
|
88
97
|
|
|
89
98
|
Raises:
|
|
90
99
|
`errors.SignMissingError`: In case the signature (hash) is missing.
|
|
@@ -93,19 +102,27 @@ class InitData:
|
|
|
93
102
|
`errors.SignInvalidError`: In case the signature (hash) is invalid.
|
|
94
103
|
"""
|
|
95
104
|
if self.hash is None:
|
|
96
|
-
|
|
105
|
+
if raise_error:
|
|
106
|
+
raise errors.SignMissingError()
|
|
107
|
+
return False
|
|
97
108
|
|
|
98
109
|
if self.auth_date is None:
|
|
99
|
-
|
|
110
|
+
if raise_error:
|
|
111
|
+
raise errors.AuthDateMissingError()
|
|
112
|
+
return False
|
|
100
113
|
|
|
101
114
|
if lifetime is not None:
|
|
102
115
|
auth_date = datetime.fromtimestamp(self.auth_date)
|
|
103
116
|
expire_date = auth_date - timedelta(seconds=lifetime)
|
|
104
117
|
if datetime.now() > expire_date:
|
|
105
|
-
|
|
118
|
+
if raise_error:
|
|
119
|
+
raise errors.ExpiredError()
|
|
120
|
+
return False
|
|
106
121
|
|
|
107
122
|
if self.hash != self.calculate_hash(bot_token):
|
|
108
|
-
|
|
123
|
+
if raise_error:
|
|
124
|
+
raise errors.SignInvalidError()
|
|
125
|
+
return False
|
|
109
126
|
|
|
110
127
|
return True
|
|
111
128
|
|
|
@@ -120,14 +137,16 @@ class InitData:
|
|
|
120
137
|
The timestamp (without timezone) representing the authorization date. If not provided, the current timestamp will be used.
|
|
121
138
|
|
|
122
139
|
Returns:
|
|
123
|
-
`
|
|
124
|
-
This
|
|
140
|
+
`InitData`:
|
|
141
|
+
This current updated init data by setting the `auth_date` and generated signature (`hash`) attributes.
|
|
125
142
|
"""
|
|
126
143
|
if auth_date is None:
|
|
127
144
|
self.auth_date = int(time.time())
|
|
128
145
|
self.auth_date = auth_date
|
|
129
146
|
self.hash = self.calculate_hash(bot_token)
|
|
130
147
|
|
|
148
|
+
return self
|
|
149
|
+
|
|
131
150
|
def calculate_hash(
|
|
132
151
|
self,
|
|
133
152
|
bot_token: str,
|
|
@@ -151,17 +170,32 @@ class InitData:
|
|
|
151
170
|
secret_key = hmac.new(
|
|
152
171
|
b"WebAppData", bot_token.encode(), hashlib.sha256
|
|
153
172
|
).digest()
|
|
173
|
+
|
|
154
174
|
return hmac.new(
|
|
155
175
|
secret_key, data_check_string, hashlib.sha256
|
|
156
176
|
).hexdigest()
|
|
157
177
|
|
|
158
178
|
@classmethod
|
|
159
179
|
def from_query_string(cls, query_string: str):
|
|
180
|
+
warnings.warn(
|
|
181
|
+
"The 'from_query_string' method is deprecated and will be removed in near stable version. Use 'parse' instead.",
|
|
182
|
+
DeprecationWarning,
|
|
183
|
+
stacklevel=2,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
return cls.parse(query_string)
|
|
187
|
+
|
|
188
|
+
@classmethod
|
|
189
|
+
def parse(cls, query_string: str):
|
|
160
190
|
"""Create an InitData object from a query string.
|
|
161
191
|
|
|
162
192
|
Parameters:
|
|
163
193
|
query_string (`str`):
|
|
164
|
-
The query string from `window.WebApp.initData` to parse and
|
|
194
|
+
The query string from `window.WebApp.initData` to parse and convert into an InitData object.
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
`InitData`:
|
|
198
|
+
An object of InitData with attributes set according to the values in the query_string.
|
|
165
199
|
|
|
166
200
|
Raises:
|
|
167
201
|
`errors.SignMissingError`: In case the signature (hash) is missing.
|
|
@@ -242,6 +276,7 @@ class InitData:
|
|
|
242
276
|
def to_query_string(self):
|
|
243
277
|
"""Returns a query string representation of the object."""
|
|
244
278
|
init_data = self.to_dict(nested=False)
|
|
279
|
+
|
|
245
280
|
return urllib.parse.urlencode(init_data)
|
|
246
281
|
|
|
247
282
|
def __str__(self) -> str:
|
|
@@ -21,9 +21,9 @@ class TestParseInitData(unittest.TestCase):
|
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
def test_valid_query_string(self):
|
|
24
|
-
init_data = InitData.
|
|
24
|
+
init_data = InitData.parse(self.query_string)
|
|
25
25
|
self.assertEqual(init_data, self.expected_init_data)
|
|
26
26
|
|
|
27
27
|
def test_invalid_query_string(self):
|
|
28
28
|
with self.assertRaises(errors.UnexpectedFormatError):
|
|
29
|
-
InitData.
|
|
29
|
+
InitData.parse(self.query_string.upper())
|
|
@@ -24,9 +24,10 @@ class TestSignInitData(unittest.TestCase):
|
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
def test_sign(self):
|
|
27
|
-
self.init_data.sign(
|
|
27
|
+
init_data = self.init_data.sign(
|
|
28
28
|
bot_token=self.bot_token,
|
|
29
29
|
auth_date=self.expected_auth_date,
|
|
30
30
|
)
|
|
31
31
|
self.assertEqual(self.init_data.hash, self.expected_hash)
|
|
32
32
|
self.assertEqual(self.init_data.auth_date, self.expected_auth_date)
|
|
33
|
+
self.assertIsInstance(init_data, InitData)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from init_data_py import InitData
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestToQueryString(unittest.TestCase):
|
|
7
|
+
def test_from_query_string_to_query_string(self):
|
|
8
|
+
query_string = "query_id=AAF03wc0AgAAAHTfBzROOCVW&user=%7B%22id%22%3A5167898484%2C%22first_name%22%3A%22xin%22%2C%22last_name%22%3A%22%22%2C%22username%22%3A%22pvnimaxin%22%2C%22language_code%22%3A%22en%22%2C%22allows_write_to_pm%22%3Atrue%7D&auth_date=1722938610&hash=8654c8c617c143abf656f4f159be2539880a56f58c2d9be622f90c0346aa162b"
|
|
9
|
+
init_data = InitData.parse(query_string)
|
|
10
|
+
generated_query_string = init_data.to_query_string()
|
|
11
|
+
self.assertEqual(generated_query_string, query_string)
|
init_data_py-0.1.0/PKG-INFO
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: init-data-py
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: A Python library that provides tools for using and validating Telegram web app init data.
|
|
5
|
-
Author-email: nimaxin <nimaxin@proton.me>
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
License-File: LICENCE
|
|
8
|
-
Requires-Python: >=3.8
|
|
9
|
-
Description-Content-Type: text/markdown
|
|
10
|
-
|
|
11
|
-
# init-data-py
|
|
12
|
-
|
|
13
|
-
A Python library that provides tools for using and validating Telegram web app init data.
|
|
14
|
-
|
|
15
|
-
## Installation
|
|
16
|
-
|
|
17
|
-
You can install the library using pip.
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
pip install init-data-py
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Usage
|
|
24
|
-
|
|
25
|
-
### Parsing.
|
|
26
|
-
|
|
27
|
-
```python
|
|
28
|
-
from init_data_py import InitData
|
|
29
|
-
|
|
30
|
-
query_string = "query_id=AAF03wc0Ag..."
|
|
31
|
-
|
|
32
|
-
InitData.from_query_string(query_string)
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Signing
|
|
36
|
-
|
|
37
|
-
```python
|
|
38
|
-
from init_data_py import InitData
|
|
39
|
-
from init_data_py.types import User
|
|
40
|
-
|
|
41
|
-
BOT_TOKEN = "7244657541:AA..."
|
|
42
|
-
|
|
43
|
-
init_data = InitData(
|
|
44
|
-
user=User(
|
|
45
|
-
id=5167898484,
|
|
46
|
-
first_name="xin",
|
|
47
|
-
username="pvnimaxin",
|
|
48
|
-
)
|
|
49
|
-
).sign(bot_token=BOT_TOKEN)
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Validation
|
|
53
|
-
|
|
54
|
-
```python
|
|
55
|
-
from init_data_py import InitData
|
|
56
|
-
|
|
57
|
-
BOT_TOKEN = "7244657541:AA..."
|
|
58
|
-
|
|
59
|
-
init_data = InitData(...)
|
|
60
|
-
is_valid = init_data.validate(bot_token=BOT_TOKEN, lifetime=3600)
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## License
|
|
64
|
-
|
|
65
|
-
This library is licensed under the [MIT License](LICENCE).
|
init_data_py-0.1.0/README.md
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# init-data-py
|
|
2
|
-
|
|
3
|
-
A Python library that provides tools for using and validating Telegram web app init data.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
You can install the library using pip.
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
pip install init-data-py
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
### Parsing.
|
|
16
|
-
|
|
17
|
-
```python
|
|
18
|
-
from init_data_py import InitData
|
|
19
|
-
|
|
20
|
-
query_string = "query_id=AAF03wc0Ag..."
|
|
21
|
-
|
|
22
|
-
InitData.from_query_string(query_string)
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Signing
|
|
26
|
-
|
|
27
|
-
```python
|
|
28
|
-
from init_data_py import InitData
|
|
29
|
-
from init_data_py.types import User
|
|
30
|
-
|
|
31
|
-
BOT_TOKEN = "7244657541:AA..."
|
|
32
|
-
|
|
33
|
-
init_data = InitData(
|
|
34
|
-
user=User(
|
|
35
|
-
id=5167898484,
|
|
36
|
-
first_name="xin",
|
|
37
|
-
username="pvnimaxin",
|
|
38
|
-
)
|
|
39
|
-
).sign(bot_token=BOT_TOKEN)
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Validation
|
|
43
|
-
|
|
44
|
-
```python
|
|
45
|
-
from init_data_py import InitData
|
|
46
|
-
|
|
47
|
-
BOT_TOKEN = "7244657541:AA..."
|
|
48
|
-
|
|
49
|
-
init_data = InitData(...)
|
|
50
|
-
is_valid = init_data.validate(bot_token=BOT_TOKEN, lifetime=3600)
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## License
|
|
54
|
-
|
|
55
|
-
This library is licensed under the [MIT License](LICENCE).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|