nlbone 0.6.11__tar.gz → 0.6.13__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 (91) hide show
  1. {nlbone-0.6.11 → nlbone-0.6.13}/PKG-INFO +1 -1
  2. {nlbone-0.6.11 → nlbone-0.6.13}/pyproject.toml +1 -1
  3. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/postgres/query_builder.py +55 -10
  4. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/container.py +8 -12
  5. {nlbone-0.6.11 → nlbone-0.6.13}/.gitignore +0 -0
  6. {nlbone-0.6.11 → nlbone-0.6.13}/LICENSE +0 -0
  7. {nlbone-0.6.11 → nlbone-0.6.13}/README.md +0 -0
  8. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/__init__.py +0 -0
  9. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/__init__.py +0 -0
  10. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/auth/__init__.py +0 -0
  11. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/auth/keycloak.py +0 -0
  12. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/auth/token_provider.py +0 -0
  13. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/cache/__init__.py +0 -0
  14. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/cache/async_redis.py +0 -0
  15. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/cache/memory.py +0 -0
  16. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/cache/pubsub_listener.py +0 -0
  17. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/cache/redis.py +0 -0
  18. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/__init__.py +0 -0
  19. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/postgres/__init__.py +0 -0
  20. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/postgres/audit.py +0 -0
  21. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/postgres/base.py +0 -0
  22. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/postgres/engine.py +0 -0
  23. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/postgres/repository.py +0 -0
  24. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/postgres/schema.py +0 -0
  25. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/postgres/uow.py +0 -0
  26. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/redis/__init__.py +0 -0
  27. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/db/redis/client.py +0 -0
  28. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/http_clients/__init__.py +0 -0
  29. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/http_clients/pricing/__init__.py +0 -0
  30. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/http_clients/pricing/pricing_service.py +0 -0
  31. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/http_clients/uploadchi/__init__.py +0 -0
  32. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/http_clients/uploadchi/uploadchi.py +0 -0
  33. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/http_clients/uploadchi/uploadchi_async.py +0 -0
  34. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/messaging/__init__.py +0 -0
  35. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/messaging/event_bus.py +0 -0
  36. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/messaging/redis.py +0 -0
  37. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/percolation/__init__.py +0 -0
  38. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/adapters/percolation/connection.py +0 -0
  39. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/config/__init__.py +0 -0
  40. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/config/logging.py +0 -0
  41. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/config/settings.py +0 -0
  42. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/__init__.py +0 -0
  43. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/application/__init__.py +0 -0
  44. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/application/base_worker.py +0 -0
  45. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/application/events.py +0 -0
  46. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/application/services/__init__.py +0 -0
  47. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/application/services.py +0 -0
  48. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/application/use_case.py +0 -0
  49. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/domain/__init__.py +0 -0
  50. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/domain/base.py +0 -0
  51. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/domain/events.py +0 -0
  52. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/domain/models.py +0 -0
  53. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/ports/__init__.py +0 -0
  54. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/ports/auth.py +0 -0
  55. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/ports/cache.py +0 -0
  56. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/ports/event_bus.py +0 -0
  57. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/ports/files.py +0 -0
  58. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/ports/messaging.py +0 -0
  59. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/ports/repo.py +0 -0
  60. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/core/ports/uow.py +0 -0
  61. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/__init__.py +0 -0
  62. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/__init__.py +0 -0
  63. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/dependencies/__init__.py +0 -0
  64. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/dependencies/async_auth.py +0 -0
  65. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/dependencies/auth.py +0 -0
  66. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/dependencies/db.py +0 -0
  67. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/dependencies/uow.py +0 -0
  68. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/exception_handlers.py +0 -0
  69. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/exceptions.py +0 -0
  70. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/middleware/__init__.py +0 -0
  71. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/middleware/access_log.py +0 -0
  72. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/middleware/add_request_context.py +0 -0
  73. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/middleware/authentication.py +0 -0
  74. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/pagination/__init__.py +0 -0
  75. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/pagination/offset_base.py +0 -0
  76. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/routers.py +0 -0
  77. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/api/schemas.py +0 -0
  78. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/cli/__init__.py +0 -0
  79. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/cli/init_db.py +0 -0
  80. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/cli/main.py +0 -0
  81. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/jobs/__init__.py +0 -0
  82. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/interfaces/jobs/sync_tokens.py +0 -0
  83. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/types.py +0 -0
  84. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/utils/__init__.py +0 -0
  85. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/utils/cache.py +0 -0
  86. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/utils/cache_keys.py +0 -0
  87. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/utils/cache_registry.py +0 -0
  88. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/utils/context.py +0 -0
  89. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/utils/http.py +0 -0
  90. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/utils/redactor.py +0 -0
  91. {nlbone-0.6.11 → nlbone-0.6.13}/src/nlbone/utils/time.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nlbone
3
- Version: 0.6.11
3
+ Version: 0.6.13
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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nlbone"
7
- version = "0.6.11"
7
+ version = "0.6.13"
8
8
  description = "Backbone package for interfaces and infrastructure in Python projects"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -28,6 +28,50 @@ class _InvalidEnum(Exception):
28
28
  pass
29
29
 
30
30
 
