documente_shared 0.1.47__tar.gz → 0.1.51__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.

Potentially problematic release.


This version of documente_shared might be problematic. Click here for more details.

Files changed (23) hide show
  1. {documente_shared-0.1.47 → documente_shared-0.1.51}/PKG-INFO +1 -1
  2. documente_shared-0.1.51/documente_shared/domain/constants.py +3 -0
  3. documente_shared-0.1.47/documente_shared/domain/entities/document_process.py → documente_shared-0.1.51/documente_shared/domain/entities/document.py +43 -37
  4. documente_shared-0.1.47/documente_shared/domain/entities/document_process_metadata.py → documente_shared-0.1.51/documente_shared/domain/entities/document_metadata.py +1 -1
  5. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/domain/enums.py +6 -6
  6. documente_shared-0.1.51/documente_shared/domain/repositories.py +25 -0
  7. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/infrastructure/dynamo_repositories.py +11 -11
  8. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/infrastructure/s3_bucket.py +1 -1
  9. {documente_shared-0.1.47 → documente_shared-0.1.51}/pyproject.toml +1 -1
  10. documente_shared-0.1.47/documente_shared/domain/repositories.py +0 -25
  11. {documente_shared-0.1.47 → documente_shared-0.1.51}/README.md +0 -0
  12. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/__init__.py +0 -0
  13. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/application/__init__.py +0 -0
  14. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/application/digest.py +0 -0
  15. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/application/exceptions.py +0 -0
  16. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/application/time_utils.py +0 -0
  17. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/application/timezone.py +0 -0
  18. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/domain/__init__.py +0 -0
  19. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/domain/base_enum.py +0 -0
  20. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/domain/entities/__init__.py +0 -0
  21. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/infrastructure/__init__.py +0 -0
  22. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/infrastructure/dynamo_table.py +0 -0
  23. {documente_shared-0.1.47 → documente_shared-0.1.51}/documente_shared/infrastructure/sqs_queue.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: documente_shared
3
- Version: 0.1.47
3
+ Version: 0.1.51
4
4
  Summary: Shared utilities for Documente AI projects
5
5
  License: MIT
6
6
  Author: Tech
@@ -0,0 +1,3 @@
1
+ import pytz
2
+
3
+ la_paz_tz = pytz.timezone("America/La_Paz")
@@ -1,14 +1,15 @@
1
1
  from dataclasses import dataclass
2
- from datetime import datetime
2
+ from datetime import datetime, tzinfo
3
3
  from decimal import Decimal
4
4
  from typing import Optional, List
5
5
 
6
6
  from documente_shared.application.time_utils import get_datetime_from_data
7
- from documente_shared.domain.entities.document_process_metadata import DocumentProcessMetadata
7
+ from documente_shared.domain.constants import la_paz_tz
8
+ from documente_shared.domain.entities.document_metadata import DocumentProcessingMetadata
8
9
  from documente_shared.domain.enums import (
9
- DocumentProcessStatus,
10
- DocumentProcessSubCategory,
11
- DocumentProcessCategory,
10
+ DocumentProcessingStatus,
11
+ DocumentProcessingSubCategory,
12
+ DocumentProcessingCategory,
12
13
  )
13
14
 
14
15
  def remove_slash_from_path(path: str) -> str:
@@ -17,13 +18,13 @@ def remove_slash_from_path(path: str) -> str:
17
18
  return path
18
19
 
19
20
  @dataclass
20
- class DocumentProcess(object):
21
+ class DocumentProcessing(object):
21
22
  digest: str
22
- status: DocumentProcessStatus
23
+ status: DocumentProcessingStatus
23
24
  file_path: Optional[str] = None
24
25
  file_bytes: Optional[bytes] = None
25
- category: Optional[DocumentProcessCategory] = None
26
- sub_category: Optional[DocumentProcessSubCategory] = None
26
+ category: Optional[DocumentProcessingCategory] = None
27
+ sub_category: Optional[DocumentProcessingSubCategory] = None
27
28
  processed_csv_path: Optional[str] = None
28
29
  processed_csv_bytes: Optional[bytes] = None
29
30
  processed_xlsx_path: Optional[str] = None
@@ -39,30 +40,30 @@ class DocumentProcess(object):
39
40
  failed_at: Optional[datetime] = None
40
41
  failed_reason: Optional[str] = None
41
42
  completed_at: Optional[datetime] = None
42
- metadata_items: Optional[List[DocumentProcessMetadata]] = None
43
+ metadata_items: Optional[List[DocumentProcessingMetadata]] = None
43
44
 
