nlbone 0.1.21__tar.gz → 0.1.24__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.
Files changed (60) hide show
  1. nlbone-0.1.24/.gitignore +58 -0
  2. {nlbone-0.1.21 → nlbone-0.1.24}/PKG-INFO +2 -1
  3. {nlbone-0.1.21 → nlbone-0.1.24}/pyproject.toml +3 -2
  4. nlbone-0.1.24/src/nlbone/adapters/db/__init__.py +2 -0
  5. nlbone-0.1.24/src/nlbone/adapters/db/sqlalchemy/engine.py +118 -0
  6. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/config/settings.py +3 -3
  7. nlbone-0.1.24/src/nlbone/interfaces/api/dependencies.py +16 -0
  8. nlbone-0.1.21/.gitignore +0 -0
  9. nlbone-0.1.21/src/nlbone/utils/__init__.py +0 -0
  10. {nlbone-0.1.21 → nlbone-0.1.24}/LICENSE +0 -0
  11. {nlbone-0.1.21 → nlbone-0.1.24}/README.md +0 -0
  12. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/__init__.py +0 -0
  13. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/__init__.py +0 -0
  14. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/auth/__init__.py +0 -0
  15. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/auth/keycloak.py +0 -0
  16. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/memory.py +0 -0
  17. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/postgres.py +0 -0
  18. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/query_builder.py +0 -0
  19. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/sqlalchemy/__init__.py +0 -0
  20. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/sqlalchemy/query/__init__.py +0 -0
  21. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/sqlalchemy/query/builder.py +0 -0
  22. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/sqlalchemy/query/coercion.py +0 -0
  23. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/sqlalchemy/query/filters.py +0 -0
  24. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/sqlalchemy/query/ordering.py +0 -0
  25. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/db/sqlalchemy/query/types.py +0 -0
  26. {nlbone-0.1.21/src/nlbone/adapters/db → nlbone-0.1.24/src/nlbone/adapters/http_clients}/__init__.py +0 -0
  27. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/http_clients/email_gateway.py +0 -0
  28. {nlbone-0.1.21/src/nlbone/adapters/http_clients → nlbone-0.1.24/src/nlbone/adapters/messaging}/__init__.py +0 -0
  29. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/adapters/messaging/redis.py +0 -0
  30. {nlbone-0.1.21/src/nlbone/adapters/messaging → nlbone-0.1.24/src/nlbone/config}/__init__.py +0 -0
  31. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/config/logging.py +0 -0
  32. {nlbone-0.1.21/src/nlbone/config → nlbone-0.1.24/src/nlbone/core}/__init__.py +0 -0
  33. {nlbone-0.1.21/src/nlbone/core → nlbone-0.1.24/src/nlbone/core/application}/__init__.py +0 -0
  34. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/core/application/services.py +0 -0
  35. {nlbone-0.1.21/src/nlbone/core/application → nlbone-0.1.24/src/nlbone/core/application/use_cases}/__init__.py +0 -0
  36. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/core/application/use_cases/register_user.py +0 -0
  37. {nlbone-0.1.21/src/nlbone/core/application/use_cases → nlbone-0.1.24/src/nlbone/core/domain}/__init__.py +0 -0
  38. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/core/domain/events.py +0 -0
  39. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/core/domain/models.py +0 -0
  40. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/core/ports/__init__.py +0 -0
  41. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/core/ports/auth.py +0 -0
  42. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/core/ports/messaging.py +0 -0
  43. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/core/ports/repo.py +0 -0
  44. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/core/{__init__.py} +0 -0
  45. {nlbone-0.1.21/src/nlbone/core/domain → nlbone-0.1.24/src/nlbone/di}/__init__.py +0 -0
  46. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/di/container.py +0 -0
  47. {nlbone-0.1.21/src/nlbone/di → nlbone-0.1.24/src/nlbone/interfaces}/__init__.py +0 -0
  48. {nlbone-0.1.21/src/nlbone/interfaces → nlbone-0.1.24/src/nlbone/interfaces/api}/__init__.py +0 -0
  49. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/interfaces/api/exceptions.py +0 -0
  50. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/interfaces/api/pagination/__init__.py +0 -0
  51. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/interfaces/api/pagination/offset_base.py +0 -0
  52. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/interfaces/api/routers.py +0 -0
  53. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/interfaces/api/schemas.py +0 -0
  54. {nlbone-0.1.21/src/nlbone/interfaces/api → nlbone-0.1.24/src/nlbone/interfaces/cli}/__init__.py +0 -0
  55. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/interfaces/cli/main.py +0 -0
  56. {nlbone-0.1.21/src/nlbone/interfaces/cli → nlbone-0.1.24/src/nlbone/interfaces/jobs}/__init__.py +0 -0
  57. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/interfaces/jobs/sync_tokens.py +0 -0
  58. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/types.py +0 -0
  59. {nlbone-0.1.21/src/nlbone/interfaces/jobs → nlbone-0.1.24/src/nlbone/utils}/__init__.py +0 -0
  60. {nlbone-0.1.21 → nlbone-0.1.24}/src/nlbone/utils/time.py +0 -0
