documente_shared 0.1.145__py3-none-any.whl

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 (63) hide show
  1. documente_shared/__init__.py +0 -0
  2. documente_shared/application/__init__.py +0 -0
  3. documente_shared/application/dates.py +7 -0
  4. documente_shared/application/digest.py +7 -0
  5. documente_shared/application/exceptions.py +23 -0
  6. documente_shared/application/files.py +27 -0
  7. documente_shared/application/json.py +45 -0
  8. documente_shared/application/numbers.py +7 -0
  9. documente_shared/application/payloads.py +29 -0
  10. documente_shared/application/query_params.py +133 -0
  11. documente_shared/application/retry_utils.py +69 -0
  12. documente_shared/application/time_utils.py +13 -0
  13. documente_shared/application/timezone.py +7 -0
  14. documente_shared/domain/__init__.py +0 -0
  15. documente_shared/domain/base_enum.py +54 -0
  16. documente_shared/domain/constants.py +8 -0
  17. documente_shared/domain/entities/__init__.py +0 -0
  18. documente_shared/domain/entities/document.py +410 -0
  19. documente_shared/domain/entities/document_metadata.py +64 -0
  20. documente_shared/domain/entities/in_memory_document.py +75 -0
  21. documente_shared/domain/entities/processing_case.py +215 -0
  22. documente_shared/domain/entities/processing_case_filters.py +51 -0
  23. documente_shared/domain/entities/processing_case_item.py +300 -0
  24. documente_shared/domain/entities/processing_case_item_filters.py +54 -0
  25. documente_shared/domain/entities/processing_documents.py +11 -0
  26. documente_shared/domain/entities/processing_event.py +71 -0
  27. documente_shared/domain/entities/scaling.py +31 -0
  28. documente_shared/domain/enums/__init__.py +0 -0
  29. documente_shared/domain/enums/circular_oficio.py +29 -0
  30. documente_shared/domain/enums/common.py +133 -0
  31. documente_shared/domain/enums/document.py +124 -0
  32. documente_shared/domain/enums/document_type_record.py +13 -0
  33. documente_shared/domain/enums/processing_case.py +66 -0
  34. documente_shared/domain/exceptions.py +5 -0
  35. documente_shared/domain/interfaces/__init__.py +0 -0
  36. documente_shared/domain/interfaces/scaling.py +10 -0
  37. documente_shared/domain/repositories/__init__.py +0 -0
  38. documente_shared/domain/repositories/document.py +24 -0
  39. documente_shared/domain/repositories/processing_case.py +36 -0
  40. documente_shared/domain/repositories/processing_case_item.py +49 -0
  41. documente_shared/infrastructure/__init__.py +0 -0
  42. documente_shared/infrastructure/documente_client.py +27 -0
  43. documente_shared/infrastructure/dynamo_table.py +75 -0
  44. documente_shared/infrastructure/lambdas.py +14 -0
  45. documente_shared/infrastructure/repositories/__init__.py +0 -0
  46. documente_shared/infrastructure/repositories/dynamo_document.py +43 -0
  47. documente_shared/infrastructure/repositories/dynamo_processing_case.py +55 -0
  48. documente_shared/infrastructure/repositories/dynamo_processing_case_item.py +70 -0
  49. documente_shared/infrastructure/repositories/http_document.py +66 -0
  50. documente_shared/infrastructure/repositories/http_processing_case.py +82 -0
  51. documente_shared/infrastructure/repositories/http_processing_case_item.py +118 -0
  52. documente_shared/infrastructure/repositories/mem_document.py +46 -0
  53. documente_shared/infrastructure/repositories/mem_processing_case.py +44 -0
  54. documente_shared/infrastructure/repositories/mem_processing_case_item.py +52 -0
  55. documente_shared/infrastructure/s3_bucket.py +58 -0
  56. documente_shared/infrastructure/services/__init__.py +0 -0
  57. documente_shared/infrastructure/services/http_scaling.py +25 -0
  58. documente_shared/infrastructure/sqs_queue.py +48 -0
  59. documente_shared/presentation/__init__.py +0 -0
  60. documente_shared/presentation/presenters.py +16 -0
  61. documente_shared-0.1.145.dist-info/METADATA +39 -0
  62. documente_shared-0.1.145.dist-info/RECORD +63 -0
  63. documente_shared-0.1.145.dist-info/WHEEL +4 -0
