tina4-python 3.11.16__tar.gz → 3.11.17__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 (152) hide show
  1. {tina4_python-3.11.16 → tina4_python-3.11.17}/PKG-INFO +1 -1
  2. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/__init__.py +1 -1
  3. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/server.py +32 -0
  4. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/debug/__init__.py +6 -3
  5. {tina4_python-3.11.16 → tina4_python-3.11.17}/.gitignore +0 -0
  6. {tina4_python-3.11.16 → tina4_python-3.11.17}/README.md +0 -0
  7. {tina4_python-3.11.16 → tina4_python-3.11.17}/pyproject.toml +0 -0
  8. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/CLAUDE.md +0 -0
  9. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/HtmlElement.py +0 -0
  10. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/Testing.py +0 -0
  11. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/ai/__init__.py +0 -0
  12. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/api/__init__.py +0 -0
  13. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/auth/__init__.py +0 -0
  14. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/cache/__init__.py +0 -0
  15. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/cli/__init__.py +0 -0
  16. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/container/__init__.py +0 -0
  17. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/__init__.py +0 -0
  18. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/cache.py +0 -0
  19. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/constants.py +0 -0
  20. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/events.py +0 -0
  21. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/middleware.py +0 -0
  22. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/rate_limiter.py +0 -0
  23. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/request.py +0 -0
  24. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/response.py +0 -0
  25. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/core/router.py +0 -0
  26. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/crud/__init__.py +0 -0
  27. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/__init__.py +0 -0
  28. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/adapter.py +0 -0
  29. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/connection.py +0 -0
  30. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/firebird.py +0 -0
  31. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/mongodb.py +0 -0
  32. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/mssql.py +0 -0
  33. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/mysql.py +0 -0
  34. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/odbc.py +0 -0
  35. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/postgres.py +0 -0
  36. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/database/sqlite.py +0 -0
  37. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/debug/error_overlay.py +0 -0
  38. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/dev_admin/__init__.py +0 -0
  39. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/dev_admin/metrics.py +0 -0
  40. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/dev_admin/plan.py +0 -0
  41. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/dev_admin/project_index.py +0 -0
  42. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/dotenv/__init__.py +0 -0
  43. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/frond/FROND.md +0 -0
  44. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/frond/__init__.py +0 -0
  45. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/frond/engine.py +0 -0
  46. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/auth/meta.json +0 -0
  47. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
  48. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/database/meta.json +0 -0
  49. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
  50. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/error-overlay/meta.json +0 -0
  51. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
  52. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/orm/meta.json +0 -0
  53. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
  54. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
  55. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/queue/meta.json +0 -0
  56. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
  57. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/rest-api/meta.json +0 -0
  58. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
  59. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/templates/meta.json +0 -0
  60. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
  61. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
  62. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/graphql/__init__.py +0 -0
  63. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/i18n/__init__.py +0 -0
  64. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/mcp/__init__.py +0 -0
  65. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/mcp/protocol.py +0 -0
  66. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/mcp/tools.py +0 -0
  67. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/messenger/__init__.py +0 -0
  68. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/migration/__init__.py +0 -0
  69. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/migration/runner.py +0 -0
  70. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/orm/__init__.py +0 -0
  71. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/orm/fields.py +0 -0
  72. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/orm/model.py +0 -0
  73. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/css/tina4.css +0 -0
  74. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/css/tina4.min.css +0 -0
  75. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/favicon.ico +0 -0
  76. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/images/logo.svg +0 -0
  77. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
  78. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/js/frond.min.js +0 -0
  79. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/js/tina4-dev-admin.js +0 -0
  80. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
  81. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/js/tina4.min.js +0 -0
  82. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/js/tina4js.min.js +0 -0
  83. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/swagger/index.html +0 -0
  84. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
  85. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/query_builder/__init__.py +0 -0
  86. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue/__init__.py +0 -0
  87. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue/job.py +0 -0
  88. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue/kafka_backend.py +0 -0
  89. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue/lite_backend.py +0 -0
  90. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue/mongo_backend.py +0 -0
  91. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue/rabbitmq_backend.py +0 -0
  92. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue_backends/__init__.py +0 -0
  93. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue_backends/kafka_backend.py +0 -0
  94. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue_backends/mongo_backend.py +0 -0
  95. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
  96. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/__init__.py +0 -0
  97. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_alerts.scss +0 -0
  98. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_badges.scss +0 -0
  99. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_buttons.scss +0 -0
  100. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_cards.scss +0 -0
  101. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_forms.scss +0 -0
  102. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_grid.scss +0 -0
  103. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_modals.scss +0 -0
  104. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_nav.scss +0 -0
  105. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_reset.scss +0 -0
  106. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_tables.scss +0 -0
  107. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_typography.scss +0 -0
  108. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_utilities.scss +0 -0
  109. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/_variables.scss +0 -0
  110. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/base.scss +0 -0
  111. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/colors.scss +0 -0
  112. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/scss/tina4css/tina4.scss +0 -0
  113. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/seeder/__init__.py +0 -0
  114. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/service/__init__.py +0 -0
  115. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/session/__init__.py +0 -0
  116. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/session_handlers/__init__.py +0 -0
  117. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/session_handlers/mongodb_handler.py +0 -0
  118. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/session_handlers/redis_handler.py +0 -0
  119. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/session_handlers/valkey_handler.py +0 -0
  120. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/swagger/__init__.py +0 -0
  121. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/components/crud.twig +0 -0
  122. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
  123. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
  124. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/docker/python/Dockerfile +0 -0
  125. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/docker/uv/Dockerfile +0 -0
  126. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/errors/302.twig +0 -0
  127. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/errors/401.twig +0 -0
  128. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/errors/403.twig +0 -0
  129. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/errors/404.twig +0 -0
  130. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/errors/500.twig +0 -0
  131. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/errors/502.twig +0 -0
  132. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/errors/503.twig +0 -0
  133. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/errors/base.twig +0 -0
  134. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/frontend/README.md +0 -0
  135. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/templates/readme.md +0 -0
  136. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/test_client/__init__.py +0 -0
  137. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
  138. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
  139. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  140. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
  141. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
  142. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
  143. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  144. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
  145. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
  146. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
  147. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
  148. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
  149. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/validator/__init__.py +0 -0
  150. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/websocket/__init__.py +0 -0
  151. {tina4_python-3.11.16 → tina4_python-3.11.17}/tina4_python/websocket/backplane.py +0 -0
  152. {tina4_python-3.11.16 → tina4_python-3.11.17}/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.11.16