@@ -0,0 +1,58 @@
1
+ # Python
2
+ local
3
+ __pycache__/
4
+ *.py[cod]
5
+ *.pyo
6
+ *.pyd
7
+ *.pdb
8
+ *.pyc
9
+
10
+ # Virtual environment
11
+ venv/
12
+ env/
13
+ ENV/
14
+ .venv/
15
+
16
+ # FastAPI
17
+ *.log
18
+ *.logs/
19
+
20
+ # PyCharm
21
+ .idea/
22
+ .idea
23
+ *.iml
24
+ *.ipr
25
+ *.iws
26
+
27
+ # Others
28
+ .DS_Store
29
+ *.sqlite3
30
+ *.db
31
+
32
+ # VSCode
33
+ .vscode/
34
+
35
+ # Test cache
36
+ htmlcov/
37
+ .coverage
38
+ .tox/
39
+ nosetests.xml
40
+ coverage.xml
41
+ *.cover
42
+ .pytest_cache/
43
+
44
+ # Build
45
+ build/
46
+ dist/
47
+ *.egg-info/
48
+ .eggs/
49
+
50
+ # dotenv
51
+ .env
52
+ .env.*
53
+
54
+ # mypy
55
+ .mypy_cache/
56
+ .dmypy.json
57
+
58
+ /dist
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nlbone
3
- Version: 0.1.21
3
+ Version: 0.1.24
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
@@ -21,6 +21,7 @@ Requires-Dist: pre-commit>=3.7; extra == 'dev'
21
21
  Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
22
22
  Requires-Dist: pytest>=8.0; extra == 'dev'
23
23
  Requires-Dist: ruff>=0.5; extra == 'dev'
24
+ Requires-Dist: tomli; extra == 'dev'
24
25
  Requires-Dist: twine; extra == 'dev'
25
26
  Description-Content-Type: text/markdown
26
27
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nlbone"
7
- version = "0.1.21"
7
+ version = "0.1.24"
8
8
  description = "Backbone package for interfaces and infrastructure in Python projects"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -30,7 +30,8 @@ dev = [
30
30
  "ruff>=0.5",
31
31
  "mypy>=1.10",
32
32
  "pre-commit>=3.7",
33
- "twine"
33
+ "twine",
34
+ "tomli"
34
35
  ]
35
36
 
36
37
  [tool.ruff]
