tina4-python 3.10.21__tar.gz → 3.10.23__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 (139) hide show
  1. {tina4_python-3.10.21 → tina4_python-3.10.23}/PKG-INFO +1 -1
  2. {tina4_python-3.10.21 → tina4_python-3.10.23}/pyproject.toml +1 -1
  3. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/__init__.py +1 -1
  4. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/frond/engine.py +30 -7
  5. {tina4_python-3.10.21 → tina4_python-3.10.23}/.gitignore +0 -0
  6. {tina4_python-3.10.21 → tina4_python-3.10.23}/README.md +0 -0
  7. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/CLAUDE.md +0 -0
  8. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/HtmlElement.py +0 -0
  9. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/Testing.py +0 -0
  10. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/ai/__init__.py +0 -0
  11. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/api/__init__.py +0 -0
  12. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/auth/__init__.py +0 -0
  13. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/cache/__init__.py +0 -0
  14. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/cli/__init__.py +0 -0
  15. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/container/__init__.py +0 -0
  16. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/core/__init__.py +0 -0
  17. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/core/cache.py +0 -0
  18. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/core/constants.py +0 -0
  19. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/core/events.py +0 -0
  20. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/core/middleware.py +0 -0
  21. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/core/request.py +0 -0
  22. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/core/response.py +0 -0
  23. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/core/router.py +0 -0
  24. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/core/server.py +0 -0
  25. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/crud/__init__.py +0 -0
  26. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/database/__init__.py +0 -0
  27. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/database/adapter.py +0 -0
  28. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/database/connection.py +0 -0
  29. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/database/firebird.py +0 -0
  30. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/database/mssql.py +0 -0
  31. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/database/mysql.py +0 -0
  32. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/database/odbc.py +0 -0
  33. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/database/postgres.py +0 -0
  34. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/database/sqlite.py +0 -0
  35. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/debug/__init__.py +0 -0
  36. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/debug/error_overlay.py +0 -0
  37. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/dev_admin/__init__.py +0 -0
  38. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/dev_reload.py +0 -0
  39. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/dotenv/__init__.py +0 -0
  40. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/frond/FROND.md +0 -0
  41. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/frond/__init__.py +0 -0
  42. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/auth/meta.json +0 -0
  43. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
  44. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/database/meta.json +0 -0
  45. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
  46. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/error-overlay/meta.json +0 -0
  47. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
  48. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/orm/meta.json +0 -0
  49. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
  50. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
  51. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/queue/meta.json +0 -0
  52. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
  53. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/rest-api/meta.json +0 -0
  54. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
  55. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/templates/meta.json +0 -0
  56. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
  57. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
  58. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/graphql/__init__.py +0 -0
  59. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/i18n/__init__.py +0 -0
  60. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/messenger/__init__.py +0 -0
  61. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/migration/__init__.py +0 -0
  62. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/migration/runner.py +0 -0
  63. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/orm/__init__.py +0 -0
  64. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/orm/fields.py +0 -0
  65. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/orm/model.py +0 -0
  66. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/css/tina4.css +0 -0
  67. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/css/tina4.min.css +0 -0
  68. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/favicon.ico +0 -0
  69. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/images/logo.svg +0 -0
  70. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
  71. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/js/frond.min.js +0 -0
  72. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
  73. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/js/tina4.min.js +0 -0
  74. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/js/tina4js.min.js +0 -0
  75. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/swagger/index.html +0 -0
  76. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
  77. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/query_builder/__init__.py +0 -0
  78. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/queue/__init__.py +0 -0
  79. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/queue_backends/__init__.py +0 -0
  80. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/queue_backends/kafka_backend.py +0 -0
  81. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/queue_backends/mongo_backend.py +0 -0
  82. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
  83. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/__init__.py +0 -0
  84. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_alerts.scss +0 -0
  85. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_badges.scss +0 -0
  86. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_buttons.scss +0 -0
  87. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_cards.scss +0 -0
  88. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_forms.scss +0 -0
  89. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_grid.scss +0 -0
  90. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_modals.scss +0 -0
  91. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_nav.scss +0 -0
  92. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_reset.scss +0 -0
  93. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_tables.scss +0 -0
  94. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_typography.scss +0 -0
  95. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_utilities.scss +0 -0
  96. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/_variables.scss +0 -0
  97. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/base.scss +0 -0
  98. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/colors.scss +0 -0
  99. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/scss/tina4css/tina4.scss +0 -0
  100. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/seeder/__init__.py +0 -0
  101. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/service/__init__.py +0 -0
  102. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/session/__init__.py +0 -0
  103. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/session_handlers/__init__.py +0 -0
  104. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/session_handlers/mongodb_handler.py +0 -0
  105. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/session_handlers/redis_handler.py +0 -0
  106. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/session_handlers/valkey_handler.py +0 -0
  107. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/swagger/__init__.py +0 -0
  108. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/components/crud.twig +0 -0
  109. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
  110. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
  111. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/docker/python/Dockerfile +0 -0
  112. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/docker/uv/Dockerfile +0 -0
  113. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/errors/302.twig +0 -0
  114. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/errors/401.twig +0 -0
  115. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/errors/403.twig +0 -0
  116. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/errors/404.twig +0 -0
  117. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/errors/500.twig +0 -0
  118. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/errors/502.twig +0 -0
  119. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/errors/503.twig +0 -0
  120. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/errors/base.twig +0 -0
  121. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/frontend/README.md +0 -0
  122. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/templates/readme.md +0 -0
  123. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/test_client/__init__.py +0 -0
  124. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
  125. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
  126. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  127. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
  128. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
  129. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
  130. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  131. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
  132. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
  133. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
  134. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
  135. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
  136. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/validator/__init__.py +0 -0
  137. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/websocket/__init__.py +0 -0
  138. {tina4_python-3.10.21 → tina4_python-3.10.23}/tina4_python/websocket/backplane.py +0 -0
  139. {tina4_python-3.10.21 → tina4_python-3.10.23}/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.21
