documente_shared 0.1.68__py3-none-any.whl → 0.1.71__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.

Potentially problematic release.


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

@@ -4,19 +4,18 @@ from datetime import datetime, tzinfo
4
4
  from decimal import Decimal
5
5
  from typing import Optional, List
6
6
 
7
- from documente_shared.application.files import remove_slash_from_path, split_file_params, get_filename_from_path
7
+ from documente_shared.application.files import remove_slash_from_path, get_filename_from_path
8
8
  from documente_shared.application.time_utils import get_datetime_from_data
9
9
  from documente_shared.domain.constants import la_paz_tz
10
10
  from documente_shared.domain.entities.document_metadata import DocumentProcessingMetadata
11
- from documente_shared.domain.enums import (
11
+ from documente_shared.domain.enums.document import (
12
12
  DocumentProcessingStatus,
13
+ DocumentProcessingCategory,
13
14
  DocumentProcessingSubCategory,
14
- DocumentProcessingCategory, DocumentProcessingSource,
15
+ DocumentProcessingSource,
15
16
  )
16
17
 
17
18
 
18
-
19
-
20
19
  @dataclass
21
20
  class DocumentProcessing(object):
22
21
  digest: str
@@ -11,7 +11,7 @@ from documente_shared.domain.enums.processing_case import ProcessingCaseCategory
11
11
 
12
12
  @dataclass
13
13
  class ProcessingCase(object):
14
- id: str
14
+ case_id: str
15
15
  status: ProcessingStatus
16
16
  category: Optional[ProcessingCaseCategory] = None
17
17
  enqueued_at: Optional[datetime] = None
@@ -61,21 +61,21 @@ class ProcessingCase(object):
61
61
  return False
62
62
 
63
63
  return (
64
- self.id == other.id
65
- and self.status == other.status
66
- and self.category == other.category
67
- and self.enqueued_at == other.enqueued_at
68
- and self.started_at == other.started_at
69
- and self.failed_at == other.failed_at
70
- and self.feedback == other.feedback
71
- and self.completed_at == other.completed_at
72
- and self.metadata == other.metadata
64
+ self.case_id == other.case_id
65
+ and self.status == other.status
66
+ and self.category == other.category
67
+ and self.enqueued_at == other.enqueued_at
68
+ and self.started_at == other.started_at
69
+ and self.failed_at == other.failed_at
70
+ and self.feedback == other.feedback
71
+ and self.completed_at == other.completed_at
72
+ and self.metadata == other.metadata
73
73
  )
74
74
 
75
75
  @property
76
76
  def to_dict(self) -> dict:
77
77
  return {
78
- 'id': self.id,
78
+ 'case_id': self.case_id,
79
79
  'status': str(self.status),
80
80
  'category': (
81
81
  str(self.category)
@@ -120,7 +120,7 @@ class ProcessingCase(object):
120
120
  @classmethod
121
121
  def from_dict(cls, data: dict) -> 'ProcessingCase':
122
122
  return cls(
123
- id=data.get('id'),
123
+ case_id=data.get('case_id'),
124
124
  status=ProcessingStatus.from_value(data.get('status')),
125
125
  category=(
126
126
  ProcessingCaseCategory.from_value(data.get('category'))
@@ -12,7 +12,7 @@ from documente_shared.domain.enums.processing_case import ProcessingDocumentType
12
12
 
13
13
  @dataclass
14
14
  class ProcessingCaseItem(object):
15
- id: str
15
+ item_id: str
16
16
  case_id: str
17
17
  digest: str
18
18
  status: ProcessingStatus
@@ -99,12 +99,12 @@ class ProcessingCaseItem(object):
99
99
  @property
100
100
  def to_dict(self) -> dict:
101
101
  return {
102
- 'id': self.id,
102
+ 'item_id': self.item_id,
103
103
  'case_id': self.case_id,
104
104
  'digest': self.digest,
105
105
  'status': str(self.status),
106
106
  'document': self.document.to_dict,
107
- 'document_type': self.document_type,
107
+ 'document_type': str(self.document_type),
108
108
  'uploaded_from': (
109
109
  str(self.uploaded_from)
110
110
  if self.uploaded_from else None
@@ -139,7 +139,6 @@ class ProcessingCaseItem(object):
139
139
  @property
140
140
  def to_simple_dict(self) -> dict:
141
141
  simple_dict = self.to_dict.copy()
142
- simple_dict.pop('metadata_items')
143
142
  return simple_dict
144
143
 
145
144
  def overload(
@@ -173,7 +172,7 @@ class ProcessingCaseItem(object):
173
172
  @classmethod
174
173
  def from_dict(cls, data: dict) -> 'ProcessingCaseItem':
175
174
  return cls(
176
- id=data.get('id'),
175
+ item_id=data.get('item_id'),
177
176
  case_id=data.get('case_id'),
178
177
  digest=data.get('digest'),
179
178
  status=ProcessingStatus.from_value(data.get('status')),
@@ -0,0 +1,49 @@
1
+ from dataclasses import dataclass
2
+ from datetime import datetime
3
+ from typing import Optional
4
+
5
+ from documente_shared.application.time_utils import get_datetime_from_data
6
+ from documente_shared.domain.entities.document import DocumentProcessing
7
+ from documente_shared.domain.entities.processing_case import ProcessingCase
8
+ from documente_shared.domain.enums.common import ProcessingType
9
+
10
+
11
+ @dataclass
12
+ class ProcessingEvent(object):
13
+ processing_type: ProcessingType
14
+ instance: DocumentProcessing | ProcessingCase | None
15
+ timestamp: Optional[datetime] = None
16
+
17
+ def __eq__(self, other: 'ProcessingEvent') -> bool:
18
+ if not other:
19
+ return False
20
+
21
+ return (
22
+ self.processing_type == other.processing_type
23
+ and self.instance == other.instance
24
+ )
25
+
26
+ @property
27
+ def to_dict(self) -> dict:
28
+ return {
29
+ 'processing_type': str(self.processing_type),
30
+ 'instance': self.instance.to_dict,
31
+ 'timestamp': self.timestamp.isoformat() if self.timestamp else None,
32
+ }
33
+
34
+ @classmethod
35
+ def from_dict(cls, data: dict) -> 'ProcessingEvent':
36
+ processing_type = ProcessingType.from_value(data.get('processing_type'))
37
+
38
+ if processing_type.is_document:
39
+ processing_instance = DocumentProcessing.from_dict(data.get('instance'))
40
+ elif processing_type.is_processing_case:
41
+ processing_instance = ProcessingCase.from_dict(data.get('instance'))
42
+ else:
43
+ processing_instance = None
44
+
45
+ return cls(
46
+ processing_type=processing_type,
47
+ instance=processing_instance,
48
+ timestamp=get_datetime_from_data(input_datetime=data.get('timestamp')),
49
+ )
File without changes
@@ -2,13 +2,13 @@ from abc import ABC, abstractmethod
2
2
  from typing import Optional, List
3
3
 
4
4
  from documente_shared.domain.entities.document import DocumentProcessing
5
- from documente_shared.domain.enums import DocumentProcessingStatus
5
+ from documente_shared.domain.enums.document import DocumentProcessingStatus
6
6
 
7
7
 
8
8
  class DocumentProcessingRepository(ABC):
9
9
 
10
10
  @abstractmethod
11
- def find(self, digest: str) ->Optional[DocumentProcessing]:
11
+ def find(self, digest: str) -> Optional[DocumentProcessing]:
12
12
  raise NotImplementedError
13
13
 
14
14
  @abstractmethod
@@ -19,7 +19,6 @@ class DocumentProcessingRepository(ABC):
19
19
  def remove(self, instance: DocumentProcessing):
20
20
  raise NotImplementedError
21
21
 
22
-
23
22
  @abstractmethod
24
23
  def filter(self, statuses: List[DocumentProcessingStatus]) -> List[DocumentProcessing]:
25
- raise NotImplementedError
24
+ raise NotImplementedError
@@ -0,0 +1,24 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Optional, List
3
+
4
+ from documente_shared.domain.entities.processing_case import ProcessingCase
5
+ from documente_shared.domain.enums.common import ProcessingStatus
6
+
7
+
8
+ class ProcessingCaseRepository(ABC):
9
+
10
+ @abstractmethod
11
+ def find(self, case_id: str) -> Optional[ProcessingCase]:
12
+ raise NotImplementedError
13
+
14
+ @abstractmethod
15
+ def persist(self, instance: ProcessingCase) -> ProcessingCase:
16
+ raise NotImplementedError
17
+
18
+ @abstractmethod
19
+ def remove(self, instance: ProcessingCase):
20
+ raise NotImplementedError
21
+
22
+ @abstractmethod
23
+ def filter(self, statuses: List[ProcessingStatus]) -> List[ProcessingCase]:
24
+ raise NotImplementedError
@@ -0,0 +1,29 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Optional, List
3
+
4
+ from documente_shared.domain.entities.processing_case import ProcessingCase
5
+ from documente_shared.domain.entities.processing_case_item import ProcessingCaseItem
6
+ from documente_shared.domain.enums.common import ProcessingStatus
7
+
8
+
9
+ class ProcessingCaseItemRepository(ABC):
10
+
11
+ @abstractmethod
12
+ def find(self, digest: str) -> Optional[ProcessingCaseItem]:
13
+ raise NotImplementedError
14
+
15
+ @abstractmethod
16
+ def persist(self, instance: ProcessingCaseItem) -> ProcessingCaseItem:
17
+ raise NotImplementedError
18
+
19
+ @abstractmethod
20
+ def remove(self, instance: ProcessingCaseItem):
21
+ raise NotImplementedError
22
+
23
+ @abstractmethod
24
+ def filter(self, statuses: List[ProcessingStatus]) -> List[ProcessingCase]:
25
+ raise NotImplementedError
26
+
27
+ @abstractmethod
28
+ def filter_by_case_id(self, case_id: str) -> List[ProcessingCase]:
29
+ raise NotImplementedError
@@ -1,11 +1,12 @@
1
- from dataclasses import dataclass
2
-
3
1
  import boto3
2
+
3
+ from dataclasses import dataclass
4
4
  from boto3.dynamodb.conditions import Key
5
5
 
6
6
 
7
7
  RETURN_VALUES = 'UPDATED_NEW'
8
8
 
9
+
9
10
  @dataclass
10
11
  class DynamoDBTable(object):
11
12
  table_name: str
@@ -50,7 +51,6 @@ class DynamoDBTable(object):
50
51
  def count(self) -> int:
51
52
  return self._table.item_count
52
53
 
53
-
54
54
  @classmethod
55
55
  def _update_expression(cls, attributes):
56
56
  return 'SET {param}'.format(
@@ -3,10 +3,10 @@ from typing import Optional, List
3
3
  from boto3.dynamodb.conditions import Key
4
4
 
5
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
- from documente_shared.infrastructure.dynamo_table import DynamoDBTable
6
+ from documente_shared.domain.enums.document import DocumentProcessingStatus
7
+ from documente_shared.domain.repositories.document import DocumentProcessingRepository
9
8
 
9
+ from documente_shared.infrastructure.dynamo_table import DynamoDBTable
10
10
 
11
11
 
12
12
  class DynamoDocumentProcessingRepository(
@@ -0,0 +1,43 @@
1
+ from typing import Optional, List
2
+
3
+ from boto3.dynamodb.conditions import Key
4
+
5
+ from documente_shared.domain.entities.processing_case import ProcessingCase
6
+ from documente_shared.domain.enums.common import ProcessingStatus
7
+ from documente_shared.domain.repositories.processing_case import ProcessingCaseRepository
8
+
9
+ from documente_shared.infrastructure.dynamo_table import DynamoDBTable
10
+
11
+
12
+ class DynamoProcessingCaseRepository(
13
+ DynamoDBTable,
14
+ ProcessingCaseRepository,
15
+ ):
16
+ def find(self, case_id: str) -> Optional[ProcessingCase]:
17
+ item = self.get(key={'case_id': case_id})
18
+ if item:
19
+ return ProcessingCase.from_dict(item)
20
+ return None
21
+
22
+ def persist(self, instance: ProcessingCase) -> ProcessingCase:
23
+ self.put(instance.to_persist_dict)
24
+ return instance
25
+
26
+ def remove(self, instance: ProcessingCase):
27
+ self.delete(key={'case_id': instance.case_id})
28
+
29
+ def filter(self, statuses: List[ProcessingStatus]) -> List[ProcessingCase]:
30
+ items = []
31
+
32
+ for status in statuses:
33
+ response = self._table.query(
34
+ IndexName='status',
35
+ KeyConditionExpression=Key('status').eq(status.value),
36
+ )
37
+ status_items = response.get('Items', [])
38
+ items.extend(status_items)
39
+
40
+ return [
41
+ ProcessingCase.from_dict(item)
42
+ for item in items
43
+ ]
@@ -0,0 +1,54 @@
1
+ from typing import Optional, List
2
+
3
+ from boto3.dynamodb.conditions import Key
4
+
5
+ from documente_shared.domain.entities.processing_case_item import ProcessingCaseItem
6
+ from documente_shared.domain.enums.common import ProcessingStatus
7
+ from documente_shared.domain.repositories.processing_case_item import ProcessingCaseItemRepository
8
+
9
+ from documente_shared.infrastructure.dynamo_table import DynamoDBTable
10
+
11
+
12
+ class DynamoProcessingCaseItemRepository(
13
+ DynamoDBTable,
14
+ ProcessingCaseItemRepository,
15
+ ):
16
+ def find(self, digest: str) -> Optional[ProcessingCaseItem]:
17
+ item = self.get(key={'digest': digest})
18
+ if item:
19
+ return ProcessingCaseItem.from_dict(item)
20
+ return None
21
+
22
+ def persist(self, instance: ProcessingCaseItem) -> ProcessingCaseItem:
23
+ self.put(instance.to_simple_dict)
24
+ return instance
25
+
26
+ def remove(self, instance: ProcessingCaseItem):
27
+ self.delete(key={'case_id': instance.case_id})
28
+
29
+ def filter(self, statuses: List[ProcessingStatus]) -> List[ProcessingCaseItem]:
30
+ items = []
31
+
32
+ for status in statuses:
33
+ response = self._table.query(
34
+ IndexName='status',
35
+ KeyConditionExpression=Key('status').eq(status.value),
36
+ )
37
+ status_items = response.get('Items', [])
38
+ items.extend(status_items)
39
+
40
+ return [
41
+ ProcessingCaseItem.from_dict(item)
42
+ for item in items
43
+ ]
44
+
45
+ def filter_by_case_id(self, case_id: str) -> List[ProcessingCaseItem]:
46
+ response = self._table.query(
47
+ IndexName='case_id',
48
+ KeyConditionExpression=Key('case_id').eq(case_id),
49
+ )
50
+ items = response.get('Items', [])
51
+ return [
52
+ ProcessingCaseItem.from_dict(item)
53
+ for item in items
54
+ ]
@@ -7,7 +7,7 @@ from dataclasses import dataclass
7
7
  @dataclass
8
8
  class SQSQueue(object):
9
9
  queue_url: str
10
- visibility_timeout: int = 60 * 10
10
+ visibility_timeout: int = 60 * 10
11
11
  waiting_timeout: int = 20
12
12
 
13
13
  def __post_init__(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: documente_shared
3
- Version: 0.1.68
3
+ Version: 0.1.71
4
4
  Summary: Shared utilities for Documente AI projects
5
5
  License: MIT
6
6
  Author: Tech
@@ -11,8 +11,9 @@ Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
- Requires-Dist: boto3 (>=1.34.80,<2.0.0)
15
- Requires-Dist: botocore (>=1.34.80,<2.0.0)
14
+ Requires-Dist: boto3 (>=1.37.19,<2.0.0)
15
+ Requires-Dist: botocore (>=1.37.19,<2.0.0)
16
+ Requires-Dist: pytz (>=2025.2,<2026.0)
16
17
  Requires-Dist: sentry-sdk (>=2.19.2,<3.0.0)
17
18
  Description-Content-Type: text/markdown
18
19
 
@@ -9,21 +9,28 @@ documente_shared/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
9
9
  documente_shared/domain/base_enum.py,sha256=DojAfn-zQdtjtImeHUpBzE6TBTm07XrbMOdW3h8RVd8,1449
10
10
  documente_shared/domain/constants.py,sha256=jOlMKFq12FgiYMJcQHku8IVwuOE5t-HEPuSV_zEeIFo,56
11
11
  documente_shared/domain/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- documente_shared/domain/entities/document.py,sha256=kaLuVJ-LVQMUdQhCReQ2Mkl7-Kmws6-TNxKnlXogYSk,12603
12
+ documente_shared/domain/entities/document.py,sha256=AthTUyA-QZE3WAT7lMoKVr_Z8mO_3qERuCnZge0DTLQ,12595
13
13
  documente_shared/domain/entities/document_metadata.py,sha256=ygyFIC5qwxlm8DUM5kvVFny9zJfPQS8vNLM2br5XsQ8,2353
14
14
  documente_shared/domain/entities/in_memory_result.py,sha256=Q1E9vnLL5Hz5xunOqWtQmJOMjoK5KN42LZr18GlBAZo,1246
15
- documente_shared/domain/entities/processing_case.py,sha256=PuwWQuXIIP5wlkWBCrkF-61TfgKSYwc9HZl1JR13xhk,4955
16
- documente_shared/domain/entities/processing_case_item.py,sha256=5wuZylIc_Lanh5PnY4ghEgbQhCtBDCExh4KRW6ZGK_4,7684
15
+ documente_shared/domain/entities/processing_case.py,sha256=xIU10DSkh_7_1DU_ttx02eS020FOtCL64dp0kf0Hgm8,5026
16
+ documente_shared/domain/entities/processing_case_item.py,sha256=rC8tE2qSw8SaOneKrg_cHtdD2WIAvFYht2qwxQdBuBU,7672
17
+ documente_shared/domain/entities/processing_event.py,sha256=m1O0gcNaE_SszeIhxM3uYPHSpyOUmize6mfRw1_bYZo,1723
17
18
  documente_shared/domain/enums/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
19
  documente_shared/domain/enums/common.py,sha256=vXldMUPhhWo0PfTgYwDSjI8bur_lYcImZYiV7yAO7DQ,2262
19
20
  documente_shared/domain/enums/document.py,sha256=NltZA1YVgJ7dVfSQdJFIE0ZUGf9Y-nxNXsVQ6GiPLL4,1827
20
21
  documente_shared/domain/enums/processing_case.py,sha256=DLVk0VnVzrKs1CvXVGHV9p8mBUHLUrOSJJ1POE-Ek3o,1546
21
- documente_shared/domain/repositories.py,sha256=g3qLUy2kT8esmvU4VxxSVnDaXeySKKQ7mUvIvxOwh9A,757
22
+ documente_shared/domain/repositories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ documente_shared/domain/repositories/document.py,sha256=vJzr6c92gqBzyhaEdjrvnoneKRrWmJ0AsvocPnhxiLU,767
24
+ documente_shared/domain/repositories/processing_case.py,sha256=7WE5RdLr04ysGXAdkJYmbfcLpMyOMeuDJGounZKMZqs,729
25
+ documente_shared/domain/repositories/processing_case_item.py,sha256=yD-v_24UzHwNdq75KRJGwHemTVFpO9LMIPSup4GbyKs,959
22
26
  documente_shared/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- documente_shared/infrastructure/dynamo_repositories.py,sha256=SEad_HLppp2h_BKDSzb9oo1VlAVRZWelOPvJPlDwbzQ,1453
24
- documente_shared/infrastructure/dynamo_table.py,sha256=dK05KgFvIYCmOdMpq9-OV_OBrP6cCngiUikCJrxlwt4,2112
27
+ documente_shared/infrastructure/dynamo_table.py,sha256=TMQbcuty7wjDMbuhI8PbT0IGXelgELsNTtqTEQeZ824,2112
28
+ documente_shared/infrastructure/repositories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ documente_shared/infrastructure/repositories/dynamo_document.py,sha256=_Yp4gtA-n-hJ2w2wAM5BMCs2Mf46Q2Kq3eHqlxudkL4,1443
30
+ documente_shared/infrastructure/repositories/dynamo_processing_case.py,sha256=Wt0di0402mrnvYNqe5ywDtFFdXjnHHvLDG4k_MQfmTE,1401
31
+ documente_shared/infrastructure/repositories/dynamo_processing_case_item.py,sha256=gG7H7hyeKTPMywTUmnq0nClrpaOqVPy7bh1OLBzV4pE,1816
25
32
  documente_shared/infrastructure/s3_bucket.py,sha256=vT_yN42RFQXubtUn8ln-j13Os_-25UGClVtXg5Bkv6I,1932
26
- documente_shared/infrastructure/sqs_queue.py,sha256=PSiTAnjXvQ-W-9mzLpH2UjbQJTvYkMiaxNaMecF-cR4,1505
27
- documente_shared-0.1.68.dist-info/METADATA,sha256=GzKC9St8yRT3mlxTKnKVBx7xbfwrNTmsX239ZvmARV0,800
28
- documente_shared-0.1.68.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
29
- documente_shared-0.1.68.dist-info/RECORD,,
33
+ documente_shared/infrastructure/sqs_queue.py,sha256=KZWeHZ9zmXmrxoNpOQX7GEdDhZ1knbPXgwSwFwJblGg,1504
34
+ documente_shared-0.1.71.dist-info/METADATA,sha256=3TPrU9cuz9uYXEg7_sJer4h_bRt6p19Zmx1WHCbxbSw,839
35
+ documente_shared-0.1.71.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
36
+ documente_shared-0.1.71.dist-info/RECORD,,