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.
Files changed (24) hide show
  1. init_data_py-0.2.0/PKG-INFO +86 -0
  2. init_data_py-0.2.0/README.md +76 -0
  3. {init_data_py-0.1.0 → init_data_py-0.2.0}/pyproject.toml +1 -1
  4. {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/__init__.py +1 -1
  5. {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/init_data.py +44 -9
  6. {init_data_py-0.1.0 → init_data_py-0.2.0}/tests/test_parse.py +2 -2
  7. {init_data_py-0.1.0 → init_data_py-0.2.0}/tests/test_sign.py +2 -1
  8. init_data_py-0.2.0/tests/test_to_query_string.py +11 -0
  9. init_data_py-0.1.0/PKG-INFO +0 -65
  10. init_data_py-0.1.0/README.md +0 -55
  11. {init_data_py-0.1.0 → init_data_py-0.2.0}/.github/workflows/publish.yml +0 -0
  12. {init_data_py-0.1.0 → init_data_py-0.2.0}/.gitignore +0 -0
  13. {init_data_py-0.1.0 → init_data_py-0.2.0}/.python-version +0 -0
  14. {init_data_py-0.1.0 → init_data_py-0.2.0}/LICENCE +0 -0
  15. {init_data_py-0.1.0 → init_data_py-0.2.0}/requirements-dev.lock +0 -0
  16. {init_data_py-0.1.0 → init_data_py-0.2.0}/requirements.lock +0 -0
  17. {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/errors/__init__.py +0 -0
  18. {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/errors/errors.py +0 -0
  19. {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/types/__init__.py +0 -0
  20. {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/types/chat.py +0 -0
  21. {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/types/object.py +0 -0
  22. {init_data_py-0.1.0 → init_data_py-0.2.0}/src/init_data_py/types/user.py +0 -0
  23. {init_data_py-0.1.0 → init_data_py-0.2.0}/tests/__init__.py +0 -0
  24. {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
+ ![Package version](https://img.shields.io/pypi/v/init-data-py?color=%2334D058&label=pypi%20package)
14
+ ![License](https://img.shields.io/github/license/nimaxin/init-data-py)
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
+ ![Package version](https://img.shields.io/pypi/v/init-data-py?color=%2334D058&label=pypi%20package)
4
+ ![License](https://img.shields.io/github/license/nimaxin/init-data-py)
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).
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "init-data-py"
3
- version = "0.1.0"
3
+ version = "0.2.0"
4
4
  description = "A Python library that provides tools for using and validating Telegram web app init data."
5
5
  authors = [
6
6
  { name = "nimaxin", email = "nimaxin@proton.me" }
@@ -1,5 +1,5 @@
1
1
  from .init_data import InitData
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.2.0"
4
4
 
5
5
  __all__ = ["InitData"]
@@ -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(self, bot_token: str, lifetime: Optional[int] = None):
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
- `True` if the init data is valid; otherwise, raises an exception.
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
- raise errors.SignMissingError()
105
+ if raise_error:
106
+ raise errors.SignMissingError()
107
+ return False
97
108
 
98
109
  if self.auth_date is None:
99
- raise errors.AuthDateMissingError()
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
- raise errors.ExpiredError()
118
+ if raise_error:
119
+ raise errors.ExpiredError()
120
+ return False
106
121
 
107
122
  if self.hash != self.calculate_hash(bot_token):
108
- raise errors.SignInvalidError()
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
- `None`:
124
- This method updates the current init data by setting the `auth_date` and generated signature (`hash`) attributes.
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 covert into an WebAppInitData object.
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.from_query_string(self.query_string)
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.from_query_string(self.query_string.upper())
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)
@@ -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).
@@ -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