pyrobale 0.3.5__py3-none-any.whl → 0.3.8__py3-none-any.whl

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.
@@ -0,0 +1 @@
1
+ from .common import *
@@ -8,3 +8,9 @@ class InvalidTokenException(PyroBaleException):
8
8
 
9
9
  class NotFoundException(PyroBaleException):
10
10
  pass
11
+
12
+ class ForbiddenException(PyroBaleException):
13
+ pass
14
+
15
+ class InternalServerException(PyroBaleException):
16
+ pass
@@ -0,0 +1,2 @@
1
+ from .enum_filters import *
2
+ from .func_filters import *
@@ -0,0 +1,12 @@
1
+ from enum import Enum
2
+
3
+ class Filters(Enum):
4
+ """Filters that you can use in handlers"""
5
+
6
+ TEXT = "text"
7
+ PHOTO = "photo"
8
+ VIDEO = "video"
9
+ AUDIO = "audio"
10
+ VOICE = "voice"
11
+ CONTACT = "contact"
12
+ LOCATION = "location"
@@ -0,0 +1,17 @@
1
+ def equals(expected_text: str):
2
+ """
3
+ Check if the event text or caption is equal to the expected text.
4
+
5
+ Args:
6
+ expected_text (str): The expected text to compare with.
7
+
8
+ Returns:
9
+ Callable: A function that checks if the event text or caption is equal to the expected text.
10
+ """
11
+ def check(event):
12
+ try:
13
+ return getattr(event, "text", None) == expected_text or getattr(event, "caption", None) == expected_text
14
+ except:
15
+ return False
16
+ return check
17
+
@@ -1,3 +1,6 @@
1
+ """# objects in pyrobale, we have a lot of objects that are used to represent
2
+ different types of data."""
3
+
1
4
  from .voice import Voice
2
5
  from .replykeyboardmarkup import ReplyKeyboardMarkup