3
+ Version: 3.11.17
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.11.16"
11
+ __version__ = "3.11.17"
12
12
 
13
13
  # ── Route decorators ──
14
14
  from tina4_python.core.router import ( # noqa: E402, F401
@@ -1615,6 +1615,38 @@ def run(host: str | None = None, port: int | None = None, no_browser: bool = Fal
1615
1615
  log_level = os.environ.get("TINA4_LOG_LEVEL", "error" if not is_production else "error")
1616
1616
  Log.configure(level=log_level, production=is_production)
1617
1617
 
1618
+ # Install a top-level exception hook so uncaught exceptions bubbling
1619
+ # out of anything (a route handler, a background task, the event
1620
+ # loop itself on startup) land in logs/error.log. Without this,
1621
+ # an uncaught exception surfaces only via Python's default stderr
1622
+ # writer and never touches Log — the same gap PHP had before its
1623
+ # set_exception_handler fix. Chains to the previous hook so any
1624
+ # debugger / IDE hook already in place still fires.
1625
+ import sys as _sys
1626
+ import traceback as _traceback
1627
+ _prior_excepthook = _sys.excepthook
1628
+
1629
+ def _tina4_excepthook(exc_type, exc_value, exc_tb):
1630
+ # KeyboardInterrupt is a user-initiated Ctrl+C, not an error —
1631
+ # defer to the prior hook (which prints a clean traceback).
1632
+ if issubclass(exc_type, KeyboardInterrupt):
1633
+ _prior_excepthook(exc_type, exc_value, exc_tb)
1634
+ return
1635
+ try:
1636
+ trace_text = "".join(_traceback.format_exception(exc_type, exc_value, exc_tb))
1637
+ Log.error(
1638
+ f"Uncaught {exc_type.__name__}: {exc_value}",
1639
+ trace=trace_text,
1640
+ )
1641
+ except Exception:
1642
+ # If logging itself fails (disk full, permissions, logger
1643
+ # not initialised yet), fall through to the prior hook so
1644
+ # the user still sees something in stderr.
1645
+ pass
1646
+ _prior_excepthook(exc_type, exc_value, exc_tb)
1647
+
1648
+ _sys.excepthook = _tina4_excepthook
1649
+
1618
1650
  # Ensure folders
1619
1651
  _ensure_folders()
1620
1652
 
@@ -200,12 +200,15 @@ class Log:
200
200
  color = cls.COLORS.get(level, "")
201
201
  print(f"{color}{line}{cls.RESET}")
202
202
 
203
- # Always write ALL levels to file (raw log, no filtering)
203
+ # Always write ALL levels to the main file (raw log, no filtering)
204
204
  if cls._writer:
205
205
  cls._writer.write(line)
206
206
 
207
- # Write errors to separate file
208
- if level == "error" and cls._error_writer:
207
+ # Mirror WARNING and ERROR into the dedicated error log so
208
+ # `tail -f logs/error.log` gives just the stuff worth looking
209
+ # at, without wading through DEBUG / INFO noise. Parity with
210
+ # tina4-php's Log class.
211
+ if cls._error_writer and cls.LEVELS.get(level, 0) >= cls.LEVELS["warning"]:
209
212
  cls._error_writer.write(line)
210
213
 
211
214
  @classmethod
File without changes