maleo-foundation 0.2.80__py3-none-any.whl → 0.2.81__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.
@@ -416,7 +416,7 @@ class ServiceManager:
416
416
  maleo_foundation=self._foundation
417
417
  )
418
418
  self._middleware.add_all()
419
- self._loggers.application.info("Middlewares addedd successfully")
419
+ self._loggers.application.info("Middlewares added successfully")
420
420
 
421
421
  #* Add exception handler(s)
422
422
  self._loggers.application.info("Adding exception handlers")
@@ -428,7 +428,7 @@ class ServiceManager:
428
428
  exc_class_or_status_code=HTTPException,
429
429
  handler=BaseExceptions.http_exception_handler
430
430
  )
431
- self._loggers.application.info("Exception handlers addedd successfully")
431
+ self._loggers.application.info("Exception handlers added successfully")
432
432
 
433
433
  #* Include router
434
434
  self._loggers.application.info("Including routers")
@@ -5,7 +5,6 @@ import traceback
5
5
  from collections import defaultdict
6
6
  from datetime import datetime, timedelta, timezone
7
7
  from typing import Awaitable, Callable, Optional, Sequence, Dict, List
8
- from uuid import UUID, uuid4
9
8
 
10
9
  from fastapi import FastAPI, Request, Response, status
11
10
  from fastapi.responses import JSONResponse
@@ -19,7 +18,8 @@ from maleo_foundation.models.responses import BaseResponses
19
18
  from maleo_foundation.models.transfers.general.token import MaleoFoundationTokenGeneralTransfers
20
19
  from maleo_foundation.models.transfers.parameters.token import MaleoFoundationTokenParametersTransfers
21
20
  from maleo_foundation.models.transfers.parameters.signature import MaleoFoundationSignatureParametersTransfers
22
- from maleo_foundation.utils.extractor import BaseExtractors
21
+ from maleo_foundation.models.transfers.general import RequestContextTransfers
22
+ from maleo_foundation.utils.extractor import extract_request_context
23
23
  from maleo_foundation.utils.logging import MiddlewareLogger
24
24
 
25
25
  RequestProcessor = Callable[[Request], Awaitable[Optional[Response]]]
@@ -46,11 +46,12 @@ class RateLimiter:
46
46
 
47
47
  def is_rate_limited(
48
48
  self,
49
- client_ip:str
49
+ request_context:RequestContextTransfers
50
50
  ) -> bool:
51
51
  """Check if client IP is rate limited and record the request."""
52
52
  with self._lock:
53
53
  now = datetime.now()
54
+ client_ip = request_context.ip_address
54
55
  self._last_seen[client_ip] = now
55
56
 
56
57
  # Remove old requests outside the window
@@ -101,7 +102,6 @@ class RateLimiter:
101
102
  f"Current tracked IPs: {len(self._requests)}"
102
103
  )
103
104
 
104
-
105
105
  class ResponseBuilder:
106
106
  """Handles response building and header management."""
107
107
 
@@ -115,42 +115,38 @@ class ResponseBuilder:
115
115
 
116
116
  def add_response_headers(
117
117
  self,
118
- request:Request,
119
118
  authentication:Authentication,
120
119
  response:Response,
121
- request_timestamp:datetime,
122
- response_timestamp:datetime,
123
- process_time:float,
124
- request_id:UUID
120
+ request_context:RequestContextTransfers,
121
+ responded_at:datetime,
122
+ process_time:float
125
123
  ) -> Response:
126
124
  """Add custom headers to response."""
127
125
  # Basic headers
128
- response.headers["X-Request-ID"] = str(request_id)
126
+ response.headers["X-Request-ID"] = str(request_context.request_id)
129
127
  response.headers["X-Process-Time"] = str(process_time)