@@ -0,0 +1,2 @@
1
+ from .sqlalchemy.engine import *
2
+ from .sqlalchemy.query import *
@@ -0,0 +1,118 @@
1
+ from contextlib import asynccontextmanager, contextmanager
2
+ from typing import Generator, Optional, Any, AsyncGenerator
3
+
4
+ from sqlalchemy import create_engine, text
5
+ from sqlalchemy.engine import Engine
6
+ from sqlalchemy.orm import Session, sessionmaker
7
+
8
+ from sqlalchemy.ext.asyncio import (
9
+ AsyncEngine,
10
+ AsyncSession,
11
+ async_sessionmaker,
12
+ create_async_engine,
13
+ )
14
+
15
+ from nlbone.config.settings import get_settings
16
+
17
+ _settings = get_settings()
18
+
19
+ ASYNC_DSN: str = _settings.POSTGRES_DB_DSN
20
+
21
+ if "+asyncpg" in ASYNC_DSN:
22
+ SYNC_DSN: str = ASYNC_DSN.replace("+asyncpg", "+psycopg")
23
+ else:
24
+ SYNC_DSN = ASYNC_DSN
25
+
26
+ _async_engine: Optional[AsyncEngine] = None
27
+ _async_session_factory: Optional[async_sessionmaker[AsyncSession]] = None
28
+
29
+ _sync_engine: Optional[Engine] = None
30
+ _sync_session_factory: Optional[sessionmaker[Session]] = None
31
+
32
+
33
+ def init_async_engine(echo: Optional[bool] = None) -> AsyncEngine:
34
+ global _async_engine, _async_session_factory
35
+ if _async_engine is not None:
36
+ return _async_engine
37
+
38
+ _async_engine = create_async_engine(
39
+ ASYNC_DSN,
40
+ echo=_settings.DEBUG if echo is None else echo,
41
+ pool_pre_ping=True,
42
+ pool_size=5,
43
+ max_overflow=10,
44
+ )
45
+ _async_session_factory = async_sessionmaker(
46
+ bind=_async_engine,
47
+ expire_on_commit=False,
48
+ autoflush=False,
49
+ )
50
+ return _async_engine
51
+
52
+
53
+ @asynccontextmanager
54
+ async def async_session() -> AsyncGenerator[AsyncSession, Any]:
55
+ if _async_session_factory is None:
56
+ init_async_engine()
57
+ assert _async_session_factory is not None
58
+ session = _async_session_factory()
59
+ try:
60
+ yield session
61
+ await session.commit()
62
+ except Exception:
63
+ await session.rollback()
64
+ raise
65
+ finally:
66
+ await session.close()
67
+
68
+
69
+ async def async_ping() -> None:
70
+ eng = init_async_engine()
71
+ async with eng.connect() as conn:
72
+ await conn.execute(text("SELECT 1"))
73
+
74
+
75
+ def init_sync_engine(echo: Optional[bool] = None) -> Engine:
76
+ global _sync_engine, _sync_session_factory
77
+ if _sync_engine is not None:
78
+ return _sync_engine
79
+
80
+ _sync_engine = create_engine(
81
+ SYNC_DSN,
82
+ echo=_settings.DEBUG if echo is None else echo,
83
+ pool_pre_ping=True,
84
+ pool_size=5,
85
+ max_overflow=10,
86
+ future=True,
87
+ )
88
+ _sync_session_factory = sessionmaker(
89
+ bind=_sync_engine,
90
+ autocommit=False,
91
+ autoflush=False,
92
+ expire_on_commit=False,
93
+ future=True,
94
+ )
95
+ return _sync_engine
96
+
97
+
98
+ @contextmanager
99
+ def sync_session() -> Generator[Session, None, None]:
100
+ if _sync_session_factory is None:
101
+ init_sync_engine()
102
+ assert _sync_session_factory is not None
103
+ s = _sync_session_factory()
104
+ try:
105
+ yield s
106
+ s.commit()
107
+ except Exception:
108
+ s.rollback()
109
+ raise
110
+ finally:
111
+ s.close()
112
+
113
+
114
+ def sync_ping() -> None:
115
+ """Health check برای اتصال sync."""
116
+ eng = init_sync_engine()
117
+ with eng.connect() as conn:
118
+ conn.execute(text("SELECT 1"))
@@ -12,7 +12,7 @@ class Settings(BaseSettings):
12
12
  ENV: Literal["local", "dev", "staging", "prod"] = Field(default="local")
13
13
  DEBUG: bool = Field(default=False)
14
14
  LOG_LEVEL: Literal["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"] = Field(default="INFO")
15
- LOG_JSON: bool = Field(default=True) # اگر False باشد، فرمت متنی ساده می‌شود.
15
+ LOG_JSON: bool = Field(default=True)
16
16
 
17
17
  # ---------------------------
18
18
  # HTTP / Timeouts
@@ -30,10 +30,10 @@ class Settings(BaseSettings):
30
30
  # ---------------------------
31
31
  # Database
32
32
  # ---------------------------
33
- DB_DSN: str = Field(default="postgresql+asyncpg://user:pass@localhost:5432/nlbone")
33
+ POSTGRES_DB_DSN: str = Field(default="postgresql+asyncpg://user:pass@localhost:5432/nlbone")
34
34
 
35
35
  # ---------------------------
36
- # Messaging / Cache (نمونه)
36
+ # Messaging / Cache
37
37
  # ---------------------------
38
38
  REDIS_URL: str = Field(default="redis://localhost:6379/0")
39
39
 
@@ -0,0 +1,16 @@
1
+ from __future__ import annotations
2
+ from typing import AsyncGenerator, Generator
3
+
4
+ from sqlalchemy.orm import Session
5
+ from sqlalchemy.ext.asyncio import AsyncSession
6
+
7
+ from nlbone.adapters.db.sqlalchemy.engine import async_session, sync_session
8
+
9
+
10
+ async def get_async_session() -> AsyncGenerator[AsyncSession, None]:
11
+ async with async_session() as s:
12
+ yield s
13
+
14
+ def get_session() -> Generator[Session, None, None]:
15
+ with sync_session() as s:
16
+ yield s
nlbone-0.1.21/.gitignore DELETED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes