arpakitlib 1.8.39__py3-none-any.whl → 1.8.41__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.
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "arpakitlib_project_template_version": "5",
3
- "arpakitlib_project_template_subversion": "7"
3
+ "arpakitlib_project_template_subversion": "9"
4
4
  }
@@ -0,0 +1,42 @@
1
+ import fastapi.requests
2
+ from fastapi import APIRouter
3
+
4
+ from project.api.authorize import APIAuthorizeData, api_authorize, require_api_key_dbm_api_authorize_middleware, \
5
+ require_user_token_dbm_api_authorize_middleware
6
+ from project.api.schema.common import BaseRouteSO
7
+ from project.api.schema.out.common.error import ErrorCommonSO
8
+ from project.api.schema.out.common.raw_data import RawDataCommonSO
9
+ from project.core.settings import get_cached_settings
10
+ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
11
+
12
+
13
+ class GetSettingsRouteSO(BaseRouteSO, RawDataCommonSO):
14
+ pass
15
+
16
+
17
+ api_router = APIRouter()
18
+
19
+
20
+ @api_router.get(
21
+ "",
22
+ name="Get settings",
23
+ status_code=fastapi.status.HTTP_200_OK,
24
+ response_model=GetSettingsRouteSO | ErrorCommonSO,
25
+ )
26
+ async def _(
27
+ *,
28
+ request: fastapi.requests.Request,
29
+ response: fastapi.responses.Response,
30
+ api_auth_data: APIAuthorizeData = fastapi.Depends(api_authorize(middlewares=[
31
+ require_api_key_dbm_api_authorize_middleware(
32
+ require_active=True
33
+ ),
34
+ require_user_token_dbm_api_authorize_middleware(
35
+ require_active_user_token=True,
36
+ require_user_roles=[UserDBM.Roles.admin]
37
+ )
38
+ ]))
39
+ ):
40
+ return GetSettingsRouteSO(
41
+ data=get_cached_settings().model_dump(mode="json")
42
+ )
@@ -3,7 +3,7 @@ from fastapi import APIRouter
3
3
  from project.api.router.admin import get_auth_data, get_arpakitlib_project_template_info, raise_fake_error, \
4
4
  reinit_sqlalchemy_db, get_story_log, init_sqlalchemy_db, get_sqlalchemy_db_table_name_to_amount, \
5
5
  get_operation_allowed_statuses, get_operation, create_operation, get_operation_allowed_types, get_log_file, \
6
- clear_log_file, check_sqlalchemy_db
6
+ clear_log_file, check_sqlalchemy_db, get_settings
7
7
 
8
8
  main_admin_api_router = APIRouter()
9
9
 
@@ -76,3 +76,8 @@ main_admin_api_router.include_router(
76
76
  router=check_sqlalchemy_db.api_router,
77
77
  prefix="/check_sqlalchemy_db"
78
78
  )
79
+
80
+ main_admin_api_router.include_router(
81
+ router=get_settings.api_router,
82
+ prefix="/get_settings"
83
+ )
@@ -1,13 +1,10 @@
1
1
  import asyncio
2
2
 
3
- import sqlalchemy
4
-
5
- from project.sqlalchemy_db_.sqlalchemy_model import SimpleDBM
3
+ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
6
4
 
7
5
 
8
6
  def __sandbox():
9
- a = sqlalchemy.inspect(SimpleDBM)
10
- print(a)
7
+ print(UserDBM.Roles.admin)
11
8
 
12
9
 
13
10
  async def __async_sandbox():
@@ -1,14 +1,15 @@
1
1
  import logging
2
2
 
3
3
  import fastapi
4
+ import sqlalchemy
4
5
  from sqladmin.authentication import AuthenticationBackend
5
6
 
6
- from arpakitlib.ar_str_util import make_none_if_blank
7
+ from arpakitlib.ar_str_util import make_none_if_blank, strip_if_not_none
7
8
  from project.core.settings import get_cached_settings
8
9
  from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
9
10
  from project.sqlalchemy_db_.sqlalchemy_model import UserTokenDBM, UserDBM
10
11
 
11
- SQLADMIN_AUTH_KEY = "sqladmin_auth_key"
12
+ SQLADMIN_AUTHORIZE_KEY = "sqladmin_authorize_key"
12
13
 
13
14
 
14
15
  class SQLAdminAuth(AuthenticationBackend):
@@ -19,15 +20,8 @@ class SQLAdminAuth(AuthenticationBackend):
19
20
  async def login(self, request: fastapi.Request) -> bool:
20
21
  form = await request.form()
21
22
 
22
- username = form.get("username")
23
- if username:
24
- username = username.strip()
25
- username = make_none_if_blank(username)
26
-
27
- password = form.get("password")
28
- if password:
29
- password = password.strip()
30
- password = make_none_if_blank(password)
23
+ username = make_none_if_blank(strip_if_not_none(form.get("username")))
24
+ password = make_none_if_blank(strip_if_not_none(form.get("password")))
31
25
 