130
- response.headers["X-Request-Timestamp"] = request_timestamp.isoformat()
131
- response.headers["X-Response-Timestamp"] = response_timestamp.isoformat()
128
+ response.headers["X-Requested-At"] = request_context.requested_at.isoformat()
129
+ response.headers["X-Responded-At"] = responded_at.isoformat()
132
130
 
133
131
  # Add signature header
134
- self._add_signature_header(request, response, request_timestamp, response_timestamp, process_time, request_id)
132
+ self._add_signature_header(response, request_context, responded_at, process_time)
135
133
 
136
134
  # Add new authorization header if needed
137
- self._add_new_authorization_header(request, authentication, response)
135
+ self._add_new_authorization_header(request_context, authentication, response)
138
136
 
139
137
  return response
140
138
 
141
139
  def _add_signature_header(
142
140
  self,
143
- request:Request,
144
141
  response:Response,
145
- request_timestamp:datetime,
146
- response_timestamp:datetime,
147
- process_time:float,
148
- request_id:UUID
142
+ request_context:RequestContextTransfers,
143
+ responded_at:datetime,
144
+ process_time:float
149
145
  ) -> None:
150
146
  """Generate and add signature header."""
151
147
  message = (
152
- f"{request.method}|{request.url.path}|{request_timestamp.isoformat()}|"
153
- f"{response_timestamp.isoformat()}|{str(process_time)}|{str(request_id)}"
148
+ f"{request_context.method}|{request_context.url}|{request_context.requested_at.isoformat()}|"
149
+ f"{responded_at.isoformat()}|{str(process_time)}|{str(request_context.request_id)}"
154
150
  )
155
151
 