31
+ from sqlalchemy.orm import aliased
32
+ from sqlalchemy.inspection import inspect
33
+ from sqlalchemy.orm.attributes import InstrumentedAttribute
34
+ from sqlalchemy.orm.relationships import RelationshipProperty
35
+
36
+
37
+ def _resolve_column_and_joins(entity, query, field_path: str, join_cache: dict[str, Any]):
38
+ parts = [p for p in field_path.split(".") if p]
39
+ if not parts:
40
+ return None, query
41
+
42
+ current_cls_or_alias = entity
43
+ current_path_key_parts: list[str] = []
44
+
45
+ for i, part in enumerate(parts):
46
+ current_path_key_parts.append(part)
47
+ path_key = ".".join(current_path_key_parts)
48
+
49
+ if not hasattr(current_cls_or_alias, part):
50
+ return None, query
51
+
52
+ attr = getattr(current_cls_or_alias, part)
53
+
54
+ prop = getattr(attr, "property", None)
55
+ if isinstance(prop, RelationshipProperty):
56
+ alias = join_cache.get(path_key)
57
+ if alias is None:
58
+ alias = aliased(prop.mapper.class_)
59
+ query = query.outerjoin(alias, attr)
60
+ join_cache[path_key] = alias
61
+ current_cls_or_alias = alias
62
+ continue
63
+
64
+ if isinstance(attr, InstrumentedAttribute):
65
+ if i == len(parts) - 1:
66
+ return attr, query
67
+ else:
68
+ return None, query
69
+
70
+ return None, query
71
+
72
+ return None, query
73
+
74
+
31
75
  def _apply_order(pagination: PaginateRequest, entity, query):
32
76
  order_clauses = []
33
77
 
@@ -112,6 +156,7 @@ def _apply_filters(pagination, entity, query):
112
156
  return query
113
157
 
114
158
  predicates = []
159
+ join_cache: dict[str, Any] = {}
115
160
 
116
161
  if getattr(pagination, "filters", None):
117
162
  for raw_field, value in pagination.filters.items():
@@ -120,10 +165,10 @@ def _apply_filters(pagination, entity, query):
120
165
 
121
166
  field, op_hint = _parse_field_and_op(raw_field)
122
167
 
123
- if not hasattr(entity, field):
168
+ col, query2 = _resolve_column_and_joins(entity, query, field, join_cache)
169
+ if col is None:
124
170
  continue
125
-
126
- col = getattr(entity, field)
171
+ query = query2
127
172
  coltype = getattr(col, "type", None)
128
173
 
129
174
  def coerce(v):
@@ -259,13 +304,13 @@ def _serialize_item(item: Any, output_cls: OutputType) -> Any:
259
304
 
260
305
 
261
306
  def get_paginated_response(
262
- pagination,
263
- entity,
264
- session: Session,
265
- *,
266
- with_count: bool = True,
267
- output_cls: Optional[Type] = None,
268
- eager_options: Optional[Sequence[LoaderOption]] = None,
307
+ pagination,
308
+ entity,
309
+ session: Session,
310
+ *,
311
+ with_count: bool = True,
312
+ output_cls: Optional[Type] = None,
313
+ eager_options: Optional[Sequence[LoaderOption]] = None,
269
314
  ) -> dict:
270
315
  query = session.query(entity)
271
316
  if eager_options:
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Any, Mapping, Optional
3
+ from typing import Dict, Optional
4
4
 
5
5
  from dependency_injector import containers, providers
6
+ from pydantic_settings import BaseSettings
6
7
 
7
8
  from nlbone.adapters.auth.keycloak import KeycloakAuthService
8
9
  from nlbone.adapters.auth.token_provider import ClientTokenProvider
@@ -15,7 +16,6 @@ from nlbone.adapters.http_clients import PricingService
15
16
  from nlbone.adapters.http_clients.uploadchi import UploadchiClient
16
17
  from nlbone.adapters.http_clients.uploadchi.uploadchi_async import UploadchiAsyncClient
17
18
  from nlbone.adapters.messaging import InMemoryEventBus
18
- from nlbone.config.settings import Settings
19
19
  from nlbone.core.ports import EventBusPort
20
20
  from nlbone.core.ports.cache import AsyncCachePort, CachePort
21
21
  from nlbone.core.ports.files import AsyncFileServicePort, FileServicePort
@@ -35,7 +35,7 @@ class Container(containers.DeclarativeContainer):
35
35
  event_bus: providers.Singleton[EventBusPort] = providers.Singleton(InMemoryEventBus)
36
36
 
37
37
  # --- Services ---
38
- auth: providers.Singleton[KeycloakAuthService] = providers.Singleton(KeycloakAuthService, settings=config)
38
+ auth: providers.Singleton[KeycloakAuthService] = providers.Singleton(KeycloakAuthService)
39
39
  token_provider = providers.Singleton(ClientTokenProvider, auth=auth, skew_seconds=30)
40
40
  file_service: providers.Singleton[FileServicePort] = providers.Singleton(
41
41
  UploadchiClient, token_provider=token_provider
@@ -60,15 +60,11 @@ class Container(containers.DeclarativeContainer):
60
60
  )
61
61
 
62
62
 
63
- def create_container(settings: Optional[Any] = None) -> Container:
63
+ def create_container(settings: Optional[BaseSettings | Dict] = None) -> Container:
64
64
  c = Container()
65
65
  if settings is not None:
66
- if isinstance(settings, Settings):
67
- c.config.override(settings)
68
- elif hasattr(settings, "model_dump"):
69
- c.config.from_dict(settings.model_dump()) # Pydantic v2
70
- elif hasattr(settings, "dict"):
71
- c.config.from_dict(settings.dict()) # Pydantic v1
72
- elif isinstance(settings, Mapping):
73
- c.config.from_dict(dict(settings))
66
+ if isinstance(settings, BaseSettings):
67
+ c.config.from_pydantic(settings)
68
+ elif isinstance(settings, Dict):
69
+ c.config.from_dict(settings)
74
70
  return c
File without changes
File without changes
File without changes
File without changes
File without changes