maleo-foundation 0.1.61__py3-none-any.whl → 0.1.62__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,6 +1,8 @@
1
1
  from fastapi import FastAPI
2
2
  from pydantic import BaseModel, Field
3
3
  from typing import List, Optional
4
+ from maleo_foundation.client.manager import MaleoFoundationClientManager
5
+ from maleo_foundation.models.schemas import BaseGeneralSchemas
4
6
  from maleo_foundation.middlewares.authentication import add_authentication_middleware
5
7
  from maleo_foundation.middlewares.base import add_base_middleware, RequestProcessor
6
8
  from maleo_foundation.middlewares.cors import add_cors_middleware
@@ -38,19 +40,24 @@ class MiddlewareLoggers(BaseModel):
38
40
  arbitrary_types_allowed=True
39
41
 
40
42
  class MiddlewareManager:
41
- def __init__(self, app:FastAPI, configurations:MiddlewareConfigurations):
42
- self._app = app
43
- self._configurations = configurations
44
-
45
- def add_all(
43
+ def __init__(
46
44
  self,
45
+ app:FastAPI,
46
+ configurations:MiddlewareConfigurations,
47
+ keys:BaseGeneralSchemas.RSAKeys,
47
48
  loggers:MiddlewareLoggers,
48
- key:str,
49
- request_processor:Optional[RequestProcessor] = None
49
+ maleo_foundation:MaleoFoundationClientManager
50
50
  ):
51
+ self._app = app
52
+ self._configurations = configurations
53
+ self._keys = keys
54
+ self._loggers = loggers
55
+ self._maleo_foundation = maleo_foundation
56
+
57
+ def add_all(self):
51
58
  self.add_cors()
52
- self.add_base(logger=loggers.base, request_processor=request_processor)
53
- self.add_authentication(logger=loggers.authentication, key=key)
59
+ self.add_base()
60
+ self.add_authentication()
54
61
 
55
62
  def add_cors(self) -> None:
56
63
  add_cors_middleware(
@@ -62,10 +69,12 @@ class MiddlewareManager:
62
69
  expose_headers=self._configurations.cors.expose_headers
63
70
  )
64
71
 
65
- def add_base(self, logger:MiddlewareLogger, request_processor:Optional[RequestProcessor] = None):
72
+ def add_base(self):
66
73
  add_base_middleware(
67
74
  app=self._app,
68
- logger=logger,
75
+ key=self._keys,
76
+ logger=self._loggers.base,
77
+ maleo_foundation=self._maleo_foundation,
69
78
  allow_origins=self._configurations.general.allow_origins,
70
79
  allow_methods=self._configurations.general.allow_methods,
71
80
  allow_headers=self._configurations.general.allow_headers,
@@ -73,9 +82,13 @@ class MiddlewareManager:
73
82
  limit=self._configurations.base.limit,
74
83
  window=self._configurations.base.window,
75
84
  cleanup_interval=self._configurations.base.cleanup_interval,
76
- ip_timeout=self._configurations.base.ip_timeout,
77
- request_processor=request_processor
85
+ ip_timeout=self._configurations.base.ip_timeout
78
86
  )
79
87
 
80
- def add_authentication(self, logger:MiddlewareLogger, key:str):
81
- add_authentication_middleware(app=self._app, logger=logger, key=key)
88
+ def add_authentication(self):
89
+ add_authentication_middleware(
90
+ app=self._app,
91
+ key=self._keys,
92
+ logger=self._loggers.authentication,
93
+ maleo_foundation=self._maleo_foundation
94
+ )
@@ -8,13 +8,13 @@ from sqlalchemy import MetaData
8
8
  from typing import Optional
9
9
  from maleo_foundation.client.manager import MaleoFoundationClientManager
10
10
  from maleo_foundation.enums import BaseEnums
11
+ from maleo_foundation.models.schemas.general import BaseGeneralSchemas
11
12
  from maleo_foundation.models.transfers.general.token import BaseTokenGeneralTransfers
12
13
  from maleo_foundation.models.transfers.parameters.token import BaseTokenParametersTransfers
13
14
  from maleo_foundation.managers.db import DatabaseConfigurations, DatabaseManager
14
15
  from maleo_foundation.managers.client.google.secret import GoogleSecretManager
15
16
  from maleo_foundation.managers.client.google.storage import GoogleCloudStorage
16
17
  from maleo_foundation.managers.middleware import MiddlewareConfigurations, BaseMiddlewareConfigurations, CORSMiddlewareConfigurations, GeneralMiddlewareConfigurations, MiddlewareLoggers, MiddlewareManager
17
- from maleo_foundation.middlewares.base import RequestProcessor
18
18
  from maleo_foundation.utils.exceptions import BaseExceptions
19
19
  from maleo_foundation.utils.loaders.json import JSONLoader
20
20
  from maleo_foundation.utils.loaders.yaml import YAMLLoader
@@ -28,11 +28,6 @@ class Settings(BaseSettings):
28
28
  STATIC_CONFIGURATIONS_PATH:str = Field("configs/static.yaml", description="Maleo's static configurations path")
29
29
  RUNTIME_CONFIGURATIONS_PATH:str = Field("configs/runtime.yaml", description="Service's runtime configurations path")
30
30
 
31
- class Keys(BaseModel):
32
- password:str = Field(..., description="Key's password")
33
- private:str = Field(..., description="Private key")
34
- public:str = Field(..., description="Public key")
35
-
36
31
  class GoogleCredentials(BaseModel):
37
32
  type:str = Field(..., description="Credentials type")
38
33
  project_id:str = Field(..., description="Google project ID")
@@ -231,10 +226,10 @@ class ServiceManager:
231
226
  password = self._secret_manager.get(name="maleo-key-password")
232
227
  private = self._secret_manager.get(name="maleo-private-key")
233
228
  public = self._secret_manager.get(name="maleo-public-key")
234
- self._keys = Keys(password=password, private=private, public=public)
229
+ self._keys = BaseGeneralSchemas.RSAKeys(password=password, private=private, public=public)
235
230
 
236
231
  @property
237
- def keys(self) -> Keys:
232
+ def keys(self) -> BaseGeneralSchemas.RSAKeys:
238
233
  return self._keys
239
234
 
240
235
  def _initialize_loggers(self) -> None:
@@ -292,15 +287,21 @@ class ServiceManager:
292
287
  return ""
293
288
  return result.data.token
294
289
 
295
- def create_app(self, router:APIRouter, lifespan:Optional[Lifespan[AppType]] = None, request_processor:Optional[RequestProcessor] = None) -> FastAPI:
290
+ def create_app(self, router:APIRouter, lifespan:Optional[Lifespan[AppType]] = None) -> FastAPI:
296
291
  self._loggers.application.info("Creating FastAPI application")
297
292
  self._app = FastAPI(title=self._configs.service.name, lifespan=lifespan)
298
293
  self._loggers.application.info("FastAPI application created successfully")
299
294
 
300
295
  #* Add middleware(s)
301
296
  self._loggers.application.info("Configuring middlewares")
302
- self._middleware = MiddlewareManager(app=self._app, configurations=self._configs.middleware)
303
- self._middleware.add_all(loggers=self.loggers.middleware, key=self._keys.public, request_processor=request_processor)
297
+ self._middleware = MiddlewareManager(
298
+ app=self._app,
299
+ configurations=self._configs.middleware,
300
+ keys=self._keys,
301
+ loggers=self._loggers.middleware,
302
+ maleo_foundation=self._clients.maleo.foundation
303
+ )
304
+ self._middleware.add_all()
304
305
  self._loggers.application.info("Middlewares addedd successfully")
305
306
 
306
307
  #* Add exception handler(s)
@@ -5,16 +5,16 @@ from starlette.requests import HTTPConnection
5
5
  from typing import Tuple
6
6
  from maleo_foundation.authentication import Credentials, User
7
7
  from maleo_foundation.client.manager import MaleoFoundationClientManager
8
- from maleo_foundation.managers.service import Keys
8
+ from maleo_foundation.models.schemas import BaseGeneralSchemas
9
9
  from maleo_foundation.models.transfers.parameters.token import BaseTokenParametersTransfers
10
10
  from maleo_foundation.utils.extractor import BaseExtractors
11
11
  from maleo_foundation.utils.logging import MiddlewareLogger
12
12
 
13
13
  class Backend(AuthenticationBackend):
14
- def __init__(self, logger:MiddlewareLogger, keys:Keys, maleo_foundation:MaleoFoundationClientManager):
14
+ def __init__(self, keys:BaseGeneralSchemas.RSAKeys, logger:MiddlewareLogger, maleo_foundation:MaleoFoundationClientManager):
15
15
  super().__init__()
16
- self._logger = logger
17
16
  self._keys = keys
17
+ self._logger = logger
18
18
  self._maleo_foundation = maleo_foundation
19
19
 
20
20
  async def authenticate(self, conn:HTTPConnection) -> Tuple[Credentials, User]:
@@ -38,7 +38,7 @@ class Backend(AuthenticationBackend):
38
38
  self._logger.info(f"Request | IP: {client_ip} | URL: {conn.url.path} - Result | Username: {decode_token_result.data.u_u} | Email: {decode_token_result.data.u_e}")
39
39
  return Credentials(token=token), User(authenticated=True, username=decode_token_result.data.u_u, email=decode_token_result.data.u_e)
40
40
 
41
- def add_authentication_middleware(app:FastAPI, logger:MiddlewareLogger, keys:Keys) -> None:
41
+ def add_authentication_middleware(app:FastAPI, keys:BaseGeneralSchemas.RSAKeys, logger:MiddlewareLogger, maleo_foundation:MaleoFoundationClientManager) -> None:
42
42
  """
43
43
  Adds Authentication middleware to the FastAPI application.
44
44
 
@@ -9,7 +9,7 @@ from fastapi.responses import JSONResponse
9
9
  from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
10
10
  from typing import Awaitable, Callable, Optional, Sequence
11
11
  from maleo_foundation.client.manager import MaleoFoundationClientManager
12
- from maleo_foundation.managers.service import Keys
12
+ from maleo_foundation.models.schemas import BaseGeneralSchemas
13
13
  from maleo_foundation.models.responses import BaseResponses
14
14
  from maleo_foundation.models.transfers.parameters.signature import BaseSignatureParametersTransfers
15
15
  from maleo_foundation.utils.extractor import BaseExtractors
@@ -22,8 +22,8 @@ class BaseMiddleware(BaseHTTPMiddleware):
22
22
  def __init__(
23
23
  self,
24
24
  app:FastAPI,
25
+ keys:BaseGeneralSchemas.RSAKeys,
25
26
  logger:MiddlewareLogger,
26
- keys:Keys,
27
27
  maleo_foundation:MaleoFoundationClientManager,
28
28
  allow_origins:Sequence[str] = (),
29
29
  allow_methods:Sequence[str] = ("GET",),
@@ -35,8 +35,8 @@ class BaseMiddleware(BaseHTTPMiddleware):
35
35
  ip_timeout:int = 300
36
36
  ):
37
37
  super().__init__(app)
38
- self._logger = logger
39
38
  self._keys = keys
39
+ self._logger = logger
40
40
  self._maleo_foundation = maleo_foundation
41
41
  self._allow_origins = allow_origins
42
42
  self._allow_methods = allow_methods
@@ -113,12 +113,17 @@ class BaseMiddleware(BaseHTTPMiddleware):
113
113
 
114
114
  return response
115
115
 
116
- def _add_response_headers(self, request:Request, response:Response, request_timestamp:datetime, process_time:int) -> Response:
116
+ def _add_response_headers(
117
+ self,
118
+ request:Request,
119
+ response:Response,
120
+ request_timestamp:datetime,
121
+ response_timestamp:datetime,
122
+ process_time:int
123
+ ) -> Response:
117
124
  response.headers["X-Process-Time"] = str(process_time) #* Add Process Time Header
118
125
  response.headers["X-Request-Timestamp"] = request_timestamp.isoformat() #* Add request timestamp header
119
- #* Define and add response timestamp header
120
- response_timestamp = datetime.now(tz=timezone.utc)
121
- response.headers["X-Response-Timestamp"] = response_timestamp.isoformat()
126
+ response.headers["X-Response-Timestamp"] = response_timestamp.isoformat() #* Define and add response timestamp header
122
127
  #* Generate signature header
123
128
  message = f"{request.method}|{request.url.path}|{request_timestamp.isoformat()}|{response_timestamp.isoformat()}|{str(process_time)}"
124
129
  sign_parameters = BaseSignatureParametersTransfers.Sign(key=self._keys.private, password=self._keys.password, message=message)
@@ -133,11 +138,12 @@ class BaseMiddleware(BaseHTTPMiddleware):
133
138
  request:Request,
134
139
  response:Response,
135
140
  request_timestamp:datetime,
141
+ response_timestamp:datetime,
136
142
  process_time:int,
137
143
  log_level:str = "info",
138
144
  client_ip:str = "unknown"
139
145
  ) -> Response:
140
- response = self._add_response_headers(request, response, request_timestamp, process_time)
146
+ response = self._add_response_headers(request, response, request_timestamp, response_timestamp, process_time)
141
147
  log_func = getattr(self._logger, log_level)
142
148
  log_func(
143
149
  f"Request | IP: {client_ip} | Method: {request.method} | URL: {request.url.path} | "
@@ -145,7 +151,15 @@ class BaseMiddleware(BaseHTTPMiddleware):
145
151
  )
146
152
  return response
147
153
 
148
- def _handle_exception(self, request:Request, error, request_timestamp:datetime, process_time:int, client_ip):
154
+ def _handle_exception(
155
+ self,
156
+ request:Request,
157
+ error,
158
+ request_timestamp:datetime,
159
+ response_timestamp:datetime,
160
+ process_time:int,
161
+ client_ip
162
+ ):
149
163
  traceback_str = traceback.format_exc().split("\n")
150
164
  error_details = {
151
165
  "error": str(error),
@@ -166,7 +180,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
166
180
  f"Headers: {dict(request.headers)} - Response | Status: 500 | Exception:\n{json.dumps(error_details, indent=4)}"
167
181
  )
168
182
 
169
- return self._add_response_headers(request, response, request_timestamp, process_time)
183
+ return self._add_response_headers(request, response, request_timestamp, response_timestamp, process_time)
170
184
 
171
185
  async def _request_processor(self, request:Request) -> Optional[Response]:
172
186
  return None
@@ -187,6 +201,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
187
201
  status_code=status.HTTP_429_TOO_MANY_REQUESTS,
188
202
  ),
189
203
  request_timestamp=request_timestamp,
204
+ response_timestamp=datetime.now(tz=timezone.utc),
190
205
  process_time=time.perf_counter() - start_time,
191
206
  log_level="warning",
192
207
  client_ip=client_ip,
@@ -199,6 +214,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
199
214
  request=request,
200
215
  response=pre_response,
201
216
  request_timestamp=request_timestamp,
217
+ response_timestamp=datetime.now(tz=timezone.utc),
202
218
  process_time=time.perf_counter() - start_time,
203
219
  log_level="info",
204
220
  client_ip=client_ip,
@@ -210,6 +226,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
210
226
  request=request,
211
227
  response=response,
212
228
  request_timestamp=request_timestamp,
229
+ response_timestamp=datetime.now(tz=timezone.utc),
213
230
  process_time=time.perf_counter() - start_time,
214
231
  log_level="info",
215
232
  client_ip=client_ip,
@@ -218,11 +235,20 @@ class BaseMiddleware(BaseHTTPMiddleware):
218
235
  return response
219
236
 
220
237
  except Exception as e:
221
- return self._handle_exception(request, e, request_timestamp, time.perf_counter() - start_time, client_ip)
238
+ return self._handle_exception(
239
+ request=request,
240
+ error=e,
241
+ request_timestamp=request_timestamp,
242
+ response_timestamp=datetime.now(tz=timezone.utc),
243
+ process_time=time.perf_counter() - start_time,
244
+ client_ip=client_ip
245
+ )
222
246
 
223
247
  def add_base_middleware(
224
248
  app:FastAPI,
249
+ keys:BaseGeneralSchemas.RSAKeys,
225
250
  logger:MiddlewareLogger,
251
+ maleo_foundation:MaleoFoundationClientManager,
226
252
  allow_origins:Sequence[str] = (),
227
253
  allow_methods:Sequence[str] = ("GET",),
228
254
  allow_headers:Sequence[str] = (),
@@ -230,8 +256,7 @@ def add_base_middleware(
230
256
  limit:int = 10,
231
257
  window:int = 1,
232
258
  cleanup_interval:int = 60,
233
- ip_timeout:int = 300,
234
- request_processor:Optional[RequestProcessor] = None
259
+ ip_timeout:int = 300
235
260
  ) -> None:
236
261
  """
237
262
  Adds Base middleware to the FastAPI application.
@@ -270,7 +295,9 @@ def add_base_middleware(
270
295
  """
271
296
  app.add_middleware(
272
297
  BaseMiddleware,
298
+ keys=keys,
273
299
  logger=logger,
300
+ maleo_foundation=maleo_foundation,
274
301
  allow_origins=allow_origins,
275
302
  allow_methods=allow_methods,
276
303
  allow_headers=allow_headers,
@@ -278,6 +305,5 @@ def add_base_middleware(
278
305
  limit=limit,
279
306
  window=window,
280
307
  cleanup_interval=cleanup_interval,
281
- ip_timeout=ip_timeout,
282
- request_processor=request_processor
308
+ ip_timeout=ip_timeout
283
309
  )
@@ -81,4 +81,9 @@ class BaseGeneralSchemas:
81
81
  secret:UUID = Field(..., description="Data's secret")
82
82
 
83
83
  class Data(BaseModel):
84
- data:BaseTypes.StringToAnyDict = Field(..., description="Data")
84
+ data:BaseTypes.StringToAnyDict = Field(..., description="Data")
85
+
86
+ class RSAKeys(BaseModel):
87
+ password:str = Field(..., description="Key's password")
88
+ private:str = Field(..., description="Private key")
89
+ public:str = Field(..., description="Public key")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maleo_foundation
3
- Version: 0.1.61
3
+ Version: 0.1.62
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -18,8 +18,8 @@ maleo_foundation/expanded_types/signature.py,sha256=zNgXRrxVCfEIGXsRANIa1Ljj-ebH
18
18
  maleo_foundation/expanded_types/token.py,sha256=4fRTJw6W5MYq71NksNrWNi7qYHQ4_lQwfu9WxwrMipc,355
19
19
  maleo_foundation/managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  maleo_foundation/managers/db.py,sha256=Pn5EZ-c1Hy6-BihN7KokHJWmBIt3Ty96fZ0zF-srtF4,5208
21
- maleo_foundation/managers/middleware.py,sha256=7CDXPMb28AR7J72TWOeKFxOlMypKezEtO9mr53a88B0,4032
22
- maleo_foundation/managers/service.py,sha256=UI5aXIgVqTud4PtI5QCSFApOALdSvMhR9O3cMW1NqIE,16960
21
+ maleo_foundation/managers/middleware.py,sha256=79G6L3p6wiKjoObK1jf1qIaPOJ-ttlIgx9ii2_p_yr4,4276
22
+ maleo_foundation/managers/service.py,sha256=X2NgK5yVRkO5HSVGhN6PgoN-1sGn9w-_PDx1lFVGj2c,16844
23
23
  maleo_foundation/managers/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  maleo_foundation/managers/client/base.py,sha256=qfWu_wxoPSSzgZwuTEwRiXERg60diAkz65Qk3fnQej4,3972
25
25
  maleo_foundation/managers/client/maleo.py,sha256=iCM47TLL-RSQ2FkTmHVPdsb2JCd1LebMx6OJvIr4vCQ,2035
@@ -28,14 +28,14 @@ maleo_foundation/managers/client/google/base.py,sha256=j3W18Pmcu9jJ5wK12bbWBI6r8
28
28
  maleo_foundation/managers/client/google/secret.py,sha256=Uh01RoOp8QOIvu8X4AGJzOJRlrfAeXHO8ZFvmKo7A-E,3114
29
29
  maleo_foundation/managers/client/google/storage.py,sha256=MPuVpLTl0QJhlBOqpxv5UtD3ANO1WCCE1sRrfHnlCZM,2355
30
30
  maleo_foundation/middlewares/__init__.py,sha256=bqE2EIFC3rWcR2AwFPR0fk2kSFfeTRzgA24GbnuT5RA,3697
31
- maleo_foundation/middlewares/authentication.py,sha256=SC9p_7lCcGYbO9GedOKiPDF12KaGFbv1OypJsnRzLww,3329
32
- maleo_foundation/middlewares/base.py,sha256=-tpnutxov5UxrKjWMxktpsZ0JqXYLQCkD3x2B3F3OCI,11821
31
+ maleo_foundation/middlewares/authentication.py,sha256=LHyHb5l8loN6aZ9g0bqQdDj9glGV7FY7rL0ZBeoSGT0,3432
32
+ maleo_foundation/middlewares/base.py,sha256=cPCaOMtKfRBUcg5zBpCdQxZCwcxMauQ2Hy7WsBvAhTw,12508
33
33
  maleo_foundation/middlewares/cors.py,sha256=9uvBvY2N6Vxa9RP_YtESxcWo6Doi6uS0lzAG9iLY7Uc,2288
34
34
  maleo_foundation/models/__init__.py,sha256=AaKehO7c1HyKhoTGRmNHDddSeBXkW-_YNrpOGBu8Ms8,246
35
35
  maleo_foundation/models/responses.py,sha256=Ka9Peb1fVuQKaxyy11FVkUPtGtzyEm_9Xfe8Vla3ml0,4764
36
36
  maleo_foundation/models/table.py,sha256=Dk5GXeO0gbBBPN2PJtZhlUx2x3vMbT4dxTBc3YLBbuc,1199
37
37
  maleo_foundation/models/schemas/__init__.py,sha256=Xj8Ahsqyra-fmEaVcGPok5GOOsPQlKcknHYMvbjvENA,277
38
- maleo_foundation/models/schemas/general.py,sha256=hEQQPcddxMsJXMb36nqItIAfp3pqUyJOlaD7nXkNM2I,3609
38
+ maleo_foundation/models/schemas/general.py,sha256=KGPP67ciKeL8cvOS3kYrVwmRx3kD33OcS88UmMn1JPE,3822
39
39
  maleo_foundation/models/schemas/parameter.py,sha256=K47z2NzmTEhUiOfRiRLyRPXoQurbWsKBL7ObXAxIWRY,2100
40
40
  maleo_foundation/models/schemas/result.py,sha256=V3dljS2AdtWW4Pf8YsnQuiCylN1bZtEY1AtYC7okWuI,1747
41
41
  maleo_foundation/models/schemas/signature.py,sha256=4DVcsBR9TnxD2R28oWk51jMtF1j5ylmorVM3jDNVlrU,609
@@ -75,7 +75,7 @@ maleo_foundation/utils/loaders/__init__.py,sha256=Dnuv7BWyglSddnbsFb96s-b3KaW7UK
75
75
  maleo_foundation/utils/loaders/json.py,sha256=NsXLq3VZSgzmEf99tV1VtrmiudWdQ8Pzh_hI4Rm0cM8,397
76
76
  maleo_foundation/utils/loaders/key.py,sha256=GZ4h1ONfp6Xx8-E8AWoGP4ajAZrwPhZRtidjn_u82Qg,2562
77
77
  maleo_foundation/utils/loaders/yaml.py,sha256=jr8v3BlgmRCMTzdNgKhIYt1tnubaJXcDSSGkKVR8pbw,362
78
- maleo_foundation-0.1.61.dist-info/METADATA,sha256=hK2ChHmwvrqLf-cO6UwXWoGSsusrU2UCjkuAhx02nsg,3390
79
- maleo_foundation-0.1.61.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
80
- maleo_foundation-0.1.61.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
81
- maleo_foundation-0.1.61.dist-info/RECORD,,
78
+ maleo_foundation-0.1.62.dist-info/METADATA,sha256=-zfYv2zsfV92MMIIfXpwF2qWc2tvyh2Zti01BAm1TKE,3390
79
+ maleo_foundation-0.1.62.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
80
+ maleo_foundation-0.1.62.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
81
+ maleo_foundation-0.1.62.dist-info/RECORD,,