156
152
  sign_parameters = MaleoFoundationSignatureParametersTransfers.Sign(
@@ -165,12 +161,12 @@ class ResponseBuilder:
165
161
 
166
162
  def _add_new_authorization_header(
167
163
  self,
168
- request:Request,
164
+ request_context:RequestContextTransfers,
169
165
  authentication:Authentication,
170
166
  response:Response
171
167
  ) -> None:
172
168
  """Add new authorization header for refresh tokens."""
173
- if not self._should_regenerate_auth(request, authentication, response):
169
+ if not self._should_regenerate_auth(request_context, authentication, response):
174
170
  return
175
171
 
176
172
  payload = MaleoFoundationTokenGeneralTransfers.BaseEncodePayload.model_validate(
@@ -189,7 +185,7 @@ class ResponseBuilder:
189
185
 
190
186
  def _should_regenerate_auth(
191
187
  self,
192
- request:Request,
188
+ request_context:RequestContextTransfers,
193
189
  authentication:Authentication,
194
190
  response:Response
195
191
  ) -> bool:
@@ -198,26 +194,20 @@ class ResponseBuilder:
198
194
  authentication.user.is_authenticated
199
195
  and authentication.credentials.token.type == BaseEnums.TokenType.REFRESH
200
196
  and 200 <= response.status_code < 300
201
- and "logout" not in request.url.path
197
+ and "logout" not in request_context.url
202
198
  )
203
199
 
204
-
205
200
  class RequestLogger:
206
201
  """Handles request/response logging."""
207
202
 
208
- def __init__(
209
- self,
210
- logger:MiddlewareLogger
211
- ):
203
+ def __init__(self, logger:MiddlewareLogger):
212
204
  self.logger = logger
213
205
 
214
206
  def log_request_response(
215
207
  self,
216
- request:Request,
217
208
  authentication:Authentication,
218
209
  response:Response,
219
- client_ip:str,
220
- request_id:UUID,
210
+ request_context:RequestContextTransfers,
221
211
  log_level:str = "info"
222
212
  ) -> None:
223
213
  """Log request and response details."""
@@ -225,39 +215,32 @@ class RequestLogger:
225
215
 
226
216
  log_func = getattr(self.logger, log_level)
227
217
  log_func(
228
- f"Request | ID: {request_id} {authentication_info} | IP: {client_ip} | "
229
- f"Host: {request.client.host} | Port: {request.client.port} | "
230
- f"Method: {request.method} | URL: {request.url.path} | "
231
- f"Headers: {dict(request.headers)} - Response | Status: {response.status_code}"
218
+ f"Request | ID: {request_context.request_id} {authentication_info} | "
219
+ f"IP: {request_context.ip_address} | Host: {request_context.host} | "
220
+ f"Method: {request_context.method} | URL: {request_context.url} - "
221
+ f"Response | Status: {response.status_code}"
232
222
  )
233
223
 
234
224
  def log_exception(
235
225
  self,
236
- request:Request,
237
226
  authentication:Authentication,
238
227
  error:Exception,
239
- client_ip:str,
240
- request_id:UUID
228
+ request_context:RequestContextTransfers
241
229
  ) -> None:
242
230
  """Log exception details."""
243
231
  authentication_info = self._get_authentication_info(authentication)
244
232
 
245
233
  error_details = {
246
- "request_id": str(request_id),
234
+ "request_context": request_context.model_dump(mode="json"),
247
235
  "error": str(error),
248
- "traceback": traceback.format_exc().split("\n"),
249
- "client_ip": client_ip,
250
- "method": request.method,
251
- "url": request.url.path,
252
- "headers": dict(request.headers),
236
+ "traceback": traceback.format_exc().split("\n")
253
237
  }
254
238
 
255
239
  self.logger.error(
256
- f"Request | ID: {request_id} {authentication_info} | IP: {client_ip} | "
257
- f"Host: {request.client.host} | Port: {request.client.port} | "
258
- f"Method: {request.method} | URL: {request.url.path} | "
259
- f"Headers: {dict(request.headers)} - Response | Status: 500 | "
260
- f"Exception:\n{json.dumps(error_details, indent=4)}"
240
+ f"Request | ID: {request_context.request_id} {authentication_info} | "
241
+ f"IP: {request_context.ip_address} | Host: {request_context.host} | "
242
+ f"Method: {request_context.method} | URL: {request_context.url} - "
243
+ f"Response | Status: 500 | Exception:\n{json.dumps(error_details, indent=4)}"
261
244
  )
262
245
 
263
246
  def _get_authentication_info(self, authentication:Authentication) -> str:
@@ -312,43 +295,36 @@ class BaseMiddleware(BaseHTTPMiddleware):
312
295
 
313
296
  async def dispatch(self, request:Request, call_next:RequestResponseEndpoint) -> Response:
314
297
  """Main middleware dispatch method."""
315
- # Generate unique request ID
316
- request_id = uuid4()
317
- request.state.request_id = request_id
318
-
319
298
  # Setup
320
299
  self.rate_limiter.cleanup_old_data(self.request_logger.logger)
321
- request_timestamp = datetime.now(tz=timezone.utc)
322
- request.state.request_timestamp = request_timestamp
300
+ request_context = extract_request_context(request)
301
+ request.state.request_context = request_context
323
302
  start_time = time.perf_counter()
324
- client_ip = BaseExtractors.extract_client_ip(request)
325
303
  authentication = Authentication(credentials=request.auth, user=request.user)
326
304
 
327
305
  try:
328
306
  # Rate limiting check
329
- if self.rate_limiter.is_rate_limited(client_ip):
307
+ if self.rate_limiter.is_rate_limited(request_context):
330
308
  return self._create_rate_limit_response(
331
- request, authentication, client_ip, request_timestamp, start_time, request_id
309
+ authentication, request_context, start_time
332
310
  )
333
311
 
334
312
  # Optional preprocessing
335
313
  pre_response = await self._request_processor(request)
336
314
  if pre_response is not None:
337
315
  return self._build_final_response(
338
- request, authentication, pre_response, client_ip,
339
- request_timestamp, start_time, request_id
316
+ authentication, pre_response, request_context, start_time
340
317
  )
341
318
 
342
319
  # Main request processing
343
320
  response = await call_next(request)
344
321
  return self._build_final_response(
345
- request, authentication, response, client_ip,
346
- request_timestamp, start_time, request_id
322
+ authentication, response, request_context, start_time
347
323
  )
348
324
 
349
325
  except Exception as e:
350
326
  return self._handle_exception(
351
- request, authentication, e, client_ip, request_timestamp, start_time, request_id
327
+ request, authentication, e, request_context, start_time
352
328
  )
353
329
 
354
330
  async def _request_processor(self, request:Request) -> Optional[Response]:
@@ -357,12 +333,9 @@ class BaseMiddleware(BaseHTTPMiddleware):
357
333
 
358
334
  def _create_rate_limit_response(
359
335
  self,
360
- request:Request,
361
336
  authentication:Authentication,
362
- client_ip:str,
363
- request_timestamp:datetime,
364
- start_time:float,
365
- request_id:UUID
337
+ request_context:RequestContextTransfers,
338
+ start_time:float
366
339
  ) -> Response:
367
340
  """Create rate limit exceeded response."""
368
341
  response = JSONResponse(
@@ -371,49 +344,42 @@ class BaseMiddleware(BaseHTTPMiddleware):
371
344
  )
372
345
 
373
346
  return self._build_final_response(
374
- request, authentication, response, client_ip,
375
- request_timestamp, start_time, request_id, log_level="warning"
347
+ authentication, response, request_context, start_time, log_level="warning"
376
348
  )
377
349
 
378
350
  def _build_final_response(
379
351
  self,
380
- request:Request,
381
352
  authentication:Authentication,
382
353
  response:Response,
383
- client_ip:str,
384
- request_timestamp:datetime,
354
+ request_context:RequestContextTransfers,
385
355
  start_time:float,
386
- request_id:UUID,
387
356
  log_level:str = "info"
388
357
  ) -> Response:
389
358
  """Build final response with headers and logging."""
390
- response_timestamp = datetime.now(tz=timezone.utc)
359
+ responded_at = datetime.now(tz=timezone.utc)
391
360
  process_time = time.perf_counter() - start_time
392
361
 
393
362
  # Add headers
394
363
  response = self.response_builder.add_response_headers(
395
- request, authentication, response, request_timestamp, response_timestamp, process_time, request_id
364
+ authentication, response, request_context, responded_at, process_time
396
365
  )
397
366
 
398
367
  # Log request/response
399
368
  self.request_logger.log_request_response(
400
- request, authentication, response, client_ip, request_id, log_level
369
+ authentication, response, request_context, log_level
401
370
  )
402
371
 
403
372
  return response
404
373
 
405
374
  def _handle_exception(
406
375
  self,
407
- request:Request,
408
376
  authentication:Authentication,
409
377
  error:Exception,
410
- client_ip:str,
411
- request_timestamp:datetime,
412
- start_time:float,
413
- request_id:UUID
378
+ request_context:RequestContextTransfers,
379
+ start_time:float
414
380
  ) -> Response:
415
381
  """Handle exceptions and create error response."""
416
- response_timestamp = datetime.now(tz=timezone.utc)
382
+ responded_at = datetime.now(tz=timezone.utc)
417
383
  process_time = time.perf_counter() - start_time
418
384
 
419
385
  response = JSONResponse(
@@ -422,11 +388,11 @@ class BaseMiddleware(BaseHTTPMiddleware):
422
388
  )
423
389
 
424
390
  # Log exception
425
- self.request_logger.log_exception(request, authentication, error, client_ip, request_id)
391
+ self.request_logger.log_exception(authentication, error, request_context)
426
392
 
427
393
  # Add headers
428
394
  return self.response_builder.add_response_headers(
429
- request, authentication, response, request_timestamp, response_timestamp, process_time, request_id
395
+ authentication, response, request_context, responded_at, process_time
430
396
  )
431
397
 
432
398
 
@@ -1,5 +1,10 @@
1
1
  from __future__ import annotations
2
+ from datetime import datetime, timezone
3
+ from pydantic import BaseModel, Field
4
+ from typing import Dict
5
+ from uuid import UUID
2
6
  from maleo_foundation.models.schemas.general import BaseGeneralSchemas
7
+ from maleo_foundation.types import BaseTypes
3
8
  from .token import MaleoFoundationTokenGeneralTransfers
4
9
 
5
10
  class BaseGeneralTransfers:
@@ -8,4 +13,23 @@ class BaseGeneralTransfers:
8
13
  class AccessTransfers(
9
14
  BaseGeneralSchemas.AccessedBy,
10
15
  BaseGeneralSchemas.AccessedAt
11
- ): pass
16
+ ): pass
17
+
18
+ class RequestContextTransfers(BaseModel):
19
+ request_id:UUID = Field(..., description="Unique identifier for tracing the request")
20
+ requested_at:datetime = Field(datetime.now(tz=timezone.utc), description="Request timestamp")
21
+ method:str = Field(..., description="Request's method")
22
+ url:str = Field(..., description="Request's URL")
23
+ path_params:Dict = Field(..., description="Request's path parameters")
24
+ query_params:Dict = Field(..., description="Request's query parameters")
25
+ ip_address:str = Field("unknown", description="Client's IP address")
26
+ is_internal:BaseTypes.OptionalBoolean = Field(None, description="True if IP is internal")
27
+ user_agent:BaseTypes.OptionalString = Field(None, description="User-Agent string")
28
+ ua_browser:BaseTypes.OptionalString = Field(None, description="Browser info from sec-ch-ua")
29
+ ua_mobile:BaseTypes.OptionalString = Field(None, description="Is mobile device?")
30
+ platform:BaseTypes.OptionalString = Field(None, description="Client platform or OS")
31
+ referer:BaseTypes.OptionalString = Field(None, description="Referrer URL")
32
+ origin:BaseTypes.OptionalString = Field(None, description="Origin of the request")
33
+ host:BaseTypes.OptionalString = Field(None, description="Host header from request")
34
+ forwarded_proto:BaseTypes.OptionalString = Field(None, description="Forwarded protocol (http/https)")
35
+ language:BaseTypes.OptionalString = Field(None, description="Accepted languages from client")
@@ -0,0 +1,9 @@
1
+ from fastapi.requests import Request
2
+ from maleo_foundation.models.transfers.general import RequestContextTransfers
3
+
4
+ class ContextDependencies:
5
+ @staticmethod
6
+ def get_request_context(
7
+ request:Request
8
+ ) -> RequestContextTransfers:
9
+ return request.state.request_context
@@ -1,20 +1,55 @@
1
+ from datetime import datetime, timezone
2
+ from fastapi import Request
1
3
  from starlette.requests import HTTPConnection
4
+ from uuid import uuid4
5
+ from maleo_foundation.models.transfers.general import RequestContextTransfers
2
6
 
3
- class BaseExtractors:
4
- @staticmethod
5
- def extract_client_ip(conn:HTTPConnection) -> str:
6
- """Extract client IP with more robust handling of proxies"""
7
- #* Check for X-Forwarded-For header (common when behind proxy/load balancer)
8
- x_forwarded_for = conn.headers.get("X-Forwarded-For")
9
- if x_forwarded_for:
10
- #* The client's IP is the first one in the list
11
- ips = [ip.strip() for ip in x_forwarded_for.split(",")]
12
- return ips[0]
13
-
14
- #* Check for X-Real-IP header (used by some proxies)
15
- x_real_ip = conn.headers.get("X-Real-IP")
16
- if x_real_ip:
17
- return x_real_ip
18
-
19
- #* Fall back to direct client connection
20
- return conn.client.host if conn.client else "unknown"
7
+ def extract_client_ip(conn:HTTPConnection) -> str:
8
+ """Extract client IP with more robust handling of proxies"""
9
+ #* Check for X-Forwarded-For header (common when behind proxy/load balancer)
10
+ x_forwarded_for = conn.headers.get("X-Forwarded-For")
11
+ if x_forwarded_for:
12
+ #* The client's IP is the first one in the list
13
+ ips = [ip.strip() for ip in x_forwarded_for.split(",")]
14
+ return ips[0]
15
+
16
+ #* Check for X-Real-IP header (used by some proxies)
17
+ x_real_ip = conn.headers.get("X-Real-IP")
18
+ if x_real_ip:
19
+ return x_real_ip
20
+
21
+ #* Fall back to direct client connection
22
+ return conn.client.host if conn.client else "unknown"
23
+
24
+ def extract_request_context(request:Request) -> RequestContextTransfers:
25
+ headers = request.headers
26
+
27
+ request_id = headers.get("x-request-id")
28
+ if request_id is None:
29
+ request_id = uuid4()
30
+
31
+ ip_address = extract_client_ip(request)
32
+
33
+ ua_browser = headers.get("sec-ch-ua", "")
34
+ if ua_browser:
35
+ ua_browser = ua_browser.replace('"', "").split(",")[0].strip()
36
+
37
+ return RequestContextTransfers(
38
+ request_id=request_id,
39
+ requested_at=datetime.now(tz=timezone.utc),
40
+ method=request.method,
41
+ url=request.url.path,
42
+ path_params=dict(request.path_params),
43
+ query_params=dict(request.query_params),
44
+ ip_address=ip_address,
45
+ is_internal=ip_address.startswith("10.") or ip_address.startswith("192.168.") or ip_address.startswith("172."),
46
+ user_agent=headers.get("user-agent"),
47
+ ua_browser=ua_browser,
48
+ ua_mobile=headers.get("sec-ch-ua-mobile"),
49
+ platform=headers.get("sec-ch-ua-platform"),
50
+ referer=headers.get("referer"),
51
+ origin=headers.get("origin"),
52
+ host=headers.get("host"),
53
+ forwarded_proto=headers.get("x-forwarded-proto"),
54
+ language=headers.get("accept-language"),
55
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maleo_foundation
3
- Version: 0.2.80
3
+ Version: 0.2.81
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -34,7 +34,7 @@ maleo_foundation/expanded_types/encryption/rsa.py,sha256=Esf_H8nMz2kOLAWa3M7dlD-
34
34
  maleo_foundation/managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  maleo_foundation/managers/db.py,sha256=cpY1IOiUytT9XXYtzS0E9OSYOuB7jBKo0XHe__uI1Jg,5340
36
36
  maleo_foundation/managers/middleware.py,sha256=77wRCC_CWc22nSDL-UJanO3rXmSB7wLzaAIXEFjXq6M,4249
37
- maleo_foundation/managers/service.py,sha256=n2ubW5NoeBBju0t0fLSWa0FxeZMLzmoRcimuCIobgzk,19284
37
+ maleo_foundation/managers/service.py,sha256=9qPmOUh5PPXu03-xnZIRU4C3mNbMOnYrfJQs87oqt6k,19282
38
38
  maleo_foundation/managers/cache/__init__.py,sha256=CeY0oof2bVl_v5WS-FKXNwn2gf3xrEMfUsHK9cHo59s,471
39
39
  maleo_foundation/managers/cache/base.py,sha256=YyPjde4KTsp2IHV6NdFMysa0ev-1GX1rtX-0jQPuIBU,837
40
40
  maleo_foundation/managers/cache/redis.py,sha256=xLa8QfXdNtghs0eBxIqc04H3XTYmxLEzrqJZAFCigvM,1150
@@ -47,7 +47,7 @@ maleo_foundation/managers/client/google/parameter.py,sha256=Lnj7mQgxWQpsQwbmDRK5
47
47
  maleo_foundation/managers/client/google/secret.py,sha256=Ski1CHYeA8vjSk2Oc2Pf4CfFrzT_RcA6NEZwza7gM7Y,4464
48
48
  maleo_foundation/managers/client/google/storage.py,sha256=Hq79cVreWR2AGwUzpD57NzziZjqxj__TqYIBRy-A9A0,5340
49
49
  maleo_foundation/middlewares/authentication.py,sha256=UL6kL65SvqrzemlIDopoO9N1C05eWlYMHVR2tiRsVEA,4821
50
- maleo_foundation/middlewares/base.py,sha256=R-N8rxUaPt7_mvK6DI8y8Jal8GfzuD7Yyx3VLp9_tQA,17097
50
+ maleo_foundation/middlewares/base.py,sha256=r3XDTEhK6BB8YZ1Y8oyqExY78s4yzOqX7s7XokRlTlw,16308
51
51
  maleo_foundation/middlewares/cors.py,sha256=9uvBvY2N6Vxa9RP_YtESxcWo6Doi6uS0lzAG9iLY7Uc,2288
52
52
  maleo_foundation/models/__init__.py,sha256=AaKehO7c1HyKhoTGRmNHDddSeBXkW-_YNrpOGBu8Ms8,246
53
53
  maleo_foundation/models/responses.py,sha256=nE5qThK-WgcYB-9J4wHzJltMA3PLmWbMI-dkxAxAdII,5631
@@ -62,7 +62,7 @@ maleo_foundation/models/schemas/result.py,sha256=MaWDyKGvZu0IcvKMj30lrMXojGV9Mhi
62
62
  maleo_foundation/models/schemas/signature.py,sha256=-5ldTnJsjwqPRbHw7PFcLKITqEXJ_qKDdRHShK75NVA,620
63
63
  maleo_foundation/models/schemas/token.py,sha256=RYq8v1T_WZIu8lcjwyV6Pp7ZjFkr_lW9x6QyDmXBsfw,563
64
64
  maleo_foundation/models/transfers/__init__.py,sha256=oJLJ3Geeme6vBw7R2Dhvdvg4ziVvzEYAGJaP-tm_90w,299
65
- maleo_foundation/models/transfers/general/__init__.py,sha256=7yQNGSihJt1db6i_zIrhLdY2Tgn5lrTxuDlAVlDh2vo,340
65
+ maleo_foundation/models/transfers/general/__init__.py,sha256=IOt9afCpDu7bO0rkZLiiLLP37w5rIZTxmnv6MD9od8E,1990
66
66
  maleo_foundation/models/transfers/general/key.py,sha256=tLKkXbwNu7Oc1MdKa8-Y7TlBAIk54h_02AmL5Yg2PrQ,751
67
67
  maleo_foundation/models/transfers/general/signature.py,sha256=J9xQy2HjpCQOnES7RJqsUnDgjFPuakQ1mxyfdTdstSE,297
68
68
  maleo_foundation/models/transfers/general/token.py,sha256=O_U6dQS7oMScJzqufl6Pe21pTxMsYhOzKH8aFLxjblQ,2895
@@ -101,7 +101,7 @@ maleo_foundation/utils/__init__.py,sha256=KoERe8U2ERGZeAKUNBPW_itk7g9YpH7v7_mD9_
101
101
  maleo_foundation/utils/client.py,sha256=F5X9TUxWQgeOHjwsMpPoSRhZANQYZ_iFv0RJDTUVhrw,2820
102
102
  maleo_foundation/utils/controller.py,sha256=D8uUfqkMpPw8M8Ykn8Uxn7dfRGwxmBxSP1h9xSkYw1I,6945
103
103
  maleo_foundation/utils/exceptions.py,sha256=eM__Mxo-BC5d7JmoBd-Wh-fmryUdfjNfOuY_eONK5Fk,6361
104
- maleo_foundation/utils/extractor.py,sha256=SZXVYDHWGaA-Dd1BUydwF2HHdZqexEielS4CjL0Ceng,814
104
+ maleo_foundation/utils/extractor.py,sha256=0HoJ0hLqt3-izaekjPfxqWjvUmXTsm4Muyttu0_VyuI,2109
105
105
  maleo_foundation/utils/logging.py,sha256=W5Fhk_xAXVqSujaY8mv3hRH4wlQSpUn4ReuMoiKcQa4,7759
106
106
  maleo_foundation/utils/merger.py,sha256=z9GROLVtGpwx84bOiakBFphKazsI-9l3F3WauTDwQLs,597
107
107
  maleo_foundation/utils/query.py,sha256=nDj-9Q-5eAOvqXqKgKjtHaFAxVAY87E0BMaVXmTN7jA,7957
@@ -109,6 +109,7 @@ maleo_foundation/utils/repository.py,sha256=knBi3xOLlhBIEtChvqbZh4wXmgrFCB3rDwQX
109
109
  maleo_foundation/utils/searcher.py,sha256=gsseMkr0swKj3l-xil5qqncTbYNkS96eieFE_ehaF8I,504
110
110
  maleo_foundation/utils/dependencies/__init__.py,sha256=0KKGrdfj8Cc5A4SRk_ZBAxzOP795Mizdb4zIBh07KC4,122
111
111
  maleo_foundation/utils/dependencies/auth.py,sha256=wS9qnmd1n2WsFhiSfyq_3Io3wwZKTENVPv4rMwxJslE,727
112
+ maleo_foundation/utils/dependencies/context.py,sha256=OXem2E00u2D3GleXhV8VI3u0cayG2CZpvVz32a0xHhs,292
112
113
  maleo_foundation/utils/formatter/__init__.py,sha256=iKf5YCbEdg1qKnFHyKqqcQbqAqEeRUf8mhI3v3dQoj8,78
113
114
  maleo_foundation/utils/formatter/case.py,sha256=TmvvlfzGdC_omMTB5vAa40TZBxQ3hnr-SYeo0M52Rlg,1352
114
115
  maleo_foundation/utils/loaders/__init__.py,sha256=P_3ycGfeDXFjAi8bE4iLWHxBveqUIdpHgGv-klRWM3s,282
@@ -118,7 +119,7 @@ maleo_foundation/utils/loaders/credential/__init__.py,sha256=qopTKvcMVoTFwyRijeg
118
119
  maleo_foundation/utils/loaders/credential/google.py,sha256=HUcuHD4tXHPt0eHInlFYxA_MDrGSOtbenpd0PX156OM,1255
119
120
  maleo_foundation/utils/loaders/key/__init__.py,sha256=hVygcC2ImHc_aVrSrOmyedR8tMUZokWUKCKOSh5ctbo,106
120
121
  maleo_foundation/utils/loaders/key/rsa.py,sha256=gDhyX6iTFtHiluuhFCozaZ3pOLKU2Y9TlrNMK_GVyGU,3796
121
- maleo_foundation-0.2.80.dist-info/METADATA,sha256=dRNIGvejuDcdeeazla9MoD2p0H1LGUATumhyh2XTB00,3598
122
- maleo_foundation-0.2.80.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
123
- maleo_foundation-0.2.80.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
124
- maleo_foundation-0.2.80.dist-info/RECORD,,
122
+ maleo_foundation-0.2.81.dist-info/METADATA,sha256=JLiCodCLzxMikL7jL0H8wQRjpRvlolRdVr-_iSfz0xM,3598
123
+ maleo_foundation-0.2.81.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
124
+ maleo_foundation-0.2.81.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
125
+ maleo_foundation-0.2.81.dist-info/RECORD,,