tina4-python 3.10.75__tar.gz → 3.10.82__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 (147) hide show
  1. {tina4_python-3.10.75 → tina4_python-3.10.82}/PKG-INFO +1 -1
  2. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/__init__.py +1 -1
  3. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/orm/__init__.py +1 -1
  4. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/orm/fields.py +1 -1
  5. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/orm/model.py +60 -6
  6. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/queue/__init__.py +212 -264
  7. tina4_python-3.10.82/tina4_python/queue/job.py +51 -0
  8. tina4_python-3.10.82/tina4_python/queue/lite_backend.py +300 -0
  9. {tina4_python-3.10.75 → tina4_python-3.10.82}/.gitignore +0 -0
  10. {tina4_python-3.10.75 → tina4_python-3.10.82}/README.md +0 -0
  11. {tina4_python-3.10.75 → tina4_python-3.10.82}/pyproject.toml +0 -0
  12. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/CLAUDE.md +0 -0
  13. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/HtmlElement.py +0 -0
  14. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/Testing.py +0 -0
  15. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/ai/__init__.py +0 -0
  16. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/api/__init__.py +0 -0
  17. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/auth/__init__.py +0 -0
  18. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/cache/__init__.py +0 -0
  19. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/cli/__init__.py +0 -0
  20. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/container/__init__.py +0 -0
  21. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/core/__init__.py +0 -0
  22. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/core/cache.py +0 -0
  23. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/core/constants.py +0 -0
  24. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/core/events.py +0 -0
  25. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/core/middleware.py +0 -0
  26. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/core/request.py +0 -0
  27. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/core/response.py +0 -0
  28. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/core/router.py +0 -0
  29. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/core/server.py +0 -0
  30. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/crud/__init__.py +0 -0
  31. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/__init__.py +0 -0
  32. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/adapter.py +0 -0
  33. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/connection.py +0 -0
  34. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/firebird.py +0 -0
  35. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/mongodb.py +0 -0
  36. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/mssql.py +0 -0
  37. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/mysql.py +0 -0
  38. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/odbc.py +0 -0
  39. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/postgres.py +0 -0
  40. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/database/sqlite.py +0 -0
  41. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/debug/__init__.py +0 -0
  42. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/debug/error_overlay.py +0 -0
  43. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/dev_admin/__init__.py +0 -0
  44. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/dev_admin/metrics.py +0 -0
  45. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/dev_reload.py +0 -0
  46. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/dotenv/__init__.py +0 -0
  47. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/frond/FROND.md +0 -0
  48. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/frond/__init__.py +0 -0
  49. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/frond/engine.py +0 -0
  50. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/auth/meta.json +0 -0
  51. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
  52. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/database/meta.json +0 -0
  53. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
  54. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/error-overlay/meta.json +0 -0
  55. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
  56. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/orm/meta.json +0 -0
  57. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
  58. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
  59. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/queue/meta.json +0 -0
  60. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
  61. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/rest-api/meta.json +0 -0
  62. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
  63. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/templates/meta.json +0 -0
  64. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
  65. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
  66. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/graphql/__init__.py +0 -0
  67. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/i18n/__init__.py +0 -0
  68. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/mcp/__init__.py +0 -0
  69. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/mcp/protocol.py +0 -0
  70. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/mcp/tools.py +0 -0
  71. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/messenger/__init__.py +0 -0
  72. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/migration/__init__.py +0 -0
  73. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/migration/runner.py +0 -0
  74. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/css/tina4.css +0 -0
  75. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/css/tina4.min.css +0 -0
  76. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/favicon.ico +0 -0
  77. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/images/logo.svg +0 -0
  78. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
  79. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/js/frond.min.js +0 -0
  80. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/js/tina4-dev-admin.js +0 -0
  81. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
  82. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/js/tina4.min.js +0 -0
  83. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/js/tina4js.min.js +0 -0
  84. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/swagger/index.html +0 -0
  85. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
  86. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/query_builder/__init__.py +0 -0
  87. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/queue_backends/__init__.py +0 -0
  88. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/queue_backends/kafka_backend.py +0 -0
  89. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/queue_backends/mongo_backend.py +0 -0
  90. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
  91. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/__init__.py +0 -0
  92. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_alerts.scss +0 -0
  93. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_badges.scss +0 -0
  94. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_buttons.scss +0 -0
  95. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_cards.scss +0 -0
  96. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_forms.scss +0 -0
  97. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_grid.scss +0 -0
  98. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_modals.scss +0 -0
  99. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_nav.scss +0 -0
  100. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_reset.scss +0 -0
  101. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_tables.scss +0 -0
  102. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_typography.scss +0 -0
  103. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_utilities.scss +0 -0
  104. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/_variables.scss +0 -0
  105. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/base.scss +0 -0
  106. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/colors.scss +0 -0
  107. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/scss/tina4css/tina4.scss +0 -0
  108. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/seeder/__init__.py +0 -0
  109. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/service/__init__.py +0 -0
  110. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/session/__init__.py +0 -0
  111. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/session_handlers/__init__.py +0 -0
  112. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/session_handlers/mongodb_handler.py +0 -0
  113. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/session_handlers/redis_handler.py +0 -0
  114. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/session_handlers/valkey_handler.py +0 -0
  115. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/swagger/__init__.py +0 -0
  116. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/components/crud.twig +0 -0
  117. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
  118. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
  119. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/docker/python/Dockerfile +0 -0
  120. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/docker/uv/Dockerfile +0 -0
  121. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/errors/302.twig +0 -0
  122. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/errors/401.twig +0 -0
  123. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/errors/403.twig +0 -0
  124. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/errors/404.twig +0 -0
  125. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/errors/500.twig +0 -0
  126. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/errors/502.twig +0 -0
  127. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/errors/503.twig +0 -0
  128. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/errors/base.twig +0 -0
  129. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/frontend/README.md +0 -0
  130. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/templates/readme.md +0 -0
  131. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/test_client/__init__.py +0 -0
  132. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
  133. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
  134. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  135. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
  136. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
  137. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
  138. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  139. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
  140. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
  141. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
  142. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
  143. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
  144. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/validator/__init__.py +0 -0
  145. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/websocket/__init__.py +0 -0
  146. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/websocket/backplane.py +0 -0
  147. {tina4_python-3.10.75 → tina4_python-3.10.82}/tina4_python/wsdl/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tina4-python