3
6
  from .inputmedias import (
@@ -1,13 +1,4 @@
1
- from typing import TYPE_CHECKING, Optional
2
-
3
- if TYPE_CHECKING:
4
- from .user import User
5
- from .message import Message
6
- from ..client import Client
7
-
8
- from .user import User
9
- from .message import Message
10
- from .chat import Chat
1
+ from typing import Optional
11
2
 
12
3
 
13
4
  class CallbackQuery:
@@ -16,27 +7,31 @@ class CallbackQuery:
16
7
  def __init__(
17
8
  self,
18
9
  id: Optional[str] = None,
19
- user: Optional["User"] = None,
20
- message: Optional["Message"] = None,
10
+ user: Optional[dict] = None,
11
+ message: Optional[dict] = None,
21
12
  data: Optional[str] = None,
22
13
  **kwargs
23
14
  ):
24
15
  self.id = id
25
- self.user: "User" = User(**user) if user else None
26
- self.message: "Message" = Message(**message) if message else None
27
- self.chat: "Chat" = self.message.chat if self.message else None
16
+ self.user = None
17
+ self.message = None
18
+ self.chat = None
28
19
  self.data = data if data else None
29
- self.bot: "Client" = kwargs.get("kwargs", {}).get("client", None)
20
+ self.bot = kwargs.get("kwargs", {}).get("client", None)
30
21
 
31
- async def answer(
32
- self, text: Optional[str] = None, show_alert: bool = False
33
- ) -> bool:
34
- """Sends a response to the callback query.
22
+ if user:
23
+ from .user import User
35
24
 
36
- :param text: The text of the response.
25
+ self.user = User(**user)
37
26
 
38
- :param show_alert: Whether to show an alert to the user.
27
+ if message:
28
+ from .message import Message
39
29
 
40
- :return: true if the response was sent successfully.
41
- """
30
+ self.message = Message(**message)
31
+ self.chat = self.message.chat if self.message else None
32
+
33
+ async def answer(
34
+ self, text: Optional[str] = None, show_alert: bool = False
35
+ ) -> bool:
36
+ """Sends a response to the callback query."""
42
37
  return await self.bot.answer_callback_query(self.id, text, show_alert)
@@ -4,10 +4,10 @@ from typing import Optional, Union
4
4
  if TYPE_CHECKING:
5
5
  from .utils import build_api_url
6
6
  from .user import User
7
+ from ..client import Client
7
8
  from .chat import Chat
8
9
  from .user import User
9
10
  from .enums import ChatType
10
- from ..client import Client
11
11
 
12
12
 
13
13
  class ChatMember:
@@ -79,8 +79,8 @@ class ChatMember:
79
79
  """Bans the chat member from the chat.
80
80
 
81
81
  :param chat_id: The ID of the chat.
82
-
83
- :return: True if the member was banned successfully, False otherwise.
82
+ :return: True if the member was banned successfully, False
83
+ otherwise.
84
84
  """
85
85
  data = await self.chat.ban(self.user.id)
86
86
  return data
@@ -88,7 +88,8 @@ class ChatMember:
88
88
  async def unban(self) -> bool:
89
89
  """Unbans the chat member from the chat.
90
90
 
91
- :return: True if the member was unbanned successfully, False otherwise.
91
+ :return: True if the member was unbanned successfully, False
92
+ otherwise.
92
93
  """
93
94
  data = await self.chat.unban(self.user.id)
94
95
  return data
pyrobale/objects/enums.py CHANGED
@@ -10,6 +10,11 @@ class UpdatesTypes(Enum):
10
10
  PRE_CHECKOUT_QUERY = "pre_checkout_query"
11
11
  MEMBER_JOINED = "member_joined"
12
12
  MEMBER_LEFT = "member_left"
13
+ SUCCESSFUL_PAYMENT = "successful_payment"
14
+ COMMAND = "message"
15
+
16
+
17
+
13
18
 
14
19
 
15
20
  class ChatAction(Enum):
@@ -18,6 +23,9 @@ class ChatAction(Enum):
18
23
  TYPING = "typing"
19
24
  PHOTO = "upload_photo"
20
25
  VIDEO = "upload_video"
26
+ REVORDVIDEO = "record_video"
27
+ VOICE = "upload_voice"
28
+ DOCUMENT = "upload_document"
21
29
 
22
30
 
23
31
  class ChatType(Enum):
@@ -15,7 +15,7 @@ class InlineKeyboardMarkup:
15
15
  callback_data: Optional[str] = None,
16
16
  url: Optional[str] = None,
17
17
  web_app: Optional[Union["WebAppInfo", str]] = None,
18
- copy_text_button: Optional["CopyTextButton"] = None,
18
+ copy_text_button: Optional[Union["CopyTextButton", str]] = None,
19
19
  **kwargs
20
20
  ) -> "InlineKeyboardMarkup":
21
21
  """Adds a button to the inline keyboard.
@@ -24,8 +24,8 @@ class InlineKeyboardMarkup:
24
24
  text (str): The text to display on the button.
25
25
  callback_data (str, optional): The callback data to send when the button is clicked.
26
26
  url (str, optional): The URL to open when the button is clicked.
27
- web_app (WebAppInfo, optional): The web app to open when the button is clicked.
28
- copy_text_button (CopyTextButton, optional): The copy text button to add to the button.
27
+ web_app (WebAppInfo OR string, optional): The web app to open when the button is clicked.
28
+ copy_text_button (CopyTextButton OR string, optional): The copy text button to add to the button.
29
29
 
30
30
  Returns:
31
31
  InlineKeyboardMarkup: The updated InlineKeyboardMarkup object.
@@ -59,7 +59,14 @@ class InlineKeyboardMarkup:
59
59
  "web_app must be a string URL or an object with to_dict() method."
60
60
  )
61
61
  elif copy_text_button:
62
- button["copy_text"] = {"text": copy_text_button.text}
62
+ if isinstance(copy_text_button, str):
63
+ button["copy_text"] = {"text": copy_text_button}
64
+ elif hasattr(copy_text_button, "text"):
65
+ button["copy_text"] = {"text": copy_text_button.text}
66
+ else:
67
+ raise ValueError(
68
+ "copy_text_button must be a string or an object with a 'text' attribute."
69
+ )
63
70
 
64
71
  if not self.inline_keyboard:
65
72
  self.inline_keyboard.append([])
@@ -24,8 +24,7 @@ if TYPE_CHECKING:
24
24
  from ..client import Client
25
25
  from ..objects.chat import Chat
26
26
  from ..objects.user import User
27
- import asyncio
28
- import aiohttp
27
+ from ..objects.inlinekeyboardmarkup import InlineKeyboardMarkup
29
28
 
30
29
 
31
30
  class Message:
@@ -125,8 +124,11 @@ class Message:
125
124
  reply_markup: Inline keyboard markup
126
125
  **kwargs: Additional keyword arguments
127
126
  """
