rainbow-rb-utils 0.1.1__tar.gz → 0.1.2.dev2__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.
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/PKG-INFO +2 -2
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/pyproject.toml +2 -2
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/parser.py +3 -3
- rainbow_rb_utils-0.1.2.dev2/src/rainbow/rb_utils/path_utils.py +36 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/program.py +4 -1
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow_rb_utils.egg-info/PKG-INFO +2 -2
- rainbow_rb_utils-0.1.2.dev2/src/rainbow_rb_utils.egg-info/requires.txt +2 -0
- rainbow_rb_utils-0.1.1/src/rainbow/rb_utils/path_utils.py +0 -29
- rainbow_rb_utils-0.1.1/src/rainbow_rb_utils.egg-info/requires.txt +0 -2
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/README.md +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/setup.cfg +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/__init__.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/asyncio_helper.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/date.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/env.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/file.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/flatbuffer.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/flow_manager.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/helper.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/manipulate.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/pagination.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/py.typed +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/service_exception.py +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow_rb_utils.egg-info/SOURCES.txt +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow_rb_utils.egg-info/dependency_links.txt +0 -0
- {rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow_rb_utils.egg-info/top_level.txt +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rainbow-rb-utils
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2.dev2
|
|
4
4
|
Summary: Rainbow Python Utilities
|
|
5
5
|
Author-email: Derek <dfd1123@rainbow-robotics.com>
|
|
6
6
|
Requires-Python: <3.14,>=3.11
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Requires-Dist: psutil<8.0.0,>=7.0.0
|
|
9
|
-
Requires-Dist: rainbow-rb-log==0.1.
|
|
9
|
+
Requires-Dist: rainbow-rb-log==0.1.2.dev2
|
|
10
10
|
|
|
11
11
|
# rb_utils
|
|
12
12
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rainbow-rb-utils"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2.dev2"
|
|
8
8
|
requires-python = ">=3.11,<3.14"
|
|
9
9
|
description = "Rainbow Python Utilities"
|
|
10
10
|
authors = [
|
|
@@ -14,7 +14,7 @@ readme = "README.md"
|
|
|
14
14
|
|
|
15
15
|
dependencies = [
|
|
16
16
|
"psutil>=7.0.0,<8.0.0",
|
|
17
|
-
"rainbow-rb-log==0.1.
|
|
17
|
+
"rainbow-rb-log==0.1.2.dev2",
|
|
18
18
|
]
|
|
19
19
|
|
|
20
20
|
[tool.setuptools]
|
|
@@ -139,11 +139,11 @@ def _normalize_filter(filter_: Any) -> dict:
|
|
|
139
139
|
try:
|
|
140
140
|
data = json.loads(s)
|
|
141
141
|
except Exception as e:
|
|
142
|
-
raise TypeError(f"filter_ JSON
|
|
142
|
+
raise TypeError(f"filter_ JSON parse failed: {e}") from e
|
|
143
143
|
if not isinstance(data, dict):
|
|
144
|
-
raise TypeError("filter_
|
|
144
|
+
raise TypeError("filter_ string must be a JSON object.")
|
|
145
145
|
return data
|
|
146
|
-
raise TypeError(f"filter_
|
|
146
|
+
raise TypeError(f"filter_ has an invalid type: {type(filter_)}")
|
|
147
147
|
|
|
148
148
|
|
|
149
149
|
def to_json(obj: Any) -> str:
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
# `{name}` 또는 `{name:path}`. group(1)=이름, group(2)=converter(없으면 None)
|
|
4
|
+
PLACEHOLDER_PATTERN = r"{(\w+)(?::(\w+))?}"
|
|
5
|
+
# 하위 호환용. 새 코드는 template_to_regex_str
|
|
6
|
+
REGEX_PATTERN = r"(?P<\1>[^/]+)"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def normalize_topic(topic: str) -> str:
|
|
10
|
+
parts = [part for part in topic.split("/") if part]
|
|
11
|
+
return "/".join(parts)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _placeholder_to_group(m: re.Match) -> str:
|
|
15
|
+
name, converter = m.group(1), m.group(2)
|
|
16
|
+
# `{x:path}` 는 슬래시 포함 1개 이상 세그먼트(FastAPI 의 :path 와 동일 의미)
|
|
17
|
+
return f"(?P<{name}>.+)" if converter == "path" else f"(?P<{name}>[^/]+)"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def template_to_regex_str(path: str) -> str:
|
|
21
|
+
# "plugin/{id}/{path:path}" -> "plugin/(?P<id>[^/]+)/(?P<path>.+)"
|
|
22
|
+
return re.sub(PLACEHOLDER_PATTERN, _placeholder_to_group, normalize_topic(path))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def is_match_path(path: str, regex: str) -> bool:
|
|
26
|
+
if not isinstance(path, str) or "{" not in path:
|
|
27
|
+
return False
|
|
28
|
+
return re.fullmatch(template_to_regex_str(path), normalize_topic(regex)) is not None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def build_path_regex(path: str):
|
|
32
|
+
return re.compile(f"^{template_to_regex_str(path)}$")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def extract_path_params(path: str) -> list[str]:
|
|
36
|
+
return [m.group(1) for m in re.finditer(PLACEHOLDER_PATTERN, path)]
|
|
@@ -109,7 +109,10 @@ def get_timeout_sec(data, error_prefix: str, default: float | None = None) -> in
|
|
|
109
109
|
|
|
110
110
|
def get_required_field(data, field_name: str, error_prefix: str):
|
|
111
111
|
value = data.get(field_name)
|
|
112
|
-
|
|
112
|
+
# numpy array 등 element-wise __eq__를 오버라이드하는 값이 올 수 있어
|
|
113
|
+
# `value in (None, "", Ellipsis)` 는 "truth value of an array is ambiguous"로 깨진다.
|
|
114
|
+
# is 비교 + 문자열 한정 "" 비교로 element-wise 비교를 피한다.
|
|
115
|
+
if value is None or value is Ellipsis or (isinstance(value, str) and value == ""):
|
|
113
116
|
raise ValueError(f"{error_prefix}: {field_name} is required")
|
|
114
117
|
return value
|
|
115
118
|
|
{rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow_rb_utils.egg-info/PKG-INFO
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rainbow-rb-utils
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2.dev2
|
|
4
4
|
Summary: Rainbow Python Utilities
|
|
5
5
|
Author-email: Derek <dfd1123@rainbow-robotics.com>
|
|
6
6
|
Requires-Python: <3.14,>=3.11
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Requires-Dist: psutil<8.0.0,>=7.0.0
|
|
9
|
-
Requires-Dist: rainbow-rb-log==0.1.
|
|
9
|
+
Requires-Dist: rainbow-rb-log==0.1.2.dev2
|
|
10
10
|
|
|
11
11
|
# rb_utils
|
|
12
12
|
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
|
|
3
|
-
PLACEHOLDER_PATTERN = r"{(\w+)}"
|
|
4
|
-
REGEX_PATTERN = r"(?P<\1>[^/]+)"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def normalize_topic(topic: str) -> str:
|
|
8
|
-
# Normalize topic by removing leading/trailing slashes and collapsing multiple slashes, e.g. "/users/{user_id}/posts/{post_id}/" -> "users/{user_id}/posts/{post_id}"
|
|
9
|
-
parts = [part for part in topic.split("/") if part]
|
|
10
|
-
return "/".join(parts)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def is_match_path(path: str, regex: str) -> bool:
|
|
14
|
-
# Check if a path matches a path template with placeholders, e.g. "/users/123/posts/456" matches "/users/{user_id}/posts/{post_id}"
|
|
15
|
-
if not isinstance(path, str) or "{" not in path:
|
|
16
|
-
return False
|
|
17
|
-
regex_str = re.sub(PLACEHOLDER_PATTERN, REGEX_PATTERN, normalize_topic(path))
|
|
18
|
-
return re.fullmatch(regex_str, normalize_topic(regex)) is not None
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def build_path_regex(path: str):
|
|
22
|
-
# Convert a path template with placeholders into a regex pattern, e.g. "/users/{user_id}/posts/{post_id}" -> re.compile(r"^/users/(?P<user_id>[^/]+)/posts/(?P<post_id>[^/]+)$")
|
|
23
|
-
regex_str = re.sub(PLACEHOLDER_PATTERN, REGEX_PATTERN, normalize_topic(path))
|
|
24
|
-
return re.compile(f"^{regex_str}$")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def extract_path_params(path: str) -> list[str]:
|
|
28
|
-
# Extract parameter names from a path template, e.g. "/users/{user_id}/posts/{post_id}" -> ["user_id", "post_id"]
|
|
29
|
-
return re.findall(PLACEHOLDER_PATTERN, path)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/asyncio_helper.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
|
{rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow/rb_utils/service_exception.py
RENAMED
|
File without changes
|
{rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow_rb_utils.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{rainbow_rb_utils-0.1.1 → rainbow_rb_utils-0.1.2.dev2}/src/rainbow_rb_utils.egg-info/top_level.txt
RENAMED
|
File without changes
|