sharedkernel 2.5.3__tar.gz → 2.5.6__tar.gz

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.
Files changed (51) hide show
  1. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/PKG-INFO +8 -1
  2. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/README.md +6 -0
  3. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/setup.py +2 -1
  4. sharedkernel-2.5.6/sharedkernel/config.py +34 -0
  5. sharedkernel-2.5.6/sharedkernel/database/distributed_cache.py +138 -0
  6. sharedkernel-2.5.6/sharedkernel/enum/__init__.py +2 -0
  7. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/enum/error_code.py +1 -0
  8. sharedkernel-2.5.6/sharedkernel/enum/redis_mode_enum.py +8 -0
  9. sharedkernel-2.5.6/sharedkernel/ip_session_service.py +98 -0
  10. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/logger/log_decorator.py +2 -4
  11. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/logger/log_middlewares.py +3 -6
  12. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/logger/logger_service.py +10 -16
  13. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel.egg-info/PKG-INFO +8 -1
  14. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel.egg-info/SOURCES.txt +4 -0
  15. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel.egg-info/requires.txt +1 -0
  16. sharedkernel-2.5.3/sharedkernel/enum/__init__.py +0 -1
  17. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/setup.cfg +0 -0
  18. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/common.py +0 -0
  19. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/data_format_converter.py +0 -0
  20. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/database/__init__.py +0 -0
  21. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/database/audit_model.py +0 -0
  22. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/database/mongo_generic_audit_repository.py +0 -0
  23. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/database/mongo_generic_repository.py +0 -0
  24. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/database/pagination_response_dto.py +0 -0
  25. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/date_converter.py +0 -0
  26. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/diff_utils.py +0 -0
  27. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/enum/sort_order.py +0 -0
  28. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/exception/__init__.py +0 -0
  29. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/exception/exception.py +0 -0
  30. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/exception/exception_handlers.py +0 -0
  31. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/file_validation.py +0 -0
  32. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/jwt_service.py +0 -0
  33. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/logger/log_dto.py +0 -0
  34. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/logger/log_enums.py +0 -0
  35. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/logger/log_info.py +0 -0
  36. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/multipart_upload.py +0 -0
  37. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/normalizer/__init__.py +0 -0
  38. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/normalizer/number_normalizer.py +0 -0
  39. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/normalizer/phone_number_normalizer.py +0 -0
  40. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/normalizer/string_normalizer.py +0 -0
  41. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/objects/__init__.py +0 -0
  42. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/objects/base_document.py +0 -0
  43. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/objects/json_string_model.py +0 -0
  44. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/objects/jwt_model.py +0 -0
  45. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/objects/result.py +0 -0
  46. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/objects/user_info.py +0 -0
  47. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/regex_masking.py +0 -0
  48. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/s3_uploader.py +0 -0
  49. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel/string_extentions.py +0 -0
  50. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel.egg-info/dependency_links.txt +0 -0
  51. {sharedkernel-2.5.3 → sharedkernel-2.5.6}/sharedkernel.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sharedkernel
3
- Version: 2.5.3
3
+ Version: 2.5.6
4
4
  Summary: sharekernel is a shared package between all python projects
5
5
  Author: Smilinno
6
6
  Description-Content-Type: text/markdown
@@ -20,6 +20,7 @@ Requires-Dist: markdown
20
20
  Requires-Dist: beautifulsoup4
21
21
  Requires-Dist: deepdiff
22
22
  Requires-Dist: kombu
23
+ Requires-Dist: redis
23
24
  Dynamic: author
24
25
  Dynamic: description
25
26
  Dynamic: description-content-type
@@ -30,6 +31,12 @@ Dynamic: summary
30
31
  this is a shared kernel package
31
32
 
32
33
  # Change Log
34
+ ### Version 2.5.6
35
+ - fix bug
36
+ ### Version 2.5.5
37
+ - fix bug
38
+ ### Version 2.5.4
39
+ - Add Ip Session Service
33
40
  ### Version 2.5.3
34
41
  - Fix bug
35
42
  ### Version 2.5.2
@@ -2,6 +2,12 @@
2
2
  this is a shared kernel package
3
3
 
4
4
  # Change Log
5
+ ### Version 2.5.6
6
+ - fix bug
7
+ ### Version 2.5.5
8
+ - fix bug
9
+ ### Version 2.5.4
10
+ - Add Ip Session Service
5
11
  ### Version 2.5.3