127
+ self.client: Client = kwargs.get("kwargs", {}).get("client")
128
128
  self.id: int = message_id
129
- self.user: "User" = User(**from_user) if from_user else None
129
+ self.user: "User" = (
130
+ User(**from_user, kwargs={"client": self.client}) if from_user else None
131
+ )
130
132
  self.date: int = date
131
133
  self.chat: Optional["Chat"] = (
132
134
  chat if isinstance(chat, Chat) else Chat(**chat) if chat else None
@@ -153,7 +155,7 @@ class Message:
153
155
  self.successful_payment: Optional["SuccessfulPayment"] = successful_payment
154
156
  self.web_app_data: Optional["WebAppData"] = web_app_data
155
157
  self.reply_markup: Optional["InlineKeyboardMarkup"] = reply_markup
156
- self.client: Client = kwargs.get("kwargs", {}).get("client")
158
+
157
159
 
158
160
  async def reply(
159
161
  self,
@@ -168,13 +170,16 @@ class Message:
168
170
  """
169
171
  if self.chat and self.chat.id:
170
172
  await self.client.send_message(
171
- self.chat.id, text, reply_markup=reply_markup
173
+ self.chat.id,
174
+ text,
175
+ reply_to_message_id=self.id,
176
+ reply_markup=reply_markup,
172
177
  )
173
178
 
174
179
  async def edit(
175
180
  self,
176
181
  text: str,
177
- reply_markup: Union["ReplyKeyboardMarkup", "InlineKeyboardMarkup"] = None,
182
+ reply_markup: Optional[InlineKeyboardMarkup] = None,
178
183
  ):
179
184
  """Edit the current message text.
180
185
 
@@ -216,7 +221,11 @@ class Message:
216
221
  """
217
222
  if self.chat and self.chat.id:
218
223
  await self.client.send_photo(
219
- self.chat.id, photo=photo, caption=caption, reply_markup=reply_markup
224
+ self.chat.id,
225
+ photo=photo,
226
+ caption=caption,
227
+ reply_to_message_id=self.id,
228
+ reply_markup=reply_markup,
220
229
  )
221
230
 
222
231
  async def reply_video(
@@ -234,7 +243,11 @@ class Message:
234
243
  """
235
244
  if self.chat and self.chat.id:
236
245
  await self.client.send_video(
237
- self.chat.id, video=video, caption=caption, reply_markup=reply_markup
246
+ self.chat.id,
247
+ video=video,
248
+ caption=caption,
249
+ reply_to_message_id=self.id,
250
+ reply_markup=reply_markup,
238
251
  )
239
252
 
240
253
  async def reply_audio(
@@ -252,7 +265,11 @@ class Message:
252
265
  """
253
266
  if self.chat and self.chat.id:
254
267
  await self.client.send_audio(
255
- self.chat.id, audio=audio, caption=caption, reply_markup=reply_markup
268
+ self.chat.id,
269
+ audio=audio,
270
+ caption=caption,
271
+ reply_to_message_id=self.id,
272
+ reply_markup=reply_markup,
256
273
  )
257
274
 
258
275
  async def reply_document(
@@ -273,6 +290,7 @@ class Message:
273
290
  self.chat.id,
274
291
  document=document,
275
292
  caption=caption,
293
+ reply_to_message_id=self.id,
276
294
  reply_markup=reply_markup,
277
295
  )
278
296
 
@@ -296,6 +314,7 @@ class Message:
296
314
  self,
297
315
  latitude: float,
298
316
  longitude: float,
317
+ horizontal_accuracy: Optional[float] = None,
299
318
  reply_markup: Union["ReplyKeyboardMarkup", "InlineKeyboardMarkup"] = None,
300
319
  ):
301
320
  """Reply with a location to the current message.
@@ -310,6 +329,8 @@ class Message:
310
329
  self.chat.id,
311
330
  latitude=latitude,
312
331
  longitude=longitude,
332
+ horizontal_accuracy=horizontal_accuracy,
333
+ reply_to_message_id=self.id,
313
334
  reply_markup=reply_markup,
314
335
  )
315
336
 
@@ -331,6 +352,7 @@ class Message:
331
352
  self.chat.id,
332
353
  phone_number=phone_number,
333
354
  first_name=first_name,
355
+ reply_to_message_id=self.id,
334
356
  reply_markup=reply_markup,
335
357
  )
336
358
 
@@ -340,9 +362,7 @@ class Message:
340
362
  description: str,
341
363
  payload: str,
342
364
  provider_token: str,
343
- currency: str,
344
- prices: list,
345
- reply_markup: Union["ReplyKeyboardMarkup", "InlineKeyboardMarkup"] = None,
365
+ prices: list
346
366
  ):