32
26
  if (
33
27
  get_cached_settings().sqladmin_authorize_keys is not None
@@ -43,23 +37,46 @@ class SQLAdminAuth(AuthenticationBackend):
43
37
  )
44
38
  ):
45
39
  if is_username_correct is True:
46
- request.session.update({SQLADMIN_AUTH_KEY: username})
40
+ request.session.update({SQLADMIN_AUTHORIZE_KEY: username})
47
41
  elif is_password_correct is True:
48
- request.session.update({SQLADMIN_AUTH_KEY: password})
42
+ request.session.update({SQLADMIN_AUTHORIZE_KEY: password})
49
43
  return True
50
44
 
51
45
  if get_cached_sqlalchemy_db() is not None and (username is not None or password is not None):
52
46
  with get_cached_sqlalchemy_db().new_session() as session:
53
- query = session.query(UserTokenDBM)
47
+ query = session.query(UserTokenDBM).filter(UserTokenDBM.is_active == True)
54
48
  if username is not None:
55
49
  query = query.filter(UserTokenDBM.value == username)
56
50
  elif password is not None:
57
51
  query = query.filter(UserTokenDBM.value == password)
52
+ else:
53
+ raise ValueError("no username and no password")
58
54
  user_token = query.one_or_none()
59
55
  if user_token is not None and user_token.user.compare_roles(UserDBM.Roles.admin):
60
- request.session.update({SQLADMIN_AUTH_KEY: user_token.value})
56
+ request.session.update({SQLADMIN_AUTHORIZE_KEY: user_token.value})
61
57
  return True
62
58
 
59
+ if get_cached_sqlalchemy_db() is not None and (username is not None and password is not None):
60
+ query = session.query(UserDBM)
61
+ query = query.filter(UserDBM.is_active == True)
62
+ _or_conditions = [
63
+ UserDBM.long_id == username,
64
+ UserDBM.slug == username,
65
+ UserDBM.email == username,
66
+ ]
67
+ if username.isdigit():
68
+ _or_conditions.append(UserDBM.id == int(username))
69
+ query = query.filter(sqlalchemy.or_(*_or_conditions))
70
+ query = query.filter(UserDBM.password == password)
71
+ user_dbm: UserDBM | None = query.one_or_none()
72
+ if user_dbm is not None and user_dbm.compare_roles(UserDBM.Roles.admin):
73
+ new_user_token_dbm = UserTokenDBM(user_id=user_dbm.id)
74
+ session.add(new_user_token_dbm)
75
+ session.commit()
76
+ session.refresh(new_user_token_dbm)
77
+ request.session.update({SQLADMIN_AUTHORIZE_KEY: new_user_token_dbm.value})
78
+ return True
79
+
63
80
  return False
64
81
 
65
82
  async def logout(self, request: fastapi.Request) -> bool:
@@ -67,7 +84,7 @@ class SQLAdminAuth(AuthenticationBackend):
67
84
  return True
68
85
 
69
86
  async def authenticate(self, request: fastapi.Request) -> bool:
70
- sqladmin_auth_key = request.session.get(SQLADMIN_AUTH_KEY)
87
+ sqladmin_auth_key = request.session.get(SQLADMIN_AUTHORIZE_KEY)
71
88
  if sqladmin_auth_key:
72
89
  sqladmin_auth_key = sqladmin_auth_key.strip()
73
90
  sqladmin_auth_key = make_none_if_blank(sqladmin_auth_key)
@@ -82,9 +99,11 @@ class SQLAdminAuth(AuthenticationBackend):
82
99
  UserTokenDBM
83
100
  ).filter(
84
101
  UserTokenDBM.value == sqladmin_auth_key
102
+ ).filter(
103
+ UserTokenDBM.is_active == True
85
104
  )
86
- user_token = query.one_or_none()
87
- if user_token is not None and user_token.user.compare_roles(UserDBM.Roles.admin):
105
+ user_token_dbm: UserTokenDBM | None = query.one_or_none()
106
+ if user_token_dbm is not None and user_token_dbm.user.compare_roles(UserDBM.Roles.admin):
88
107
  return True
89
108
 
90
109
  return False
@@ -13,6 +13,7 @@ class UserMV(SimpleMV, model=UserDBM):
13
13
  UserDBM.email,
14
14
  UserDBM.roles,
15
15
  UserDBM.is_active,
16
+ UserDBM.password,
16
17
  UserDBM.tg_id,
17
18
  UserDBM.tg_bot_last_action_dt,
18
19
  UserDBM.tg_data,
@@ -40,6 +40,11 @@ class UserDBM(SimpleDBM):
40
40
  server_default="true",
41
41
  nullable=False
42
42
  )
43
+ password: Mapped[str | None] = mapped_column(
44
+ sqlalchemy.TEXT,
45
+ index=True,
46
+ nullable=True
47
+ )
43
48
  tg_id: Mapped[int | None] = mapped_column(
44
49
  sqlalchemy.BIGINT,
45
50
  unique=True,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arpakitlib
3
- Version: 1.8.39
3
+ Version: 1.8.41
4
4
  Summary: arpakitlib
5
5
  License: Apache-2.0
6
6
  Keywords: arpakitlib,arpakit,arpakit-company,arpakitcompany,arpakit_company
@@ -8,7 +8,7 @@ arpakitlib/_arpakit_project_template_v_5/alembic/env.py,sha256=Qesmnj5A2kB-Doeuf
8
8
  arpakitlib/_arpakit_project_template_v_5/alembic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
9
9
  arpakitlib/_arpakit_project_template_v_5/alembic/versions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  arpakitlib/_arpakit_project_template_v_5/alembic.ini,sha256=8fuyeEvGBiPGbxEFy8ISBV3xX_fgVmuhEGpB10_B5Uo,3733
11
- arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json,sha256=tHWnMtxRMs4bWD1lB84oODv26e4-p2zTK1wpLWHvG9g,97
11
+ arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json,sha256=UxuwFiz4xIUfSWNYNCUUkJPV25uB6wWHtAnFWUT0O3Y,97
12
12
  arpakitlib/_arpakit_project_template_v_5/command/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  arpakitlib/_arpakit_project_template_v_5/command/alembic_history.sh,sha256=OMnDNtHIksGh9iavWnzbtxcudZW4vjdcISsBXvzZSPw,22
14
14
  arpakitlib/_arpakit_project_template_v_5/command/alembic_revision_autogenerate.sh,sha256=yW2i-SBOtBx15Ya0poVQqKkJM5t2JZp06r9AEW-DmGE,46
@@ -103,10 +103,11 @@ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_log_file.p
103
103
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation.py,sha256=bF2IstPPA2I1v29aoPBHsxlQhWI9bzAWBjGfg8lDUpg,2416
104
104
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation_allowed_statuses.py,sha256=gRvpuBo60rDpzBhRtS2ElRjHS9KZqKgJQaiSjoY8BZY,1328
105
105
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation_allowed_types.py,sha256=wACUgyQy4pkVUUKakBUyzxQxW4_3OqA3GShPj5MRWEM,1307
106
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_settings.py,sha256=3CgM2vt17RNetUowzQd3ySCsFWXt9ZU4CcVsYZnt9H4,1361
106
107
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_sqlalchemy_db_table_name_to_amount.py,sha256=6XFnF-Yv2QajvY7OfPphjDDlOVb5xVz8afY6f_-NqWc,1391
107
108
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_story_log.py,sha256=7y2OFyEePVooC6REPII64s_WbEWs3GSltpQLGaBKgQA,2406
108
109
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/init_sqlalchemy_db.py,sha256=PRsYoEfej5qAFspBqqQCDRZXOIwF358QIzh1HuYIDl4,1493
109
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/main_router.py,sha256=7je8zr-0j_myHqBsN9DeB5yP6MzFiIUntEhvlu26Z6M,2125
110
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/main_router.py,sha256=hOpea2gHlVkiHaq4M8_y1kNfrjC7RJ1qk6O4D4q19Jw,2243
110
111
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/raise_fake_error.py,sha256=kMr06QR39XVUoVwUuwJHoQmaWHvlfi2j53ZCMX3CU48,1048
111
112
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/reinit_sqlalchemy_db.py,sha256=oZNxVfGP83uM5WKh0-3uJRCYRuxlSJ7lAtRGOBTg0lM,1509
112
113
  arpakitlib/_arpakit_project_template_v_5/project/api/router/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -197,7 +198,7 @@ arpakitlib/_arpakit_project_template_v_5/project/resource/static/swagger-ui/swag
197
198
  arpakitlib/_arpakit_project_template_v_5/project/resource/static/swagger-ui/swagger-ui.js,sha256=yHKu9z0C2kOO5j9n9D8oQzuBLeEoMGrFcMWQN27V554,339285
198
199
  arpakitlib/_arpakit_project_template_v_5/project/resource/static/swagger-ui/swagger-ui.js.map,sha256=jeX-b8zAm2jsTGGCznrc49McbLKSfXspwECPhEAp0Xc,1159444
199
200
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
200
- arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_1.py,sha256=BSfR1KIpJCpAO7Iyiw591wrbuXa893TkR42tydvJNJ0,287
201
+ arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_1.py,sha256=SJ_VICHmbPL6duwOrT2kRnnH_MQrCvbfMRPTS05wazc,246
201
202
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_2.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
202
203
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_3.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
203
204
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_4.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
@@ -214,7 +215,7 @@ arpakitlib/_arpakit_project_template_v_5/project/site/router/__init__.py,sha256=
214
215
  arpakitlib/_arpakit_project_template_v_5/project/site/router/main_router.py,sha256=J5jNfgd-3OiWTtuubimEUz6wrOogupj9PkUdDmwz-2U,62
215
216
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
216
217
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/add_admin_in_app.py,sha256=JTXLf18DQVsZtoe6yFpZIVJI95rgJofnTe9YKyVwwhQ,851
217
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/admin_authorize.py,sha256=0yL6YIobNvc4SGOV_Hq_NuugoM_b6WD8Pb_0eqgnZHo,3692
218
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/admin_authorize.py,sha256=S5BtbbLEl-D0DlwDPOkWYpjqQhFaUoqvvlElAmbP25c,4937
218
219
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/asgi.py,sha256=DRlRPkcOGXOccfP73oKEXolZTsc5VWdQgEG-qoW03ms,99
219
220
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/create_sqladmin_app.py,sha256=x5F8--5KA4cmTrb6kAAmp6fVd2TiqxPOzxqUkSEhSG4,1298
220
221
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/event.py,sha256=LjAUYNlsX9Sj_QLMzYuTQbbYYbIMHhbsSjTXt-G7lOE,849
@@ -223,7 +224,7 @@ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py
223
224
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/common.py,sha256=US1tueTCPvAdse6TLT6yRLUHbvwGGagApYhFJzE_6Yc,576
224
225
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/operation.py,sha256=ZPoq3SueGJfR_aWk-a6dIHRNmO1Qa-8kHUW0aR4ZW3g,920
225
226
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py,sha256=GMSICxW_A8RTCtoENDEjce-R8GRLKtHa-OU5OLMdH5s,720
226
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py,sha256=k7p-7FMkglydvp8Q9ZiEnFN15pGlfKvxqRywBhG9Yyo,771
227
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py,sha256=LYPqVRpaxmicWV3_STW7Ko56vrdeJizeAINknBN12bM,797
227
228
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py,sha256=OvvWwzZV6QJGt5XL1KPgPSVN5TvBeawgbWSFYX81KUQ,802
228
229
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
229
230
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/const.py,sha256=dcvj5C9E2F2KCsGZPBBncQf_EvVJAC1qQgnyD8P4ZEw,6
@@ -233,7 +234,7 @@ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model
233
234
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/common.py,sha256=xhMxNea8ndjmdsNwp_a9L_VUkkRb8jjVLhczxDasNss,2090
234
235
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/operation.py,sha256=rwLyqChjx_EOsw9nj333NFxZJ1Qpfj9Yz6POO4Wq690,3670
235
236
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/story_log.py,sha256=iarF0bREQAlXlqw0XvTEPkYVAUdRz4idAZEOnqISfCY,1451
236
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py,sha256=zURCFrwmB45gq0QKbDFzFHLv9xdkCXWyVCSTZ9SOBzg,4909
237
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py,sha256=_pqpJ9ClDguwwi-bWaP1BYkT2vgaIaSw_cqvHvQRFKE,5032
237
238
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py,sha256=CRcpUp93WvcFqOsCcLMEVexWMzUYUtImukDZSeBcJtc,1617
238
239
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/util.py,sha256=QSA_nT6aWdtE412-Uj3VTd7yh3dzS4HugDK9FivjTPo,570
239
240
  arpakitlib/_arpakit_project_template_v_5/project/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -368,8 +369,8 @@ arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,40
368
369
  arpakitlib/ar_wata_api_client.py,sha256=gdHOqDbuqxhTjVDtRW1DvkRJLdDofCrOq51GTctzLns,242
369
370
  arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
370
371
  arpakitlib/ar_zabbix_api_client_util.py,sha256=AV7yxzG46blyQQDI-is0BwHfzuZlrkiHOkuOpfzQ90A,7934
371
- arpakitlib-1.8.39.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
372
- arpakitlib-1.8.39.dist-info/METADATA,sha256=xHNeRJ9pc9QohSxVp16CwDlxCiayVi7BHEKXBSUUARM,3477
373
- arpakitlib-1.8.39.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
374
- arpakitlib-1.8.39.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
375
- arpakitlib-1.8.39.dist-info/RECORD,,
372
+ arpakitlib-1.8.41.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
373
+ arpakitlib-1.8.41.dist-info/METADATA,sha256=zuwhjzTci1nBmftTugfwsuVZpCsWrR7v0ordbnWOzRk,3477
374
+ arpakitlib-1.8.41.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
375
+ arpakitlib-1.8.41.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
376
+ arpakitlib-1.8.41.dist-info/RECORD,,