6
12
  - Fix bug
7
13
  ### Version 2.5.2
@@ -37,9 +37,10 @@ setup(
37
37
  "beautifulsoup4",
38
38
  "deepdiff",
39
39
  "kombu",
40
+ "redis",
40
41
  ],
41
42
  # *strongly* suggested for sharing
42
- version="2.5.3",
43
+ version="2.5.6",
43
44
  description="sharekernel is a shared package between all python projects",
44
45
  long_description=long_description,
45
46
  long_description_content_type="text/markdown",
@@ -0,0 +1,34 @@
1
+ import os
2
+
3
+ # Log *******************************************************************************
4
+ LOG_ENABLE = True if os.getenv("LOG_ENABLE", "False").lower() == "true" else False
5
+ RABBITMQ_USER = os.getenv("RABBITMQ_USER")
6
+ RABBITMQ_PASSWORD = os.getenv("RABBITMQ_PASSWORD")
7
+ RABBITMQ_HOST = os.getenv("RABBITMQ_HOST")
8
+ RABBITMQ_VHOST = os.getenv("RABBITMQ_VHOST")
9
+ LOG_EXCHANGE = os.getenv("LOG_EXCHANGE")
10
+ LOG_REQUESTS_QUEUE = os.getenv("LOG_REQUESTS_QUEUE")
11
+ SERVICE_NAME = os.getenv("SERVICE_NAME")
12
+ IP_HEADER_NAME = os.getenv("IP_HEADER_NAME")
13
+
14
+ # IP Session ************************************************************************
15
+ IP_SESSION_AUTH_ENABLE = True if os.getenv("IP_SESSION_AUTH_ENABLE", "False").lower() == "true" else False
16
+ APIKEY_HEADER_NAME = os.getenv("APIKEY_HEADER_NAME")
17
+ WHITE_LIST_IP = os.getenv("WHITE_LIST_IP") #192.168.0.0/16, 10.0.0.0/24, 11.22.33.44
18
+ IP_SESSION_CACHE_DATABASE_NUMBER = os.getenv("IP_SESSION_CACHE_DATABASE_NUMBER")
19
+
20
+
21
+ # REDIS *****************************************************************************
22
+ REDIS_URL = os.getenv("REDIS_URL")
23
+ REDIS_PASSWORD = os.getenv("REDIS_PASSWORD")
24
+ REDIS_USER = os.getenv("REDIS_USER")
25
+ REDIS_CONNECTION_STRING = os.getenv("REDIS_CONNECTION_STRING")
26
+ CACHE_DATABASE_NUMBER = os.getenv("CACHE_DATABASE_NUMBER")
27
+ REDIS_CONNECTION_STRING = os.getenv(
28
+ "REDIS_CONNECTION_STRING", f"redis://{REDIS_USER}:{REDIS_PASSWORD}@{REDIS_URL}"
29
+ )
30
+ CACHE_EXPIRE_TIME_HOURS = int(os.getenv("CACHE_EXPIRE_TIME_HOURS", 24))
31
+ REDIS_SENTINELS = os.getenv("REDIS_SENTINELS")
32
+ REDIS_MASTER_NAME = os.getenv("REDIS_MASTER_NAME")
33
+ REDIS_CLUSTER_NODES = os.getenv("REDIS_CLUSTER_NODES")
34
+ REDIS_MODE = os.getenv("REDIS_MODE") # sentinel / cluster / standalone
@@ -0,0 +1,138 @@
1
+ from typing import Generic, List, Optional, Tuple, Type, TypeVar
2
+
3
+ import redis
4
+ from pydantic import BaseModel
5
+ from redis import Redis
6
+ from redis.sentinel import Sentinel
7
+ from redis.cluster import RedisCluster, ClusterNode
8
+ from sharedkernel.exception.exception import BusinessException
9
+
10
+ from sharedkernel import config
11
+ from sharedkernel.enum import ErrorCode, RedisMode
12
+
13
+ T = TypeVar("T", bound=BaseModel)
14
+
15
+
16
+ from typing import List, Tuple
17
+
18
+ def parse_nodes(value: str) -> List[Tuple[str, int]]:
19
+ if not value:
20
+ return []
21
+
22
+ sentinels = []
23
+ for item in value.split(","):
24
+ item = item.strip()
25
+
26
+ if ":" in item:
27
+ host, port = item.rsplit(":", 1)
28
+ port = int(port)
29
+ else:
30
+ host = item
31
+ port = 6379
32
+
33
+ sentinels.append((host, port))
34
+
35
+ return sentinels
36
+
37
+
38
+
39
+ def get_redis_client(cache_database_number=config.CACHE_DATABASE_NUMBER) -> Redis:
40
+ redis_mode = config.REDIS_MODE
41
+ if redis_mode == RedisMode.SENTINEL:
42
+ sentinels = parse_nodes(config.REDIS_SENTINELS)
43
+
44
+ sentinel = Sentinel(sentinels)
45
+ return sentinel.master_for(
46
+ service_name=config.REDIS_MASTER_NAME,
47
+ db=cache_database_number,
48
+ username=config.REDIS_USER,
49
+ password=config.REDIS_PASSWORD,
50
+ # decode_responses=True,
51
+ )
52
+
53
+ elif redis_mode == RedisMode.CLUSTER:
54
+ nodes = parse_nodes(config.REDIS_CLUSTER_NODES)
55
+
56
+ startup_nodes = [ClusterNode(host=h, port=p) for h, p in nodes]
57
+
58
+ return RedisCluster(
59
+ startup_nodes=startup_nodes,
60
+ username=config.REDIS_USER,
61
+ password=config.REDIS_PASSWORD,
62
+ )
63
+
64
+ else:
65
+ return redis.Redis.from_url(
66
+ url=f"{config.REDIS_CONNECTION_STRING}/{cache_database_number}"
67
+ )
68
+
69
+
70
+
71
+ class DistributedCache(Generic[T]):
72
+ def __init__(
73
+ self,
74
+ namespace: str,
75
+ model: Type[T],
76
+ expire_time_hour: int = config.CACHE_EXPIRE_TIME_HOURS,
77
+ ):
78
+ """
79
+ :param namespace: Prefix for the key
80
+ :param model: The Pydantic model class to store/retrieve
81
+ :param expire_time_hour: Time-to-live for each item in hours
82
+ """
83
+
84
+ self.client = get_redis_client()
85
+ if not self.client.ping():
86
+ raise BusinessException(ErrorCode.Internal_Server)
87
+
88
+ self.namespace = namespace
89
+ self.model = model
90
+ self.expire_time = self.expire_time_to_seconds(expire_time_hour)
91
+
92
+ def expire_time_to_seconds(self, hours: int) -> int:
93
+ return hours * 60 * 60
94
+
95
+ def _pref(self, key: str) -> str:
96
+ return f"{self.namespace}:{key}"
97
+
98
+ def _serialize(self, value: T) -> str:
99
+ return value.model_dump_json()
100
+
101
+ def _deserialize(self, raw: bytes) -> T:
102
+ return self.model.model_validate_json(raw.decode())
103
+
104
+ def set(self, key: str, value: T) -> None:
105
+ if value is None:
106
+ return
107
+ skey = self._pref(key)
108
+ payload = self._serialize(value)
109
+ self.client.set(skey, payload, ex=self.expire_time)
110
+
111
+ def get(self, key: str) -> Optional[T]:
112
+ skey = self._pref(key)
113
+ raw = self.client.get(skey)
114
+ if raw is None:
115
+ return None
116
+ return self._deserialize(raw)
117
+
118
+ def get_all_ids(self) -> list[str]:
119
+ return [
120
+ raw.decode().split(":")[1]
121
+ for raw in self.client.scan_iter(f"{self.namespace}:*")
122
+ ]
123
+
124
+ def exists(self, key: str) -> bool:
125
+ skey = self._pref(key)
126
+ return self.client.exists(skey)
127
+
128
+ def delete(self, key):
129
+ self.client.delete(key)
130
+
131
+ def delete_group(self, key_prefix: str):
132
+ pattern = f"{self.namespace}:{key_prefix}*"
133
+ for k in self.client.scan_iter(pattern):
134
+ self.client.delete(k)
135
+
136
+ def clear(self):
137
+ for k in self.client.scan_iter(f"{self.namespace}:*"):
138
+ self.client.delete(k)
@@ -0,0 +1,2 @@
1
+ from .error_code import ErrorCode
2
+ from .redis_mode_enum import RedisMode
@@ -8,3 +8,4 @@ class ErrorCode(str, Enum):
8
8
  Success = "با موفقیت انجام شد"
