channel-app 0.0.156__py3-none-any.whl → 0.0.157a2__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.
- channel_app/app/order/service.py +82 -41
- channel_app/core/settings.py +1 -0
- channel_app/database/__init__.py +0 -0
- channel_app/database/models.py +58 -0
- channel_app/database/services.py +8 -0
- channel_app/logs/__init__.py +0 -0
- channel_app/logs/encoders.py +22 -0
- channel_app/logs/enums.py +13 -0
- channel_app/logs/services.py +212 -0
- {channel_app-0.0.156.dist-info → channel_app-0.0.157a2.dist-info}/METADATA +1 -1
- {channel_app-0.0.156.dist-info → channel_app-0.0.157a2.dist-info}/RECORD +13 -6
- {channel_app-0.0.156.dist-info → channel_app-0.0.157a2.dist-info}/WHEEL +0 -0
- {channel_app-0.0.156.dist-info → channel_app-0.0.157a2.dist-info}/top_level.txt +0 -0
channel_app/app/order/service.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import uuid
|
1
2
|
from dataclasses import asdict
|
2
3
|
from typing import List, Generator, Union
|
3
4
|
|
@@ -19,6 +20,7 @@ from channel_app.core.data import (BatchRequestResponseDto,
|
|
19
20
|
CancelOrderDto,
|
20
21
|
ChannelUpdateOrderItemDto)
|
21
22
|
from channel_app.core.settings import OmnitronIntegration, ChannelIntegration
|
23
|
+
from channel_app.logs.services import LogService
|
22
24
|
from channel_app.omnitron.batch_request import ClientBatchRequest
|
23
25
|
from channel_app.omnitron.constants import (BatchRequestStatus, ContentType,
|
24
26
|
FailedReasonType)
|
@@ -33,48 +35,87 @@ class OrderService(object):
|
|
33
35
|
batch_service = ClientBatchRequest
|
34
36
|
|
35
37
|
def fetch_and_create_order(self, is_success_log=True):
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
get_orders: Generator
|
44
|
-
order_batch_objects = []
|
45
|
-
while True:
|
46
|
-
try:
|
47
|
-
channel_create_order, report_list, _ = next(get_orders)
|
48
|
-
except StopIteration:
|
49
|
-
break
|
50
|
-
|
51
|
-
# tips
|
52
|
-
channel_create_order: ChannelCreateOrderDto
|
53
|
-
report_list: List[ErrorReportDto]
|
54
|
-
for report in report_list:
|
55
|
-
if is_success_log or not report.is_ok:
|
56
|
-
report.error_code = \
|
57
|
-
f"{omnitron_integration.batch_request.local_batch_id}" \
|
58
|
-
f"-Channel-GetOrders_{channel_create_order.order.number}"
|
59
|
-
omnitron_integration.do_action(
|
60
|
-
key='create_error_report',
|
61
|
-
objects=report)
|
38
|
+
log_service = LogService()
|
39
|
+
tx_id = uuid.uuid4()
|
40
|
+
log_service.create_flow(
|
41
|
+
name="OrderSync",
|
42
|
+
transaction_id=tx_id,
|
43
|
+
)
|
62
44
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
45
|
+
try:
|
46
|
+
with log_service.step("fetch_orders"):
|
47
|
+
with OmnitronIntegration(
|
48
|
+
content_type=ContentType.order.value
|
49
|
+
) as omnitron_integration:
|
50
|
+
|
51
|
+
with log_service.step("get_orders"):
|
52
|
+
get_orders = ChannelIntegration().do_action(
|
53
|
+
key='get_orders',
|
54
|
+
batch_request=omnitron_integration.batch_request
|
55
|
+
)
|
56
|
+
|
57
|
+
get_orders: Generator
|
58
|
+
order_batch_objects = []
|
59
|
+
while True:
|
60
|
+
try:
|
61
|
+
channel_create_order, report_list, _ = next(get_orders)
|
62
|
+
except StopIteration:
|
63
|
+
break
|
64
|
+
|
65
|
+
# tips
|
66
|
+
channel_create_order: ChannelCreateOrderDto
|
67
|
+
metadata = {
|
68
|
+
"order_number": channel_create_order.order.number
|
69
|
+
}
|
70
|
+
|
71
|
+
report_list: List[ErrorReportDto]
|
72
|
+
for report in report_list:
|
73
|
+
if is_success_log or not report.is_ok:
|
74
|
+
report.error_code = \
|
75
|
+
f"{omnitron_integration.batch_request.local_batch_id}" \
|
76
|
+
f"-Channel-GetOrders_{channel_create_order.order.number}"
|
77
|
+
try:
|
78
|
+
|
79
|
+
with log_service.step("create_error_report", metadata=metadata):
|
80
|
+
omnitron_integration.do_action(
|
81
|
+
key='create_error_report',
|
82
|
+
objects=report
|
83
|
+
)
|
84
|
+
except Exception as err:
|
85
|
+
log_service.add_exception(err)
|
86
|
+
raise
|
87
|
+
|
88
|
+
try:
|
89
|
+
with log_service.step("create_order", metadata=metadata):
|
90
|
+
order = self.create_order(
|
91
|
+
omnitron_integration=omnitron_integration,
|
92
|
+
channel_order=channel_create_order
|
93
|
+
)
|
94
|
+
except Exception as err:
|
95
|
+
log_service.add_exception(err)
|
96
|
+
raise
|
97
|
+
|
98
|
+
if order and omnitron_integration.batch_request.objects:
|
99
|
+
order_batch_objects.extend(omnitron_integration.batch_request.objects)
|
100
|
+
|
101
|
+
omnitron_integration.batch_request.objects = order_batch_objects
|
102
|
+
|
103
|
+
with log_service.step("batch_to_done"):
|
104
|
+
try:
|
105
|
+
self.batch_service(settings.OMNITRON_CHANNEL_ID).to_done(
|
106
|
+
batch_request=omnitron_integration.batch_request
|
107
|
+
)
|
108
|
+
except requests_exceptions.HTTPError as exc:
|
109
|
+
log_service.add_exception(exc)
|
110
|
+
if exc.response.status_code == 406 and "batch_request_status_100_1" in exc.response.text:
|
111
|
+
pass
|
112
|
+
else:
|
113
|
+
raise exc
|
114
|
+
except Exception as fatal:
|
115
|
+
log_service.add_exception(fatal)
|
116
|
+
raise
|
117
|
+
finally:
|
118
|
+
log_service.save()
|
78
119
|
|
79
120
|
def create_order(self, omnitron_integration: OmnitronIntegration,
|
80
121
|
channel_order: ChannelCreateOrderDto
|
channel_app/core/settings.py
CHANGED
@@ -17,6 +17,7 @@ CACHE_PORT = os.getenv("CACHE_PORT")
|
|
17
17
|
BROKER_HOST = os.getenv("BROKER_HOST")
|
18
18
|
BROKER_PORT = os.getenv("BROKER_PORT")
|
19
19
|
BROKER_DATABASE_INDEX = os.getenv("BROKER_DATABASE_INDEX")
|
20
|
+
DATABASE_URI = os.getenv("DATABASE_URI")
|
20
21
|
SENTRY_DSN = os.getenv("SENTRY_DSN")
|
21
22
|
DEFAULT_CONNECTION_POOL_COUNT = os.getenv("DEFAULT_CONNECTION_POOL_COUNT") or 10
|
22
23
|
DEFAULT_CONNECTION_POOL_MAX_SIZE = os.getenv("DEFAULT_CONNECTION_POOL_COUNT") or 10
|
File without changes
|
@@ -0,0 +1,58 @@
|
|
1
|
+
from datetime import datetime, timezone
|
2
|
+
import uuid
|
3
|
+
from sqlalchemy import JSON, Column, DateTime, ForeignKey, Integer, String, Enum as SqlEnum, Text
|
4
|
+
from sqlalchemy.dialects.postgresql import UUID
|
5
|
+
from sqlalchemy.orm import DeclarativeBase, relationship
|
6
|
+
|
7
|
+
from channel_app.logs.enums import LogFlowAuthor, LogStepStatus
|
8
|
+
|
9
|
+
|
10
|
+
class Base(DeclarativeBase):
|
11
|
+
pass
|
12
|
+
|
13
|
+
|
14
|
+
class LogFlowModel(Base):
|
15
|
+
__tablename__ = "log_flows"
|
16
|
+
|
17
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
18
|
+
transaction_id = Column(UUID(as_uuid=True), unique=True, nullable=False)
|
19
|
+
flow_name = Column(String(255), nullable=False)
|
20
|
+
flow_author = Column(SqlEnum(LogFlowAuthor), default=LogFlowAuthor.system, nullable=False)
|
21
|
+
|
22
|
+
started_at = Column(DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc))
|
23
|
+
ended_at = Column(DateTime(timezone=True), nullable=True)
|
24
|
+
|
25
|
+
status = Column(SqlEnum(LogStepStatus), nullable=True)
|
26
|
+
s3_key = Column(Text, nullable=True)
|
27
|
+
|
28
|
+
def __repr__(self):
|
29
|
+
return f"<FlowLog(transaction_id={self.transaction_id}, flow_name={self.flow_name})>"
|
30
|
+
|
31
|
+
|
32
|
+
class LogStepModel(Base):
|
33
|
+
__tablename__ = "log_steps"
|
34
|
+
|
35
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
36
|
+
flow_id = Column(UUID(as_uuid=True), ForeignKey("log_flows.id", ondelete="CASCADE"), nullable=False)
|
37
|
+
step_name = Column(String(255), nullable=False)
|
38
|
+
status = Column(SqlEnum(LogStepStatus, native_enum=False), nullable=False)
|
39
|
+
start_time = Column(DateTime(timezone=True), nullable=False)
|
40
|
+
end_time = Column(DateTime(timezone=True))
|
41
|
+
duration_ms = Column(Integer)
|
42
|
+
error_message = Column(String)
|
43
|
+
step_metadata = Column(JSON)
|
44
|
+
|
45
|
+
exceptions = relationship("LogStepExceptionModel", back_populates="step", cascade="all, delete-orphan")
|
46
|
+
|
47
|
+
|
48
|
+
class LogStepExceptionModel(Base):
|
49
|
+
__tablename__ = "log_step_exceptions"
|
50
|
+
|
51
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
52
|
+
step_id = Column(UUID(as_uuid=True), ForeignKey("log_steps.id", ondelete="CASCADE"), nullable=False)
|
53
|
+
type = Column(String(128), nullable=False)
|
54
|
+
message = Column(String)
|
55
|
+
traceback = Column(String)
|
56
|
+
created_at = Column(DateTime(timezone=True), nullable=False)
|
57
|
+
|
58
|
+
step = relationship("LogStepModel", back_populates="exceptions")
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
import json
|
3
|
+
import uuid
|
4
|
+
|
5
|
+
|
6
|
+
class UUIDEncoder(json.JSONEncoder):
|
7
|
+
"""
|
8
|
+
Custom JSON encoder that handles UUID and datetime objects.
|
9
|
+
|
10
|
+
This encoder extends the standard JSONEncoder to properly serialize:
|
11
|
+
- UUID objects (converted to strings)
|
12
|
+
- datetime objects (converted to ISO format)
|
13
|
+
"""
|
14
|
+
def default(self, obj):
|
15
|
+
if isinstance(obj, uuid.UUID):
|
16
|
+
# Convert UUID to string
|
17
|
+
return str(obj)
|
18
|
+
elif isinstance(obj, datetime):
|
19
|
+
# Convert datetime to ISO format string
|
20
|
+
return obj.isoformat()
|
21
|
+
# Let the base class handle other types or raise TypeError
|
22
|
+
return super().default(obj)
|
@@ -0,0 +1,212 @@
|
|
1
|
+
from contextlib import contextmanager
|
2
|
+
import json
|
3
|
+
import os
|
4
|
+
import traceback
|
5
|
+
from typing import Optional
|
6
|
+
import uuid
|
7
|
+
from datetime import datetime, timezone
|
8
|
+
import boto3
|
9
|
+
from sqlalchemy.orm import scoped_session, sessionmaker
|
10
|
+
|
11
|
+
from channel_app.database.models import (
|
12
|
+
LogFlowModel,
|
13
|
+
LogStepExceptionModel,
|
14
|
+
LogStepModel,
|
15
|
+
)
|
16
|
+
from channel_app.database.services import DatabaseService
|
17
|
+
from channel_app.logs.encoders import UUIDEncoder
|
18
|
+
from channel_app.logs.enums import LogFlowAuthor, LogStepStatus
|
19
|
+
|
20
|
+
|
21
|
+
class LogService:
|
22
|
+
database_service = DatabaseService()
|
23
|
+
|
24
|
+
def __init__(self):
|
25
|
+
self.flow = {}
|
26
|
+
self.steps = []
|
27
|
+
self.exceptions = []
|
28
|
+
|
29
|
+
self.db_engine = self.database_service.create_engine()
|
30
|
+
self.s3_client = S3Client()
|
31
|
+
|
32
|
+
def create_flow(
|
33
|
+
self,
|
34
|
+
name: str,
|
35
|
+
transaction_id: str,
|
36
|
+
flow_author: LogFlowAuthor = LogFlowAuthor.system,
|
37
|
+
):
|
38
|
+
self.flow = {
|
39
|
+
"id": uuid.uuid4(),
|
40
|
+
"transaction_id": transaction_id or str(uuid.uuid4()),
|
41
|
+
"flow_name": name,
|
42
|
+
"flow_author": flow_author.value,
|
43
|
+
"started_at": datetime.now(timezone.utc),
|
44
|
+
}
|
45
|
+
|
46
|
+
@contextmanager
|
47
|
+
def step(self, name: str, metadata: Optional[dict] = None):
|
48
|
+
now = datetime.now(timezone.utc)
|
49
|
+
self._add_step(name, start=True, metadata=metadata)
|
50
|
+
try:
|
51
|
+
yield
|
52
|
+
self._add_step(name, end=True)
|
53
|
+
except Exception as exc:
|
54
|
+
self.add_exception(exc)
|
55
|
+
for step in reversed(self.steps):
|
56
|
+
if (
|
57
|
+
step["step_name"] == name
|
58
|
+
and step.get("status") == LogStepStatus.in_progress.value
|
59
|
+
):
|
60
|
+
step["end_time"] = now
|
61
|
+
step["status"] = LogStepStatus.failure.value
|
62
|
+
step["error"] = str(exc)
|
63
|
+
break
|
64
|
+
raise
|
65
|
+
|
66
|
+
def _add_step(self, name, start=False, end=False, metadata=None):
|
67
|
+
now = datetime.now(timezone.utc)
|
68
|
+
if start:
|
69
|
+
self.steps.append(
|
70
|
+
{
|
71
|
+
"id": uuid.uuid4(),
|
72
|
+
"step_name": name,
|
73
|
+
"start_time": now,
|
74
|
+
"status": LogStepStatus.in_progress.value,
|
75
|
+
"metadata": metadata or {},
|
76
|
+
}
|
77
|
+
)
|
78
|
+
elif end:
|
79
|
+
for step in reversed(self.steps):
|
80
|
+
if (
|
81
|
+
step["step_name"] == name
|
82
|
+
and step["status"] == LogStepStatus.in_progress.value
|
83
|
+
):
|
84
|
+
step["end_time"] = now
|
85
|
+
step["status"] = LogStepStatus.success.value
|
86
|
+
step["duration_ms"] = int(
|
87
|
+
(now - step["start_time"]).total_seconds() * 1000
|
88
|
+
)
|
89
|
+
|
90
|
+
def add_exception(self, exc: Exception):
|
91
|
+
tb = traceback.format_exc()
|
92
|
+
exc_obj = {
|
93
|
+
"id": uuid.uuid4(),
|
94
|
+
"type": type(exc).__name__,
|
95
|
+
"message": str(exc),
|
96
|
+
"traceback": tb,
|
97
|
+
}
|
98
|
+
self.exceptions.append(exc_obj)
|
99
|
+
# If this flow has related step, update the step to FAILURE
|
100
|
+
if self.steps:
|
101
|
+
self.steps[-1]["status"] = LogStepStatus.failure.value
|
102
|
+
self.steps[-1]["error"] = str(exc)
|
103
|
+
self.steps[-1].setdefault("exceptions", []).append(exc_obj)
|
104
|
+
|
105
|
+
def save(self):
|
106
|
+
self.flow["ended_at"] = datetime.now(timezone.utc)
|
107
|
+
full_log_content = {
|
108
|
+
**self.flow,
|
109
|
+
"steps": self.steps,
|
110
|
+
"exceptions": self.exceptions,
|
111
|
+
}
|
112
|
+
s3_key = f"logs/{self.flow['flow_name']}/{self.flow['transaction_id']}.json"
|
113
|
+
|
114
|
+
self.s3_client.upload_object(s3_key, full_log_content)
|
115
|
+
|
116
|
+
log_flow_object = LogFlowModel(
|
117
|
+
id=self.flow["id"],
|
118
|
+
transaction_id=str(self.flow["transaction_id"]),
|
119
|
+
flow_name=self.flow["flow_name"],
|
120
|
+
flow_author=self.flow["flow_author"],
|
121
|
+
started_at=self.flow["started_at"],
|
122
|
+
ended_at=self.flow["ended_at"],
|
123
|
+
status=(
|
124
|
+
self.steps[-1]["status"] if self.steps else LogStepStatus.failure.value
|
125
|
+
),
|
126
|
+
s3_key=s3_key,
|
127
|
+
)
|
128
|
+
|
129
|
+
step_models = []
|
130
|
+
exception_models = []
|
131
|
+
for step in self.steps:
|
132
|
+
step_model = LogStepModel(
|
133
|
+
id=step["id"],
|
134
|
+
flow_id=self.flow["id"],
|
135
|
+
step_name=step["step_name"],
|
136
|
+
status=step["status"],
|
137
|
+
start_time=step["start_time"],
|
138
|
+
end_time=step.get("end_time"),
|
139
|
+
duration_ms=step.get("duration_ms"),
|
140
|
+
error_message=step.get("error"),
|
141
|
+
step_metadata=step.get("metadata"),
|
142
|
+
)
|
143
|
+
step_models.append(step_model)
|
144
|
+
|
145
|
+
for exc in step.get("exceptions", []):
|
146
|
+
exception_models.append(
|
147
|
+
LogStepExceptionModel(
|
148
|
+
id=exc["id"],
|
149
|
+
step_id=step["id"],
|
150
|
+
type=exc["type"],
|
151
|
+
message=exc["message"],
|
152
|
+
traceback=exc["traceback"],
|
153
|
+
created_at=self.flow["ended_at"],
|
154
|
+
)
|
155
|
+
)
|
156
|
+
|
157
|
+
self._save_to_db(log_flow_object, step_models, exception_models)
|
158
|
+
|
159
|
+
def _save_to_db(self, flow_obj, step_objs, exception_objs):
|
160
|
+
session = scoped_session(sessionmaker(bind=self.db_engine))
|
161
|
+
try:
|
162
|
+
session.add(flow_obj)
|
163
|
+
session.add_all(step_objs)
|
164
|
+
if exception_objs:
|
165
|
+
session.add_all(exception_objs)
|
166
|
+
session.commit()
|
167
|
+
except Exception:
|
168
|
+
session.rollback()
|
169
|
+
raise
|
170
|
+
finally:
|
171
|
+
session.close()
|
172
|
+
|
173
|
+
|
174
|
+
class S3Client:
|
175
|
+
def __init__(self):
|
176
|
+
self._validate_credentials()
|
177
|
+
self.client = boto3.client("s3")
|
178
|
+
self.bucket = os.getenv("LOGGING_S3_BUCKET", "default-bucket-name")
|
179
|
+
|
180
|
+
def _validate_credentials(self):
|
181
|
+
required_env_vars = {
|
182
|
+
"AWS_ACCESS_KEY_ID": os.getenv("AWS_ACCESS_KEY_ID"),
|
183
|
+
"AWS_SECRET_ACCESS_KEY": os.getenv("AWS_SECRET_ACCESS_KEY"),
|
184
|
+
"AWS_REGION": os.getenv("AWS_REGION"),
|
185
|
+
"LOGGING_S3_BUCKET": os.getenv("LOGGING_S3_BUCKET"),
|
186
|
+
}
|
187
|
+
|
188
|
+
missing_vars = [
|
189
|
+
name for name, value in required_env_vars.items() if value is None
|
190
|
+
]
|
191
|
+
|
192
|
+
if missing_vars:
|
193
|
+
raise ValueError(
|
194
|
+
f"S3 Client initialization failed: missing AWS credentials: {', '.join(missing_vars)}"
|
195
|
+
)
|
196
|
+
|
197
|
+
def set_bucket(self, bucket_name: str):
|
198
|
+
self.bucket = bucket_name
|
199
|
+
return self
|
200
|
+
|
201
|
+
def upload_object(self, key: str, content: dict):
|
202
|
+
try:
|
203
|
+
body = json.dumps(content, indent=2, cls=UUIDEncoder).encode("utf-8")
|
204
|
+
self.client.put_object(
|
205
|
+
Bucket=self.bucket,
|
206
|
+
Key=key,
|
207
|
+
Body=body,
|
208
|
+
ContentType="application/json",
|
209
|
+
)
|
210
|
+
except Exception as e:
|
211
|
+
print(f"[S3 Upload Error] {e}")
|
212
|
+
raise
|
@@ -1,7 +1,7 @@
|
|
1
1
|
channel_app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
channel_app/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
channel_app/app/order/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
channel_app/app/order/service.py,sha256=
|
4
|
+
channel_app/app/order/service.py,sha256=GZ8StGwvICtI0DWMtYFq1mB9GPdojNpjCh9oVrHlHJE,22366
|
5
5
|
channel_app/app/product/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
channel_app/app/product/service.py,sha256=7DZF-Vtoaf5eKT1m_ccEOAqUxWSO7Csop4HEtJmcrvw,10646
|
7
7
|
channel_app/app/product_image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -29,9 +29,16 @@ channel_app/core/commands.py,sha256=wM0ZlH_GHaYLKy2SWab_aKuZCsSahUuHeBa_tqi3W4A,
|
|
29
29
|
channel_app/core/data.py,sha256=SlsXB0MW0epC2nrM0uEnaCBYK3Nz0kXFXZ1n4t8iomg,6931
|
30
30
|
channel_app/core/integration.py,sha256=OqpN8B3KBLsjjrbZXZaNVF6NtObejh7P_7kGFj1xU3o,2817
|
31
31
|
channel_app/core/products.py,sha256=uInjFw-vze1XP8vWEeq4VWDZVQQIiatoe1YsQ6n_H5E,2092
|
32
|
-
channel_app/core/settings.py,sha256=
|
32
|
+
channel_app/core/settings.py,sha256=ZkEiumBmRSBXd4W7RdyHrTwj7Un0Ynktab1zr8N_86I,1288
|
33
33
|
channel_app/core/tests.py,sha256=ucgnLyb3D8H2JvjjH6icdRZzZQoMFbnlnFLylhoJ0Js,434
|
34
34
|
channel_app/core/utilities.py,sha256=3iSU4RHFSsdTWBfUYBK23CRGtAIC-nYIBIJLm0Dlx3o,4168
|
35
|
+
channel_app/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
|
+
channel_app/database/models.py,sha256=cdjLcfJe-OYZzk1fl3JL6ght8jryRYLwMF2uV3srM-o,2314
|
37
|
+
channel_app/database/services.py,sha256=0zHLAcJAKRU6hKEaS9DmsX_2gIE29hh__DfHHx3JuSE,216
|
38
|
+
channel_app/logs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
|
+
channel_app/logs/encoders.py,sha256=6CVgtkV7DrjxGpNXCJgT9bn9B2Ep0lHgtm-0ES7A57I,703
|
40
|
+
channel_app/logs/enums.py,sha256=If6ZjwRTerbJypYI8WjdsleHR7FjlV-TP2nBppFVEc4,214
|
41
|
+
channel_app/logs/services.py,sha256=O488OStOe9C-2AIU34bjHEBB3_XywgGlLEn77JJHUu4,7173
|
35
42
|
channel_app/omnitron/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
43
|
channel_app/omnitron/batch_request.py,sha256=S8IHtbI1RtVLbnOwtfXSmkrREGp8wUYW2E-eu5omwyY,3550
|
37
44
|
channel_app/omnitron/constants.py,sha256=WZR6k_k2zZfN7lfi1ZLv1PphsHIq_LiZgw6Nd6LduvE,2793
|
@@ -58,7 +65,7 @@ channel_app/omnitron/commands/tests/test_product_images.py,sha256=y6tmiJ00kd2GTq
|
|
58
65
|
channel_app/omnitron/commands/tests/test_product_prices.py,sha256=5HPX9PmjGw6gk3oNrwtWLqdrOkfeNx1mYP-pYwOesZU,3496
|
59
66
|
channel_app/omnitron/commands/tests/test_product_stocks.py,sha256=q4RGlrCNUUJyN5CBL1fzrvdd4Q3xt816mbMRQT0XEd0,3496
|
60
67
|
channel_app/omnitron/commands/tests/test_products.py,sha256=uj5KLaubY3XNu0hidOH-u-Djfboe81Hj7-lP--01Le0,103494
|
61
|
-
channel_app-0.0.
|
62
|
-
channel_app-0.0.
|
63
|
-
channel_app-0.0.
|
64
|
-
channel_app-0.0.
|
68
|
+
channel_app-0.0.157a2.dist-info/METADATA,sha256=qyT2b6_Y3MwOreXTMrwfW3D113VS133PS5sAKy711OI,311
|
69
|
+
channel_app-0.0.157a2.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
70
|
+
channel_app-0.0.157a2.dist-info/top_level.txt,sha256=JT-gM6L5Cwxr1xEoN7NHrREDs-d6iGFGfRnK-NrJ3tU,12
|
71
|
+
channel_app-0.0.157a2.dist-info/RECORD,,
|
File without changes
|
File without changes
|