sharedkernel 2.7.0__tar.gz → 2.9.0__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.
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/PKG-INFO +6 -1
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/README.md +4 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/setup.py +4 -1
- sharedkernel-2.9.0/sharedkernel/chunker/chunk_rule.py +84 -0
- sharedkernel-2.9.0/sharedkernel/chunker/text_chunker.py +107 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/config.py +0 -1
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/cache/redis_generic_cache.py +1 -1
- sharedkernel-2.9.0/sharedkernel/enum/__init__.py +7 -0
- sharedkernel-2.9.0/sharedkernel/enum/error_code.py +21 -0
- sharedkernel-2.9.0/sharedkernel/enum/feature_display_type.py +5 -0
- sharedkernel-2.9.0/sharedkernel/enum/feature_key.py +11 -0
- sharedkernel-2.9.0/sharedkernel/enum/order_type.py +5 -0
- sharedkernel-2.9.0/sharedkernel/enum/plan_interval.py +7 -0
- sharedkernel-2.9.0/sharedkernel/enum/plan_type.py +7 -0
- sharedkernel-2.9.0/sharedkernel/objects/subscription.py +33 -0
- sharedkernel-2.9.0/sharedkernel/toolbox_service.py +70 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel.egg-info/PKG-INFO +6 -1
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel.egg-info/SOURCES.txt +9 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel.egg-info/requires.txt +1 -0
- sharedkernel-2.7.0/sharedkernel/enum/__init__.py +0 -2
- sharedkernel-2.7.0/sharedkernel/enum/error_code.py +0 -11
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/setup.cfg +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/common.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/data_format_converter.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/__init__.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/audit_model.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/cache/__init__.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/cache/cache_repository.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/distributed_cache.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/mongo_generic_audit_repository.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/mongo_generic_repository.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/mongo_health_checker.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/pagination_response_dto.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/date_converter.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/diff_utils.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/enum/redis_mode_enum.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/enum/sort_order.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/exception/__init__.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/exception/exception.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/exception/exception_handlers.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/file_validation.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/ip_session_service.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/jwt_service.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/logger/log_decorator.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/logger/log_dto.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/logger/log_enums.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/logger/log_info.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/logger/log_middlewares.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/logger/logger_service.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/multipart_upload.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/normalizer/__init__.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/normalizer/number_normalizer.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/normalizer/phone_number_normalizer.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/normalizer/string_normalizer.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/objects/__init__.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/objects/base_document.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/objects/json_string_model.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/objects/jwt_model.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/objects/result.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/objects/user_info.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/regex_masking.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/s3_uploader.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/string_extentions.py +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel.egg-info/dependency_links.txt +0 -0
- {sharedkernel-2.7.0 → sharedkernel-2.9.0}/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.
|
|
3
|
+
Version: 2.9.0
|
|
4
4
|
Summary: sharekernel is a shared package between all python projects
|
|
5
5
|
Author: Smilinno
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -21,6 +21,7 @@ Requires-Dist: beautifulsoup4
|
|
|
21
21
|
Requires-Dist: deepdiff
|
|
22
22
|
Requires-Dist: kombu
|
|
23
23
|
Requires-Dist: redis==8.0.0
|
|
24
|
+
Requires-Dist: aiohttp
|
|
24
25
|
Dynamic: author
|
|
25
26
|
Dynamic: description
|
|
26
27
|
Dynamic: description-content-type
|
|
@@ -31,6 +32,10 @@ Dynamic: summary
|
|
|
31
32
|
this is a shared kernel package
|
|
32
33
|
|
|
33
34
|
# Change Log
|
|
35
|
+
### Version 2.9.0
|
|
36
|
+
- Add toolbox_service
|
|
37
|
+
### Version 2.8.0
|
|
38
|
+
- Add chunker for tts
|
|
34
39
|
### Version 2.7.0
|
|
35
40
|
- Add Redis and cache repository
|
|
36
41
|
### Version 2.6.4
|
|
@@ -19,6 +19,8 @@ setup(
|
|
|
19
19
|
"sharedkernel.objects",
|
|
20
20
|
"sharedkernel.normalizer",
|
|
21
21
|
"sharedkernel.logger",
|
|
22
|
+
"sharedkernel.chunker",
|
|
23
|
+
|
|
22
24
|
],
|
|
23
25
|
# Needed for dependencies
|
|
24
26
|
install_requires=[
|
|
@@ -39,9 +41,10 @@ setup(
|
|
|
39
41
|
"deepdiff",
|
|
40
42
|
"kombu",
|
|
41
43
|
"redis==8.0.0",
|
|
44
|
+
"aiohttp",
|
|
42
45
|
],
|
|
43
46
|
# *strongly* suggested for sharing
|
|
44
|
-
version="2.
|
|
47
|
+
version="2.9.0",
|
|
45
48
|
description="sharekernel is a shared package between all python projects",
|
|
46
49
|
long_description=long_description,
|
|
47
50
|
long_description_content_type="text/markdown",
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import re
|
|
3
|
+
from typing import List, Optional, Protocol, Tuple
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SplitRule(Protocol):
|
|
7
|
+
"""Interface for chunk split rules."""
|
|
8
|
+
|
|
9
|
+
def apply(
|
|
10
|
+
self, segment: str, offset: int
|
|
11
|
+
) -> Tuple[Optional[int], Optional[str], Optional[str]]: ...
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class PunctuationRule(SplitRule):
|
|
15
|
+
"""Split after the first matching punctuation character."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, punctuations: str = ".,;:!?"):
|
|
18
|
+
self.punctuations = set(punctuations)
|
|
19
|
+
|
|
20
|
+
def apply(
|
|
21
|
+
self, segment: str, offset: int
|
|
22
|
+
) -> Tuple[Optional[int], Optional[str], Optional[str]]:
|
|
23
|
+
for i, ch in enumerate(segment):
|
|
24
|
+
if ch in self.punctuations:
|
|
25
|
+
return offset + i + 1, ch, "punctuation"
|
|
26
|
+
return None, None, None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class RegexRule(SplitRule):
|
|
30
|
+
"""Split after the first regex match."""
|
|
31
|
+
|
|
32
|
+
def __init__(self, pattern: str):
|
|
33
|
+
self.regex = re.compile(pattern) if pattern else None
|
|
34
|
+
|
|
35
|
+
def apply(
|
|
36
|
+
self, segment: str, offset: int
|
|
37
|
+
) -> Tuple[Optional[int], Optional[str], Optional[str]]:
|
|
38
|
+
if not self.regex:
|
|
39
|
+
return None, None, None
|
|
40
|
+
m = self.regex.search(segment)
|
|
41
|
+
if m:
|
|
42
|
+
return offset + m.end(), segment[m.start() : m.end()], "regex"
|
|
43
|
+
return None, None, None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class CutWordRule(SplitRule):
|
|
47
|
+
"""Split after the first occurrence of any configured word/phrase."""
|
|
48
|
+
|
|
49
|
+
def __init__(self, cut_words: List[str]):
|
|
50
|
+
self.cut_words = [w.lower() for w in cut_words]
|
|
51
|
+
|
|
52
|
+
def apply(
|
|
53
|
+
self, segment: str, offset: int
|
|
54
|
+
) -> Tuple[Optional[int], Optional[str], Optional[str]]:
|
|
55
|
+
lowered = segment.lower()
|
|
56
|
+
for word in self.cut_words:
|
|
57
|
+
idx = lowered.find(word)
|
|
58
|
+
if idx != -1:
|
|
59
|
+
phrase = segment[idx : idx + len(word)]
|
|
60
|
+
return offset + idx + len(word), phrase, "cut_word"
|
|
61
|
+
return None, None, None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class SpaceFallbackRule(SplitRule):
|
|
65
|
+
"""Split near the center on space; otherwise hard-cut at max_len."""
|
|
66
|
+
|
|
67
|
+
def __init__(self, max_len: int):
|
|
68
|
+
self.max_len = max_len
|
|
69
|
+
|
|
70
|
+
def apply(
|
|
71
|
+
self, segment: str, offset: int
|
|
72
|
+
) -> Tuple[Optional[int], Optional[str], Optional[str]]:
|
|
73
|
+
centre = len(segment) // 2
|
|
74
|
+
left = segment.rfind(" ", 0, centre)
|
|
75
|
+
right = segment.find(" ", centre)
|
|
76
|
+
|
|
77
|
+
if left != -1:
|
|
78
|
+
split = left
|
|
79
|
+
elif right != -1:
|
|
80
|
+
split = right
|
|
81
|
+
else:
|
|
82
|
+
split = self.max_len
|
|
83
|
+
|
|
84
|
+
return offset + split, None, "space_fallback"
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
from .chunk_rule import (
|
|
5
|
+
SplitRule,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class Chunk:
|
|
11
|
+
"""A single chunk produced by TextChunker."""
|
|
12
|
+
|
|
13
|
+
text: str
|
|
14
|
+
number: int
|
|
15
|
+
begin: int
|
|
16
|
+
end: int
|
|
17
|
+
method: str
|
|
18
|
+
phrase: Optional[str]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TextChunker:
|
|
22
|
+
"""Split text into chunks based on ordered split rules."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, min_len: int, max_len: int, rules: List[SplitRule]):
|
|
25
|
+
if min_len < 1:
|
|
26
|
+
raise ValueError("min_len must be >= 1")
|
|
27
|
+
if max_len < min_len:
|
|
28
|
+
raise ValueError("max_len must be >= min_len")
|
|
29
|
+
|
|
30
|
+
self.min_len = min_len
|
|
31
|
+
self.max_len = max_len
|
|
32
|
+
self.rules = rules
|
|
33
|
+
|
|
34
|
+
def chunk(self, text: str) -> List[Chunk]:
|
|
35
|
+
if not text:
|
|
36
|
+
return []
|
|
37
|
+
|
|
38
|
+
chunks: List[Chunk] = []
|
|
39
|
+
pos = 0
|
|
40
|
+
number = 1
|
|
41
|
+
|
|
42
|
+
while pos < len(text):
|
|
43
|
+
if len(text) - pos <= self.max_len:
|
|
44
|
+
chunk_text = text[pos:]
|
|
45
|
+
chunks.append(Chunk(chunk_text, number, pos, len(text), "final", None))
|
|
46
|
+
break
|
|
47
|
+
|
|
48
|
+
window_end = pos + self.max_len
|
|
49
|
+
window = text[pos:window_end]
|
|
50
|
+
|
|
51
|
+
split_idx: Optional[int] = None
|
|
52
|
+
phrase: Optional[str] = None
|
|
53
|
+
method: Optional[str] = None
|
|
54
|
+
|
|
55
|
+
for rule in self.rules:
|
|
56
|
+
candidate, cand_phrase, cand_method = rule.apply(window, pos)
|
|
57
|
+
if candidate is not None and candidate - pos >= self.min_len:
|
|
58
|
+
split_idx, phrase, method = candidate, cand_phrase, cand_method
|
|
59
|
+
break
|
|
60
|
+
|
|
61
|
+
if split_idx is None:
|
|
62
|
+
split_idx = pos + self.max_len
|
|
63
|
+
method = "hard_cut"
|
|
64
|
+
|
|
65
|
+
chunk_text = text[pos:split_idx]
|
|
66
|
+
chunks.append(Chunk(chunk_text, number, pos, split_idx, method, phrase))
|
|
67
|
+
pos = split_idx
|
|
68
|
+
number += 1
|
|
69
|
+
|
|
70
|
+
return chunks
|
|
71
|
+
|
|
72
|
+
def chunks(self, text: str):
|
|
73
|
+
"""Yield chunks lazily, using the same logic as `chunk`."""
|
|
74
|
+
if not text:
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
pos = 0
|
|
78
|
+
number = 1
|
|
79
|
+
|
|
80
|
+
while pos < len(text):
|
|
81
|
+
if len(text) - pos <= self.max_len:
|
|
82
|
+
chunk_text = text[pos:]
|
|
83
|
+
yield Chunk(chunk_text, number, pos, len(text), "final", None)
|
|
84
|
+
break
|
|
85
|
+
|
|
86
|
+
window_end = pos + self.max_len
|
|
87
|
+
window = text[pos:window_end]
|
|
88
|
+
|
|
89
|
+
split_idx: Optional[int] = None
|
|
90
|
+
phrase: Optional[str] = None
|
|
91
|
+
method: Optional[str] = None
|
|
92
|
+
|
|
93
|
+
for rule in self.rules:
|
|
94
|
+
candidate, cand_phrase, cand_method = rule.apply(window, pos)
|
|
95
|
+
if candidate is not None and candidate - pos >= self.min_len:
|
|
96
|
+
split_idx, phrase, method = candidate, cand_phrase, cand_method
|
|
97
|
+
break
|
|
98
|
+
|
|
99
|
+
if split_idx is None:
|
|
100
|
+
split_idx = pos + self.max_len
|
|
101
|
+
method = "hard_cut"
|
|
102
|
+
|
|
103
|
+
chunk_text = text[pos:split_idx]
|
|
104
|
+
yield Chunk(chunk_text, number, pos, split_idx, method, phrase)
|
|
105
|
+
|
|
106
|
+
pos = split_idx
|
|
107
|
+
number += 1
|
|
@@ -26,7 +26,6 @@ IP_SESSION_CACHE_DATABASE_NUMBER = os.getenv("IP_SESSION_CACHE_DATABASE_NUMBER")
|
|
|
26
26
|
REDIS_URL = os.getenv("REDIS_URL")
|
|
27
27
|
REDIS_PASSWORD = os.getenv("REDIS_PASSWORD")
|
|
28
28
|
REDIS_USER = os.getenv("REDIS_USER")
|
|
29
|
-
REDIS_CONNECTION_STRING = os.getenv("REDIS_CONNECTION_STRING")
|
|
30
29
|
CACHE_DATABASE_NUMBER = os.getenv("CACHE_DATABASE_NUMBER")
|
|
31
30
|
REDIS_CONNECTION_STRING = os.getenv(
|
|
32
31
|
"REDIS_CONNECTION_STRING", f"redis://{REDIS_USER}:{REDIS_PASSWORD}@{REDIS_URL}"
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from .error_code import ErrorCode
|
|
2
|
+
from .redis_mode_enum import RedisMode
|
|
3
|
+
from .feature_key import FeatureKey
|
|
4
|
+
from .plan_type import PlanType
|
|
5
|
+
from .plan_interval import PlanInterval
|
|
6
|
+
from .order_type import OrderType
|
|
7
|
+
from .feature_display_type import FeatureDisplayType
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ErrorCode(str, Enum):
|
|
5
|
+
Item_NotFound = "یافت نشد"
|
|
6
|
+
Internal_Server = "خطایی در سیستم رخ داده است"
|
|
7
|
+
UnAuthorized = "توکن دسترسی معتبر نمی باشد"
|
|
8
|
+
Success = "با موفقیت انجام شد"
|
|
9
|
+
Intents_Count_Should_Equal_One = "فقط یک اینتنت میتوانید وارد نمایید"
|
|
10
|
+
Unsupported_Date_Type = "تاریخ داده شده پیشتیبانی نمیشود."
|
|
11
|
+
Unsupported_IP = "آی پی داده شده معتبر نمی باشد"
|
|
12
|
+
Subscription_Not_Found = "اشتراک فعالی برای شما یافت نشد"
|
|
13
|
+
Subscription_Insufficient_Bot_Feature = "اعتبار شما برای ساخت بات کافی نیست"
|
|
14
|
+
Subscription_Insufficient_Message_Feature = "اعتبار شما برای ارسال پیام کافی نیست"
|
|
15
|
+
Subscription_Insufficient_URL_FEATURE = "اعتبار تعداد پردازش آدرس شما به اتمام رسیده"
|
|
16
|
+
Subscription_Insufficient_TEXT_FEATURE = "اعتبار تعداد پردازش متن شما به اتمام رسیده"
|
|
17
|
+
Subscription_Insufficient_FILE_FEATURE = "اعتبار تعداد پردازش فایل شما به اتمام رسیده"
|
|
18
|
+
Subscription_Insufficient_OCR_FEATURE = "اعتبار تعداد پردازش صفحات تصویر به متن شما به اتمام رسیده"
|
|
19
|
+
Subscription_Insufficient_TTS_FEATURE = "اعتبار تعداد پردازش متن به گفتار شما به اتمام رسیده"
|
|
20
|
+
Subscription_Insufficient_ASR_FEATURE = "اعتبار تعداد پردازش گفتار به متن شما به اتمام رسیده"
|
|
21
|
+
Subscription_Expired = "اشتراک شما منقضی شده است"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
from sharedkernel.objects.base_document import BaseDocument
|
|
5
|
+
from sharedkernel.enum import PlanInterval, OrderType, PlanType, FeatureKey, FeatureDisplayType
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SubscriptionFeature(BaseModel):
|
|
9
|
+
feature_key: FeatureKey
|
|
10
|
+
feature_unit: Optional[str] = None
|
|
11
|
+
remaining: int
|
|
12
|
+
original: int
|
|
13
|
+
title: str
|
|
14
|
+
description: Optional[str] = None
|
|
15
|
+
display_type: FeatureDisplayType = FeatureDisplayType.CIRCULAR
|
|
16
|
+
|
|
17
|
+
class Subscription(BaseDocument):
|
|
18
|
+
order_id: str
|
|
19
|
+
plan_id: str
|
|
20
|
+
plan_title: str
|
|
21
|
+
user_id: str
|
|
22
|
+
workspace_id: str
|
|
23
|
+
interval: PlanInterval
|
|
24
|
+
interval_count: int
|
|
25
|
+
type: OrderType
|
|
26
|
+
plan_type: PlanType | None = PlanType.FREE
|
|
27
|
+
features: List[SubscriptionFeature] | None = []
|
|
28
|
+
paid_at: datetime | None = None
|
|
29
|
+
from_date: datetime | None = None
|
|
30
|
+
to_date: datetime | None = None
|
|
31
|
+
is_active: bool
|
|
32
|
+
sum_messages: int | None = 0
|
|
33
|
+
avg_messages: float | None = 0
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from typing import Type
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
import aiohttp
|
|
4
|
+
|
|
5
|
+
from sharedkernel.objects.result import Result
|
|
6
|
+
from sharedkernel.enum import FeatureKey, PlanType
|
|
7
|
+
from sharedkernel.enum import ErrorCode
|
|
8
|
+
from sharedkernel.objects.subscription import Subscription
|
|
9
|
+
from sharedkernel.exception.exception import BusinessException
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ToolboxService:
|
|
13
|
+
def __init__(self, cache):
|
|
14
|
+
self.cache = cache
|
|
15
|
+
|
|
16
|
+
async def send_request(
|
|
17
|
+
self,
|
|
18
|
+
method: str,
|
|
19
|
+
endpoint: str,
|
|
20
|
+
payload: dict = None,
|
|
21
|
+
params: dict | None = None,
|
|
22
|
+
headers: dict | None = None,
|
|
23
|
+
model: Type[BaseModel] | None = None,
|
|
24
|
+
) -> Result:
|
|
25
|
+
|
|
26
|
+
async with aiohttp.ClientSession() as session:
|
|
27
|
+
async with session.request(
|
|
28
|
+
method=method.upper(),
|
|
29
|
+
url=endpoint,
|
|
30
|
+
json=payload,
|
|
31
|
+
params=params,
|
|
32
|
+
headers=headers,
|
|
33
|
+
) as response:
|
|
34
|
+
|
|
35
|
+
response_data = await response.json()
|
|
36
|
+
return Result(
|
|
37
|
+
**response_data,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def check_user_subscription(
|
|
43
|
+
self,
|
|
44
|
+
user_subscription: Subscription,
|
|
45
|
+
feature: FeatureKey,
|
|
46
|
+
quantity: int = 1
|
|
47
|
+
):
|
|
48
|
+
|
|
49
|
+
feature_errors = {
|
|
50
|
+
FeatureKey.MESSAGES: ErrorCode.Subscription_Insufficient_Message_Feature,
|
|
51
|
+
FeatureKey.BOTS: ErrorCode.Subscription_Insufficient_Bot_Feature,
|
|
52
|
+
FeatureKey.URLS: ErrorCode.Subscription_Insufficient_URL_FEATURE,
|
|
53
|
+
FeatureKey.TEXTS: ErrorCode.Subscription_Insufficient_TEXT_FEATURE,
|
|
54
|
+
FeatureKey.FILES: ErrorCode.Subscription_Insufficient_FILE_FEATURE,
|
|
55
|
+
FeatureKey.OCR: ErrorCode.Subscription_Insufficient_OCR_FEATURE,
|
|
56
|
+
FeatureKey.TTS: ErrorCode.Subscription_Insufficient_TTS_FEATURE,
|
|
57
|
+
FeatureKey.ASR: ErrorCode.Subscription_Insufficient_ASR_FEATURE,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if not user_subscription:
|
|
61
|
+
raise BusinessException(error_code=ErrorCode.Subscription_Not_Found)
|
|
62
|
+
|
|
63
|
+
if user_subscription.plan_type == PlanType.UNLIMITED:
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
for _feature in user_subscription.features:
|
|
67
|
+
if _feature.feature_key == feature:
|
|
68
|
+
if _feature.remaining - quantity < 0:
|
|
69
|
+
raise BusinessException(error_code=feature_errors[feature])
|
|
70
|
+
break
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sharedkernel
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.0
|
|
4
4
|
Summary: sharekernel is a shared package between all python projects
|
|
5
5
|
Author: Smilinno
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -21,6 +21,7 @@ Requires-Dist: beautifulsoup4
|
|
|
21
21
|
Requires-Dist: deepdiff
|
|
22
22
|
Requires-Dist: kombu
|
|
23
23
|
Requires-Dist: redis==8.0.0
|
|
24
|
+
Requires-Dist: aiohttp
|
|
24
25
|
Dynamic: author
|
|
25
26
|
Dynamic: description
|
|
26
27
|
Dynamic: description-content-type
|
|
@@ -31,6 +32,10 @@ Dynamic: summary
|
|
|
31
32
|
this is a shared kernel package
|
|
32
33
|
|
|
33
34
|
# Change Log
|
|
35
|
+
### Version 2.9.0
|
|
36
|
+
- Add toolbox_service
|
|
37
|
+
### Version 2.8.0
|
|
38
|
+
- Add chunker for tts
|
|
34
39
|
### Version 2.7.0
|
|
35
40
|
- Add Redis and cache repository
|
|
36
41
|
### Version 2.6.4
|
|
@@ -12,11 +12,14 @@ sharedkernel/multipart_upload.py
|
|
|
12
12
|
sharedkernel/regex_masking.py
|
|
13
13
|
sharedkernel/s3_uploader.py
|
|
14
14
|
sharedkernel/string_extentions.py
|
|
15
|
+
sharedkernel/toolbox_service.py
|
|
15
16
|
sharedkernel.egg-info/PKG-INFO
|
|
16
17
|
sharedkernel.egg-info/SOURCES.txt
|
|
17
18
|
sharedkernel.egg-info/dependency_links.txt
|
|
18
19
|
sharedkernel.egg-info/requires.txt
|
|
19
20
|
sharedkernel.egg-info/top_level.txt
|
|
21
|
+
sharedkernel/chunker/chunk_rule.py
|
|
22
|
+
sharedkernel/chunker/text_chunker.py
|
|
20
23
|
sharedkernel/database/__init__.py
|
|
21
24
|
sharedkernel/database/audit_model.py
|
|
22
25
|
sharedkernel/database/distributed_cache.py
|
|
@@ -29,6 +32,11 @@ sharedkernel/database/cache/cache_repository.py
|
|
|
29
32
|
sharedkernel/database/cache/redis_generic_cache.py
|
|
30
33
|
sharedkernel/enum/__init__.py
|
|
31
34
|
sharedkernel/enum/error_code.py
|
|
35
|
+
sharedkernel/enum/feature_display_type.py
|
|
36
|
+
sharedkernel/enum/feature_key.py
|
|
37
|
+
sharedkernel/enum/order_type.py
|
|
38
|
+
sharedkernel/enum/plan_interval.py
|
|
39
|
+
sharedkernel/enum/plan_type.py
|
|
32
40
|
sharedkernel/enum/redis_mode_enum.py
|
|
33
41
|
sharedkernel/enum/sort_order.py
|
|
34
42
|
sharedkernel/exception/__init__.py
|
|
@@ -49,4 +57,5 @@ sharedkernel/objects/base_document.py
|
|
|
49
57
|
sharedkernel/objects/json_string_model.py
|
|
50
58
|
sharedkernel/objects/jwt_model.py
|
|
51
59
|
sharedkernel/objects/result.py
|
|
60
|
+
sharedkernel/objects/subscription.py
|
|
52
61
|
sharedkernel/objects/user_info.py
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from enum import Enum
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class ErrorCode(str, Enum):
|
|
5
|
-
Item_NotFound = "یافت نشد"
|
|
6
|
-
Internal_Server = "خطایی در سیستم رخ داده است"
|
|
7
|
-
UnAuthorized = "توکن دسترسی معتبر نمی باشد"
|
|
8
|
-
Success = "با موفقیت انجام شد"
|
|
9
|
-
Intents_Count_Should_Equal_One = "فقط یک اینتنت میتوانید وارد نمایید"
|
|
10
|
-
Unsupported_Date_Type = "تاریخ داده شده پیشتیبانی نمیشود."
|
|
11
|
-
Unsupported_IP = "آی پی داده شده معتبر نمی باشد"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/database/mongo_generic_audit_repository.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sharedkernel-2.7.0 → sharedkernel-2.9.0}/sharedkernel/normalizer/phone_number_normalizer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|