9
9
  Intents_Count_Should_Equal_One = "فقط یک اینتنت میتوانید وارد نمایید"
10
10
  Unsupported_Date_Type = "تاریخ داده شده پیشتیبانی نمیشود."
11
+ Unsupported_IP = "آی پی داده شده معتبر نمی باشد"
@@ -0,0 +1,8 @@
1
+
2
+ from enum import Enum
3
+
4
+ class RedisMode(str, Enum):
5
+ SENTINEL = "sentinel"
6
+ CLUSTER = "cluster"
7
+ STANDALONE = "standalone"
8
+
@@ -0,0 +1,98 @@
1
+ import json
2
+ import ipaddress
3
+ from typing import List
4
+ from fastapi import Request
5
+ from sharedkernel.exception.exception import UnAuthorizedException, BusinessException
6
+ from sharedkernel.database.distributed_cache import get_redis_client
7
+ from sharedkernel.logger.log_decorator import unified_logger
8
+ from sharedkernel.enum import ErrorCode
9
+ from sharedkernel import config
10
+
11
+
12
+ class IPSessionAuth:
13
+
14
+ def __init__(self):
15
+ self.redis = get_redis_client(cache_database_number=config.IP_SESSION_CACHE_DATABASE_NUMBER)
16
+ self.whitelist_networks = self._load_whitelist(config.WHITE_LIST_IP)
17
+
18
+
19
+ def _load_whitelist(self, raw_value):
20
+ if not raw_value:
21
+ return []
22
+
23
+ entries = [e.strip() for e in raw_value.split(",") if e.strip()]
24
+
25
+ networks = []
26
+
27
+ for entry in entries:
28
+ try:
29
+ if "/" in entry:
30
+ networks.append(ipaddress.ip_network(entry, strict=False))
31
+
32
+ else:
33
+ ip = ipaddress.ip_address(entry)
34
+ networks.append(ipaddress.ip_network(f"{ip}/32"))
35
+
36
+ except ValueError:
37
+ raise BusinessException(ErrorCode.Unsupported_IP)
38
+
39
+ return networks
40
+
41
+
42
+ def _is_ip_allowed(self, ip_str: str) -> bool:
43
+ try:
44
+ ip = ipaddress.ip_address(ip_str)
45
+ except ValueError:
46
+ raise BusinessException(ErrorCode.Unsupported_IP)
47
+
48
+ return any(ip in net for net in self.whitelist_networks)
49
+
50
+
51
+ @unified_logger()
52
+ def ip_session_auth(self, request: Request):
53
+
54
+ if not config.IP_SESSION_AUTH_ENABLE:
55
+ return
56
+
57
+ api_key = request.headers.get(config.APIKEY_HEADER_NAME)
58
+
59
+ if api_key:
60
+ return
61
+
62
+ state = getattr(request.state, "decoded_token", None)
63
+ if not state:
64
+ raise UnAuthorizedException()
65
+
66
+ nameid = state.get("nameid")
67
+ sessionid = state.get("sessionId")
68
+
69
+ if not nameid or not sessionid:
70
+ raise UnAuthorizedException()
71
+
72
+ request_ip = request.headers.get(config.IP_HEADER_NAME)
73
+ if not request_ip:
74
+ raise UnAuthorizedException()
75
+
76
+ request_ip = request_ip.strip()
77
+
78
+ if self._is_ip_allowed(request_ip):
79
+ return
80
+
81
+ redis_key = f"userId:{nameid}:session:{sessionid}"
82
+ user_data = self.redis.get(redis_key)
83
+
84
+ if not user_data:
85
+ raise UnAuthorizedException()
86
+
87
+ try:
88
+ payload = json.loads(user_data.decode())
89
+ except (ValueError, UnicodeDecodeError, TypeError):
90
+ raise UnAuthorizedException()
91
+
92
+ stored_ip = payload.get("Ip")
93
+
94
+ if not stored_ip:
95
+ raise UnAuthorizedException()
96
+
97
+ if stored_ip.strip() != request_ip:
98
+ raise UnAuthorizedException()
@@ -2,12 +2,10 @@ import inspect
2
2
  from functools import wraps
