arpakitlib 1.4.0__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/AUTHOR.md +6 -0
- arpakitlib/LICENSE +201 -0
- arpakitlib/NOTICE +2 -0
- arpakitlib/README.md +6 -0
- arpakitlib/__init__.py +0 -0
- arpakitlib/ar_additional_model_util.py +8 -0
- arpakitlib/ar_aiogram_util.py +363 -0
- arpakitlib/ar_arpakit_lib_module_util.py +150 -0
- arpakitlib/ar_arpakit_schedule_uust_api_client.py +527 -0
- arpakitlib/ar_arpakitlib_info.py +11 -0
- arpakitlib/ar_base64_util.py +30 -0
- arpakitlib/ar_base_worker.py +77 -0
- arpakitlib/ar_cache_file.py +124 -0
- arpakitlib/ar_datetime_util.py +38 -0
- arpakitlib/ar_dict_util.py +24 -0
- arpakitlib/ar_dream_ai_api_client.py +120 -0
- arpakitlib/ar_encrypt_and_decrypt_util.py +23 -0
- arpakitlib/ar_enumeration.py +76 -0
- arpakitlib/ar_fastapi_static/redoc/redoc.standalone.js +1826 -0
- arpakitlib/ar_fastapi_static/swagger-ui/favicon-16x16.png +0 -0
- arpakitlib/ar_fastapi_static/swagger-ui/favicon-32x32.png +0 -0
- arpakitlib/ar_fastapi_static/swagger-ui/index.css +16 -0
- arpakitlib/ar_fastapi_static/swagger-ui/index.html +19 -0
- arpakitlib/ar_fastapi_static/swagger-ui/oauth2-redirect.html +79 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-initializer.js +20 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-bundle.js +2 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-bundle.js.map +1 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-es-bundle-core.js +3 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-es-bundle-core.js.map +1 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-es-bundle.js +2 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-es-bundle.js.map +1 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-standalone-preset.js +2 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-standalone-preset.js.map +1 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css +3 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css.map +1 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js +2 -0
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js.map +1 -0
- arpakitlib/ar_fastapi_util.py +294 -0
- arpakitlib/ar_file_storage_in_dir.py +127 -0
- arpakitlib/ar_generate_env_example.py +16 -0
- arpakitlib/ar_hash_util.py +19 -0
- arpakitlib/ar_http_request_util.py +75 -0
- arpakitlib/ar_ip_util.py +50 -0
- arpakitlib/ar_json_db.py +231 -0
- arpakitlib/ar_json_util.py +28 -0
- arpakitlib/ar_jwt_util.py +38 -0
- arpakitlib/ar_list_of_dicts_to_xlsx.py +32 -0
- arpakitlib/ar_list_util.py +26 -0
- arpakitlib/ar_logging_util.py +45 -0
- arpakitlib/ar_mongodb_util.py +143 -0
- arpakitlib/ar_need_type_util.py +58 -0
- arpakitlib/ar_openai_util.py +59 -0
- arpakitlib/ar_parse_command.py +102 -0
- arpakitlib/ar_postgresql_util.py +45 -0
- arpakitlib/ar_run_cmd.py +48 -0
- arpakitlib/ar_safe_sleep.py +23 -0
- arpakitlib/ar_schedule_uust_api_client.py +216 -0
- arpakitlib/ar_sqlalchemy_util.py +124 -0
- arpakitlib/ar_ssh_runner.py +260 -0
- arpakitlib/ar_str_util.py +79 -0
- arpakitlib/ar_type_util.py +82 -0
- arpakitlib/ar_yookassa_api_client.py +224 -0
- arpakitlib/ar_zabbix_util.py +190 -0
- arpakitlib-1.4.0.dist-info/LICENSE +201 -0
- arpakitlib-1.4.0.dist-info/METADATA +327 -0
- arpakitlib-1.4.0.dist-info/NOTICE +2 -0
- arpakitlib-1.4.0.dist-info/RECORD +68 -0
- arpakitlib-1.4.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def convert_base64_string_to_bytes(base64_string: str, raise_for_error: bool = False) -> Optional[bytes]:
|
|
8
|
+
try:
|
|
9
|
+
return base64.b64decode(base64_string)
|
|
10
|
+
except Exception as e:
|
|
11
|
+
if raise_for_error:
|
|
12
|
+
raise e
|
|
13
|
+
return None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def convert_bytes_to_base64_string(bytes_: bytes, raise_for_error: bool = False) -> Optional[str]:
|
|
17
|
+
try:
|
|
18
|
+
return base64.b64encode(bytes_).decode()
|
|
19
|
+
except Exception as e:
|
|
20
|
+
if raise_for_error:
|
|
21
|
+
raise e
|
|
22
|
+
return None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def __example():
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == '__main__':
|
|
30
|
+
__example()
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from abc import ABC
|
|
4
|
+
from datetime import timedelta
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from arpakitlib.ar_safe_sleep import safe_sleep
|
|
8
|
+
|
|
9
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseWorker(ABC):
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
self.worker_name = self.__class__.__name__
|
|
16
|
+
self._logger = logging.getLogger(self.worker_name)
|
|
17
|
+
self.timeout_after_run: float | None = timedelta(seconds=15).total_seconds()
|
|
18
|
+
self.timeout_after_err_in_run: float | None = timedelta(seconds=15).total_seconds()
|
|
19
|
+
|
|
20
|
+
def sync_on_startup(self):
|
|
21
|
+
self._logger.info("sync_on_startup")
|
|
22
|
+
|
|
23
|
+
def sync_run(self):
|
|
24
|
+
raise NotImplementedError()
|
|
25
|
+
|
|
26
|
+
def sync_run_on_error(self, exception: BaseException, kwargs: dict[str, Any]):
|
|
27
|
+
self._logger.info("sync_run_on_error")
|
|
28
|
+
self._logger.exception(exception)
|
|
29
|
+
|
|
30
|
+
def safe_sync_run(self):
|
|
31
|
+
self._logger.info(f"safe_sync_run")
|
|
32
|
+
self.sync_on_startup()
|
|
33
|
+
while True:
|
|
34
|
+
try:
|
|
35
|
+
self.sync_run()
|
|
36
|
+
if self.timeout_after_run is not None:
|
|
37
|
+
safe_sleep(self.timeout_after_run)
|
|
38
|
+
except BaseException as exception:
|
|
39
|
+
self.sync_run_on_error(exception=exception, kwargs={})
|
|
40
|
+
if self.timeout_after_err_in_run is not None:
|
|
41
|
+
safe_sleep(self.timeout_after_err_in_run)
|
|
42
|
+
|
|
43
|
+
async def async_on_startup(self):
|
|
44
|
+
self._logger.info("async_on_startup")
|
|
45
|
+
|
|
46
|
+
async def async_run(self):
|
|
47
|
+
raise NotImplementedError()
|
|
48
|
+
|
|
49
|
+
async def async_run_on_error(self, exception: BaseException, kwargs: dict[str, Any]):
|
|
50
|
+
self._logger.info("async_run_on_error")
|
|
51
|
+
self._logger.exception(exception)
|
|
52
|
+
|
|
53
|
+
async def async_safe_run(self):
|
|
54
|
+
self._logger.info(f"async_safe_run")
|
|
55
|
+
await self.async_on_startup()
|
|
56
|
+
while True:
|
|
57
|
+
try:
|
|
58
|
+
await self.async_run()
|
|
59
|
+
if self.timeout_after_run is not None:
|
|
60
|
+
await asyncio.sleep(self.timeout_after_run)
|
|
61
|
+
except BaseException as exception:
|
|
62
|
+
await self.async_run_on_error(exception=exception, kwargs={})
|
|
63
|
+
if self.timeout_after_err_in_run is not None:
|
|
64
|
+
await asyncio.sleep(self.timeout_after_err_in_run)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def __example():
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
async def __async_example():
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == '__main__':
|
|
76
|
+
__example()
|
|
77
|
+
asyncio.run(__async_example())
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import Optional, Any
|
|
4
|
+
|
|
5
|
+
import pytz
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
from arpakitlib.ar_json_db import JSONDbFile
|
|
9
|
+
from arpakitlib.ar_type_util import raise_for_type
|
|
10
|
+
|
|
11
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CacheBlock(BaseModel):
|
|
15
|
+
key: str
|
|
16
|
+
data: Any
|
|
17
|
+
last_update_dt: datetime
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CacheFile:
|
|
21
|
+
|
|
22
|
+
def __init__(self, *, json_db_file: JSONDbFile):
|
|
23
|
+
self.json_db_file = json_db_file
|
|
24
|
+
self._logger = logging.getLogger(self.__class__.__name__)
|
|
25
|
+
|
|
26
|
+
def __len__(self) -> int:
|
|
27
|
+
return self.json_db_file.count_records()
|
|
28
|
+
|
|
29
|
+
def __str__(self) -> str:
|
|
30
|
+
return f"CacheFile ({self.json_db_file.filepath}) ({self.json_db_file.count_records()})"
|
|
31
|
+
|
|
32
|
+
def __repr__(self) -> str:
|
|
33
|
+
return f"CacheFile ({self.json_db_file.filepath}) ({self.json_db_file.count_records()})"
|
|
34
|
+
|
|
35
|
+
def create_block(
|
|
36
|
+
self,
|
|
37
|
+
*,
|
|
38
|
+
key: str,
|
|
39
|
+
data: Any,
|
|
40
|
+
last_update_dt: Optional[datetime] = None
|
|
41
|
+
) -> CacheBlock:
|
|
42
|
+
raise_for_type(key, str)
|
|
43
|
+
|
|
44
|
+
if last_update_dt is None:
|
|
45
|
+
last_update_dt = datetime.now(tz=pytz.UTC)
|
|
46
|
+
raise_for_type(last_update_dt, datetime)
|
|
47
|
+
last_update_dt = last_update_dt.astimezone(tz=pytz.UTC)
|
|
48
|
+
|
|
49
|
+
_, record = self.json_db_file.create_record(
|
|
50
|
+
record_id=key,
|
|
51
|
+
record={
|
|
52
|
+
"data": data,
|
|
53
|
+
"last_update_dt": last_update_dt.isoformat()
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return CacheBlock(
|
|
58
|
+
key=key,
|
|
59
|
+
data=record["data"],
|
|
60
|
+
last_update_dt=datetime.fromisoformat(record["last_update_dt"])
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def get_block(self, key: str) -> Optional[CacheBlock]:
|
|
64
|
+
raise_for_type(key, str)
|
|
65
|
+
|
|
66
|
+
record = self.json_db_file.get_record(record_id=key)
|
|
67
|
+
if record is None:
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
return CacheBlock(
|
|
71
|
+
key=key,
|
|
72
|
+
data=record["data"],
|
|
73
|
+
last_update_dt=datetime.fromisoformat(record["last_update_dt"])
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
def get_blocks(self) -> list[CacheBlock]:
|
|
77
|
+
return [
|
|
78
|
+
CacheBlock(
|
|
79
|
+
key=record_id,
|
|
80
|
+
data=record["data"],
|
|
81
|
+
last_update_dt=datetime.fromisoformat(record["last_update_dt"])
|
|
82
|
+
)
|
|
83
|
+
for record_id, record in self.json_db_file.get_records()
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
def update_block(
|
|
87
|
+
self,
|
|
88
|
+
*,
|
|
89
|
+
key: str,
|
|
90
|
+
data: Optional[dict[str, Any]] = None,
|
|
91
|
+
last_update_dt: Optional[datetime] = None
|
|
92
|
+
) -> CacheBlock:
|
|
93
|
+
raise_for_type(key, str)
|
|
94
|
+
record = self.json_db_file.get_record(record_id=key)
|
|
95
|
+
if record is None:
|
|
96
|
+
raise ValueError(f"block (key='{key}') not exists")
|
|
97
|
+
|
|
98
|
+
if data is not None:
|
|
99
|
+
raise_for_type(data, dict)
|
|
100
|
+
record["data"] = data
|
|
101
|
+
|
|
102
|
+
if last_update_dt is not None:
|
|
103
|
+
raise_for_type(last_update_dt, datetime)
|
|
104
|
+
last_update_dt = last_update_dt.astimezone(tz=pytz.UTC)
|
|
105
|
+
record["last_update_dt"] = last_update_dt.isoformat()
|
|
106
|
+
|
|
107
|
+
self.json_db_file.update_record(record_id=key, record=record)
|
|
108
|
+
|
|
109
|
+
return self.get_block(key=key)
|
|
110
|
+
|
|
111
|
+
def remove_block(self, key: str):
|
|
112
|
+
raise_for_type(key, str)
|
|
113
|
+
self.json_db_file.rm_record(record_id=key)
|
|
114
|
+
|
|
115
|
+
def remove_blocks(self):
|
|
116
|
+
self.json_db_file.rm_all_records()
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def __example():
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
if __name__ == '__main__':
|
|
124
|
+
__example()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from datetime import datetime, date
|
|
2
|
+
|
|
3
|
+
import pytz
|
|
4
|
+
|
|
5
|
+
from arpakitlib.ar_type_util import raise_for_type
|
|
6
|
+
|
|
7
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def convert_dt_tz(dt: datetime, tz_info):
|
|
11
|
+
return dt.astimezone(tz_info)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def convert_dt_tz_to_utc(dt: datetime):
|
|
15
|
+
return convert_dt_tz(dt=dt, tz_info=pytz.UTC)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def now_utc_dt() -> datetime:
|
|
19
|
+
return datetime.now(tz=pytz.UTC)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def birth_date_to_age(*, birth_date: date, raise_if_age_negative: bool = False) -> int:
|
|
23
|
+
raise_for_type(birth_date, date)
|
|
24
|
+
now_utc_dt_date = now_utc_dt().date()
|
|
25
|
+
res = now_utc_dt_date.year - birth_date.year
|
|
26
|
+
if (now_utc_dt_date.month, now_utc_dt_date.day) < (birth_date.month, birth_date.day):
|
|
27
|
+
res -= 1
|
|
28
|
+
if raise_if_age_negative and res < 0:
|
|
29
|
+
raise ValueError("raise_if_negative and res < 0")
|
|
30
|
+
return res
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def __example():
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
if __name__ == '__main__':
|
|
38
|
+
__example()
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def combine_dicts(*dicts: dict) -> dict:
|
|
7
|
+
res = {}
|
|
8
|
+
for dict_ in dicts:
|
|
9
|
+
res.update(dict_)
|
|
10
|
+
return res
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def replace_dict_key(*, dict_: dict, old_key: Any, new_key: Any):
|
|
14
|
+
if old_key in dict_:
|
|
15
|
+
dict_[new_key] = dict_.pop(old_key)
|
|
16
|
+
return dict_
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def __example():
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if __name__ == '__main__':
|
|
24
|
+
__example()
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from asyncio import sleep
|
|
4
|
+
from datetime import timedelta
|
|
5
|
+
from urllib.parse import urljoin
|
|
6
|
+
|
|
7
|
+
import aiohttp
|
|
8
|
+
from aiohttp import ClientResponseError, ClientResponse, ClientTimeout
|
|
9
|
+
from pydantic import ConfigDict, BaseModel
|
|
10
|
+
|
|
11
|
+
from arpakitlib.ar_base64_util import convert_base64_string_to_bytes
|
|
12
|
+
from arpakitlib.ar_json_util import safely_transfer_to_json_str
|
|
13
|
+
|
|
14
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BaseAPIModel(BaseModel):
|
|
18
|
+
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True, from_attributes=True)
|
|
19
|
+
|
|
20
|
+
def simple_json(self) -> str:
|
|
21
|
+
return safely_transfer_to_json_str(self.model_dump(mode="json"))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class GenerateImageFromNumberResApiModel(BaseAPIModel):
|
|
25
|
+
image_filename: str
|
|
26
|
+
image_url: str
|
|
27
|
+
image_base64: str
|
|
28
|
+
|
|
29
|
+
def save_file(self, filepath: str):
|
|
30
|
+
with open(filepath, mode="wb") as f:
|
|
31
|
+
f.write(convert_base64_string_to_bytes(base64_string=self.image_base64))
|
|
32
|
+
return filepath
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class DreamAIAPIClient:
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
*,
|
|
39
|
+
base_url: str = "https://api.dream_ai.arpakit.com/api/v1",
|
|
40
|
+
api_key: str | None = None
|
|
41
|
+
):
|
|
42
|
+
self._logger = logging.getLogger(__name__)
|
|
43
|
+
self.api_key = api_key
|
|
44
|
+
base_url = base_url.strip()
|
|
45
|
+
if not base_url.endswith("/"):
|
|
46
|
+
base_url += "/"
|
|
47
|
+
self.base_url = base_url
|
|
48
|
+
self.headers = {"Content-Type": "application/json"}
|
|
49
|
+
if api_key is not None:
|
|
50
|
+
self.headers.update({"apikey": api_key})
|
|
51
|
+
|
|
52
|
+
async def _async_make_request(self, *, method: str = "GET", url: str, **kwargs) -> ClientResponse:
|
|
53
|
+
max_tries = 7
|
|
54
|
+
tries = 0
|
|
55
|
+
|
|
56
|
+
kwargs["url"] = url
|
|
57
|
+
kwargs["method"] = method
|
|
58
|
+
kwargs["timeout"] = ClientTimeout(total=timedelta(seconds=15).total_seconds())
|
|
59
|
+
kwargs["headers"] = self.headers
|
|
60
|
+
|
|
61
|
+
while True:
|
|
62
|
+
tries += 1
|
|
63
|
+
self._logger.info(f"{method} {url}")
|
|
64
|
+
try:
|
|
65
|
+
async with aiohttp.ClientSession() as session:
|
|
66
|
+
async with session.request(**kwargs) as response:
|
|
67
|
+
await response.read()
|
|
68
|
+
return response
|
|
69
|
+
except Exception as err:
|
|
70
|
+
self._logger.warning(f"{tries}/{max_tries} {err} {method} {url}")
|
|
71
|
+
if tries >= max_tries:
|
|
72
|
+
raise err
|
|
73
|
+
await sleep(timedelta(seconds=0.1).total_seconds())
|
|
74
|
+
continue
|
|
75
|
+
|
|
76
|
+
async def healthcheck(self) -> bool:
|
|
77
|
+
response = await self._async_make_request(method="GET", url=urljoin(self.base_url, "healthcheck"))
|
|
78
|
+
response.raise_for_status()
|
|
79
|
+
json_data = await response.json()
|
|
80
|
+
return json_data["data"]["healthcheck"]
|
|
81
|
+
|
|
82
|
+
async def is_healthcheck_good(self) -> bool:
|
|
83
|
+
try:
|
|
84
|
+
return await self.healthcheck()
|
|
85
|
+
except ClientResponseError:
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
async def auth_healthcheck(self) -> bool:
|
|
89
|
+
response = await self._async_make_request(method="GET", url=urljoin(self.base_url, "auth_healthcheck"))
|
|
90
|
+
response.raise_for_status()
|
|
91
|
+
json_data = await response.json()
|
|
92
|
+
return json_data["data"]["auth_healthcheck"]
|
|
93
|
+
|
|
94
|
+
async def is_auth_healthcheck_good(self) -> bool:
|
|
95
|
+
try:
|
|
96
|
+
return await self.auth_healthcheck()
|
|
97
|
+
except ClientResponseError:
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
async def generate_image_from_number(self, *, number: int) -> GenerateImageFromNumberResApiModel:
|
|
101
|
+
response = await self._async_make_request(
|
|
102
|
+
method="GET", url=urljoin(self.base_url, "generate_image_from_number"),
|
|
103
|
+
params={"number": number}
|
|
104
|
+
)
|
|
105
|
+
response.raise_for_status()
|
|
106
|
+
json_data = await response.json()
|
|
107
|
+
return GenerateImageFromNumberResApiModel.model_validate(json_data)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def __example():
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
async def __async_example():
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
if __name__ == '__main__':
|
|
119
|
+
__example()
|
|
120
|
+
asyncio.run(__async_example())
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from cryptography.fernet import Fernet
|
|
2
|
+
|
|
3
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def generate_secret_key() -> str:
|
|
7
|
+
return Fernet.generate_key().decode()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def encrypt_with_secret_key(string: str, secret_key: str) -> str:
|
|
11
|
+
return Fernet(secret_key.encode()).encrypt(string.encode()).decode()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def decrypt_with_secret_key(string: str, secret_key: str) -> str:
|
|
15
|
+
return Fernet(secret_key.encode()).decrypt(string.encode()).decode()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def __example():
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if __name__ == '__main__':
|
|
23
|
+
__example()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from typing import Union, Iterator, Iterable
|
|
2
|
+
|
|
3
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
|
4
|
+
|
|
5
|
+
ValueType = Union[int, str]
|
|
6
|
+
ValuesForParseType = Union[ValueType, Iterable[ValueType]]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EasyEnumeration:
|
|
10
|
+
@classmethod
|
|
11
|
+
def iter_values(cls) -> Iterator[ValueType]:
|
|
12
|
+
big_dict = {}
|
|
13
|
+
for class_ in reversed(cls.mro()):
|
|
14
|
+
big_dict.update(class_.__dict__)
|
|
15
|
+
big_dict.update(cls.__dict__)
|
|
16
|
+
|
|
17
|
+
keys = list(big_dict.keys())
|
|
18
|
+
|
|
19
|
+
for key in keys:
|
|
20
|
+
|
|
21
|
+
if not isinstance(key, str):
|
|
22
|
+
continue
|
|
23
|
+
|
|
24
|
+
if key.startswith("__") or key.endswith("__"):
|
|
25
|
+
continue
|
|
26
|
+
|
|
27
|
+
value = big_dict[key]
|
|
28
|
+
if type(value) not in [str, int]:
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
yield value
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def values_set(cls) -> set[ValueType]:
|
|
35
|
+
return set(cls.iter_values())
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
def values_list(cls) -> list[ValueType]:
|
|
39
|
+
return list(cls.iter_values())
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
def parse_values(cls, *values: ValuesForParseType, validate: bool = False) -> list[ValueType]:
|
|
43
|
+
res = []
|
|
44
|
+
|
|
45
|
+
for value in values:
|
|
46
|
+
|
|
47
|
+
if isinstance(value, str) or isinstance(value, int):
|
|
48
|
+
if validate is True and value not in cls.values_set():
|
|
49
|
+
raise ValueError(f"validate is True and {value} not in {cls.values_set()}")
|
|
50
|
+
res.append(value)
|
|
51
|
+
|
|
52
|
+
elif isinstance(value, Iterable):
|
|
53
|
+
for value_ in value:
|
|
54
|
+
if isinstance(value_, str) or isinstance(value_, int):
|
|
55
|
+
if validate is True and value_ not in cls.values_set():
|
|
56
|
+
raise ValueError(f"validate is True and {value_} not in {cls.values_set()}")
|
|
57
|
+
res.append(value_)
|
|
58
|
+
else:
|
|
59
|
+
raise TypeError(f"bad type, value={value}, type={type(value)}")
|
|
60
|
+
|
|
61
|
+
else:
|
|
62
|
+
raise TypeError(f"bad type, value={value}, type={type(value)}")
|
|
63
|
+
|
|
64
|
+
return res
|
|
65
|
+
|
|
66
|
+
@classmethod
|
|
67
|
+
def parse_and_validate_values(cls, *values: ValuesForParseType) -> list[ValueType]:
|
|
68
|
+
return cls.parse_values(*values, validate=True)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def __example():
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == '__main__':
|
|
76
|
+
__example()
|