documente_shared 0.1.187__tar.gz → 0.1.188__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.
- documente_shared-0.1.188/.claude/commands/commit.md +34 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/Makefile +14 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/PKG-INFO +2 -1
- documente_shared-0.1.188/documente_shared/application/digest.py +7 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/exceptions.py +5 -2
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/files.py +8 -6
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/json.py +2 -2
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/numbers.py +1 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/payloads.py +3 -3
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/query_params.py +0 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/retry_utils.py +16 -9
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/base_enum.py +3 -3
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/constants.py +4 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/document.py +127 -143
- documente_shared-0.1.188/documente_shared/domain/entities/document_metadata.py +62 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/document_type.py +13 -11
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/in_memory_document.py +7 -3
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/processing_case.py +50 -62
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/processing_case_item.py +91 -119
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/processing_case_item_filters.py +1 -2
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/processing_event.py +14 -17
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/workspace.py +15 -18
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/workspace_document.py +3 -9
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/workspace_document_page.py +21 -35
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/enums/common.py +24 -25
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/enums/document.py +26 -27
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/enums/document_type_record.py +4 -4
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/enums/processing_case.py +17 -17
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/enums/processing_case_validator.py +3 -4
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/exceptions.py +1 -4
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/filters/document_type.py +6 -4
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/filters/workspace.py +7 -5
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/filters/workspace_document.py +13 -11
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/filters/workspace_document_page.py +6 -4
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/helpers/dicts.py +1 -5
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/interfaces/scaling.py +0 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/pagination/entities.py +1 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/pagination/response.py +0 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/repositories/document.py +0 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/repositories/processing_case.py +0 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/repositories/processing_case_item.py +0 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/repositories/processing_record.py +0 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/repositories/workspace_document_page.py +3 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/batch_queue.py +3 -2
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/documente_client.py +28 -9
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/dynamo_table.py +11 -17
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/lambdas.py +3 -3
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/dynamo_document.py +6 -9
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/dynamo_processing_case.py +6 -9
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/dynamo_processing_case_item.py +7 -10
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/http_document.py +6 -9
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/http_processing_case.py +6 -10
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/http_processing_case_item.py +4 -7
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/http_processing_record.py +5 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/http_workspace_document_page.py +10 -6
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/mem_document.py +2 -5
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/mem_processing_case.py +1 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/mem_processing_case_item.py +2 -7
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/s3_bucket.py +5 -9
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/services/http_scaling.py +1 -3
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/sqs_queue.py +10 -13
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/presentation/presenters.py +1 -1
- documente_shared-0.1.188/pyproject.toml +215 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/application/test_files.py +7 -4
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/application/test_payloads.py +8 -17
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/conftest.py +1 -1
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/domain/entities/test_in_memory_document.py +19 -14
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/domain/entities/test_processing_case.py +16 -16
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documents.py +44 -34
- {documente_shared-0.1.187 → documente_shared-0.1.188}/uv.lock +39 -1
- documente_shared-0.1.187/documente_shared/application/digest.py +0 -7
- documente_shared-0.1.187/documente_shared/domain/entities/document_metadata.py +0 -64
- documente_shared-0.1.187/pyproject.toml +0 -48
- {documente_shared-0.1.187 → documente_shared-0.1.188}/.github/workflows/publish.yml +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/.gitignore +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/.vscode/settings.json +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/Dockerfile +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/README.md +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/cases.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/docker-compose.yml +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/dates.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/logging.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/time_utils.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/timezone.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/processing_case_filters.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/processing_documents.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/processing_record.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/entities/scaling.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/enums/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/enums/circular_oficio.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/enums/workspace.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/filters/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/helpers/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/helpers/encoding.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/helpers/lists.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/helpers/values.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/interfaces/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/interfaces/queue.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/pagination/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/repositories/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/repositories/document_type.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/repositories/workspace.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/domain/repositories/workspace_document.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/http_document_type.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/http_workspace.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/http_workspace_document.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/repositories/mem_processing_record.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/infrastructure/services/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/presentation/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/publish.sh +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/application/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/domain/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/domain/entities/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/domain/entities/test_processing_case_item.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/domain/entities/test_processing_record.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/domain/enums/test_processing_case_validator.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/infrastructure/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/infrastructure/repositories/__init__.py +0 -0
- {documente_shared-0.1.187 → documente_shared-0.1.188}/tests/documente_shared/infrastructure/repositories/test_http_processing_record.py +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*)
|
|
3
|
+
argument-hint: [message]
|
|
4
|
+
description: Create a git commit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
- Current git status: !`git status`
|
|
10
|
+
- Current git diff: !`git diff HEAD`
|
|
11
|
+
- Current branch: !`git branch --show-current`
|
|
12
|
+
- Recent commits: !`git log --oneline -10`
|
|
13
|
+
|
|
14
|
+
## Your task
|
|
15
|
+
|
|
16
|
+
Based on the above changes, create a single git commit following the **Conventional Commits** specification.
|
|
17
|
+
|
|
18
|
+
### Commit message format
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
<type>(<scope>): <description>
|
|
22
|
+
|
|
23
|
+
[optional body]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Rules
|
|
27
|
+
|
|
28
|
+
1. **type** must be one of: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`
|
|
29
|
+
2. **scope** is optional but recommended — use the domain or module affected (e.g., `auth`, `transactions`, `ui`)
|
|
30
|
+
3. **description** must be lowercase, imperative mood, no period at the end
|
|
31
|
+
4. Add a **body** only if the changes need further explanation
|
|
32
|
+
5. If the argument `$ARGUMENTS` is provided, use it as guidance for the commit message
|
|
33
|
+
6. Do not include any "Co-Authored-By" lines in the commit message
|
|
34
|
+
7. Before committing, stage all modified, deleted, and untracked files that are part of the changes using `git add`. Include both tracked changes and new untracked files relevant to the work. Do NOT stage files that contain secrets (`.env`, credentials, etc.)
|
|
@@ -25,6 +25,20 @@ clean:
|
|
|
25
25
|
docker ps -aq | xargs docker stop
|
|
26
26
|
docker ps -aq | xargs docker rm
|
|
27
27
|
|
|
28
|
+
lint:
|
|
29
|
+
uv run ruff check documente_shared tests
|
|
30
|
+
|
|
31
|
+
lint_fix:
|
|
32
|
+
uv run ruff check --fix documente_shared tests
|
|
33
|
+
|
|
34
|
+
format:
|
|
35
|
+
uv run ruff format documente_shared tests
|
|
36
|
+
|
|
37
|
+
format_check:
|
|
38
|
+
uv run ruff format --check documente_shared tests
|
|
39
|
+
|
|
40
|
+
check: lint format_check
|
|
41
|
+
|
|
28
42
|
test:
|
|
29
43
|
$(COMPOSE_PACKAGE) bash -c "uv run pytest --pyargs $(ARG)"
|
|
30
44
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: documente_shared
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.188
|
|
4
4
|
Summary: Shared utilities for LlamitAI projects
|
|
5
5
|
Author-email: Tech <tech@llamitai.com>
|
|
6
6
|
License: MIT
|
|
@@ -11,6 +11,7 @@ Requires-Dist: pydantic>=2.12.5
|
|
|
11
11
|
Requires-Dist: requests>=2.32.5
|
|
12
12
|
Requires-Dist: sentry-sdk>=2.52.0
|
|
13
13
|
Requires-Dist: structlog>=25.5.0
|
|
14
|
+
Requires-Dist: tenacity>=9.1.4
|
|
14
15
|
Requires-Dist: unidecode>=1.4.0
|
|
15
16
|
Description-Content-Type: text/markdown
|
|
16
17
|
|
{documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/exceptions.py
RENAMED
|
@@ -4,13 +4,15 @@ from typing import Callable, Any, TypeVar
|
|
|
4
4
|
|
|
5
5
|
F = TypeVar("F", bound=Callable[..., Any])
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
|
|
8
|
+
def initialize_sentry(dsn: str, environment: str = "dev") -> None:
|
|
9
|
+
if not sentry_sdk.Hub.current.client:
|
|
9
10
|
sentry_sdk.init(
|
|
10
11
|
dsn=dsn,
|
|
11
12
|
environment=environment,
|
|
12
13
|
)
|
|
13
14
|
|
|
15
|
+
|
|
14
16
|
def track_exceptions(func: F) -> F:
|
|
15
17
|
@wraps(func)
|
|
16
18
|
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
@@ -20,4 +22,5 @@ def track_exceptions(func: F) -> F:
|
|
|
20
22
|
sentry_sdk.capture_exception(e)
|
|
21
23
|
sentry_sdk.flush()
|
|
22
24
|
raise
|
|
25
|
+
|
|
23
26
|
return wrapper # type: ignore
|
|
@@ -7,7 +7,7 @@ def split_file_params(filepath: str) -> Tuple[str, str, str]:
|
|
|
7
7
|
folder_path = path.dirname(filepath)
|
|
8
8
|
filename = path.splitext(path.basename(filepath))[0]
|
|
9
9
|
extension = path.splitext(filepath)[1]
|
|
10
|
-
extension = extension.replace(
|
|
10
|
+
extension = extension.replace(".", "")
|
|
11
11
|
return folder_path, filename, extension
|
|
12
12
|
|
|
13
13
|
|
|
@@ -18,20 +18,22 @@ def get_filename_from_path(file_path: Optional[str]) -> Optional[str]:
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def remove_slash_from_path(file_path: str) -> str:
|
|
21
|
-
if file_path and file_path.startswith(
|
|
21
|
+
if file_path and file_path.startswith("/"):
|
|
22
22
|
return file_path[1:]
|
|
23
23
|
return file_path
|
|
24
24
|
|
|
25
|
+
|
|
25
26
|
def remove_extension(filename: str) -> str:
|
|
26
|
-
if filename and
|
|
27
|
-
return filename.rsplit(
|
|
27
|
+
if filename and "." in filename:
|
|
28
|
+
return filename.rsplit(".", 1)[0]
|
|
28
29
|
return filename
|
|
29
30
|
|
|
31
|
+
|
|
30
32
|
def build_bucket_file_key(file_path: str) -> str:
|
|
31
33
|
if not file_path:
|
|
32
|
-
return
|
|
34
|
+
return ""
|
|
33
35
|
parsed = urlparse(file_path)
|
|
34
36
|
if parsed.scheme and parsed.netloc:
|
|
35
|
-
return parsed.path.lstrip(
|
|
37
|
+
return parsed.path.lstrip("/")
|
|
36
38
|
|
|
37
39
|
return remove_slash_from_path(file_path)
|
|
@@ -32,8 +32,8 @@ def safe_format(data: Any) -> Any:
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def normalize_key(key: str) -> str:
|
|
35
|
-
normalized = unicodedata.normalize(
|
|
36
|
-
underscored = re.sub(r
|
|
35
|
+
normalized = unicodedata.normalize("NFC", key)
|
|
36
|
+
underscored = re.sub(r"\s+", "_", normalized)
|
|
37
37
|
return underscored
|
|
38
38
|
|
|
39
39
|
|
{documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/payloads.py
RENAMED
|
@@ -2,8 +2,9 @@ import re
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
def camel_to_snake_key(name: str) -> str:
|
|
5
|
-
s1 = re.sub(
|
|
6
|
-
return re.sub(
|
|
5
|
+
s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
|
|
6
|
+
return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower()
|
|
7
|
+
|
|
7
8
|
|
|
8
9
|
def camel_to_snake(data: dict | list) -> dict | list:
|
|
9
10
|
if isinstance(data, dict):
|
|
@@ -26,4 +27,3 @@ def snake_to_camel(data: dict | list) -> dict | list:
|
|
|
26
27
|
return [snake_to_camel(item) for item in data]
|
|
27
28
|
else:
|
|
28
29
|
return data
|
|
29
|
-
|
{documente_shared-0.1.187 → documente_shared-0.1.188}/documente_shared/application/retry_utils.py
RENAMED
|
@@ -2,6 +2,7 @@ import time
|
|
|
2
2
|
import random
|
|
3
3
|
from functools import wraps
|
|
4
4
|
from typing import Optional, Callable
|
|
5
|
+
|
|
5
6
|
import structlog
|
|
6
7
|
|
|
7
8
|
logger = structlog.get_logger()
|
|
@@ -23,12 +24,12 @@ def retry_on_size_integrity(base_delay: float = 0.8, max_retries: int = 3):
|
|
|
23
24
|
file_key=file_key,
|
|
24
25
|
)
|
|
25
26
|
if attempt < max_retries - 1:
|
|
26
|
-
delay = base_delay * (2
|
|
27
|
+
delay = base_delay * (2**attempt) + random.uniform(0, base_delay)
|
|
27
28
|
time.sleep(delay)
|
|
28
29
|
continue
|
|
29
30
|
raise RuntimeError(f"No se pudo obtener file_context para {file_key}")
|
|
30
31
|
|
|
31
|
-
if
|
|
32
|
+
if "Body" not in file_context:
|
|
32
33
|
logger.warning(
|
|
33
34
|
"[shared.retry.body_not_found]",
|
|
34
35
|
attempt=attempt + 1,
|
|
@@ -36,19 +37,23 @@ def retry_on_size_integrity(base_delay: float = 0.8, max_retries: int = 3):
|
|
|
36
37
|
file_key=file_key,
|
|
37
38
|
)
|
|
38
39
|
if attempt < max_retries - 1:
|
|
39
|
-
delay = base_delay * (2
|
|
40
|
+
delay = base_delay * (2**attempt) + random.uniform(0, base_delay)
|
|
40
41
|
time.sleep(delay)
|
|
41
42
|
continue
|
|
42
43
|
raise RuntimeError(f"'Body' no encontrado en file_context para {file_key}")
|
|
43
44
|
|
|
44
|
-
expected_size = file_context.get(
|
|
45
|
-
body = file_context[
|
|
45
|
+
expected_size = file_context.get("ContentLength", 0)
|
|
46
|
+
body = file_context["Body"].read()
|
|
46
47
|
actual_size = len(body)
|
|
47
48
|
|
|
48
49
|
if expected_size == actual_size:
|
|
49
|
-
file_context[
|
|
50
|
+
file_context["Body"] = body
|
|
50
51
|
if attempt > 0:
|
|
51
|
-
logger.info(
|
|
52
|
+
logger.info(
|
|
53
|
+
"[shared.retry.download_success]",
|
|
54
|
+
file_key=file_key,
|
|
55
|
+
attempts=attempt + 1,
|
|
56
|
+
)
|
|
52
57
|
return file_context
|
|
53
58
|
|
|
54
59
|
logger.warning(
|
|
@@ -61,7 +66,7 @@ def retry_on_size_integrity(base_delay: float = 0.8, max_retries: int = 3):
|
|
|
61
66
|
)
|
|
62
67
|
|
|
63
68
|
if attempt < max_retries - 1:
|
|
64
|
-
delay = base_delay * (2
|
|
69
|
+
delay = base_delay * (2**attempt) + random.uniform(0, base_delay)
|
|
65
70
|
time.sleep(delay)
|
|
66
71
|
|
|
67
72
|
except Exception as e:
|
|
@@ -74,7 +79,7 @@ def retry_on_size_integrity(base_delay: float = 0.8, max_retries: int = 3):
|
|
|
74
79
|
error=str(e),
|
|
75
80
|
)
|
|
76
81
|
if attempt < max_retries - 1:
|
|
77
|
-
delay = base_delay * (2
|
|
82
|
+
delay = base_delay * (2**attempt) + random.uniform(0, base_delay)
|
|
78
83
|
time.sleep(delay)
|
|
79
84
|
continue
|
|
80
85
|
raise
|
|
@@ -82,5 +87,7 @@ def retry_on_size_integrity(base_delay: float = 0.8, max_retries: int = 3):
|
|
|
82
87
|
raise RuntimeError(
|
|
83
88
|
f"Descarga incompleta/inconsistente de S3 para {file_key} después de {max_retries} intentos"
|
|
84
89
|
)
|
|
90
|
+
|
|
85
91
|
return wrapper
|
|
92
|
+
|
|
86
93
|
return decorator
|
|
@@ -38,17 +38,17 @@ class BaseEnum(Enum):
|
|
|
38
38
|
return [
|
|
39
39
|
value
|
|
40
40
|
for key, value in cls.__dict__.items()
|
|
41
|
-
if isinstance(value, str) and not key.startswith(
|
|
41
|
+
if isinstance(value, str) and not key.startswith("__")
|
|
42
42
|
]
|
|
43
43
|
|
|
44
44
|
@classmethod
|
|
45
45
|
def from_value(
|
|
46
46
|
cls,
|
|
47
47
|
value: Union[str, int],
|
|
48
|
-
) -> Optional[
|
|
48
|
+
) -> Optional["BaseEnum"]:
|
|
49
49
|
for tag in cls:
|
|
50
50
|
if isinstance(tag.value, str) and str(tag.value).upper() == str(value).upper():
|
|
51
51
|
return tag
|
|
52
52
|
elif not isinstance(tag.value, str) and tag.value == value:
|
|
53
53
|
return tag
|
|
54
|
-
return None
|
|
54
|
+
return None
|
|
@@ -7,4 +7,7 @@ la_paz_tz = ZoneInfo("America/La_Paz")
|
|
|
7
7
|
DOCUMENTE_API_URL = environ.get("DOCUMENTE_API_URL")
|
|
8
8
|
DOCUMENTE_API_KEY = environ.get("DOCUMENTE_API_KEY")
|
|
9
9
|
|
|
10
|
-
DEFAULT_PAGINATION_PAGE_SIZE = 50
|
|
10
|
+
DEFAULT_PAGINATION_PAGE_SIZE = 50
|
|
11
|
+
|
|
12
|
+
HTTP_RETRY_TOTAL = 3
|
|
13
|
+
HTTP_RETRY_BACKOFF_FACTOR = 0.5
|