documente_shared 0.1.200b0__tar.gz → 0.1.200b2__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.200b0 → documente_shared-0.1.200b2}/PKG-INFO +1 -1
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/layout.py +8 -0
- documente_shared-0.1.200b2/documente_shared/infrastructure/lambda_job_results.py +38 -0
- documente_shared-0.1.200b2/documente_shared/infrastructure/lambdas.py +69 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/s3_bucket.py +18 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/pyproject.toml +1 -1
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/uv.lock +1 -1
- documente_shared-0.1.200b0/documente_shared/infrastructure/lambdas.py +0 -37
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/.claude/commands/commit.md +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/.github/workflows/publish.yml +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/.gitignore +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/.vscode/settings.json +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/Dockerfile +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/Makefile +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/README.md +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/cases.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/docker-compose.yml +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/dates.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/digest.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/exceptions.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/files.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/json.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/logging.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/numbers.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/payloads.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/query_params.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/retry_utils.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/time_utils.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/timezone.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/base_enum.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/constants.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/document_metadata.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/document_type.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/in_memory_document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/processing_case.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/processing_case_filters.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/processing_case_item.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/processing_case_item_filters.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/processing_documents.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/processing_event.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/processing_record.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/scaling.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/workspace.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/workspace_document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/workspace_document_page.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/circular_oficio.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/common.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/document_type_record.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/processing_case.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/processing_case_validator.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/vnext.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/workspace.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/exceptions.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/filters/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/filters/document_type.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/filters/workspace.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/filters/workspace_document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/filters/workspace_document_page.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/helpers/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/helpers/dicts.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/helpers/encoding.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/helpers/lists.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/helpers/values.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/interfaces/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/interfaces/queue.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/interfaces/scaling.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/pagination/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/pagination/entities.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/pagination/response.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/repositories/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/repositories/document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/repositories/document_type.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/repositories/processing_case.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/repositories/processing_case_item.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/repositories/processing_record.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/repositories/workspace.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/repositories/workspace_document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/repositories/workspace_document_page.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/batch_queue.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/documente_client.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/dynamo_table.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/dynamo_document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/dynamo_processing_case.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/dynamo_processing_case_item.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/http_document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/http_document_type.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/http_processing_case.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/http_processing_case_item.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/http_processing_record.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/http_workspace.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/http_workspace_document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/http_workspace_document_page.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/mem_document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/mem_processing_case.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/mem_processing_case_item.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/repositories/mem_processing_record.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/services/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/services/http_scaling.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/infrastructure/sqs_queue.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/presentation/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/presentation/presenters.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/publish.sh +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/application/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/application/test_files.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/application/test_payloads.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/conftest.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/domain/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/domain/entities/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/domain/entities/test_in_memory_document.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/domain/entities/test_processing_case.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/domain/entities/test_processing_case_item.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/domain/entities/test_processing_record.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/domain/enums/test_processing_case_validator.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/infrastructure/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/infrastructure/repositories/__init__.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/infrastructure/repositories/test_http_processing_record.py +0 -0
- {documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documents.py +0 -0
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/entities/layout.py
RENAMED
|
@@ -75,3 +75,11 @@ class PageRange(BaseModel):
|
|
|
75
75
|
end: Optional[int] = None
|
|
76
76
|
|
|
77
77
|
model_config = ConfigDict(extra="ignore")
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def label(self) -> str:
|
|
81
|
+
# Espeja PageRange.label de las lambdas, que lo usan para nombrar el resultado en S3:
|
|
82
|
+
# start ausente es 1, end ausente es "end".
|
|
83
|
+
start_page = self.start if self.start is not None else 1
|
|
84
|
+
end_page = self.end if self.end is not None else "end"
|
|
85
|
+
return f"{start_page}-{end_page}"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
from documente_shared.infrastructure.s3_bucket import S3Bucket
|
|
4
|
+
|
|
5
|
+
DEFAULT_JOB_RESULT_TIMEOUT = 960
|
|
6
|
+
DEFAULT_JOB_RESULT_POLL_INTERVAL = 5
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def build_job_result_key(job_id: str, step_name: str) -> str:
|
|
10
|
+
# Contrato de S3JobResultStore en las lambdas: el mismo output_uri que devuelve la invocacion
|
|
11
|
+
# sincronica, construido aca para que la asincronica no dependa de una respuesta.
|
|
12
|
+
return f"jobs/{job_id}/{step_name}.json"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def discard_previous_job_result(s3_bucket: S3Bucket, job_result_key: str) -> None:
|
|
16
|
+
# Sin esto la espera puede leer el resultado de una corrida anterior y devolverlo como propio.
|
|
17
|
+
# Lo que se borra es un artefacto derivado que la lambda reescribe en cada corrida, incluso en
|
|
18
|
+
# cache hit: su cache real no vive en este archivo.
|
|
19
|
+
s3_bucket.delete(file_key=job_result_key)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def wait_for_job_result(
|
|
23
|
+
s3_bucket: S3Bucket,
|
|
24
|
+
job_result_key: str,
|
|
25
|
+
timeout_seconds: int = DEFAULT_JOB_RESULT_TIMEOUT,
|
|
26
|
+
poll_interval_seconds: float = DEFAULT_JOB_RESULT_POLL_INTERVAL,
|
|
27
|
+
) -> dict:
|
|
28
|
+
deadline = time.monotonic() + timeout_seconds
|
|
29
|
+
while True:
|
|
30
|
+
job_result = s3_bucket.get_json(file_key=job_result_key)
|
|
31
|
+
if job_result is not None:
|
|
32
|
+
return job_result
|
|
33
|
+
if time.monotonic() >= deadline:
|
|
34
|
+
raise TimeoutError(
|
|
35
|
+
f"Lambda job result not found after {timeout_seconds}s: "
|
|
36
|
+
f"s3://{s3_bucket.bucket_name}/{job_result_key}"
|
|
37
|
+
)
|
|
38
|
+
time.sleep(poll_interval_seconds)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from functools import lru_cache
|
|
3
|
+
|
|
4
|
+
import boto3
|
|
5
|
+
from botocore.config import Config
|
|
6
|
+
|
|
7
|
+
# Synchronous invocations travel through a PrivateLink interface endpoint, whose idle timeout is a
|
|
8
|
+
# hard, non configurable 350s. A synchronous invoke leaves the flow completely idle while the
|
|
9
|
+
# function runs, so past that point the flow is silently dropped and the response can never arrive.
|
|
10
|
+
# Waiting any longer than the endpoint allows only delays a failure that already happened.
|
|
11
|
+
DEFAULT_LAMBDA_READ_TIMEOUT = 350
|
|
12
|
+
|
|
13
|
+
# An asynchronous invocation only enqueues the event, so the call returns in milliseconds no matter
|
|
14
|
+
# how long the function then runs.
|
|
15
|
+
DEFAULT_LAMBDA_ENQUEUE_TIMEOUT = 60
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@lru_cache(maxsize=None)
|
|
19
|
+
def _get_lambda_client(read_timeout: int):
|
|
20
|
+
# No retries: the read timeout is shorter than the function timeout, so a read timeout means the
|
|
21
|
+
# invocation is still running on the other side. Retrying it would start a second execution of a
|
|
22
|
+
# function that is not idempotent.
|
|
23
|
+
lambda_config = Config(
|
|
24
|
+
read_timeout=read_timeout,
|
|
25
|
+
connect_timeout=30,
|
|
26
|
+
tcp_keepalive=True,
|
|
27
|
+
retries={"max_attempts": 0, "mode": "standard"},
|
|
28
|
+
)
|
|
29
|
+
return boto3.client("lambda", config=lambda_config)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def invoke_lambda(
|
|
33
|
+
function_name: str,
|
|
34
|
+
payload: dict,
|
|
35
|
+
read_timeout: int = DEFAULT_LAMBDA_READ_TIMEOUT,
|
|
36
|
+
) -> dict | list | None:
|
|
37
|
+
client = _get_lambda_client(read_timeout)
|
|
38
|
+
|
|
39
|
+
response = client.invoke(
|
|
40
|
+
FunctionName=function_name,
|
|
41
|
+
InvocationType="RequestResponse",
|
|
42
|
+
Payload=json.dumps(payload),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
return json.loads(response["Payload"].read().decode("utf-8"))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def invoke_lambda_async(
|
|
49
|
+
function_name: str,
|
|
50
|
+
payload: dict,
|
|
51
|
+
read_timeout: int = DEFAULT_LAMBDA_ENQUEUE_TIMEOUT,
|
|
52
|
+
) -> int:
|
|
53
|
+
# There is no response payload to wait for, so the caller never holds a connection open while the
|
|
54
|
+
# function runs. The result travels out of band: the function writes it to its own deterministic
|
|
55
|
+
# output location and the caller reads it from there.
|
|
56
|
+
#
|
|
57
|
+
# Lambda retries a failed asynchronous invocation by itself (MaximumRetryAttempts defaults to 2
|
|
58
|
+
# on the function's event invoke config) and silently drops events it cannot deliver. Both are
|
|
59
|
+
# function side settings, invisible from here, so anything invoked this way has to tolerate
|
|
60
|
+
# running more than once for the same payload.
|
|
61
|
+
client = _get_lambda_client(read_timeout)
|
|
62
|
+
|
|
63
|
+
response = client.invoke(
|
|
64
|
+
FunctionName=function_name,
|
|
65
|
+
InvocationType="Event",
|
|
66
|
+
Payload=json.dumps(payload),
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
return response["StatusCode"]
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import boto3
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
from botocore.exceptions import ClientError
|
|
2
5
|
|
|
3
6
|
from dataclasses import dataclass
|
|
4
7
|
from typing import Optional
|
|
@@ -7,6 +10,9 @@ from documente_shared.domain.entities.document import remove_slash_from_path
|
|
|
7
10
|
from documente_shared.application.retry_utils import retry_on_size_integrity
|
|
8
11
|
|
|
9
12
|
|
|
13
|
+
MISSING_OBJECT_ERROR_CODES = ("NoSuchKey", "404")
|
|
14
|
+
|
|
15
|
+
|
|
10
16
|
def remove_none_values(data: dict) -> dict: # noqa: WPS110
|
|
11
17
|
return {key: value for key, value in data.items() if value is not None} # noqa: WPS110
|
|
12
18
|
|
|
@@ -39,6 +45,18 @@ class S3Bucket(object):
|
|
|
39
45
|
return None
|
|
40
46
|
return file_context["Body"] if "Body" in file_context else None
|
|
41
47
|
|
|
48
|
+
def get_json(self, file_key: str) -> Optional[dict]:
|
|
49
|
+
# Sin el retry de get(): aca la ausencia del objeto es una respuesta valida y no algo que
|
|
50
|
+
# convenga reintentar, asi que se puede usar para preguntar si un resultado ya esta.
|
|
51
|
+
cleaned_file_key = remove_slash_from_path(file_key)
|
|
52
|
+
try:
|
|
53
|
+
file_context = self._resource.Object(self.bucket_name, cleaned_file_key).get()
|
|
54
|
+
except ClientError as client_error:
|
|
55
|
+
if client_error.response["Error"]["Code"] in MISSING_OBJECT_ERROR_CODES:
|
|
56
|
+
return None
|
|
57
|
+
raise
|
|
58
|
+
return json.loads(file_context["Body"].read().decode("utf-8"))
|
|
59
|
+
|
|
42
60
|
def upload(self, file_key: str, file_content, content_type: Optional[str] = None):
|
|
43
61
|
cleaned_file_key = remove_slash_from_path(file_key)
|
|
44
62
|
optional_params = {"ContentType": content_type}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from functools import lru_cache
|
|
3
|
-
|
|
4
|
-
import boto3
|
|
5
|
-
from botocore.config import Config
|
|
6
|
-
|
|
7
|
-
DEFAULT_LAMBDA_READ_TIMEOUT = 900
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@lru_cache(maxsize=None)
|
|
11
|
-
def _get_lambda_client(read_timeout: int):
|
|
12
|
-
# Invocations are long running and not idempotent: the read timeout must outlast the target
|
|
13
|
-
# function timeout and retries must stay disabled, so a slow response never triggers a second
|
|
14
|
-
# invocation of the same job.
|
|
15
|
-
lambda_config = Config(
|
|
16
|
-
read_timeout=read_timeout,
|
|
17
|
-
connect_timeout=10,
|
|
18
|
-
tcp_keepalive=True,
|
|
19
|
-
retries={"max_attempts": 0, "mode": "standard"},
|
|
20
|
-
)
|
|
21
|
-
return boto3.client("lambda", config=lambda_config)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def invoke_lambda(
|
|
25
|
-
function_name: str,
|
|
26
|
-
payload: dict,
|
|
27
|
-
read_timeout: int = DEFAULT_LAMBDA_READ_TIMEOUT,
|
|
28
|
-
) -> dict | list | None:
|
|
29
|
-
client = _get_lambda_client(read_timeout)
|
|
30
|
-
|
|
31
|
-
response = client.invoke(
|
|
32
|
-
FunctionName=function_name,
|
|
33
|
-
InvocationType="RequestResponse",
|
|
34
|
-
Payload=json.dumps(payload),
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
return json.loads(response["Payload"].read().decode("utf-8"))
|
|
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
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/__init__.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/dates.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/digest.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/exceptions.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/files.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/json.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/logging.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/numbers.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/payloads.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/time_utils.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/application/timezone.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/__init__.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/base_enum.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/constants.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
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/common.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/document.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/vnext.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/enums/workspace.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/helpers/dicts.py
RENAMED
|
File without changes
|
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/helpers/lists.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/domain/helpers/values.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
|
|
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
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/documente_shared/presentation/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/conftest.py
RENAMED
|
File without changes
|
{documente_shared-0.1.200b0 → documente_shared-0.1.200b2}/tests/documente_shared/domain/__init__.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
|