3
3
  from typing import Callable, Type
4
4
  from asyncio import iscoroutinefunction
5
- import os
6
5
 
7
6
  from sharedkernel.logger.logger_service import LoggerService
7
+ from sharedkernel import config
8
8
 
9
- LOG_ENABLE = True if os.getenv("LOG_ENABLE", "True").lower() == "true" else False
10
- print("Log Enable" if LOG_ENABLE else "Log Disable")
11
9
 
12
10
  logger = LoggerService()
13
11
 
@@ -37,7 +35,7 @@ def decorate_class_methods(cls: Type) -> Type:
37
35
  def unified_logger(endpoint_name: str = None, class_name: str = None) -> Callable:
38
36
  def decorator(target: Callable | Type):
39
37
 
40
- if not LOG_ENABLE:
38
+ if not config.LOG_ENABLE:
41
39
  return target
42
40
 
43
41
  if inspect.isclass(target):
@@ -1,25 +1,22 @@
1
1
  import uuid
2
2
  from typing import Callable
3
- import os
4
3
  from fastapi import Request, Response
5
4
  from starlette.middleware.base import BaseHTTPMiddleware
6
5
 
7
6
 
8
7
  from sharedkernel.logger.log_info import log_info
9
8
  from sharedkernel.logger.log_dto import LogDTO
