nlbone 0.6.19__py3-none-any.whl → 0.7.0__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.
- nlbone/adapters/db/postgres/__init__.py +1 -1
- nlbone/adapters/db/postgres/base.py +2 -1
- nlbone/adapters/db/postgres/query_builder.py +1 -1
- nlbone/adapters/db/postgres/repository.py +254 -29
- nlbone/adapters/db/postgres/uow.py +36 -1
- nlbone/adapters/messaging/__init__.py +1 -1
- nlbone/adapters/messaging/event_bus.py +97 -17
- nlbone/adapters/messaging/rabbitmq.py +45 -0
- nlbone/adapters/outbox/__init__.py +1 -0
- nlbone/adapters/outbox/outbox_consumer.py +112 -0
- nlbone/adapters/outbox/outbox_repo.py +191 -0
- nlbone/adapters/ticketing/client.py +39 -0
- nlbone/config/settings.py +14 -5
- nlbone/container.py +1 -8
- nlbone/core/application/bus.py +169 -0
- nlbone/core/application/di.py +128 -0
- nlbone/core/application/registry.py +129 -0
- nlbone/core/domain/base.py +30 -9
- nlbone/core/domain/models.py +46 -3
- nlbone/core/ports/__init__.py +0 -2
- nlbone/core/ports/event_bus.py +23 -6
- nlbone/core/ports/outbox.py +73 -0
- nlbone/core/ports/repository.py +116 -0
- nlbone/core/ports/uow.py +20 -1
- nlbone/interfaces/api/additional_filed/field_registry.py +2 -0
- nlbone/interfaces/cli/crypto.py +22 -0
- nlbone/interfaces/cli/init_db.py +39 -2
- nlbone/interfaces/cli/main.py +4 -0
- nlbone/interfaces/cli/ticket.py +29 -0
- nlbone/interfaces/jobs/dispatch_outbox.py +3 -2
- nlbone/utils/crypto.py +32 -0
- nlbone/utils/normalize_mobile.py +33 -0
- {nlbone-0.6.19.dist-info → nlbone-0.7.0.dist-info}/METADATA +4 -2
- {nlbone-0.6.19.dist-info → nlbone-0.7.0.dist-info}/RECORD +38 -31
- nlbone/adapters/repositories/outbox_repo.py +0 -20
- nlbone/core/application/command_bus.py +0 -25
- nlbone/core/application/events.py +0 -20
- nlbone/core/application/services.py +0 -0
- nlbone/core/domain/events.py +0 -0
- nlbone/core/ports/messaging.py +0 -0
- nlbone/core/ports/repo.py +0 -19
- /nlbone/adapters/{messaging/redis.py → ticketing/__init__.py} +0 -0
- {nlbone-0.6.19.dist-info → nlbone-0.7.0.dist-info}/WHEEL +0 -0
- {nlbone-0.6.19.dist-info → nlbone-0.7.0.dist-info}/entry_points.txt +0 -0
- {nlbone-0.6.19.dist-info → nlbone-0.7.0.dist-info}/licenses/LICENSE +0 -0
nlbone/interfaces/cli/init_db.py
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
1
5
|
import typer
|
|
2
6
|
|
|
3
7
|
from nlbone.adapters.db import Base, init_sync_engine, sync_ping
|
|
@@ -5,9 +9,42 @@ from nlbone.adapters.db import Base, init_sync_engine, sync_ping
|
|
|
5
9
|
init_db_command = typer.Typer(help="Database utilities")
|
|
6
10
|
|
|
7
11
|
|
|
12
|
+
def _import_target(target: str):
|
|
13
|
+
"""Import a module or call a bootstrap function if using 'module:function' syntax."""
|
|
14
|
+
if ":" in target:
|
|
15
|
+
mod_name, attr = target.split(":", 1)
|
|
16
|
+
mod = importlib.import_module(mod_name)
|
|
17
|
+
getattr(mod, attr)()
|
|
18
|
+
else:
|
|
19
|
+
importlib.import_module(target)
|
|
20
|
+
|
|
21
|
+
|
|
8
22
|
@init_db_command.command("init")
|
|
9
|
-
def init_db(
|
|
10
|
-
"""
|
|
23
|
+
def init_db(
|
|
24
|
+
drop: bool = typer.Option(False, "--drop", help="Drop all tables before creating them"),
|
|
25
|
+
models: list[str] = typer.Option(
|
|
26
|
+
None,
|
|
27
|
+
"--models",
|
|
28
|
+
"-m",
|
|
29
|
+
help=(
|
|
30
|
+
"List of modules or bootstrap functions to import before create_all. "
|
|
31
|
+
"For example: app.models or app.bootstrap:register_models"
|
|
32
|
+
),
|
|
33
|
+
),
|
|
34
|
+
add_cwd: bool = typer.Option(
|
|
35
|
+
True,
|
|
36
|
+
"--add-cwd/--no-add-cwd",
|
|
37
|
+
help=("Add the current working directory to sys.path so imports work relative to the host project root."),
|
|
38
|
+
),
|
|
39
|
+
):
|
|
40
|
+
"""Create (and optionally drop) the database schema."""
|
|
41
|
+
|
|
42
|
+
if add_cwd:
|
|
43
|
+
sys.path.insert(0, str(Path.cwd()))
|
|
44
|
+
|
|
45
|
+
for target in models or []:
|
|
46
|
+
_import_target(target)
|
|
47
|
+
|
|
11
48
|
engine = init_sync_engine()
|
|
12
49
|
if drop:
|
|
13
50
|
Base.metadata.drop_all(bind=engine)
|
nlbone/interfaces/cli/main.py
CHANGED
|
@@ -4,11 +4,15 @@ import typer
|
|
|
4
4
|
|
|
5
5
|
from nlbone.adapters.db import init_sync_engine
|
|
6
6
|
from nlbone.config.settings import get_settings
|
|
7
|
+
from nlbone.interfaces.cli.crypto import crypto_command
|
|
7
8
|
from nlbone.interfaces.cli.init_db import init_db_command
|
|
9
|
+
from nlbone.interfaces.cli.ticket import app as ticket_command
|
|
8
10
|
|
|
9
11
|
app = typer.Typer(help="NLBone CLI")
|
|
10
12
|
|
|
11
13
|
app.add_typer(init_db_command, name="db")
|
|
14
|
+
app.add_typer(crypto_command, name="crypto")
|
|
15
|
+
app.add_typer(ticket_command, name="ticket")
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
@app.callback()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import typer
|
|
3
|
+
|
|
4
|
+
from nlbone.adapters.ticketing.client import TicketingClient, CreateTicketIn
|
|
5
|
+
|
|
6
|
+
app = typer.Typer(add_completion=False)
|
|
7
|
+
|
|
8
|
+
@app.command("create")
|
|
9
|
+
def send_sample():
|
|
10
|
+
payload = CreateTicketIn(
|
|
11
|
+
assignee_id= "153",
|
|
12
|
+
category_id= 2,
|
|
13
|
+
channel= "site_chat",
|
|
14
|
+
direction= "incoming",
|
|
15
|
+
entity_id= "153",
|
|
16
|
+
entity_type= "user",
|
|
17
|
+
message= "سلام خوبی",
|
|
18
|
+
priority= "medium",
|
|
19
|
+
product_id= 0,
|
|
20
|
+
status= "open",
|
|
21
|
+
title= "پشتیبانی فنی (ثبت نام و لاگین)",
|
|
22
|
+
user_id= 153,
|
|
23
|
+
)
|
|
24
|
+
client = TicketingClient()
|
|
25
|
+
asyncio.run(client.create_ticket(payload, created_by_id=995836))
|
|
26
|
+
print("Ticket message published (or logged if Noop).")
|
|
27
|
+
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
app()
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from nlbone.adapters.messaging.internal_router import internal_router
|
|
2
2
|
from nlbone.core.ports.event_bus import IntegrationPublisher
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
def run_dispatch_outbox(outbox_repo, publisher: IntegrationPublisher):
|
|
5
6
|
batch = outbox_repo.fetch_pending(limit=200)
|
|
6
7
|
for rec in batch:
|
|
@@ -12,8 +13,8 @@ def run_dispatch_outbox(outbox_repo, publisher: IntegrationPublisher):
|
|
|
12
13
|
else:
|
|
13
14
|
publisher.publish(topic, payload)
|
|
14
15
|
outbox_repo.mark_sent(rec["id"])
|
|
15
|
-
except TemporaryError:
|
|
16
|
-
|
|
16
|
+
# except TemporaryError:
|
|
17
|
+
# outbox_repo.schedule_retry(rec["id"], rec["retries"])
|
|
17
18
|
except Exception:
|
|
18
19
|
# mark_failed یا retry policy
|
|
19
20
|
outbox_repo.schedule_retry(rec["id"], rec["retries"])
|
nlbone/utils/crypto.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import hashlib
|
|
3
|
+
from functools import lru_cache
|
|
4
|
+
|
|
5
|
+
from cryptography.fernet import Fernet
|
|
6
|
+
|
|
7
|
+
from nlbone.config.settings import get_settings
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _get_fernet_key() -> bytes:
|
|
11
|
+
settings = get_settings()
|
|
12
|
+
fernet_key = settings.FERNET_KEY
|
|
13
|
+
|
|
14
|
+
if not fernet_key or not fernet_key.strip():
|
|
15
|
+
raise Exception("❌ FERNET_KEY is required in .env")
|
|
16
|
+
|
|
17
|
+
digest = hashlib.sha256(fernet_key.encode()).digest()
|
|
18
|
+
|
|
19
|
+
return base64.urlsafe_b64encode(digest)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@lru_cache(maxsize=1)
|
|
23
|
+
def get_fernet():
|
|
24
|
+
return Fernet(_get_fernet_key())
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def encrypt_text(plaintext: str) -> str:
|
|
28
|
+
return get_fernet().encrypt(plaintext.encode()).decode()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def decrypt_text(token: str) -> str:
|
|
32
|
+
return get_fernet().decrypt(token.encode()).decode()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def normalize_mobile(mobile, strip_zero=True, add_country_code=True):
|
|
6
|
+
if not mobile:
|
|
7
|
+
return ""
|
|
8
|
+
|
|
9
|
+
mobile = re.sub(r"\D", "", str(mobile))
|
|
10
|
+
|
|
11
|
+
if mobile.startswith("0098"):
|
|
12
|
+
mobile = mobile[4:]
|
|
13
|
+
elif mobile.startswith("98") and len(mobile) > 10:
|
|
14
|
+
mobile = mobile[2:]
|
|
15
|
+
|
|
16
|
+
if strip_zero and mobile.startswith("0"):
|
|
17
|
+
mobile = mobile[1:]
|
|
18
|
+
|
|
19
|
+
if add_country_code:
|
|
20
|
+
if not mobile.startswith("98"):
|
|
21
|
+
mobile = f"98{mobile}"
|
|
22
|
+
|
|
23
|
+
return mobile
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def remove_duplicates(items: List[str]) -> List[str]:
|
|
27
|
+
seen = set()
|
|
28
|
+
out = []
|
|
29
|
+
for x in items:
|
|
30
|
+
if x and x not in seen:
|
|
31
|
+
seen.add(x)
|
|
32
|
+
out.append(x)
|
|
33
|
+
return out
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nlbone
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Backbone package for interfaces and infrastructure in Python projects
|
|
5
5
|
Author-email: Amir Hosein Kahkbazzadeh <a.khakbazzadeh@gmail.com>
|
|
6
6
|
License: MIT
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
|
+
Requires-Dist: aio-pika>=9.5.7
|
|
9
10
|
Requires-Dist: anyio>=4.0
|
|
10
11
|
Requires-Dist: cachetools>=6.2.0
|
|
12
|
+
Requires-Dist: cryptography~=45.0.4
|
|
11
13
|
Requires-Dist: dependency-injector>=4.48.1
|
|
12
14
|
Requires-Dist: elasticsearch==8.14.0
|
|
13
15
|
Requires-Dist: fastapi>=0.116
|
|
@@ -22,7 +24,7 @@ Requires-Dist: redis~=6.4.0
|
|
|
22
24
|
Requires-Dist: sqlalchemy>=2.0
|
|
23
25
|
Requires-Dist: starlette>=0.47
|
|
24
26
|
Requires-Dist: typer>=0.17.4
|
|
25
|
-
Requires-Dist: uvicorn
|
|
27
|
+
Requires-Dist: uvicorn==0.35
|
|
26
28
|
Description-Content-Type: text/markdown
|
|
27
29
|
|
|
28
30
|
# nlbone
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
nlbone/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
nlbone/container.py,sha256=
|
|
2
|
+
nlbone/container.py,sha256=I3Ev5L-CvfOquR4cyueIiplRriZ-_q_QlH_Xne9lA0k,2698
|
|
3
3
|
nlbone/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
nlbone/adapters/__init__.py,sha256=NzUmk4XPyp3GJOw7VSE86xkQMZLtG3MrOoXLeoB551M,41
|
|
5
5
|
nlbone/adapters/auth/__init__.py,sha256=hkDHvsFhw_UiOHG9ZSMqjiAhK4wumEforitveSZswVw,42
|
|
@@ -11,14 +11,14 @@ nlbone/adapters/cache/memory.py,sha256=y8M4erHQXApiSMAqG6Qk4pxEb60hRdu1szPv6iqvO
|
|
|
11
11
|
nlbone/adapters/cache/pubsub_listener.py,sha256=3vfK4O4EzuQQhTsbZ_bweP06o99kDSyHJ5PrfUotUaE,1460
|
|
12
12
|
nlbone/adapters/cache/redis.py,sha256=2Y1DYHBLCrbHTO6O7pw85u3qY6OnCIFTYJ-HBvBs0FM,4608
|
|
13
13
|
nlbone/adapters/db/__init__.py,sha256=0CDSySEk4jJsqmwI0eNuaaLJOJDt8_iSiHBsFdC-L3s,212
|
|
14
|
-
nlbone/adapters/db/postgres/__init__.py,sha256=
|
|
14
|
+
nlbone/adapters/db/postgres/__init__.py,sha256=tvCpHOdZbpQ57o7k-plq7L0e1uZe5_Frbh7I-LxW7zM,313
|
|
15
15
|
nlbone/adapters/db/postgres/audit.py,sha256=IuWkPitr70UyQ6-GkAedckp8U-Z4cTgzFbdt_bQv1VQ,4800
|
|
16
|
-
nlbone/adapters/db/postgres/base.py,sha256=
|
|
16
|
+
nlbone/adapters/db/postgres/base.py,sha256=I89PsEeR9ADEScG8D5pVSncPrPRBmf-KQQkjajl7Koo,132
|
|
17
17
|
nlbone/adapters/db/postgres/engine.py,sha256=UCegauVB1gvo42ThytYnn5VIcQBwR-5xhcXYFApRFNk,3448
|
|
18
|
-
nlbone/adapters/db/postgres/query_builder.py,sha256=
|
|
19
|
-
nlbone/adapters/db/postgres/repository.py,sha256=
|
|
18
|
+
nlbone/adapters/db/postgres/query_builder.py,sha256=Qv_2oZ5OxZwtN3Ts-jaAX_8sLBzb1mpGBhlNF7aR6Wk,12543
|
|
19
|
+
nlbone/adapters/db/postgres/repository.py,sha256=n01TAzdKd-UbOhirE6KMosuvRdJG2l1cszwVHjTM-Ks,10345
|
|
20
20
|
nlbone/adapters/db/postgres/schema.py,sha256=NlE7Rr8uXypsw4oWkdZhZwcIBHQEPIpoHLxcUo98i6s,1039
|
|
21
|
-
nlbone/adapters/db/postgres/uow.py,sha256=
|
|
21
|
+
nlbone/adapters/db/postgres/uow.py,sha256=2vRp4RBkh9RVniEY6CMXNHt-XXK9W2CDNKR1upT5EJE,3788
|
|
22
22
|
nlbone/adapters/db/redis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
23
|
nlbone/adapters/db/redis/client.py,sha256=5SUnwP2-GrueSFimUbiqDvrQsumvIE2aeozk8l-vOfQ,466
|
|
24
24
|
nlbone/adapters/http_clients/__init__.py,sha256=w-Yr9CLuXMU71N0Ada5HbvP1DB53wqeP6B-i5rALlTo,150
|
|
@@ -27,36 +27,39 @@ nlbone/adapters/http_clients/pricing/pricing_service.py,sha256=fYfMQh3qW_YDNkBW1
|
|
|
27
27
|
nlbone/adapters/http_clients/uploadchi/__init__.py,sha256=uBzEOuVtY22teWW2b36Pitkdk5yVdSqa6xbg22JfTNg,105
|
|
28
28
|
nlbone/adapters/http_clients/uploadchi/uploadchi.py,sha256=erpjOees25FW0nuK1PkYS-oU0h8MeRV9Rhs1cf3gaEs,4881
|
|
29
29
|
nlbone/adapters/http_clients/uploadchi/uploadchi_async.py,sha256=PQbVNeaYde5CmgT3vcnQoI1PGeSs9AxHlPFuB8biOmU,4717
|
|
30
|
-
nlbone/adapters/messaging/__init__.py,sha256=
|
|
31
|
-
nlbone/adapters/messaging/event_bus.py,sha256=
|
|
32
|
-
nlbone/adapters/messaging/
|
|
30
|
+
nlbone/adapters/messaging/__init__.py,sha256=o6ZiMihm_MhRXfcEpcjHBB3JGQovQbg3pxe0qS6516c,41
|
|
31
|
+
nlbone/adapters/messaging/event_bus.py,sha256=MSM70JPHoDK17efWlh20ATT1O0KW7xWnwZ5D-gI6U_w,3773
|
|
32
|
+
nlbone/adapters/messaging/rabbitmq.py,sha256=jO58NvsZnAEoS3nvsfdjQgqnzraD8f5Op3PqDAVt0RM,2007
|
|
33
|
+
nlbone/adapters/outbox/__init__.py,sha256=S_5t-rI0e3Gj_IegkuMnvwwqkU8BUqLBazJ-nWlFDAM,117
|
|
34
|
+
nlbone/adapters/outbox/outbox_consumer.py,sha256=Pjc8gAKapR-JznhgLXfsDrk5_W2e7QSCQbKlU2nDU4I,3114
|
|
35
|
+
nlbone/adapters/outbox/outbox_repo.py,sha256=X8YOhbpB8zgxlBw8Na1I9lEfhI4cEhsYZVb2oIiYlGo,6708
|
|
33
36
|
nlbone/adapters/percolation/__init__.py,sha256=0h1Bw7FzxgkDIHxeoyQXSfegrhP6VbpYV4QC8njYdRE,38
|
|
34
37
|
nlbone/adapters/percolation/connection.py,sha256=1iJISSwMEh4r_6nJI7mYf_v64Q0eeU1eSI0wLIfOK14,415
|
|
35
38
|
nlbone/adapters/repositories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
nlbone/adapters/
|
|
39
|
+
nlbone/adapters/ticketing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
|
+
nlbone/adapters/ticketing/client.py,sha256=V5_u7cxV67eAG4jj4vUD23VWGiMXIXSAU362pNS6hYU,1289
|
|
37
41
|
nlbone/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
42
|
nlbone/config/logging.py,sha256=Ot6Ctf7EQZlW8YNB-uBdleqI6wixn5fH0Eo6QRgNkQk,4358
|
|
39
|
-
nlbone/config/settings.py,sha256=
|
|
43
|
+
nlbone/config/settings.py,sha256=Zld9ie7X1v2xPZzNVbsHV-EXo6RICf9GIABHwTKuivQ,4332
|
|
40
44
|
nlbone/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
45
|
nlbone/core/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
46
|
nlbone/core/application/base_worker.py,sha256=5brIToSd-vi6tw0ukhHnUZGZhOLq1SQ-NRRy-kp6D24,1193
|
|
43
|
-
nlbone/core/application/
|
|
44
|
-
nlbone/core/application/
|
|
45
|
-
nlbone/core/application/
|
|
47
|
+
nlbone/core/application/bus.py,sha256=bi40pu_-6bBllRxqvBNpf7ByHXPsfrUacs-JxM0d18Q,6432
|
|
48
|
+
nlbone/core/application/di.py,sha256=gfxSawmT7jV6fnvOSgZrNt4yIPUg2FSQsT7euShg774,4117
|
|
49
|
+
nlbone/core/application/registry.py,sha256=dTqV_4bkMsLJ60CesZuEel5xO36cD1qikiaCLJXIGOw,4660
|
|
46
50
|
nlbone/core/application/use_case.py,sha256=3GMQZ3CFK5cbLoBNBgohPft6GBq2j9_wr8iKRq_osQA,247
|
|
47
51
|
nlbone/core/application/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
52
|
nlbone/core/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
|
-
nlbone/core/domain/base.py,sha256=
|
|
50
|
-
nlbone/core/domain/
|
|
51
|
-
nlbone/core/
|
|
52
|
-
nlbone/core/ports/__init__.py,sha256=gx-Ubj7h-1vvnu56sNnRqmer7HHfW3rX2WLl-0AX5U0,214
|
|
53
|
+
nlbone/core/domain/base.py,sha256=6C_wsn4CfFlW7n6ACsyA4r-ZciF4xUv18y0LzhCqMq4,1434
|
|
54
|
+
nlbone/core/domain/models.py,sha256=VEIfzruBXcF5XrDrWEvh9q-Ba9-9x_JG20wZsBF5thc,3270
|
|
55
|
+
nlbone/core/ports/__init__.py,sha256=syJg3fAjQALD5Rjfm9wi9bQpkIvNTWjE9AURBmy587o,132
|
|
53
56
|
nlbone/core/ports/auth.py,sha256=C-GmUqHNx4bAku6KbW_OTpPXCEfurBWWyDi9KxpTi9M,553
|
|
54
57
|
nlbone/core/ports/cache.py,sha256=8pP_z4ta7PNNG8UiSrEF4xMZRm2wLPxISZvdPt7QnxQ,2351
|
|
55
|
-
nlbone/core/ports/event_bus.py,sha256=
|
|
58
|
+
nlbone/core/ports/event_bus.py,sha256=7iC8WRBg-EmcKJx7AVPkP-r823SLKGuDxGp9WF4q-_U,824
|
|
56
59
|
nlbone/core/ports/files.py,sha256=7Ov2ITYRpPwwDTZGCeNVISg8e3A9l08jbOgpTImgfK8,1863
|
|
57
|
-
nlbone/core/ports/
|
|
58
|
-
nlbone/core/ports/
|
|
59
|
-
nlbone/core/ports/uow.py,sha256=
|
|
60
|
+
nlbone/core/ports/outbox.py,sha256=mjA3uHS_ycE1oD4Ht8uDUf8QbwoC8r7llb6gBoIbAZU,2274
|
|
61
|
+
nlbone/core/ports/repository.py,sha256=Ee8iSt4WxUIt113zLd7hq0HwtHc8r8qRSFBMTiGuJq4,2822
|
|
62
|
+
nlbone/core/ports/uow.py,sha256=VhqSc-Ryt9m-rlNMiXTzD3dPGz6mM_JxND8D0UJGRu4,962
|
|
60
63
|
nlbone/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
64
|
nlbone/interfaces/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
62
65
|
nlbone/interfaces/api/exception_handlers.py,sha256=vxNEBgAaQygLgAz1UNt3wHj0SdCJOwtLOv_BwTfir3o,4050
|
|
@@ -65,7 +68,7 @@ nlbone/interfaces/api/routers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
|
65
68
|
nlbone/interfaces/api/schemas.py,sha256=NIEKeTdJtwwIkIxL7WURNZF8g34I4TlRAqs-x1Uq7YI,108
|
|
66
69
|
nlbone/interfaces/api/additional_filed/__init__.py,sha256=BWemliLSQV9iq1vdUaF733q0FOSipSWBOQk9eYj732Q,318
|
|
67
70
|
nlbone/interfaces/api/additional_filed/assembler.py,sha256=80sFuNiquqdLPOcx7MoQ_ud9fAJtA327M77Z9V47pIU,1956
|
|
68
|
-
nlbone/interfaces/api/additional_filed/field_registry.py,sha256=
|
|
71
|
+
nlbone/interfaces/api/additional_filed/field_registry.py,sha256=IhIvzHWOMtKv8iTdFu7LzQboi4SFTLOyJqKdYPY8xFE,5418
|
|
69
72
|
nlbone/interfaces/api/additional_filed/resolver.py,sha256=jv1TIBBHN4LBIMwHGipcy4iq0uP0r6udyaqvhRzb8Bk,4655
|
|
70
73
|
nlbone/interfaces/api/additional_filed/default_field_rules/__init__.py,sha256=LUSAOO3xRUt5ptlraIx7H-7dSkdr1D-WprmnqXRB16g,48
|
|
71
74
|
nlbone/interfaces/api/additional_filed/default_field_rules/image_field_rules.py,sha256=ecKqPeXZ-YiF14RK9PmK7ln3PCzpCUc18S5zm5IF3fw,339
|
|
@@ -84,21 +87,25 @@ nlbone/interfaces/api/schema/__init__.py,sha256=LAqgynfupeqOQ6u0I5ucrcYnojRMZUg9
|
|
|
84
87
|
nlbone/interfaces/api/schema/adaptive_schema.py,sha256=bdWBNpP2NfOJ_in4btXn0lrZOK70x-OqfmZ-NpIJdoQ,3347
|
|
85
88
|
nlbone/interfaces/api/schema/base_response_model.py,sha256=lkBs7k0IcQiSQdJ3KvqDQPr_zwqKNbwaQjcwAE_chnU,599
|
|
86
89
|
nlbone/interfaces/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
87
|
-
nlbone/interfaces/cli/
|
|
88
|
-
nlbone/interfaces/cli/
|
|
90
|
+
nlbone/interfaces/cli/crypto.py,sha256=lh2uUbSYKT6XxAt9uP1-VksopqAgdxiSKoKgXwXB0aE,692
|
|
91
|
+
nlbone/interfaces/cli/init_db.py,sha256=Hk3aZ8w9KdfgQfDWaOnIgNEAegn2uNggkkSgDXQLgyc,1791
|
|
92
|
+
nlbone/interfaces/cli/main.py,sha256=wI6YQMTQ4wxH-5ncFgrKKk2uVoinqO70oaWziOkfsfw,895
|
|
93
|
+
nlbone/interfaces/cli/ticket.py,sha256=7-T-4VTh6X41C2EX_oNvAFCRpQOe9UOfXCmLy-07TqQ,798
|
|
89
94
|
nlbone/interfaces/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
90
|
-
nlbone/interfaces/jobs/dispatch_outbox.py,sha256=
|
|
95
|
+
nlbone/interfaces/jobs/dispatch_outbox.py,sha256=yLZSC3nvkgxT2LL4Pq_DYzCyf_tZB-FknrjjgN89GFg,809
|
|
91
96
|
nlbone/interfaces/jobs/sync_tokens.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
92
97
|
nlbone/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
93
98
|
nlbone/utils/cache.py,sha256=hVfkR62o5vllDrE_nY4At10wK0It6qpZ45K1xoj10cQ,5931
|
|
94
99
|
nlbone/utils/cache_keys.py,sha256=Y2YSellHTbUOcoaNbl1jaD4r485VU_e4KXsfBWhYTBo,1075
|
|
95
100
|
nlbone/utils/cache_registry.py,sha256=w28sEfUQZAhzCCqVH5TflWQY3nyDXyEcFWt8hkuHRHw,823
|
|
96
101
|
nlbone/utils/context.py,sha256=MmclJ24BG2uvSTg1IK7J-Da9BhVFDQ5ag4Ggs2FF1_w,1600
|
|
102
|
+
nlbone/utils/crypto.py,sha256=PX0Tlf2nqXcGbuv16J26MoUPzo2c4xcD4sZBXxhBXgQ,746
|
|
97
103
|
nlbone/utils/http.py,sha256=UXUoXgQdTRNT08ho8zl-C5ekfDsD8uf-JiMQ323ooqw,872
|
|
104
|
+
nlbone/utils/normalize_mobile.py,sha256=sGH4tV9gX-6eVKozviNWJhm1DN1J28Nj-ERldCYkS_E,732
|
|
98
105
|
nlbone/utils/redactor.py,sha256=-V4HrHmHwPi3Kez587Ek1uJlgK35qGSrwBOvcbw8Jas,1279
|
|
99
106
|
nlbone/utils/time.py,sha256=DjjyQ9GLsfXoT6NK8RDW2rOlJg3e6sF04Jw6PBUrSvg,1268
|
|
100
|
-
nlbone-0.
|
|
101
|
-
nlbone-0.
|
|
102
|
-
nlbone-0.
|
|
103
|
-
nlbone-0.
|
|
104
|
-
nlbone-0.
|
|
107
|
+
nlbone-0.7.0.dist-info/METADATA,sha256=GGuW7XamhW1Bg6v2NX5E09NS5L4W41k6MikQane4Fq8,2294
|
|
108
|
+
nlbone-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
109
|
+
nlbone-0.7.0.dist-info/entry_points.txt,sha256=CpIL45t5nbhl1dGQPhfIIDfqqak3teK0SxPGBBr7YCk,59
|
|
110
|
+
nlbone-0.7.0.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
111
|
+
nlbone-0.7.0.dist-info/RECORD,,
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
|
|
3
|
-
class OutboxRecord(dict):
|
|
4
|
-
pass
|
|
5
|
-
|
|
6
|
-
class OutboxRepository:
|
|
7
|
-
def __init__(self, engine):
|
|
8
|
-
self._engine = engine
|
|
9
|
-
|
|
10
|
-
def add(self, msg) -> None:
|
|
11
|
-
...
|
|
12
|
-
|
|
13
|
-
def fetch_pending(self, limit: int = 100) -> List[OutboxRecord]:
|
|
14
|
-
...
|
|
15
|
-
|
|
16
|
-
def mark_sent(self, msg_id: int) -> None:
|
|
17
|
-
...
|
|
18
|
-
|
|
19
|
-
def schedule_retry(self, msg_id: int, retries: int, backoff_base: int = 2) -> None:
|
|
20
|
-
...
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Protocol, Type, Any, Dict
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@dataclass(frozen=True)
|
|
6
|
-
class Command:
|
|
7
|
-
pass
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class CommandHandler(Protocol):
|
|
11
|
-
def __call__(self, command: Command) -> Any: ...
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class CommandBus:
|
|
15
|
-
def __init__(self) -> None:
|
|
16
|
-
self._handlers: Dict[Type[Command], CommandHandler] = {}
|
|
17
|
-
|
|
18
|
-
def register(self, cmd_type: Type[Command], handler: CommandHandler) -> None:
|
|
19
|
-
self._handlers[cmd_type] = handler
|
|
20
|
-
|
|
21
|
-
def dispatch(self, command: Command) -> Any:
|
|
22
|
-
handler = self._handlers.get(type(command))
|
|
23
|
-
if handler is None:
|
|
24
|
-
raise LookupError(f"No handler registered for {type(command).__name__}")
|
|
25
|
-
return handler(command)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from typing import Iterable, Sequence
|
|
2
|
-
|
|
3
|
-
from nlbone.core.domain.base import AggregateRoot, DomainEvent
|
|
4
|
-
from nlbone.core.ports.event_bus import EventBusPort
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def collect_events(*aggregates: Iterable[AggregateRoot]) -> list[DomainEvent]:
|
|
8
|
-
events: list[DomainEvent] = []
|
|
9
|
-
for agg in aggregates:
|
|
10
|
-
if isinstance(agg, AggregateRoot):
|
|
11
|
-
events.extend(agg.pull_events())
|
|
12
|
-
else:
|
|
13
|
-
for a in agg:
|
|
14
|
-
events.extend(a.pull_events())
|
|
15
|
-
return events
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def publish_events(bus: EventBusPort, events: Sequence[DomainEvent]) -> None:
|
|
19
|
-
if events:
|
|
20
|
-
bus.publish(events)
|
|
File without changes
|
nlbone/core/domain/events.py
DELETED
|
File without changes
|
nlbone/core/ports/messaging.py
DELETED
|
File without changes
|
nlbone/core/ports/repo.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Iterable, List, Optional, Protocol, TypeVar
|
|
4
|
-
|
|
5
|
-
T = TypeVar("T")
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Repository(Protocol[T]): # ← نه Protocol, Generic[T]
|
|
9
|
-
def get(self, id) -> Optional[T]: ...
|
|
10
|
-
def add(self, obj: T) -> None: ...
|
|
11
|
-
def remove(self, obj: T) -> None: ...
|
|
12
|
-
def list(self, *, limit: int | None = None, offset: int = 0) -> Iterable[T]: ...
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class AsyncRepository(Protocol[T]):
|
|
16
|
-
async def get(self, id) -> Optional[T]: ...
|
|
17
|
-
def add(self, obj: T) -> None: ...
|
|
18
|
-
async def remove(self, obj: T) -> None: ...
|
|
19
|
-
async def list(self, *, limit: int | None = None, offset: int = 0) -> List[T]: ...
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|