@@ -0,0 +1,58 @@
1
+ import boto3
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Optional
5
+
6
+ from documente_shared.domain.entities.document import remove_slash_from_path
7
+ from documente_shared.application.retry_utils import retry_on_size_integrity
8
+
9
+ def remove_none_values(data: dict) -> dict: # noqa: WPS110
10
+ return {key: value for key, value in data.items() if value is not None} # noqa: WPS110
11
+
12
+
13
+ @dataclass
14
+ class S3Bucket(object):
15
+ bucket_name: str
16
+
17
+ def __post_init__(self):
18
+ self._resource = boto3.resource('s3')
19
+
20
+ @retry_on_size_integrity()
21
+ def get(self, file_key: str) -> Optional[dict]:
22
+ try:
23
+ return self._resource.Object(self.bucket_name, file_key).get()
24
+ except self._resource.meta.client.exceptions.NoSuchKey:
25
+ return None
26
+
27
+ def get_bytes(self, file_key: str) -> Optional[bytes]:
28
+ cleaned_file_key = remove_slash_from_path(file_key)
29
+ file_context = self.get(cleaned_file_key)
30
+ if not file_context:
31
+ return None
32
+ return (
33
+ file_context['Body']
34
+ if 'Body' in file_context
35
+ else None
36
+ )
37
+
38
+ def upload(self, file_key: str, file_content, content_type: Optional[str] = None):
39
+ cleaned_file_key = remove_slash_from_path(file_key)
40
+ optional_params = {'ContentType': content_type}
41
+ return self._resource.Object(self.bucket_name, cleaned_file_key).put(
42
+ Body=file_content,
43
+ **remove_none_values(optional_params),
44
+ )
45
+
46
+ def delete(self, file_key: str):
47
+ cleaned_file_key = remove_slash_from_path(file_key)
48
+ return self._resource.Object(self.bucket_name, cleaned_file_key).delete()
49
+
50
+ def get_url(self, file_key: str):
51
+ cleaned_file_key = remove_slash_from_path(file_key)
52
+ return 'https://{bucket_url}.s3.amazonaws.com/{file_key}'.format(
53
+ bucket_url=self.bucket_name,
54
+ file_key=cleaned_file_key,
55
+ )
56
+
57
+ def read(self, file_key: str) -> bytes:
58
+ return self.get(file_key)['Body'].read()
File without changes
@@ -0,0 +1,25 @@
1
+ from dataclasses import dataclass
2
+
3
+ from loguru import logger
4
+
5
+ from documente_shared.application.payloads import camel_to_snake
6
+ from documente_shared.domain.entities.scaling import ScalingRequirements
7
+ from documente_shared.domain.interfaces.scaling import ScalingService
8
+ from documente_shared.infrastructure.documente_client import DocumenteClientMixin
9
+
10
+
11
+ @dataclass
12
+ class HttpScalingService(
13
+ DocumenteClientMixin,
14
+ ScalingService,
15
+ ):
16
+ def get_requirements(self) -> ScalingRequirements:
17
+ response = self.session.get(f"{self.api_url}/v1/scaling-requirements/")
18
+ if response.status_code == 200:
19
+ response_json = response.json()
20
+ return ScalingRequirements.from_dict(
21
+ data=camel_to_snake(response_json.get('data', {}))
22
+ )
23
+
24
+ logger.warning(f'Error getting scaling requirements: {response.text}')
25
+ return ScalingRequirements()
@@ -0,0 +1,48 @@
1
+ import json
2
+ import boto3
3
+
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass
8
+ class SQSQueue(object):
9
+ queue_url: str
10
+ visibility_timeout: int = 60 * 10
11
+ waiting_timeout: int = 20
12
+
13
+ def __post_init__(self):
14
+ self._client = boto3.client('sqs')
15
+
16
+ def send_message(
17
+ self,
18
+ payload: dict,
19
+ message_attributes: dict = None,
20
+ delay_seconds: dict = None,
21
+ message_group_id: dict = None,
22
+ message_deduplication_id: dict =None,
23
+ ):
24
+ message_params = {
25
+ 'QueueUrl': self.queue_url,
26
+ 'MessageBody': json.dumps(payload),
27
+ 'MessageAttributes': message_attributes,
28
+ 'DelaySeconds': delay_seconds,
29
+ 'MessageGroupId': message_group_id,
30
+ 'MessageDeduplicationId': message_deduplication_id,
31
+ }
32
+ clean_params = {key: value for key, value in message_params.items() if value}
33
+ return self._client.send_message(**clean_params)
34
+
35
+ def delete_message(self, receipt_handle: str):
36
+ return self._client.delete_message(
37
+ QueueUrl=self.queue_url,
38
+ ReceiptHandle=receipt_handle
39
+ )
40
+
41
+ def fetch_messages(self, num_messages: int = 1) -> list[dict]:
42
+ response = self._client.receive_message(
43
+ QueueUrl=self.queue_url,
44
+ MaxNumberOfMessages=num_messages,
45
+ VisibilityTimeout=self.visibility_timeout,
46
+ WaitTimeSeconds=self.waiting_timeout,
47
+ )
48
+ return response.get('Messages', [])
File without changes
@@ -0,0 +1,16 @@
1
+ from dataclasses import dataclass
2
+
3
+ from documente_shared.application.dates import utc_now
4
+ from documente_shared.domain.enums.common import TaskResultStatus
5
+
6
+
7
+ @dataclass
8
+ class TaskResultPresenter(object):
9
+ status: TaskResultStatus = TaskResultStatus.SUCCESS
10
+
11
+ @property
12
+ def to_dict(self) -> dict:
13
+ return {
14
+ "status": str(self.status),
15
+ "completed_at": utc_now().isoformat(),
16
+ }
@@ -0,0 +1,39 @@
1
+ Metadata-Version: 2.1
2
+ Name: documente_shared
3
+ Version: 0.1.145
4
+ Summary: Shared utilities for Documente AI projects
5
+ License: MIT
6
+ Author: Tech
7
+ Author-email: tech@llamitai.com
8
+ Requires-Python: >=3.10,<3.13
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Requires-Dist: boto3 (>=1.37.19,<2.0.0)
15
+ Requires-Dist: botocore (>=1.37.19,<2.0.0)
16
+ Requires-Dist: loguru (>=0.7.3,<0.8.0)
17
+ Requires-Dist: pytz (>=2025.2,<2026.0)
18
+ Requires-Dist: requests (>=2.32.3,<3.0.0)
19
+ Requires-Dist: sentry-sdk (>=2.19.2,<3.0.0)
20
+ Requires-Dist: unidecode (>=1.3.8,<2.0.0)
21
+ Description-Content-Type: text/markdown
22
+
23
+
24
+ # Documente Shared
25
+
26
+ Utilidades para proyectos Documente AI
27
+
28
+ ## Instalación
29
+
30
+ ```bash
31
+ make build
32
+ ```
33
+
34
+ ## Publicación
35
+ Publica `documente-shared` en PyPi
36
+
37
+ ```bash
38
+ make publish
39
+ ```
@@ -0,0 +1,63 @@
1
+ documente_shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ documente_shared/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ documente_shared/application/dates.py,sha256=uExNddWmX9VEX_u420JGoC7fL-ieJ4956I0aw_WX3sQ,109
4
+ documente_shared/application/digest.py,sha256=Um6E8WfFri2_lly4RFWydJyvSfPZGFcOX-opEOzDCWc,172
5
+ documente_shared/application/exceptions.py,sha256=lQM8m7wmI9OTLGva0gd7s7YT7ldaTk_Ln4t32PpzNf8,654
6
+ documente_shared/application/files.py,sha256=_qkpeFPVmHyNhD6_PFZdzhyYvshJVeeSiwuTggK-A9Q,793
7
+ documente_shared/application/json.py,sha256=5y67-DoiJlq_fLefgJ8YBVsdyua4KykxbSUKQqcwnnQ,1223
8
+ documente_shared/application/numbers.py,sha256=rik1SqMxLzXNL2S5Yh1Q8CSONdcjjoCBnByFasxR4_Q,212
9
+ documente_shared/application/payloads.py,sha256=gLVTGM1gPfcaRXQMddGRKK0qSazMvyribpRB7WADTNg,922
10
+ documente_shared/application/query_params.py,sha256=dy-OcCzLt4ZDseMm5vB3uzYzFFjEiit8nKaTzODUGPg,4025
11
+ documente_shared/application/retry_utils.py,sha256=8Cj8oQp8mUynEeQNOyH_FRwODTku8KyljijYVxW7_sw,3140
12
+ documente_shared/application/time_utils.py,sha256=_fxgh8VoGPkdsft47COJ16vFwt8pMbHIJCgDFHLSlrU,435
13
+ documente_shared/application/timezone.py,sha256=NHpzTzOPD_fWQiJ4BrRqt_TIDs5XyB5ZMR7x8vUk8gQ,183
14
+ documente_shared/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ documente_shared/domain/base_enum.py,sha256=DojAfn-zQdtjtImeHUpBzE6TBTm07XrbMOdW3h8RVd8,1449
16
+ documente_shared/domain/constants.py,sha256=NG5BGaXBr_FnzudjTRPxpDpyiSDdaB_PLCdlYlFUQeU,187
17
+ documente_shared/domain/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ documente_shared/domain/entities/document.py,sha256=RSpKwP2x5KRqXezhJ25NpQs7-QpH_6EdBayARXYLi8w,14696
19
+ documente_shared/domain/entities/document_metadata.py,sha256=ygyFIC5qwxlm8DUM5kvVFny9zJfPQS8vNLM2br5XsQ8,2353
20
+ documente_shared/domain/entities/in_memory_document.py,sha256=6LlUtF9YbFPNxP-ytrWkFYQzvdJJJ9iC8X4_U125hEE,2113
21
+ documente_shared/domain/entities/processing_case.py,sha256=acfkT5aadsfFFf4Ihwgm8xOc7PaGLH_326I8ppLpY54,7554
22
+ documente_shared/domain/entities/processing_case_filters.py,sha256=harKyu7QEuL1bI_Z8_UxkVCMo5r9vHeNHyi_Ja07vjs,1953
23
+ documente_shared/domain/entities/processing_case_item.py,sha256=IN46jCGIv_DXEp1HQbqZiDteVS2UzEob7WLS4VXft1s,10586
24
+ documente_shared/domain/entities/processing_case_item_filters.py,sha256=R_AvDCB496Lww1qn2OwtltqULKE3IpcJB0ejnmRkg7Q,2009
25
+ documente_shared/domain/entities/processing_documents.py,sha256=YYuTkdCNkqlO8cA0onJsZYtstxGt9M5NMuIO_87lB14,352
26
+ documente_shared/domain/entities/processing_event.py,sha256=sejo9eM4A6fDDFq3qCX3V1GMGwQVUh_5oJaPDiUwpoc,2350
27
+ documente_shared/domain/entities/scaling.py,sha256=j_-6RL9cvZZukA6B7I17OuwNfUfHUfuSTt2wMsEXNl8,1019
28
+ documente_shared/domain/enums/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ documente_shared/domain/enums/circular_oficio.py,sha256=iHwWaM8uEYmVhAFZU1xpAdDQPlIn_el2uL3WYX2I9X4,732
30
+ documente_shared/domain/enums/common.py,sha256=tgM098gKYHCp8LVNA6FKd-O_Meoi0Cx_UjQ3OKLxGYY,3127
31
+ documente_shared/domain/enums/document.py,sha256=QwvckW-VJBSujllIVloKlZUh1pI5UnX4oueYbV5CYGw,3205
32
+ documente_shared/domain/enums/document_type_record.py,sha256=yAs-L1znL94IG2rjJ7Bcu-5vIPkr8eZP0ZN1fg2Ksbo,424
33
+ documente_shared/domain/enums/processing_case.py,sha256=IF8ivf42TY67Vg9-3SYJvmptzsskMtlqPCUNfekoq10,1794
34
+ documente_shared/domain/exceptions.py,sha256=S2xkkFPiR8jVmA6UhRb-bPVrm6JvohXw2MUhZOzdnRo,58
35
+ documente_shared/domain/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ documente_shared/domain/interfaces/scaling.py,sha256=yWAud0rcLKMMf2-QxEE__GRpzqUY0H9_qxlQTfnRYmw,249
37
+ documente_shared/domain/repositories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ documente_shared/domain/repositories/document.py,sha256=EZCbz8ManC1C2JcGuQQIJKON28AUAnUITZjy2zotRbY,819
39
+ documente_shared/domain/repositories/processing_case.py,sha256=1vGe4084q6AWaIEx8GgVAu0qm1gkResVyH5UZxmfNi4,1126
40
+ documente_shared/domain/repositories/processing_case_item.py,sha256=iUWD_tZWifB7gEDjVZL1CIFAu59q7lWkcJ4Kic5cNvc,1516
41
+ documente_shared/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ documente_shared/infrastructure/documente_client.py,sha256=u6k73yIefuEkCsHULMpVCydFzrSXclf_5oQd2D7CkKU,698
43
+ documente_shared/infrastructure/dynamo_table.py,sha256=TMQbcuty7wjDMbuhI8PbT0IGXelgELsNTtqTEQeZ824,2112
44
+ documente_shared/infrastructure/lambdas.py,sha256=sGgkw7Mhvuq2TpbW_RNdf5JvQnuzxWYH6gPOVtQ4DtE,357
45
+ documente_shared/infrastructure/repositories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ documente_shared/infrastructure/repositories/dynamo_document.py,sha256=CU3bljm83TwHO4YSUkFDUI0RPhV1yCllpNSL8_8dwBo,1495
47
+ documente_shared/infrastructure/repositories/dynamo_processing_case.py,sha256=bQQWjRknHAogXhabK1aCeYyiB73HWUX3t_TCpCx9ITo,1794
48
+ documente_shared/infrastructure/repositories/dynamo_processing_case_item.py,sha256=gD9WCA3sizp74AaWSzk-eIeZJj2_et7yJ6Q0PNQnoWg,2297
49
+ documente_shared/infrastructure/repositories/http_document.py,sha256=Qc5D5Q0fpHYLyxOMlBYMdnRhGM-lF7ZNqQxZyClsvsA,2666
50
+ documente_shared/infrastructure/repositories/http_processing_case.py,sha256=qO5O5zADNVj1ibHGgoGEIEiGbGovgMIwmMzYQ0S7ALA,3074
51
+ documente_shared/infrastructure/repositories/http_processing_case_item.py,sha256=Txmke8k2krMfuc3Sj9mabRw4OQDaVOtB5Gp9PPTOZ78,4458
52
+ documente_shared/infrastructure/repositories/mem_document.py,sha256=L4ebQljMKixnM_qI0StszUUYCCTHA_WAXW3RbPdYJFs,1559
53
+ documente_shared/infrastructure/repositories/mem_processing_case.py,sha256=ayyhtXGHLIIhtlTUjlr1s4AKn01QBFW6zKNYYL138J8,1464
54
+ documente_shared/infrastructure/repositories/mem_processing_case_item.py,sha256=kGURB2dmnhpRWxzxLCdQmhzsMAboGEKLyI3_F9UV2AQ,1566
55
+ documente_shared/infrastructure/s3_bucket.py,sha256=yaT8hkgNUk5Q6ts-E2Igo4b6nBldFi8KE_dFnJyt4JA,2032
56
+ documente_shared/infrastructure/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
+ documente_shared/infrastructure/services/http_scaling.py,sha256=cIo-61nfIwbtO86EGi5r1tFi9g3VJXldhguddt4JUyc,906
58
+ documente_shared/infrastructure/sqs_queue.py,sha256=KZWeHZ9zmXmrxoNpOQX7GEdDhZ1knbPXgwSwFwJblGg,1504
59
+ documente_shared/presentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ documente_shared/presentation/presenters.py,sha256=GGAEwefmjCIVepsUA2oZOVLxXbhhiISPM0Jgt6dT6O0,423
61
+ documente_shared-0.1.145.dist-info/METADATA,sha256=yzh_s94WhZRwCe3LDGkfkXnPxB9bjvUpbvEulRBwuMc,963
62
+ documente_shared-0.1.145.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
63
+ documente_shared-0.1.145.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 1.9.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any