44
45
  def __post_init__(self):
45
46
  self.metadata_items = self.metadata_items or []
46
47
 
47
48
  @property
48
49
  def is_pending(self) -> bool:
49
- return self.status == DocumentProcessStatus.PENDING
50
+ return self.status == DocumentProcessingStatus.PENDING
50
51
 
51
52
  @property
52
53
  def is_enqueued(self) -> bool:
53
- return self.status == DocumentProcessStatus.ENQUEUED
54
+ return self.status == DocumentProcessingStatus.ENQUEUED
54
55
 
55
56
  @property
56
57
  def is_processing(self) -> bool:
57
- return self.status == DocumentProcessStatus.PROCESSING
58
+ return self.status == DocumentProcessingStatus.PROCESSING
58
59
 
59
60
  @property
60
61
  def is_completed(self) -> bool:
61
- return self.status == DocumentProcessStatus.COMPLETED
62
+ return self.status == DocumentProcessingStatus.COMPLETED
62
63
 
63
64
  @property
64
65
  def is_failed(self) -> bool:
65
- return self.status == DocumentProcessStatus.FAILED
66
+ return self.status == DocumentProcessingStatus.FAILED
66
67
 
67
68
  @property
68
69
  def is_valid(self) -> bool:
@@ -75,29 +76,33 @@ class DocumentProcess(object):
75
76
  @property
76
77
  def is_finished(self) -> bool:
77
78
  return self.status in [
78
- DocumentProcessStatus.COMPLETED,
79
- DocumentProcessStatus.FAILED,
79
+ DocumentProcessingStatus.COMPLETED,
80
+ DocumentProcessingStatus.FAILED,
80
81
  ]
81
82
 
82
- def enqueue(self):
83
- self.status = DocumentProcessStatus.ENQUEUED
84
- self.enqueued_at = datetime.now()
83
+ def enqueue(self, timezone: tzinfo = la_paz_tz):
84
+ self.status = DocumentProcessingStatus.ENQUEUED
85
+ self.enqueued_at = datetime.now(tz=timezone)
85
86
 
86
- def processing(self):
87
- self.status = DocumentProcessStatus.PROCESSING
88
- self.started_at = datetime.now()
87
+ def processing(self, timezone: tzinfo = la_paz_tz):
88
+ self.status = DocumentProcessingStatus.PROCESSING
89
+ self.started_at = datetime.now(tz=timezone)
89
90
 
90
- def failed(self, error_message: Optional[str] = None):
91
+ def failed(
92
+ self,
93
+ error_message: Optional[str] = None,
94
+ timezone: tzinfo = la_paz_tz,
95
+ ):
91
96
  self.failed_reason = error_message
92
- self.status = DocumentProcessStatus.FAILED
93
- self.failed_at = datetime.now()
97
+ self.status = DocumentProcessingStatus.FAILED
98
+ self.failed_at = datetime.now(tz=timezone)
94
99
 
95
- def completed(self):
96
- self.status = DocumentProcessStatus.COMPLETED
97
- self.completed_at = datetime.now()
100
+ def completed(self, timezone: tzinfo = la_paz_tz):
101
+ self.status = DocumentProcessingStatus.COMPLETED
102
+ self.completed_at = datetime.now(tz=timezone)
98
103
 
99
104
  def deleted(self):
100
- self.status = DocumentProcessStatus.DELETED
105
+ self.status = DocumentProcessingStatus.DELETED
101
106
 
102
107
  @property
103
108
  def file_key(self) -> str:
@@ -128,7 +133,7 @@ class DocumentProcess(object):
128
133
  filename_with_extension = self.extended_filename
129
134
  return filename_with_extension.split('.')[0]
130
135
 
131
- def __eq__(self, other: 'DocumentProcess') -> bool:
136
+ def __eq__(self, other: 'DocumentProcessing') -> bool:
132
137
  if not other:
133
138
  return False
134
139
 
@@ -185,7 +190,7 @@ class DocumentProcess(object):
185
190
 
186
191
  def overload(
187
192
  self,
188
- new_instance: 'DocumentProcess',
193
+ new_instance: 'DocumentProcessing',
189
194
  properties: List[str] = None,
190
195
  ):
