arpakitlib 1.8.327__py3-none-any.whl → 1.8.332__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.
Potentially problematic release.
This version of arpakitlib might be problematic. Click here for more details.
- arpakitlib/ar_openai_api_client_util.py +204 -0
- {arpakitlib-1.8.327.dist-info → arpakitlib-1.8.332.dist-info}/METADATA +3 -3
- {arpakitlib-1.8.327.dist-info → arpakitlib-1.8.332.dist-info}/RECORD +7 -6
- /arpakitlib/{ar_safe_func.py → ar_safe_func_util.py} +0 -0
- {arpakitlib-1.8.327.dist-info → arpakitlib-1.8.332.dist-info}/WHEEL +0 -0
- {arpakitlib-1.8.327.dist-info → arpakitlib-1.8.332.dist-info}/entry_points.txt +0 -0
- {arpakitlib-1.8.327.dist-info → arpakitlib-1.8.332.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
import httpx
|
|
7
|
+
from arpakitlib.ar_base64_util import convert_file_to_base64_string
|
|
8
|
+
from openai import OpenAI, AsyncOpenAI
|
|
9
|
+
from openai.types.chat import ChatCompletion
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
https://platform.openai.com/docs/
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class EasyOpenAIAPIClient:
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
*,
|
|
20
|
+
open_ai: OpenAI,
|
|
21
|
+
async_open_ai: AsyncOpenAI
|
|
22
|
+
):
|
|
23
|
+
self._logger = logging.getLogger(self.__class__.__name__)
|
|
24
|
+
|
|
25
|
+
self.open_ai = open_ai
|
|
26
|
+
self.async_open_ai = async_open_ai
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def create_easily(
|
|
30
|
+
cls,
|
|
31
|
+
openai_api_key: str,
|
|
32
|
+
openai_api_base_url: str | None = "https://api.proxyapi.ru/openai/v1"
|
|
33
|
+
) -> EasyOpenAIAPIClient:
|
|
34
|
+
return EasyOpenAIAPIClient(
|
|
35
|
+
open_ai=OpenAI(
|
|
36
|
+
api_key=openai_api_key,
|
|
37
|
+
base_url=openai_api_base_url,
|
|
38
|
+
timeout=httpx.Timeout(
|
|
39
|
+
timeout=300, # общий таймаут
|
|
40
|
+
connect=5, # таймаут подключения
|
|
41
|
+
read=300, # чтение ответа
|
|
42
|
+
write=60, # запись запроса
|
|
43
|
+
pool=10
|
|
44
|
+
)
|
|
45
|
+
),
|
|
46
|
+
async_open_ai=AsyncOpenAI(
|
|
47
|
+
api_key=openai_api_key,
|
|
48
|
+
base_url=openai_api_base_url,
|
|
49
|
+
http_client=httpx.AsyncClient(
|
|
50
|
+
timeout=httpx.Timeout(
|
|
51
|
+
timeout=300,
|
|
52
|
+
connect=5,
|
|
53
|
+
read=300,
|
|
54
|
+
write=60,
|
|
55
|
+
pool=10
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def check_conn(self):
|
|
62
|
+
self.open_ai.models.list()
|
|
63
|
+
|
|
64
|
+
def is_conn_good(self) -> bool:
|
|
65
|
+
try:
|
|
66
|
+
self.check_conn()
|
|
67
|
+
return True
|
|
68
|
+
except Exception as e:
|
|
69
|
+
self._logger.error(e)
|
|
70
|
+
return False
|
|
71
|
+
|
|
72
|
+
async def async_check_conn(self):
|
|
73
|
+
await self.async_open_ai.models.list()
|
|
74
|
+
|
|
75
|
+
async def async_is_conn_good(self) -> bool:
|
|
76
|
+
try:
|
|
77
|
+
await self.async_check_conn()
|
|
78
|
+
return True
|
|
79
|
+
except Exception as e:
|
|
80
|
+
self._logger.error(e)
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
def simple_ask(
|
|
84
|
+
self,
|
|
85
|
+
*,
|
|
86
|
+
prompt: str | None = None,
|
|
87
|
+
text: str,
|
|
88
|
+
model: str = "gpt-4o",
|
|
89
|
+
image_links: str | list[str] | None = None,
|
|
90
|
+
image_filepaths: str | list[str] | None = None
|
|
91
|
+
) -> ChatCompletion:
|
|
92
|
+
if isinstance(image_links, str):
|
|
93
|
+
image_links = [image_links]
|
|
94
|
+
if isinstance(image_filepaths, str):
|
|
95
|
+
image_filepaths = [image_filepaths]
|
|
96
|
+
|
|
97
|
+
messages = []
|
|
98
|
+
|
|
99
|
+
if prompt is not None:
|
|
100
|
+
messages.append({
|
|
101
|
+
"role": "system",
|
|
102
|
+
"content": prompt
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
content = [{"type": "text", "text": text}]
|
|
106
|
+
|
|
107
|
+
if image_links:
|
|
108
|
+
for link in image_links:
|
|
109
|
+
content.append({
|
|
110
|
+
"type": "image_url",
|
|
111
|
+
"image_url": {"url": link}
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
if image_filepaths:
|
|
115
|
+
for path in image_filepaths:
|
|
116
|
+
base64_url = convert_file_to_base64_string(filepath=path, raise_for_error=True)
|
|
117
|
+
content.append({
|
|
118
|
+
"type": "image_url",
|
|
119
|
+
"image_url": {"url": base64_url}
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
messages.append({
|
|
123
|
+
"role": "user",
|
|
124
|
+
"content": content
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
response: ChatCompletion = self.open_ai.chat.completions.create(
|
|
128
|
+
model=model,
|
|
129
|
+
messages=messages,
|
|
130
|
+
n=1,
|
|
131
|
+
temperature=0.1,
|
|
132
|
+
top_p=0.9,
|
|
133
|
+
max_tokens=1000
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
return response
|
|
137
|
+
|
|
138
|
+
async def async_simple_ask(
|
|
139
|
+
self,
|
|
140
|
+
*,
|
|
141
|
+
prompt: str | None = None,
|
|
142
|
+
text: str,
|
|
143
|
+
model: str = "gpt-4o",
|
|
144
|
+
image_links: str | list[str] | None = None,
|
|
145
|
+
image_filepaths: str | list[str] | None = None
|
|
146
|
+
) -> ChatCompletion:
|
|
147
|
+
if isinstance(image_links, str):
|
|
148
|
+
image_links = [image_links]
|
|
149
|
+
if isinstance(image_filepaths, str):
|
|
150
|
+
image_filepaths = [image_filepaths]
|
|
151
|
+
|
|
152
|
+
messages = []
|
|
153
|
+
|
|
154
|
+
if prompt is not None:
|
|
155
|
+
messages.append({
|
|
156
|
+
"role": "system",
|
|
157
|
+
"content": prompt
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
content = [{"type": "text", "text": text}]
|
|
161
|
+
|
|
162
|
+
if image_links:
|
|
163
|
+
for link in image_links:
|
|
164
|
+
content.append({
|
|
165
|
+
"type": "image_url",
|
|
166
|
+
"image_url": {"url": link}
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
if image_filepaths:
|
|
170
|
+
for path in image_filepaths:
|
|
171
|
+
base64_url = convert_file_to_base64_string(filepath=path, raise_for_error=True)
|
|
172
|
+
content.append({
|
|
173
|
+
"type": "image_url",
|
|
174
|
+
"image_url": {"url": base64_url}
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
messages.append({
|
|
178
|
+
"role": "user",
|
|
179
|
+
"content": content
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
response: ChatCompletion = await self.async_open_ai.chat.completions.create(
|
|
183
|
+
model=model,
|
|
184
|
+
messages=messages,
|
|
185
|
+
n=1,
|
|
186
|
+
temperature=0.1,
|
|
187
|
+
top_p=0.9,
|
|
188
|
+
max_tokens=1000
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
return response
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def __example():
|
|
195
|
+
pass
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
async def __async_example():
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
if __name__ == '__main__':
|
|
203
|
+
__example()
|
|
204
|
+
asyncio.run(__async_example())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: arpakitlib
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.332
|
|
4
4
|
Summary: arpakitlib
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
17
17
|
Classifier: Operating System :: OS Independent
|
|
18
18
|
Classifier: Topic :: Software Development :: Libraries
|
|
19
19
|
Requires-Dist: aio-pika (>=9.5.4,<10.0.0)
|
|
20
|
-
Requires-Dist: aiogram (>=3.
|
|
20
|
+
Requires-Dist: aiogram (>=3.22.0,<4.0.0)
|
|
21
21
|
Requires-Dist: aiohttp (>=3.11.16,<4.0.0)
|
|
22
22
|
Requires-Dist: aiohttp-socks (>=0.10.1,<0.11.0)
|
|
23
23
|
Requires-Dist: aiosmtplib (>=4.0.0,<5.0.0)
|
|
@@ -45,7 +45,7 @@ Requires-Dist: pydantic (>=2.10.5,<3.0.0)
|
|
|
45
45
|
Requires-Dist: pydantic-settings (>=2.7.1,<3.0.0)
|
|
46
46
|
Requires-Dist: pyjwt (>=2.10.1,<3.0.0)
|
|
47
47
|
Requires-Dist: pymongo (>=4.10.1,<5.0.0)
|
|
48
|
-
Requires-Dist: pytelegrambotapi (>=4.
|
|
48
|
+
Requires-Dist: pytelegrambotapi (>=4.29.1,<5.0.0)
|
|
49
49
|
Requires-Dist: pytest (>=8.4.2,<9.0.0)
|
|
50
50
|
Requires-Dist: pytz (>=2024.2,<2025.0)
|
|
51
51
|
Requires-Dist: qrcode (>=8.2,<9.0)
|
|
@@ -408,6 +408,7 @@ arpakitlib/ar_log_async_func_if_error_util.py,sha256=8qtcxRk6OqfwVsGE2wCpuIY7fju
|
|
|
408
408
|
arpakitlib/ar_logging_util.py,sha256=8TdaCWeSk4_GAmuWFO49l8JAVfLJCqUxgSpTYvlWvsk,1308
|
|
409
409
|
arpakitlib/ar_mongodb_util.py,sha256=orRb81o9CzD9kkWbbNQCbSMTl2xLcctUDdx_FxirKww,3411
|
|
410
410
|
arpakitlib/ar_need_type_util.py,sha256=XmY1kswz8j9oo5f9CxRu0_zgfvxWrXPYKOj6MM04sGk,2604
|
|
411
|
+
arpakitlib/ar_openai_api_client_util.py,sha256=dIPHNrDRkclRa__qPj7glkv232C97tzAAFEFuXtvV1E,5569
|
|
411
412
|
arpakitlib/ar_parse_command_util.py,sha256=1WTdQoWVshoDZ1jDaKeTzajfqaYHP3FNO0-REyo1aMY,3003
|
|
412
413
|
arpakitlib/ar_postgresql_util.py,sha256=1AuLjEaa1Lg4pzn-ukCVnDi35Eg1k91APRTqZhIJAdo,945
|
|
413
414
|
arpakitlib/ar_pydantic_schema_from_sqlalchemy_model_util.py,sha256=SddmsEdRdVbmdZ5aSuwy6DfGYmYx_JO6lKzuEJeBAV8,10553
|
|
@@ -417,7 +418,7 @@ arpakitlib/ar_really_validate_email_util.py,sha256=HBfhyiDB3INI6Iq6hR2WOMKA5wVWW
|
|
|
417
418
|
arpakitlib/ar_really_validate_url_util.py,sha256=aaSPVMbz2DSqlC2yk2g44-kTIiHlITfJwIG97L-Y93U,1309
|
|
418
419
|
arpakitlib/ar_retry_func_util.py,sha256=LB4FJRsu2cssnPw6X8bCEcaGpQsXhkLkgeU37w1t9fU,2250
|
|
419
420
|
arpakitlib/ar_run_cmd_util.py,sha256=D_rPavKMmWkQtwvZFz-Io5Ak8eSODHkcFeLPzNVC68g,1072
|
|
420
|
-
arpakitlib/
|
|
421
|
+
arpakitlib/ar_safe_func_util.py,sha256=JQNaM3q4Z6nUE8bDfzXNBGkWSXm0PZ-GMMvu6UWUIYk,2400
|
|
421
422
|
arpakitlib/ar_settings_util.py,sha256=FeQQkuVrLVYkFAIg3Wy6ysyTt_sqLTX0REAe60gbM3k,2361
|
|
422
423
|
arpakitlib/ar_sleep_util.py,sha256=ggaj7ML6QK_ADsHMcyu6GUmUpQ_9B9n-SKYH17h-9lM,1045
|
|
423
424
|
arpakitlib/ar_sqladmin_util.py,sha256=SEoaowAPF3lhxPsNjwmOymNJ55Ty9rmzvsDm7gD5Ceo,861
|
|
@@ -428,8 +429,8 @@ arpakitlib/ar_str_util.py,sha256=6KlLL-SB8gzK-6gwQEd3zuYbRvtjd9HFpJ9-xHbkH6U,435
|
|
|
428
429
|
arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,4049
|
|
429
430
|
arpakitlib/ar_uppercase_env_keys_util.py,sha256=BsUCJhfchBIav0AE54_tVgYcE4p1JYoWdPGCHWZnROA,2790
|
|
430
431
|
arpakitlib/ar_yookassa_api_client_util.py,sha256=7DL_0GyIOTuSNBHUO3qWxAXMKlBRHjKgcA6ttst8k1A,5265
|
|
431
|
-
arpakitlib-1.8.
|
|
432
|
-
arpakitlib-1.8.
|
|
433
|
-
arpakitlib-1.8.
|
|
434
|
-
arpakitlib-1.8.
|
|
435
|
-
arpakitlib-1.8.
|
|
432
|
+
arpakitlib-1.8.332.dist-info/METADATA,sha256=EohLsrJDv0HiRnX78HHtdWjNe68iHoddMF-yXxDarQU,3804
|
|
433
|
+
arpakitlib-1.8.332.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
434
|
+
arpakitlib-1.8.332.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
|
|
435
|
+
arpakitlib-1.8.332.dist-info/licenses/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
|
|
436
|
+
arpakitlib-1.8.332.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|