10
-
11
- IP_HEADER_NAME = os.getenv("IP_HEADER_NAME", "true-client-ip")
12
- LOG_ENABLE = True if os.getenv("LOG_ENABLE", "True").lower() == "true" else False
9
+ from sharedkernel import config
13
10
 
14
11
  class LogMiddleware(BaseHTTPMiddleware):
15
12
 
16
13
  async def dispatch(self, request: Request, call_next: Callable) -> Response:
17
14
 
18
- if not LOG_ENABLE:
15
+ if not config.LOG_ENABLE:
19
16
  return await call_next(request)
20
17
 
21
18
  correlation_id = request.headers.get("x-request-id") or uuid.uuid4().hex
22
- ip_address = request.headers.get(IP_HEADER_NAME)
19
+ ip_address = request.headers.get(config.IP_HEADER_NAME)
23
20
  log_obj = LogDTO(
24
21
  CorrelationId=correlation_id,
25
22
  RequestPath=request.url.path,
@@ -4,7 +4,6 @@ from pydantic import BaseModel
4
4
  from typing import Optional
5
5
  import datetime
6
6
  import uuid
7
- import os
8
7
 
9
8
  from sharedkernel.logger.log_info import log_info
10
9
  from sharedkernel.enum import ErrorCode
@@ -12,26 +11,19 @@ from sharedkernel.objects.user_info import current_user_info
12
11
  from sharedkernel.exception.exception import BusinessException
13
12
  from sharedkernel.logger.log_dto import LogDTO
14
13
  from sharedkernel.logger.log_enums import LogEventTypeEnum, LogLevelEnum
14
+ from sharedkernel import config
15
15
 
16
- RABBITMQ_USER = os.getenv("RABBITMQ_USER")
17
- RABBITMQ_PASSWORD = os.getenv("RABBITMQ_PASSWORD")
18
- RABBITMQ_HOST = os.getenv("RABBITMQ_HOST")
19
- RABBITMQ_VHOST = os.getenv("RABBITMQ_VHOST")
20
- LOG_EXCHANGE = os.getenv("LOG_EXCHANGE")
21
- LOG_REQUESTS_QUEUE = os.getenv("LOG_REQUESTS_QUEUE")
22
- SERVICE_NAME = os.getenv("SERVICE_NAME")
23
- IP_HEADER_NAME = os.getenv("IP_HEADER_NAME", "IP_HEADER_NAME")
24
16
 
25
17
  rabbitmq_url = (
26
- f"amqp://{RABBITMQ_USER}:{RABBITMQ_PASSWORD}"
27
- f"@{RABBITMQ_HOST}/{RABBITMQ_VHOST}"
18
+ f"amqp://{config.RABBITMQ_USER}:{config.RABBITMQ_PASSWORD}"
19
+ f"@{config.RABBITMQ_HOST}/{config.RABBITMQ_VHOST}"
28
20
  )
29
21
 
30
22
  class LoggerService:
31
23
  def __init__(self):
32
24
  self._connection: Optional[Connection] = None
33
25
  self._producer: Optional[Producer] = None
34
- self._exchange = Exchange(LOG_EXCHANGE, type="topic")
26
+ self._exchange = Exchange(config.LOG_EXCHANGE, type="topic")
35
27
 
36
28
 
37
29
  def _ensure_connection(self):
@@ -47,10 +39,10 @@ class LoggerService:
47
39
  self._producer.publish(
48
40
  body=log.model_dump_json(),
49
41
  exchange=self._exchange,
50
- routing_key=LOG_REQUESTS_QUEUE,
42
+ routing_key=config.LOG_REQUESTS_QUEUE,
51
43
  headers={
52
44
  "cap-msg-id": str(uuid.uuid4()),
53
- "cap-msg-name": LOG_REQUESTS_QUEUE,
45
+ "cap-msg-name": config.LOG_REQUESTS_QUEUE,
54
46
  },
55
47
  content_type="application/json",
56
48
  retry=True
@@ -70,7 +62,7 @@ class LoggerService:
70
62
  user = current_user_info.get(None)
71
63
  if user:
72
64
  log.UserId = user.nameid
73
- log.ServiceName = SERVICE_NAME
65
+ log.ServiceName = config.SERVICE_NAME
74
66
  log.MethodName = method_name
75
67
  log.Description = endpoint_name
76
68
  log.IsSuccess = is_success
@@ -141,8 +133,10 @@ class LoggerService:
141
133
 
142
134
  @staticmethod
143
135
  def websocket_handler(websocket: WebSocket):
136
+ if not config.LOG_ENABLE:
137
+ return
144
138
  correlation_id = websocket.headers.get("x-request-id") or uuid.uuid4().hex
145
- ip_address = websocket.headers.get(IP_HEADER_NAME)
139
+ ip_address = websocket.headers.get(config.IP_HEADER_NAME)
146
140
 
147
141
  log_obj = LogDTO(
148
142
  CorrelationId=correlation_id,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sharedkernel
3
- Version: 2.5.3
3
+ Version: 2.5.6
4
4
  Summary: sharekernel is a shared package between all python projects
5
5
  Author: Smilinno
6
6
  Description-Content-Type: text/markdown
@@ -20,6 +20,7 @@ Requires-Dist: markdown
20
20
  Requires-Dist: beautifulsoup4
21
21
  Requires-Dist: deepdiff
22
22
  Requires-Dist: kombu
23
+ Requires-Dist: redis
23
24
  Dynamic: author
24
25
  Dynamic: description
25
26
  Dynamic: description-content-type
@@ -30,6 +31,12 @@ Dynamic: summary
30
31
  this is a shared kernel package
31
32
 
32
33
  # Change Log
34
+ ### Version 2.5.6
35
+ - fix bug
36
+ ### Version 2.5.5
37
+ - fix bug
38
+ ### Version 2.5.4
39
+ - Add Ip Session Service
33
40
  ### Version 2.5.3
34
41
  - Fix bug
35
42
  ### Version 2.5.2
@@ -1,10 +1,12 @@
1
1
  README.md
2
2
  setup.py
3
3
  sharedkernel/common.py
4
+ sharedkernel/config.py
4
5
  sharedkernel/data_format_converter.py
5
6
  sharedkernel/date_converter.py
6
7
  sharedkernel/diff_utils.py
7
8
  sharedkernel/file_validation.py
9
+ sharedkernel/ip_session_service.py
8
10
  sharedkernel/jwt_service.py
9
11
  sharedkernel/multipart_upload.py
10
12
  sharedkernel/regex_masking.py
@@ -17,11 +19,13 @@ sharedkernel.egg-info/requires.txt
17
19
  sharedkernel.egg-info/top_level.txt
18
20
  sharedkernel/database/__init__.py
19
21
  sharedkernel/database/audit_model.py
22
+ sharedkernel/database/distributed_cache.py
20
23
  sharedkernel/database/mongo_generic_audit_repository.py
21
24
  sharedkernel/database/mongo_generic_repository.py
22
25
  sharedkernel/database/pagination_response_dto.py
23
26
  sharedkernel/enum/__init__.py
24
27
  sharedkernel/enum/error_code.py
28
+ sharedkernel/enum/redis_mode_enum.py
25
29
  sharedkernel/enum/sort_order.py
26
30
  sharedkernel/exception/__init__.py
27
31
  sharedkernel/exception/exception.py
@@ -14,3 +14,4 @@ markdown
14
14
  beautifulsoup4
15
15
  deepdiff
16
16
  kombu
17
+ redis
@@ -1 +0,0 @@
1
- from .error_code import ErrorCode
File without changes