191
196
  instance_properties = properties or [
@@ -202,6 +207,7 @@ class DocumentProcess(object):
202
207
  'processed_json_path',
203
208
  'processed_json_bytes',
204
209
  'processed_metadata_path',
210
+ 'processed_metadata_bytes',
205
211
  'processing_time',
206
212
  'issued_at',
207
213
  'uploaded_at',
@@ -219,17 +225,17 @@ class DocumentProcess(object):
219
225
  return self
220
226
 
221
227
  @classmethod
222
- def from_dict(cls, data: dict) -> 'DocumentProcess':
228
+ def from_dict(cls, data: dict) -> 'DocumentProcessing':
223
229
  return cls(
224
230
  digest=data.get('digest'),
225
- status=DocumentProcessStatus.from_value(data.get('status')),
231
+ status=DocumentProcessingStatus.from_value(data.get('status')),
226
232
  file_path=data.get('file_path'),
227
233
  category=(
228
- DocumentProcessCategory.from_value(data.get('category'))
234
+ DocumentProcessingCategory.from_value(data.get('category'))
229
235
  if data.get('category') else None
230
236
  ),
231
237
  sub_category=(
232
- DocumentProcessSubCategory.from_value(data.get('sub_category'))
238
+ DocumentProcessingSubCategory.from_value(data.get('sub_category'))
233
239
  if data.get('sub_category') else None
234
240
  ),
235
241
  processed_csv_path=data.get('processed_csv_path'),
@@ -248,7 +254,7 @@ class DocumentProcess(object):
248
254
  failed_reason=data.get('failed_reason'),
249
255
  completed_at=get_datetime_from_data(input_datetime=data.get('completed_at')),
250
256
  metadata_items=[
251
- DocumentProcessMetadata.from_dict(metadata)
257
+ DocumentProcessingMetadata.from_dict(metadata)
252
258
  for metadata in data.get('metadata_items', [])
253
259
  ],
254
260
  )
@@ -4,7 +4,7 @@ from typing import Optional
4
4
 
5
5
 
6
6
  @dataclass
7
- class DocumentProcessMetadata(object):
7
+ class DocumentProcessingMetadata(object):
8
8
  publication_date: Optional[datetime] = None
9
9
  num_circular: Optional[str] = None
10
10
  asfi_identifier: Optional[str] = None
@@ -1,7 +1,7 @@
1
1
  from documente_shared.domain.base_enum import BaseEnum
2
2
 
3
3
 
4
- class DocumentProcessStatus(BaseEnum):
4
+ class DocumentProcessingStatus(BaseEnum):
5
5
  PENDING = 'PENDING'
6
6
  ENQUEUED = 'ENQUEUED'
7
7
  PROCESSING = 'PROCESSING'
@@ -11,20 +11,20 @@ class DocumentProcessStatus(BaseEnum):
11
11
  CANCELLED = 'CANCELLED'
12
12
 
13
13
 
14
- class DocumentProcessCategory(BaseEnum):
14
+ class DocumentProcessingCategory(BaseEnum):
15
15
  CIRCULAR = 'CIRCULAR'
16
16
  DESGRAVAMEN = 'DESGRAVAMEN'
17
17
 
18
18
  @property
19
19
  def is_circular(self):
20
- return self == DocumentProcessCategory.CIRCULAR
20
+ return self == DocumentProcessingCategory.CIRCULAR
21
21
 
22
22
  @property
23
23
  def is_desgravamen(self):
24
- return self == DocumentProcessCategory.DESGRAVAMEN
24
+ return self == DocumentProcessingCategory.DESGRAVAMEN
25
25
 
26
26
 
27
- class DocumentProcessSubCategory(BaseEnum):
27
+ class DocumentProcessingSubCategory(BaseEnum):
28
28
  # Circulares
29
29
  CC_COMBINADA = 'CC_COMBINADA'
30
30
  CC_NORMATIVA = 'CC_NORMATIVA'
@@ -32,5 +32,5 @@ class DocumentProcessSubCategory(BaseEnum):
32
32
  CC_RETENCION_SUSPENSION_REMISION = 'CC_RETENCION_SUSPENSION_REMISION'
33
33
 
34
34
  # Desgravamenes
35
- DS_CREDISEGUROS = 'DS_CREDISEGUROS'
35
+ DS_CREDISEGURO = 'DS_CREDISEGURO'
36
36
 
@@ -0,0 +1,25 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Optional, List
3
+
4
+ from documente_shared.domain.entities.document import DocumentProcessing
5
+ from documente_shared.domain.enums import DocumentProcessingStatus
6
+
7
+
8
+ class DocumentProcessingRepository(ABC):
9
+
10
+ @abstractmethod
11
+ def find(self, digest: str) ->Optional[DocumentProcessing]:
12
+ raise NotImplementedError
13
+
14
+ @abstractmethod
15
+ def persist(self, instance: DocumentProcessing) -> DocumentProcessing:
16
+ raise NotImplementedError
17
+
18
+ @abstractmethod
19
+ def remove(self, instance: DocumentProcessing):
20
+ raise NotImplementedError
21
+
22
+
23
+ @abstractmethod
24
+ def filter(self, statuses: List[DocumentProcessingStatus]) -> List[DocumentProcessing]:
25
+ raise NotImplementedError
@@ -2,31 +2,31 @@ from typing import Optional, List
2
2
 
3
3
  from boto3.dynamodb.conditions import Key
4
4
 
5
- from documente_shared.domain.entities.document_process import DocumentProcess
6
- from documente_shared.domain.enums import DocumentProcessStatus
7
- from documente_shared.domain.repositories import DocumentProcessRepository
5
+ from documente_shared.domain.entities.document import DocumentProcessing
6
+ from documente_shared.domain.enums import DocumentProcessingStatus, DocumentProcessingCategory
7
+ from documente_shared.domain.repositories import DocumentProcessingRepository
8
8
  from documente_shared.infrastructure.dynamo_table import DynamoDBTable
9
9
 
10
10
 
11
11
 
12
- class DynamoDocumentProcessRepository(
12
+ class DynamoDocumentProcessingRepository(
13
13
  DynamoDBTable,
14
- DocumentProcessRepository,
14
+ DocumentProcessingRepository,
15
15
  ):
16
- def find(self, digest: str) -> Optional[DocumentProcess]:
16
+ def find(self, digest: str) -> Optional[DocumentProcessing]:
17
17
  item = self.get(key={'digest': digest})
18
18
  if item:
19
- return DocumentProcess.from_dict(item)
19
+ return DocumentProcessing.from_dict(item)
20
20
  return None
21
21
 
22
- def persist(self, instance: DocumentProcess) -> DocumentProcess:
22
+ def persist(self, instance: DocumentProcessing) -> DocumentProcessing:
23
23
  self.put(instance.to_simple_dict)
24
24
  return instance
25
25
 
26
- def remove(self, instance: DocumentProcess):
26
+ def remove(self, instance: DocumentProcessing):
27
27
  self.delete(key={'digest': instance.digest})
28
28
 
29
- def filter(self, statuses: List[DocumentProcessStatus]) -> List[DocumentProcess]:
29
+ def filter(self, statuses: List[DocumentProcessingStatus]) -> List[DocumentProcessing]:
30
30
  items = []
31
31
 
32
32
  for status in statuses:
@@ -38,6 +38,6 @@ class DynamoDocumentProcessRepository(
38
38
  items.extend(status_items)
39
39
 
40
40
  return [
41
- DocumentProcess.from_dict(item)
41
+ DocumentProcessing.from_dict(item)
42
42
  for item in items
43
43
  ]
@@ -3,7 +3,7 @@ import boto3
3
3
  from dataclasses import dataclass
4
4
  from typing import Optional
5
5
 
6
- from documente_shared.domain.entities.document_process import remove_slash_from_path
6
+ from documente_shared.domain.entities.document import remove_slash_from_path
7
7
 
8
8
 
9
9
  def remove_none_values(data: dict) -> dict: # noqa: WPS110
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "documente_shared"
3
- version = "0.1.47"
3
+ version = "0.1.51"
4
4
  description = "Shared utilities for Documente AI projects"
5
5
  authors = ["Tech <tech@llamitai.com>"]
6
6
  license = "MIT"
@@ -1,25 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from typing import Optional, List
3
-
4
- from documente_shared.domain.entities.document_process import DocumentProcess
5
- from documente_shared.domain.enums import DocumentProcessStatus
6
-
7
-
8
- class DocumentProcessRepository(ABC):
9
-
10
- @abstractmethod
11
- def find(self, digest: str) ->Optional[DocumentProcess]:
12
- raise NotImplementedError
13
-
14
- @abstractmethod
15
- def persist(self, instance: DocumentProcess) -> DocumentProcess:
16
- raise NotImplementedError
17
-
18
- @abstractmethod
19
- def remove(self, instance: DocumentProcess):
20
- raise NotImplementedError
21
-
22
-
23
- @abstractmethod
24
- def filter(self, statuses: List[DocumentProcessStatus]) -> List[DocumentProcess]:
25
- raise NotImplementedError