tsf-sh 1.0.1__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,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: tsf-sh
3
+ Version: 1.0.1
4
+ Summary: Асинхронная Python библиотека для работы с tsf.sh API
5
+ Home-page: https://tsf.sh
6
+ Author: Towux
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ Requires-Dist: httpx>=0.24.0
20
+ Dynamic: author
21
+ Dynamic: classifier
22
+ Dynamic: description
23
+ Dynamic: description-content-type
24
+ Dynamic: home-page
25
+ Dynamic: requires-dist
26
+ Dynamic: requires-python
27
+ Dynamic: summary
28
+
29
+ # tsf-sh
30
+
31
+ Асинхронная Python библиотека для работы с [tsf.sh](https://tsf.sh) API - сервисом для сокращения ссылок.
32
+
33
+ ## Установка
34
+
35
+ ```bash
36
+ pip install tsf-sh
37
+ ```
38
+
39
+ ## Требования
40
+
41
+ - Python 3.8+
42
+ - httpx 0.24.0+
43
+
44
+ ## Быстрый старт
45
+
46
+ ```python
47
+ import asyncio
48
+ from tsf_sh import Client
49
+
50
+ async def main():
51
+ # Инициализация клиента
52
+ client = Client(api_key="your-api-key")
53
+
54
+ # Создание короткой ссылки
55
+ link = await client.create_link(
56
+ url="https://example.com",
57
+ ttl_hours=24
58
+ )
59
+ print(f"Создана ссылка: {link.short_url}")
60
+
61
+ # Получение информации о ссылке
62
+ link_info = await client.get_link(link.code)
63
+ print(f"Переходов: {link_info.clicks}")
64
+
65
+ # Закрытие клиента
66
+ await client.close()
67
+
68
+ asyncio.run(main())
69
+ ```
70
+
71
+ ## Использование с контекстным менеджером
72
+
73
+ ```python
74
+ import asyncio
75
+ from tsf_sh import Client
76
+
77
+ async def main():
78
+ async with Client(api_key="your-api-key") as client:
79
+ # Создание ссылки
80
+ link = await client.create_link("https://example.com")
81
+ print(f"Ссылка: {link.short_url}")
82
+
83
+ # Получение списка всех ссылок
84
+ links = await client.get_links()
85
+ print(f"Всего ссылок: {len(links)}")
86
+
87
+ # Получение статистики
88
+ stats = await client.get_stats()
89
+ print(f"Всего переходов: {stats.total_clicks}")
90
+
91
+ asyncio.run(main())
92
+ ```
93
+
94
+ ## API методы
95
+
96
+ ### Создание ссылки
97
+
98
+ ```python
99
+ link = await client.create_link(
100
+ url="https://example.com",
101
+ ttl_hours=24, # Время жизни в часах (1-24)
102
+ password="optional_password" # Опциональный пароль
103
+ )
104
+ ```
105
+
106
+ ### Получение списка ссылок
107
+
108
+ ```python
109
+ links = await client.get_links()
110
+ # Список отсортирован по дате создания (новые первые)
111
+ ```
112
+
113
+ ### Получение информации о ссылке
114
+
115
+ ```python
116
+ link = await client.get_link("abc123")
117
+ print(f"URL: {link.original_url}")
118
+ print(f"Переходов: {link.clicks}")
119
+ print(f"Истекает: {link.expires_datetime}")
120
+ ```
121
+
122
+ ### Удаление ссылки
123
+
124
+ ```python
125
+ await client.delete_link("abc123")
126
+ ```
127
+
128
+ ### Продление времени жизни ссылки
129
+
130
+ ```python
131
+ link = await client.extend_link("abc123", ttl_hours=24)
132
+ # TTL устанавливается от текущего момента
133
+ ```
134
+
135
+ ### Установка пароля
136
+
137
+ ```python
138
+ await client.set_password("abc123", "my_password")
139
+ ```
140
+
141
+ ### Удаление пароля
142
+
143
+ ```python
144
+ await client.remove_password("abc123")
145
+ ```
146
+
147
+ ### Перегенерация кода ссылки
148
+
149
+ ```python
150
+ new_code = await client.reroll_code("abc123")
151
+ print(f"Новый код: {new_code}")
152
+ ```
153
+
154
+ ### Получение статистики
155
+
156
+ ```python
157
+ stats = await client.get_stats()
158
+ print(f"Активных ссылок: {stats.links_count}")
159
+ print(f"Всего переходов: {stats.total_clicks}")
160
+ ```
161
+
162
+ ### Проверка здоровья API
163
+
164
+ ```python
165
+ health = await client.health_check()
166
+ print(f"Статус: {health.status}")
167
+ print(f"Redis: {health.services['redis']}")
168
+ ```
169
+
170
+ ## Модели данных
171
+
172
+ ### Link
173
+
174
+ ```python
175
+ link.code # Код ссылки
176
+ link.short_url # Короткая ссылка
177
+ link.original_url # Оригинальный URL
178
+ link.clicks # Количество переходов
179
+ link.ttl_seconds # Время жизни в секундах
180
+ link.created_at # Unix timestamp создания
181
+ link.expires_at # Unix timestamp истечения
182
+ link.has_password # Наличие пароля
183
+ link.created_datetime # datetime объект для created_at
184
+ link.expires_datetime # datetime объект для expires_at
185
+ link.is_expired # Проверка истечения
186
+ link.remaining_seconds # Оставшееся время жизни
187
+ ```
188
+
189
+ ### LinkStats
190
+
191
+ ```python
192
+ stats.links_count # Количество активных ссылок
193
+ stats.total_clicks # Всего переходов
194
+ ```
195
+
196
+ ### HealthStatus
197
+
198
+ ```python
199
+ health.status # "healthy" или "degraded"
200
+ health.services # Словарь со статусами сервисов
201
+ health.is_healthy # True если API здоров
202
+ ```
203
+
204
+ ## Обработка ошибок
205
+
206
+ Библиотека выбрасывает специфичные исключения для разных типов ошибок:
207
+
208
+ ```python
209
+ from tsf_sh import (
210
+ ValidationError, # 400 - Ошибка валидации
211
+ UnauthorizedError, # 401 - Неверный API ключ
212
+ ForbiddenError, # 403 - Требуется премиум
213
+ NotFoundError, # 404 - Ресурс не найден
214
+ ConflictError, # 409 - Конфликт (ссылка уже существует)
215
+ RateLimitError, # 429 - Превышен лимит запросов
216
+ InternalServerError # 500 - Внутренняя ошибка сервера
217
+ )
218
+
219
+ try:
220
+ link = await client.create_link("invalid-url")
221
+ except ValidationError as e:
222
+ print(f"Ошибка валидации: {e.message}")
223
+ except ConflictError as e:
224
+ print(f"Ссылка уже существует: {e.existing_code}")
225
+ except RateLimitError as e:
226
+ print(f"Лимит превышен. Попробуйте через {e.reset_time} секунд")
227
+ ```
228
+
229
+ ## Получение API ключа
230
+
231
+ API ключ можно получить в Telegram боте [@tsf_sh_bot](https://t.me/tsf_sh_bot) в разделе профиля, но только после покупки премиума. Премиум покупается навсегда.
232
+
233
+ ## Лицензия
234
+
235
+ MIT
236
+
237
+ ## Ссылки
238
+
239
+ - [Документация API](https://tsf.sh/api/docs)
240
+ - [Telegram бот](https://t.me/tsf_sh_bot)
241
+
@@ -0,0 +1,10 @@
1
+ tests/__init__.py,sha256=SsNyijrCMUFgNu0GcJr1MAzRn0hxMd7eYjeYwiVHc_I,59
2
+ tests/test_client.py,sha256=tLbyXAYCS7dqEpihCJdVjSqxySilM2Zj_5XVqN-4OIs,26439
3
+ tsf_sh/__init__.py,sha256=CASxuiCk2ibcsjkPt21Wk8wXqo4zF8wbf1IioX7gDHc,670
4
+ tsf_sh/client.py,sha256=ZRApcPiY6KZbjQlrdSyF6gIi08xsCKsTG3WxUSPCjvA,12550
5
+ tsf_sh/exceptions.py,sha256=pY9yABA2kXL_Zn8OsHc4F3hy_L3HS_KckF3I0MiFp-c,2186
6
+ tsf_sh/models.py,sha256=ZkUb_4dM6jlMHQulKkcxR4c-4KwwGZgNCo1_p9HEgBk,2742
7
+ tsf_sh-1.0.1.dist-info/METADATA,sha256=fNnB3H0cccoj-axOFgEwr3ZWVJs-GmKCPwR7GD20lgA,7319
8
+ tsf_sh-1.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
+ tsf_sh-1.0.1.dist-info/top_level.txt,sha256=JcscsZMfZac3ie7Dd8z-N1wHhuZx3YjdJTJDPsresJs,13
10
+ tsf_sh-1.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ tests
2
+ tsf_sh