3
+ Version: 3.10.23
4
4
  Summary: Tina4 Python v3 — Zero-dependency, lightweight web framework
5
5
  Author-email: Andre van Zuydam <andrevanzuydam@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tina4-python"
3
- version = "3.10.21"
3
+ version = "3.10.23"
4
4
  description = "Tina4 Python v3 — Zero-dependency, lightweight web framework"
5
5
  authors = [
6
6
  {name = "Andre van Zuydam", email = "andrevanzuydam@gmail.com"}
@@ -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.21"
11
+ __version__ = "3.10.23"
12
12
 
13
13
  # ── HTTP Constants ──
14
14
  from tina4_python.core.constants import ( # noqa: E402, F401
@@ -9,6 +9,7 @@ import re
9
9
  import html
10
10
  import hashlib
11
11
  import json
12
+ import secrets
12
13
  from functools import lru_cache
13
14
  from pathlib import Path
14
15
  from datetime import datetime
@@ -940,8 +941,8 @@ def _wordwrap(text: str, width: int) -> str:
940
941
  # ── Form Token ─────────────────────────────────────────────────
941
942
 
942
943
 
943
- def _form_token(descriptor: str = "", session_id: str = "") -> str:
944
- """Generate a JWT form token and return a hidden input element.
944
+ def _generate_form_jwt(descriptor: str = "", session_id: str = "") -> str:
945
+ """Generate a JWT form token string.
945
946
 
946
947
  Args:
947
948
  descriptor: Optional string to enrich the token payload.
@@ -949,13 +950,11 @@ def _form_token(descriptor: str = "", session_id: str = "") -> str:
949
950
  - ``"admin_panel"``: payload is ``{"type": "form", "context": "admin_panel"}``
950
951
  - ``"checkout|order_123"``: payload is ``{"type": "form", "context": "checkout", "ref": "order_123"}``
951
952
  session_id: Optional session ID to bind the token to a specific session.
952
- When provided, the CSRF middleware will verify the token belongs to
953
- the same session. If empty, checks ``_form_token_session_id`` global.
954
953
 
955
954
  Returns:
956
- ``<input type="hidden" name="formToken" value="TOKEN">``
955
+ The raw JWT string.
957
956
  """
958
- payload = {"type": "form"}
957
+ payload = {"type": "form", "nonce": secrets.token_hex(8)}
959
958
  if descriptor:
960
959
  descriptor = str(descriptor)
961
960
  if "|" in descriptor:
@@ -973,10 +972,32 @@ def _form_token(descriptor: str = "", session_id: str = "") -> str:
973
972
  secret = os.environ.get("SECRET", "tina4-default-secret")
974
973
  ttl = int(os.environ.get("TINA4_TOKEN_EXPIRES_IN", "60"))
975
974
  auth = _FrondAuth(secret=secret, expires_in=ttl)
976
- token = auth.get_token(payload)
975
+ return auth.get_token(payload)
976
+
977
+
978
+ def _form_token(descriptor: str = "", session_id: str = "") -> str:
979
+ """Generate a JWT form token and return a hidden input element.
980
+
981
+ Usage in templates: ``{{ form_token() }}`` or ``{{ "context" | form_token }}``
982
+
983
+ Returns:
984
+ ``<input type="hidden" name="formToken" value="TOKEN">``
985
+ """
986
+ token = _generate_form_jwt(descriptor, session_id)
977
987
  return SafeString(f'<input type="hidden" name="formToken" value="{token}">')
978
988
 
979
989
 
990
+ def _form_token_value(descriptor: str = "", session_id: str = "") -> str:
991
+ """Generate a JWT form token and return just the raw token string.
992
+
993
+ Usage in templates: ``{{ formTokenValue("Sleek") }}``
994
+
995
+ Returns:
996
+ The raw JWT string (no HTML wrapper).
997
+ """
998
+ return SafeString(_generate_form_jwt(descriptor, session_id))
999
+
1000
+
980
1001
  # Module-level session ID holder — set by the server before rendering templates
981
1002
  # so that form_token() can bind tokens to the current session.
982
1003
  _form_token_session_id: str = ""
@@ -1015,6 +1036,8 @@ class Frond:
1015
1036
 
1016
1037
  # Built-in global functions
1017
1038
  self._globals["form_token"] = _form_token
1039
+ self._globals["formTokenValue"] = _form_token_value
1040
+ self._globals["form_token_value"] = _form_token_value
1018
1041
 
1019
1042
  def sandbox(self, allowed_filters: list[str] = None,
1020
1043
  allowed_tags: list[str] = None,
File without changes