3
- Version: 3.10.75
3
+ Version: 3.10.82
4
4
  Summary: Tina4 for Python — 54 built-in features, zero dependencies
5
5
  Author-email: Andre van Zuydam <andrevanzuydam@gmail.com>
6
6
  License: MIT
@@ -8,7 +8,7 @@ Tina4 Python v3.0 — Zero-dependency, lightweight web framework.
8
8
 
9
9
  One import, everything works.
10
10
  """
11
- __version__ = "3.10.75"
11
+ __version__ = "3.10.82"
12
12
 
13
13
  # ── Route decorators ──
14
14
  from tina4_python.core.router import ( # noqa: E402, F401
@@ -12,7 +12,7 @@ Active Record ORM with SQL-first paradigm.
12
12
 
13
13
  # SQL-first — you write the SQL, ORM maps results
14
14
  users = User.select("SELECT * FROM users WHERE active = ?", [1])
15
- user = User.find(1)
15
+ user = User.find_by_id(1)
16
16
  user.name = "Updated"
17
17
  user.save()
18
18
  """
@@ -262,7 +262,7 @@ class BelongsToDescriptor(RelationshipDescriptor):
262
262
  fk_value = getattr(obj, fk, None)
263
263
  if fk_value is None:
264
264
  return None
265
- return related_cls.find(fk_value)
265
+ return related_cls.find_by_id(fk_value)
266
266
 
267
267
 
268
268
  def has_many(model_name: str, foreign_key: str = None) -> HasManyDescriptor:
@@ -365,15 +365,69 @@ class ORM(metaclass=ORMMeta):
365
365
  return cls.select_one(sql, [pk_value], include=include)
366
366
 
367
367
  @classmethod
368
- def find(cls, pk_value, include: list[str] = None):
369
- """Alias for find_by_id()."""
370
- return cls.find_by_id(pk_value, include)
368
+ def find(cls, filter: dict = None, limit: int = 100, offset: int = 0, order_by: str = None, include: list[str] = None):
369
+ """Find records by filter dict.
371
370
 
372
- def load(self, sql: str, params: list = None, include: list[str] = None) -> bool:
373
- """Load a record into this instance via selectOne.
371
+ Usage:
372
+ User.find({"name": "Alice"}) → [User, ...]
373
+ User.find({"age": 18}, limit=10) → [User, ...]
374
+ User.find(order_by="name ASC") → [User, ...]
375
+ User.find() → all records
376
+
377
+ Args:
378
+ filter: Dict of {column: value} pairs (AND-ed together).
379
+ limit: Max records to return.
380
+ offset: Starting offset.
381
+ order_by: ORDER BY clause (e.g. "name ASC").
382
+ include: Relationship names to eager-load.
383
+ """
384
+ db = cls._get_db()
385
+ table = cls._get_table()
386
+ conditions = []
387
+ params = []
388
+
389
+ if filter:
390
+ for key, value in filter.items():
391
+ col = cls.field_mapping.get(key, key)
392
+ conditions.append(f"{col} = ?")
393
+ params.append(value)
394
+
395
+ if cls.soft_delete:
396
+ conditions.append("deleted_at IS NULL")
397
+
398
+ sql = f"SELECT * FROM {table}"
399
+ if conditions:
400
+ sql += " WHERE " + " AND ".join(conditions)
401
+ if order_by:
402
+ sql += f" ORDER BY {order_by}"
403
+
404
+ return cls.select(sql, params, limit=limit, offset=offset, include=include)
405
+
406
+ def load(self, filter: str = None, params: list = None, include: list[str] = None) -> bool:
407
+ """Load a record into this instance.
408
+
409
+ Usage:
410
+ orm.id = 1; orm.load() — uses PK already set
411
+ orm.load("id = ?", [1]) — filter with params
412
+ orm.load("id = 1") — filter string
374
413
 
375
414
  Returns True if a record was found and loaded, False otherwise.
376
415
  """
416
+ db = self._get_db()
417
+ table = self._get_table()
418
+
419
+ if filter is None:
420
+ # No args — use the primary key value already set
421
+ pk = self._get_pk()
422
+ pk_value = getattr(self, pk, None)
423
+ if pk_value is None:
424
+ return False
425
+ pk_col = self.field_mapping.get(pk, self._fields[pk].column)
426
+ sql = f"SELECT * FROM {table} WHERE {pk_col} = ?"
427
+ params = [pk_value]
428
+ else:
429
+ sql = f"SELECT * FROM {table} WHERE {filter}"
430
+
377
431
  cls = type(self)
378
432
  result = cls.select_one(sql, params, include=include)
379
433
  if result is None:
@@ -614,7 +668,7 @@ class ORM(metaclass=ORMMeta):
614
668
  fk_value = getattr(self, fk, None)
615
669
  if fk_value is None:
616
670
  return None
617
- return related_class.find(fk_value)
671
+ return related_class.find_by_id(fk_value)
618
672
 
619
673
  @classmethod
620
674
  def _eager_load(cls, instances: list, include: list[str]):