347
367
  """Reply with an invoice to the current message.
348
368
 
@@ -351,7 +371,6 @@ class Message:
351
371
  description: Product description
352
372
  payload: Bot-defined invoice payload
353
373
  provider_token: Payment provider token
354
- currency: Three-letter ISO 4217 currency code
355
374
  prices: Price breakdown (amount in smallest units)
356
375
  reply_markup: Optional keyboard markup
357
376
  """
@@ -362,7 +381,5 @@ class Message:
362
381
  description=description,
363
382
  payload=payload,
364
383
  provider_token=provider_token,
365
- currency=currency,
366
- prices=prices,
367
- reply_markup=reply_markup,
384
+ prices=prices
368
385
  )
pyrobale/objects/user.py CHANGED
@@ -1,20 +1,22 @@
1
- from typing import Optional, Union
2
- from .utils import build_api_url
3
- import asyncio
4
- import aiohttp
1
+ from typing import Optional, TYPE_CHECKING
2
+
3
+ if TYPE_CHECKING:
4
+ from ..client import Client
5
5
 
6
6
 
7
7
  class User:
8
8
  def __init__(
9
9
  self,
10
- id: int,
11
- is_bot: bool,
12
- first_name: str,
13
- last_name: Optional[str],
14
- username: Optional[str],
10
+ id: int = None,
11
+ is_bot: bool = None,
12
+ first_name: str = None,
13
+ last_name: Optional[str] = None,
14
+ username: Optional[str] = None,
15
+ **kwargs
15
16
  ):
16
17
  self.id = id
17
18
  self.is_bot = is_bot
18
19
  self.first_name = first_name
19
20
  self.last_name = last_name
20
21
  self.username = username
22
+ self.client: Optional["Client"] = kwargs.get("client", None)
pyrobale/objects/utils.py CHANGED
@@ -1,4 +1,4 @@
1
- import asyncio
1
+ from ..exceptions import *
2
2
  import aiohttp
3
3
 
4
4
 
@@ -9,13 +9,33 @@ def build_api_url(base: str, endpoint: str) -> str:
9
9
  async def make_post(url: str, data: dict = None, headers: dict = None) -> dict:
10
10
  async with aiohttp.ClientSession() as session:
11
11
  async with session.post(url, json=data, headers=headers) as response:
12
- return await response.json()
12
+ json = await response.json()
13
+ if json['ok']:
14
+ if 'result' in json.keys():
15
+ return json
16
+ else:
17
+ if json['error_code'] == 404:
18
+ raise NotFoundException(f"Error not found 404 : {json['description'] if json['description'] else 'No description returned in error'}")
19
+ elif json['error_code'] == 403:
20
+ raise ForbiddenException(f"Error Forbidden 403 : {json['description'] if json['description'] else 'No description returned in error'}")
21
+ else:
22
+ raise PyroBaleException(f"unknown error : {json['description'] if json['description'] else 'No description!'}")
13
23
 
14
24
 
15
25
  async def make_get(url: str, headers: dict = None) -> dict:
16
26
  async with aiohttp.ClientSession() as session:
17
27
  async with session.get(url, headers=headers) as response:
18
- return await response.json()
28
+ json = await response.json()
29
+ if json['ok']:
30
+ if 'result' in json.keys():
31
+ return json
32
+ else:
33
+ if json['error_code'] == 404:
34
+ raise NotFoundException(f"Error not found 404 : {json['description'] if json['description'] else 'No description returned in error'}")
35
+ elif json['error_code'] == 403:
36
+ raise ForbiddenException(f"Error Forbidden 403 : {json['description'] if json['description'] else 'No description returned in error'}")
37
+ else:
38
+ raise PyroBaleException(f"unknown error : {json['description'] if json['description'] else 'No description'}")
19
39
 
20
40
 
21
41
  def pythonize(dictionary: dict) -> dict:
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyrobale
3
+ Version: 0.3.8
4
+ Summary: A python wrapper for bale api
5
+ Project-URL: github, https://github.com/pyrobale/pyrobale
6
+ Project-URL: website, https://pyrobale.github.io
7
+ Author-email: Ali Safamanesh <darg.q.a.a@gmail.com>, Aydin Rahbaran <codewizaard9@gmail.com>
8
+ License: MIT License
9
+
10
+ Copyright (c) 2025 PyroBale Team
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ License-File: LICENSE
30
+ Classifier: License :: OSI Approved :: MIT License
31
+ Classifier: Operating System :: OS Independent
32
+ Classifier: Programming Language :: Python :: 3
33
+ Requires-Python: >=3.9
34
+ Requires-Dist: aiohttp
35
+ Description-Content-Type: text/markdown
36
+
37
+ ![pyrobaletext](https://raw.githubusercontent.com/pyrobale/pyrobale/refs/heads/main/pyrobaletext.png)
38
+
39
+ # Bale Bot API Python Library
40
+
41
+ A modern, easy-to-use Python wrapper for the Bale Bot API that makes building Bale bots simple and intuitive.
42
+
43
+ ## Features
44
+
45
+ - 🚀 **Simple & Intuitive** - Clean, Pythonic API design
46
+ - 📨 **Full Message Support** - Text, photos, videos, documents, and more
47
+ - ⌨️ **Interactive Elements** - Inline keyboards, reply keyboards, and buttons
48
+ - 🔄 **Real-time Updates** - Webhook and polling support
49
+ - 📁 **File Handling** - Easy upload and download of media files
50
+ - 🛡️ **Error Handling** - Comprehensive exception handling
51
+ - 📖 **Type Hints** - Full typing support for better development experience
52
+ - ⚡ **Async Support** - asynchronous operations
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ pip install pyrobale
58
+ ```
59
+
60
+ ## Quick Start
61
+
62
+ ```python
63
+ from pyrobale.client import Client
64
+ from pyrobale.objects import Message, UpdatesTypes
65
+
66
+ bot = Client("YOUR_BOT_TOKEN")
67
+
68
+ @bot.on_message()
69
+ async def message_handler(message: Message):
70
+ await message.reply("Hello, world!")
71
+
72
+ bot.run()
73
+ ```
74
+
75
+ ## Examples
76
+
77
+ ### Conversation Bot
78
+ ```python
79
+ from pyrobale.objects import *
80
+ from pyrobale.client import Client, Message, UpdatesTypes
81
+
82
+ client = Client("YOUR_BOT_TOKEN")
83
+
84
+ async def handle_message(message: Message):
85
+ if message.text == "/start":
86
+ await message.reply("Hi! Im a pyrobale RoBot!")
87
+ await client.wait_for(UpdatesTypes.MESSAGE)
88
+ await message.reply("Okay! wait_for Test Compeleted")
89
+
90
+ client.add_handler(UpdatesTypes.MESSAGE, handle_message)
91
+
92
+ client.run()
93
+ ```
94
+
95
+ ### Echo Bot
96
+ ```python
97
+ from pyrobale.client import Client
98
+ from pyrobale.objects import Message, UpdatesTypes
99
+
100
+ bot = Client("YOUR_BOT_TOKEN")
101
+
102
+ @bot.on_message()
103
+ async def message_handler(message: Message):
104
+ await message.reply(message.text)
105
+
106
+ bot.run()
107
+ ```
108
+
109
+ ### Inline Keyboard
110
+ ```python
111
+ from pyrobale.client import Client
112
+ from pyrobale.objects import Message, UpdatesTypes, InlineKeyboardButton, InlineKeyboardMarkup, CopyTextButton
113
+
114
+ bot = Client("YOUR_BOT_TOKEN")
115
+ async def message_handler(message: Message):
116
+ buttons = InlineKeyboardMarkup()
117
+ buttons.add_button("URL", url="https://google.com")
118
+ buttons.add_button("Callback", callback_data="callback")
119
+ buttons.add_row()
120
+ buttons.add_button("WebApp", web_app="https://daradege.ir")
121
+ buttons.add_button("Copy", copy_text_button=CopyTextButton("TEXT"))
122
+ await message.reply("Hello, world!", reply_markup=buttons)
123
+ ```
124
+
125
+
126
+ ## Core Abilities
127
+
128
+ - **Message Handling** - Process text, commands, and media messages
129
+ - **Callback Queries** - Handle inline keyboard interactions
130
+ - **File Operations** - Send and receive photos, videos, documents
131
+ - **Chat Management** - Get chat info, member management
132
+ - **Custom Keyboards** - Create interactive user interfaces
133
+ - **Webhook Support** - Production-ready webhook handling
134
+ - **Middleware Support** - Add custom processing layers
135
+
136
+ ## Documentation
137
+
138
+ For detailed documentation and advanced usage, visit our [documentation site](https://pyrobale.readthedocs.io).
139
+
140
+ ## Contributing
141
+
142
+ Contributions are welcome! Please feel free to submit a Pull Request.
143
+
144
+ ## License
145
+
146
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
147
+
148
+ ## Support
149
+
150
+ - 📖 [Documentation](https://pyrobale.readthedocs.io)
151
+ - 🐛 [Issue Tracker](https://github.com/pyrobale/pyrobale/issues)
152
+ - 💬 [Discussions](https://github.com/pyrobale/pyrobale/discussions)
@@ -1,28 +1,32 @@
1
- pyrobale/__init__.py,sha256=JHnoAuKziwl7pysBJLpmXDN4YoKeDXhiL6joscEFh_Y,78
2
- pyrobale/client/__init__.py,sha256=ehsCuqAVpJuXzwolZCCcySHZZJawqNT-yr2LIgP52II,21104
3
- pyrobale/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- pyrobale/exceptions/common.py,sha256=waAfMFzCsrDr9lS11N0Yzs2v1BX_2ucwV15K1Dq9tYA,159
5
- pyrobale/objects/__init__.py,sha256=cQP_MKQH4WeJPjhQHt864jUFEBw7jOwIh2w5pCUbbUE,2132
1
+ pyrobale/__init__.py,sha256=tC4gr6RIg4tYdzoBDFQCU2CDigXytc-MQ7yH6BJzTzM,3651
2
+ pyrobale/StateMachine/__init__.py,sha256=TRCBwcr4UlnpU2Olik0vOtNASUOK7_O6RMAG6RrVYlM,1911
3
+ pyrobale/client/__init__.py,sha256=xl7TyimdjJLLEPmhpRGV_0-JIN8hCPISmYwle7a6eSI,45539
4
+ pyrobale/exceptions/__init__.py,sha256=oa412OuokRm9Vf3XlCJLqpZjz9ZcuxAKxnEBvOK7u2M,21
5
+ pyrobale/exceptions/common.py,sha256=6ubWjGNmbRbNuzM_ohPuLvGhLdCiCZ-RscEERnv3JMA,273
6
+ pyrobale/filters/__init__.py,sha256=Q-VFK1U5W9jMWneAqNLNlYSTZI2gjnAkwA-lcqF9GbU,55
7
+ pyrobale/filters/enum_filters.py,sha256=5kVtmZ1dCbhUx-_T7tPFbgx8KxAz0W3clwCjOvZy5R0,239
8
+ pyrobale/filters/func_filters.py,sha256=C4cIckRkHk5ISvWFdrvLVFZPmYA1nuNCzC84BpEdkc0,523
9
+ pyrobale/objects/__init__.py,sha256=uy0xBJc5d-1TnlPD6CgxAaUjBnIvQs-GuAgLeEKoXSQ,2239
6
10
  pyrobale/objects/animation.py,sha256=jpM9V8AOaGLWkcENTDmsxKf57Abf-MArYBLfU6GwkD0,978
7
11
  pyrobale/objects/audio.py,sha256=q14wz5WpC3SgKZkAlH-D9M554RYQNDwuCT2z7v7IZYU,696
8
- pyrobale/objects/callbackquery.py,sha256=VlogbysCpdPjAIvrF6CvcJeSUco4WKPXjrvUprEaF1g,1281
12
+ pyrobale/objects/callbackquery.py,sha256=jALmTVXU6tc6OppTTrhGERCzugzazYrT39AhhGE-UeI,1018
9
13
  pyrobale/objects/chat.py,sha256=gQ1wpmB63Ot51aeSBAiWzbw9lFgCpJjlm9hlYNBQJ88,16566
10
- pyrobale/objects/chatmember.py,sha256=CyoX4R4vkNoPjki7U4tgslmEc51g1nn9Q7tUyPeHa58,6868
14
+ pyrobale/objects/chatmember.py,sha256=IyAGmuZZ5HlJVYjrfXEKbLoNc7etMytrK-gOeKKo0CU,6895
11
15
  pyrobale/objects/chatphoto.py,sha256=vOb5xzpr3oBiCloi2_ufBnVlUfmcPqSTmMMMTTBYdJo,533
12
16
  pyrobale/objects/contact.py,sha256=6LDxT5RoGbY5Tsw64lg5-jvKSRmmvOiIJha1HqdTaG4,411
13
17
  pyrobale/objects/copytextbutton.py,sha256=CbFWeY9Ebor7dnHJpQUMB1zYhJWl7b5a2T_cdmo1qQ0,134
14
18
  pyrobale/objects/document.py,sha256=cI9_McPzySNKZaQmOma9eX75a3YsyzkVrLvUBDIuwsA,661
15
- pyrobale/objects/enums.py,sha256=O7n5ErPGuhGMd-JdOgJvCqV5q5ukZ2xNsUb0RoEtboA,554
19
+ pyrobale/objects/enums.py,sha256=-8SQ6jvAk4n5oYTSU--E3rZ2kGABy51SbK9QruMQf-Y,720
16
20
  pyrobale/objects/file.py,sha256=4PBfjouP0knd1vFDNs7mx_jwBoDQVBKS7ESjzF4Y6E8,360
17
21
  pyrobale/objects/inlinekeyboardbutton.py,sha256=w4HehdisD7RQodS66gG-DJjaf0gO2U-6wYaVXaatTN8,617
18
- pyrobale/objects/inlinekeyboardmarkup.py,sha256=shNpYUT25EqT0PQFa-c1tEma_6mJIpBwXQ0IqcTGg4M,2887
22
+ pyrobale/objects/inlinekeyboardmarkup.py,sha256=pMcJDCI3iTvn7OZFPOCV_xnsq9Atx7ixdfKyObdGG1M,3254
19
23
  pyrobale/objects/inputfile.py,sha256=vjw96uJZzp4UargWd2p3OQKyvTpHu2PH_dR_RwwshRI,621
20
24
  pyrobale/objects/inputmedias.py,sha256=2h5YKWNjrrLD1QKZ5J_iOfpCZIRpAZST9q7eBd8edo0,6248
21
25
  pyrobale/objects/invoice.py,sha256=hI225mtsSSV7fYre6aFHp-o1NxUT8MLugJAD6NfAeIs,375
22
26
  pyrobale/objects/keyboardbutton.py,sha256=J7c1ma7swjk3zkgcD7vnMdIMsBGExicmbm1bnP_puzU,459
23
27
  pyrobale/objects/labeledprice.py,sha256=d-fbOLzpkBslfor13BXGeVoySKCcSxsXY4QVwub2Z9o,228
24
28
  pyrobale/objects/location.py,sha256=w_9sRJRntLpNbn8Jk6JhRJVVigD9Bd4BxbjFyglxWhU,143
25
- pyrobale/objects/message.py,sha256=5mtVEsC6j8LkwW834IHTEl4AGvoFbKDURjAAV6YUP3E,14094
29
+ pyrobale/objects/message.py,sha256=cCe0qU0ClGc66S7tW6TexnDzqyAafeKgN_h0h8UZMfs,14532
26
30
  pyrobale/objects/messageid.py,sha256=DrWKV8y9m9H8G_Fj68KgiJKwDJOGduNJGJ-Dyn8N580,95
27
31
  pyrobale/objects/photosize.py,sha256=I4hnmi46uoU-cW7hPN_tTT9kn0u80BtG5QJ3uRjoUiE,298
28
32
  pyrobale/objects/precheckoutquery.py,sha256=Rtjh1qqRc9TRZMJU1W5r0B8y7K5dayLMXX6WH9h1Ul4,470
@@ -31,13 +35,13 @@ pyrobale/objects/sticker.py,sha256=yLzWAm1fikMVISExdCG0R-rVu1_M31LLw6sHt0sBehE,3
31
35
  pyrobale/objects/stickerset.py,sha256=xlSdlnb5TCzI_MCkB_bJsZPgELVevbO7R3BAYN2jIt8,269
32
36
  pyrobale/objects/successfulpayment.py,sha256=aEAApcd60dByqPw253jEifG_CVsbLYiphB1ep3CEm2E,502
33
37
  pyrobale/objects/update.py,sha256=cDR9hpcC8r4bJjixgMQD84Dg_-8ZrlZq1HninVVVDuQ,716
34
- pyrobale/objects/user.py,sha256=PDPJGq89PARg6Ha38FR1N4ZanpbSMpI_siXh5ZHfsvg,437
35
- pyrobale/objects/utils.py,sha256=WVR6eTXbVzTZeNPgb_qNEyGv7ctppTsuAL2c5x48ljo,861
38
+ pyrobale/objects/user.py,sha256=uCvG3k7rIbGP73fFQt_uy7-shS-BRWAL2aEcCEZWyWY,554
39
+ pyrobale/objects/utils.py,sha256=Odyy6y9wKexYBUrk-iErtrV-iEHHOWw-32yTU_iS_AU,2288
36
40
  pyrobale/objects/video.py,sha256=DuZMGHio_w8yQvi87Vc3XpJOpEaltkM4_bNRSeocPZo,509
37
41
  pyrobale/objects/voice.py,sha256=ZdsJFH2IsBwelEk4rb4oZfX9xrfJ2_DgfjsMc0e4Tmg,148
38
42
  pyrobale/objects/webappdata.py,sha256=QlZlCa8Mylt8VmcdgdoHeyita5CVnz2WsT1yueEY1tY,78
39
43
  pyrobale/objects/webappinfo.py,sha256=qnTvfNqx91Yzbc1gO5y4XQ3w6g0RpMUqMuF5wk_EZMc,75
40
- pyrobale-0.3.5.dist-info/METADATA,sha256=Z_bbIivEemBz3HVdg0-X0ObOp4im-VRF1KABsveI7C4,4214
41
- pyrobale-0.3.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
42
- pyrobale-0.3.5.dist-info/licenses/LICENSE,sha256=F8U4JY2aXNJspsrcVW0zf6watzK22FMPTF3NkS36tss,1070
43
- pyrobale-0.3.5.dist-info/RECORD,,
44
+ pyrobale-0.3.8.dist-info/METADATA,sha256=386ZydRqEYd61G8-SgfJH_3eTz4YnNFgcb0l-nhp80A,5262
45
+ pyrobale-0.3.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
46
+ pyrobale-0.3.8.dist-info/licenses/LICENSE,sha256=rf_1ZkId-bcjw1kHBq6bV5t5TVob3RgjUyjfKr1CHAk,1070
47
+ pyrobale-0.3.8.dist-info/RECORD,,
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Ali Safamanesh
3
+ Copyright (c) 2025 PyroBale Team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.