tina4-python 3.10.40__tar.gz → 3.10.41__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 (143) hide show
  1. {tina4_python-3.10.40 → tina4_python-3.10.41}/PKG-INFO +53 -36
  2. {tina4_python-3.10.40 → tina4_python-3.10.41}/README.md +51 -34
  3. {tina4_python-3.10.40 → tina4_python-3.10.41}/pyproject.toml +2 -2
  4. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/CLAUDE.md +2 -2
  5. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/orm/model.py +7 -8
  6. {tina4_python-3.10.40 → tina4_python-3.10.41}/.gitignore +0 -0
  7. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/HtmlElement.py +0 -0
  8. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/Testing.py +0 -0
  9. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/__init__.py +0 -0
  10. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/ai/__init__.py +0 -0
  11. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/api/__init__.py +0 -0
  12. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/auth/__init__.py +0 -0
  13. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/cache/__init__.py +0 -0
  14. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/cli/__init__.py +0 -0
  15. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/container/__init__.py +0 -0
  16. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/core/__init__.py +0 -0
  17. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/core/cache.py +0 -0
  18. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/core/constants.py +0 -0
  19. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/core/events.py +0 -0
  20. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/core/middleware.py +0 -0
  21. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/core/request.py +0 -0
  22. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/core/response.py +0 -0
  23. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/core/router.py +0 -0
  24. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/core/server.py +0 -0
  25. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/crud/__init__.py +0 -0
  26. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/database/__init__.py +0 -0
  27. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/database/adapter.py +0 -0
  28. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/database/connection.py +0 -0
  29. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/database/firebird.py +0 -0
  30. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/database/mssql.py +0 -0
  31. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/database/mysql.py +0 -0
  32. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/database/odbc.py +0 -0
  33. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/database/postgres.py +0 -0
  34. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/database/sqlite.py +0 -0
  35. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/debug/__init__.py +0 -0
  36. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/debug/error_overlay.py +0 -0
  37. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/dev_admin/__init__.py +0 -0
  38. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/dev_admin/metrics.py +0 -0
  39. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/dev_reload.py +0 -0
  40. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/dotenv/__init__.py +0 -0
  41. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/frond/FROND.md +0 -0
  42. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/frond/__init__.py +0 -0
  43. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/frond/engine.py +0 -0
  44. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/auth/meta.json +0 -0
  45. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
  46. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/database/meta.json +0 -0
  47. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
  48. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/error-overlay/meta.json +0 -0
  49. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
  50. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/orm/meta.json +0 -0
  51. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
  52. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
  53. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/queue/meta.json +0 -0
  54. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
  55. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/rest-api/meta.json +0 -0
  56. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
  57. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/templates/meta.json +0 -0
  58. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
  59. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
  60. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/graphql/__init__.py +0 -0
  61. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/i18n/__init__.py +0 -0
  62. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/mcp/__init__.py +0 -0
  63. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/mcp/protocol.py +0 -0
  64. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/mcp/tools.py +0 -0
  65. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/messenger/__init__.py +0 -0
  66. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/migration/__init__.py +0 -0
  67. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/migration/runner.py +0 -0
  68. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/orm/__init__.py +0 -0
  69. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/orm/fields.py +0 -0
  70. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/css/tina4.css +0 -0
  71. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/css/tina4.min.css +0 -0
  72. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/favicon.ico +0 -0
  73. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/images/logo.svg +0 -0
  74. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
  75. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/js/frond.min.js +0 -0
  76. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
  77. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/js/tina4.min.js +0 -0
  78. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/js/tina4js.min.js +0 -0
  79. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/swagger/index.html +0 -0
  80. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
  81. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/query_builder/__init__.py +0 -0
  82. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/queue/__init__.py +0 -0
  83. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/queue_backends/__init__.py +0 -0
  84. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/queue_backends/kafka_backend.py +0 -0
  85. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/queue_backends/mongo_backend.py +0 -0
  86. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
  87. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/__init__.py +0 -0
  88. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_alerts.scss +0 -0
  89. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_badges.scss +0 -0
  90. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_buttons.scss +0 -0
  91. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_cards.scss +0 -0
  92. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_forms.scss +0 -0
  93. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_grid.scss +0 -0
  94. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_modals.scss +0 -0
  95. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_nav.scss +0 -0
  96. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_reset.scss +0 -0
  97. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_tables.scss +0 -0
  98. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_typography.scss +0 -0
  99. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_utilities.scss +0 -0
  100. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/_variables.scss +0 -0
  101. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/base.scss +0 -0
  102. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/colors.scss +0 -0
  103. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/scss/tina4css/tina4.scss +0 -0
  104. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/seeder/__init__.py +0 -0
  105. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/service/__init__.py +0 -0
  106. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/session/__init__.py +0 -0
  107. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/session_handlers/__init__.py +0 -0
  108. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/session_handlers/mongodb_handler.py +0 -0
  109. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/session_handlers/redis_handler.py +0 -0
  110. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/session_handlers/valkey_handler.py +0 -0
  111. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/swagger/__init__.py +0 -0
  112. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/components/crud.twig +0 -0
  113. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
  114. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
  115. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/docker/python/Dockerfile +0 -0
  116. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/docker/uv/Dockerfile +0 -0
  117. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/errors/302.twig +0 -0
  118. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/errors/401.twig +0 -0
  119. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/errors/403.twig +0 -0
  120. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/errors/404.twig +0 -0
  121. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/errors/500.twig +0 -0
  122. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/errors/502.twig +0 -0
  123. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/errors/503.twig +0 -0
  124. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/errors/base.twig +0 -0
  125. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/frontend/README.md +0 -0
  126. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/templates/readme.md +0 -0
  127. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/test_client/__init__.py +0 -0
  128. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
  129. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
  130. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  131. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
  132. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
  133. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
  134. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  135. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
  136. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
  137. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
  138. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
  139. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
  140. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/validator/__init__.py +0 -0
  141. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/websocket/__init__.py +0 -0
  142. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/websocket/backplane.py +0 -0
  143. {tina4_python-3.10.40 → tina4_python-3.10.41}/tina4_python/wsdl/__init__.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tina4-python
3
- Version: 3.10.40
4
- Summary: Tina4 Python v3 Zero-dependency, lightweight web framework
3
+ Version: 3.10.41
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
7
7
  Requires-Python: >=3.12
@@ -35,16 +35,15 @@ Description-Content-Type: text/markdown
35
35
  </p>
36
36
 
37
37
  <h1 align="center">Tina4 Python</h1>
38
- <h3 align="center">This Is Now A 4Framework</h3>
39
38
 
40
39
  <p align="center">
41
- Laravel joy. Python speed. 10x less code. Zero third-party dependencies.
40
+ 54 built-in features. Zero dependencies. One import, everything works.
42
41
  </p>
43
42
 
44
43
  <p align="center">
45
44
  <a href="https://pypi.org/project/tina4-python/"><img src="https://img.shields.io/pypi/v/tina4-python?color=7b1fa2&label=PyPI" alt="PyPI"></a>
46
- <img src="https://img.shields.io/badge/tests-1%2C791%20passing-brightgreen" alt="Tests">
47
- <img src="https://img.shields.io/badge/features-38-blue" alt="Features">
45
+ <img src="https://img.shields.io/badge/tests-2%2C066%20passing-brightgreen" alt="Tests">
46
+ <img src="https://img.shields.io/badge/features-54-blue" alt="Features">
48
47
  <img src="https://img.shields.io/badge/dependencies-0-brightgreen" alt="Zero Deps">
49
48
  <a href="https://tina4.com"><img src="https://img.shields.io/badge/docs-tina4.com-7b1fa2" alt="Docs"></a>
50
49
  </p>
@@ -54,6 +53,7 @@ Description-Content-Type: text/markdown
54
53
  <a href="#getting-started">Getting Started</a> &bull;
55
54
  <a href="#features">Features</a> &bull;
56
55
  <a href="#cli-reference">CLI Reference</a> &bull;
56
+ <a href="#cross-framework-parity">Parity</a> &bull;
57
57
  <a href="https://tina4.com">tina4.com</a>
58
58
  </p>
59
59
 
@@ -102,27 +102,24 @@ Open http://localhost:7145
102
102
 
103
103
  ---
104
104
 
105
- ## What's Included
105
+ ## What's Built In (54 Features)
106
106
 
107
107
  Every feature is built from scratch -- no pip install, no node_modules, no third-party runtime dependencies in core.
108
108
 
109
109
  | Category | Features |
110
110
  |----------|----------|
111
- | **HTTP** | ASGI server, decorator routing, path params (`{id:int}`, `{p:path}`), middleware pipeline, CORS, rate limiting, graceful shutdown |
112
- | **Templates** | Frond engine (Twig-compatible), inheritance, partials, 35+ filters, macros, fragment caching, sandboxing |
113
- | **ORM** | Active Record, typed fields with validation, soft delete, relationships (`has_one`/`has_many`/`belongs_to`), scopes, result caching, multi-database |
114
- | **Database** | SQLite, PostgreSQL, MySQL, MSSQL, Firebird -- unified adapter interface, query caching (TINA4_DB_CACHE=true for 4x speedup) |
115
- | **Auth** | Zero-dep JWT (HS256), sessions (file/Redis/Valkey/MongoDB/database), password hashing, form tokens |
116
- | **API** | Swagger/OpenAPI auto-generation, GraphQL with ORM auto-schema and GraphiQL IDE, WSDL/SOAP with auto WSDL |
117
- | **Background** | Queue (SQLite/RabbitMQ/Kafka/MongoDB) with priority, delayed jobs, retry, batch processing |
118
- | **Real-time** | Native asyncio WebSocket (RFC 6455), per-path routing, connection manager |
119
- | **Frontend** | tina4-css (~24 KB), frond.js helper, SCSS compiler, live reload, CSS hot-reload |
120
- | **DX** | Dev admin dashboard (11 tabs), error overlay, request inspector, AI tool integration, Carbonah green benchmarks |
121
- | **Data** | Migrations with rollback, 50+ fake data generators, ORM and table seeders |
122
- | **Mail** | SMTP send (plain/HTML/attachments), IMAP read/search, dev mailbox capture |
123
- | **Other** | REST client, localization (6 languages), cache (memory/Redis/file), event system, inline testing, messenger (.env driven), configurable error pages, HTML element builder |
124
-
125
- **1,633 tests across 38 built-in features. Zero dependencies. All Carbonah benchmarks rated A+.**
111
+ | **Core HTTP** (7) | Router with path params (`{id:int}`, `{p:path}`), Server, Request/Response, Middleware pipeline, Static file serving, CORS |
112
+ | **Database** (6) | SQLite, PostgreSQL, MySQL, MSSQL, Firebird — unified adapter, connection pooling, query cache, transactions, race-safe ID generation, SQL dialect translation |
113
+ | **ORM** (7) | Active Record with typed fields, relationships (`has_one`/`has_many`/`belongs_to`), soft delete, QueryBuilder + MongoDB support, Auto-CRUD generator, migrations with rollback |
114
+ | **Auth & Security** (5) | JWT (HS256/RS256), password hashing (PBKDF2-SHA256), API key validation, rate limiting, CSRF form tokens |
115
+ | **Templating** (3) | Frond engine (Twig/Jinja2-compatible, pre-compiled 2.8x faster), SCSS auto-compilation, built-in CSS (~24 KB) |
116
+ | **API & Integration** (5) | HTTP client (zero-dep), GraphQL with ORM auto-schema + GraphiQL IDE, WSDL/SOAP with auto WSDL, WebSocket (RFC 6455) + Redis backplane, MCP server (24 dev tools) |
117
+ | **Background** (3) | Job queue (File/RabbitMQ/Kafka/MongoDB) with priority, delay, retry, dead letters — service runner — event system (on/emit/once/off) |
118
+ | **Data & Storage** (4) | Session (File/Redis/Valkey/MongoDB/DB), response cache (LRU, TTL), seeder + 50+ fake data generators, messenger (SMTP/IMAP) |
119
+ | **Developer Tools** (7) | Dev dashboard (11 tabs), dev toolbar, error overlay (Catppuccin Mocha), dev mailbox, hot reload + CSS hot-reload, code metrics (complexity, coupling, maintainability), AI context installer (7 tools) |
120
+ | **Utilities** (7) | DI container (transient + singleton), HtmlElement builder, inline testing (`@tests` decorator), i18n (6 languages), Swagger/OpenAPI auto-generation, CLI scaffolding (`generate model/route/migration/middleware`), structured logging |
121
+
122
+ **2,066 tests. Zero dependencies. Full parity across Python, PHP, Ruby, and Node.js.**
126
123
 
127
124
  For full documentation visit **[tina4.com](https://tina4.com)**.
128
125
 
@@ -712,23 +709,43 @@ tina4python ai --all # Install for ALL supported tools
712
709
 
713
710
  Supported: Claude Code, Cursor, GitHub Copilot, Windsurf, Aider, Cline, OpenAI Codex CLI. Generates framework-aware context so AI assistants understand Tina4's conventions.
714
711
 
715
- ## Carbonah Green Benchmarks
712
+ ## Performance
716
713
 
717
- All 9 benchmarks rated **A+** (South Africa grid, 1000 iterations each):
714
+ Benchmarked with `wrk` 5,000 requests, 50 concurrent, median of 3 runs:
718
715
 
719
- | Benchmark | SCI (gCO2eq) | Grade |
720
- |-----------|-------------|-------|
721
- | JSON Hello World | 0.000864 | A+ |
722
- | Single DB Query | 0.000538 | A+ |
723
- | Multiple DB Queries | 0.001350 | A+ |
724
- | Template Rendering | 0.003237 | A+ |
725
- | Large JSON Payload | 0.000983 | A+ |
726
- | Plaintext Response | 0.000377 | A+ |
727
- | CRUD Cycle | 0.000456 | A+ |
728
- | Paginated Query | 0.000990 | A+ |
729
- | Framework Startup | 0.000801 | A+ |
716
+ | Framework | JSON req/s | Deps | Features |
717
+ |-----------|-----------|------|----------|
718
+ | **Tina4 Python** | **6,508** | 0 | 54 |
719
+ | FastAPI | 12,652 | 12+ | ~8 |
720
+ | Flask | 4,928 | 6+ | ~7 |
721
+ | Bottle | 4,355 | 0 | ~5 |
722
+ | Django | 4,050 | 20+ | ~22 |
730
723
 
731
- Run locally: `python benchmarks/run_carbonah.py`
724
+ Tina4 Python delivers competitive throughput with **zero dependencies and 54 features** — frameworks with higher req/s have a fraction of the functionality and require dozens of third-party packages.
725
+
726
+ **Across all 4 Tina4 implementations:**
727
+
728
+ | | Python | PHP | Ruby | Node.js |
729
+ |---|--------|-----|------|---------|
730
+ | **JSON req/s** | 6,508 | 29,293 | 10,243 | 84,771 |
731
+ | **Dependencies** | 0 | 0 | 0 | 0 |
732
+ | **Features** | 54 | 54 | 54 | 54 |
733
+
734
+ Run benchmarks locally: `python benchmarks/benchmark.py --python`
735
+
736
+ ---
737
+
738
+ ## Cross-Framework Parity
739
+
740
+ Tina4 ships identical features across four languages — same architecture, same conventions, same 54 features:
741
+
742
+ | | Python | PHP | Ruby | Node.js |
743
+ |---|--------|-----|------|---------|
744
+ | **Package** | `tina4-python` | `tina4stack/tina4php` | `tina4ruby` | `tina4-nodejs` |
745
+ | **Tests** | 2,066 | 1,427 | 1,793 | 1,950 |
746
+ | **Default port** | 7145 | 7146 | 7147 | 7148 |
747
+
748
+ **7,236 tests** across all 4 frameworks. See [tina4.com](https://tina4.com).
732
749
 
733
750
  ---
734
751
 
@@ -3,16 +3,15 @@
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Tina4 Python</h1>
6
- <h3 align="center">This Is Now A 4Framework</h3>
7
6
 
8
7
  <p align="center">
9
- Laravel joy. Python speed. 10x less code. Zero third-party dependencies.
8
+ 54 built-in features. Zero dependencies. One import, everything works.
10
9
  </p>
11
10
 
12
11
  <p align="center">
13
12
  <a href="https://pypi.org/project/tina4-python/"><img src="https://img.shields.io/pypi/v/tina4-python?color=7b1fa2&label=PyPI" alt="PyPI"></a>
14
- <img src="https://img.shields.io/badge/tests-1%2C791%20passing-brightgreen" alt="Tests">
15
- <img src="https://img.shields.io/badge/features-38-blue" alt="Features">
13
+ <img src="https://img.shields.io/badge/tests-2%2C066%20passing-brightgreen" alt="Tests">
14
+ <img src="https://img.shields.io/badge/features-54-blue" alt="Features">
16
15
  <img src="https://img.shields.io/badge/dependencies-0-brightgreen" alt="Zero Deps">
17
16
  <a href="https://tina4.com"><img src="https://img.shields.io/badge/docs-tina4.com-7b1fa2" alt="Docs"></a>
18
17
  </p>
@@ -22,6 +21,7 @@
22
21
  <a href="#getting-started">Getting Started</a> &bull;
23
22
  <a href="#features">Features</a> &bull;
24
23
  <a href="#cli-reference">CLI Reference</a> &bull;
24
+ <a href="#cross-framework-parity">Parity</a> &bull;
25
25
  <a href="https://tina4.com">tina4.com</a>
26
26
  </p>
27
27
 
@@ -70,27 +70,24 @@ Open http://localhost:7145
70
70
 
71
71
  ---
72
72
 
73
- ## What's Included
73
+ ## What's Built In (54 Features)
74
74
 
75
75
  Every feature is built from scratch -- no pip install, no node_modules, no third-party runtime dependencies in core.
76
76
 
77
77
  | Category | Features |
78
78
  |----------|----------|
79
- | **HTTP** | ASGI server, decorator routing, path params (`{id:int}`, `{p:path}`), middleware pipeline, CORS, rate limiting, graceful shutdown |
80
- | **Templates** | Frond engine (Twig-compatible), inheritance, partials, 35+ filters, macros, fragment caching, sandboxing |
81
- | **ORM** | Active Record, typed fields with validation, soft delete, relationships (`has_one`/`has_many`/`belongs_to`), scopes, result caching, multi-database |
82
- | **Database** | SQLite, PostgreSQL, MySQL, MSSQL, Firebird -- unified adapter interface, query caching (TINA4_DB_CACHE=true for 4x speedup) |
83
- | **Auth** | Zero-dep JWT (HS256), sessions (file/Redis/Valkey/MongoDB/database), password hashing, form tokens |
84
- | **API** | Swagger/OpenAPI auto-generation, GraphQL with ORM auto-schema and GraphiQL IDE, WSDL/SOAP with auto WSDL |
85
- | **Background** | Queue (SQLite/RabbitMQ/Kafka/MongoDB) with priority, delayed jobs, retry, batch processing |
86
- | **Real-time** | Native asyncio WebSocket (RFC 6455), per-path routing, connection manager |
87
- | **Frontend** | tina4-css (~24 KB), frond.js helper, SCSS compiler, live reload, CSS hot-reload |
88
- | **DX** | Dev admin dashboard (11 tabs), error overlay, request inspector, AI tool integration, Carbonah green benchmarks |
89
- | **Data** | Migrations with rollback, 50+ fake data generators, ORM and table seeders |
90
- | **Mail** | SMTP send (plain/HTML/attachments), IMAP read/search, dev mailbox capture |
91
- | **Other** | REST client, localization (6 languages), cache (memory/Redis/file), event system, inline testing, messenger (.env driven), configurable error pages, HTML element builder |
92
-
93
- **1,633 tests across 38 built-in features. Zero dependencies. All Carbonah benchmarks rated A+.**
79
+ | **Core HTTP** (7) | Router with path params (`{id:int}`, `{p:path}`), Server, Request/Response, Middleware pipeline, Static file serving, CORS |
80
+ | **Database** (6) | SQLite, PostgreSQL, MySQL, MSSQL, Firebird — unified adapter, connection pooling, query cache, transactions, race-safe ID generation, SQL dialect translation |
81
+ | **ORM** (7) | Active Record with typed fields, relationships (`has_one`/`has_many`/`belongs_to`), soft delete, QueryBuilder + MongoDB support, Auto-CRUD generator, migrations with rollback |
82
+ | **Auth & Security** (5) | JWT (HS256/RS256), password hashing (PBKDF2-SHA256), API key validation, rate limiting, CSRF form tokens |
83
+ | **Templating** (3) | Frond engine (Twig/Jinja2-compatible, pre-compiled 2.8x faster), SCSS auto-compilation, built-in CSS (~24 KB) |
84
+ | **API & Integration** (5) | HTTP client (zero-dep), GraphQL with ORM auto-schema + GraphiQL IDE, WSDL/SOAP with auto WSDL, WebSocket (RFC 6455) + Redis backplane, MCP server (24 dev tools) |
85
+ | **Background** (3) | Job queue (File/RabbitMQ/Kafka/MongoDB) with priority, delay, retry, dead letters — service runner — event system (on/emit/once/off) |
86
+ | **Data & Storage** (4) | Session (File/Redis/Valkey/MongoDB/DB), response cache (LRU, TTL), seeder + 50+ fake data generators, messenger (SMTP/IMAP) |
87
+ | **Developer Tools** (7) | Dev dashboard (11 tabs), dev toolbar, error overlay (Catppuccin Mocha), dev mailbox, hot reload + CSS hot-reload, code metrics (complexity, coupling, maintainability), AI context installer (7 tools) |
88
+ | **Utilities** (7) | DI container (transient + singleton), HtmlElement builder, inline testing (`@tests` decorator), i18n (6 languages), Swagger/OpenAPI auto-generation, CLI scaffolding (`generate model/route/migration/middleware`), structured logging |
89
+
90
+ **2,066 tests. Zero dependencies. Full parity across Python, PHP, Ruby, and Node.js.**
94
91
 
95
92
  For full documentation visit **[tina4.com](https://tina4.com)**.
96
93
 
@@ -680,23 +677,43 @@ tina4python ai --all # Install for ALL supported tools
680
677
 
681
678
  Supported: Claude Code, Cursor, GitHub Copilot, Windsurf, Aider, Cline, OpenAI Codex CLI. Generates framework-aware context so AI assistants understand Tina4's conventions.
682
679
 
683
- ## Carbonah Green Benchmarks
680
+ ## Performance
684
681
 
685
- All 9 benchmarks rated **A+** (South Africa grid, 1000 iterations each):
682
+ Benchmarked with `wrk` 5,000 requests, 50 concurrent, median of 3 runs:
686
683
 
687
- | Benchmark | SCI (gCO2eq) | Grade |
688
- |-----------|-------------|-------|
689
- | JSON Hello World | 0.000864 | A+ |
690
- | Single DB Query | 0.000538 | A+ |
691
- | Multiple DB Queries | 0.001350 | A+ |
692
- | Template Rendering | 0.003237 | A+ |
693
- | Large JSON Payload | 0.000983 | A+ |
694
- | Plaintext Response | 0.000377 | A+ |
695
- | CRUD Cycle | 0.000456 | A+ |
696
- | Paginated Query | 0.000990 | A+ |
697
- | Framework Startup | 0.000801 | A+ |
684
+ | Framework | JSON req/s | Deps | Features |
685
+ |-----------|-----------|------|----------|
686
+ | **Tina4 Python** | **6,508** | 0 | 54 |
687
+ | FastAPI | 12,652 | 12+ | ~8 |
688
+ | Flask | 4,928 | 6+ | ~7 |
689
+ | Bottle | 4,355 | 0 | ~5 |
690
+ | Django | 4,050 | 20+ | ~22 |
698
691
 
699
- Run locally: `python benchmarks/run_carbonah.py`
692
+ Tina4 Python delivers competitive throughput with **zero dependencies and 54 features** — frameworks with higher req/s have a fraction of the functionality and require dozens of third-party packages.
693
+
694
+ **Across all 4 Tina4 implementations:**
695
+
696
+ | | Python | PHP | Ruby | Node.js |
697
+ |---|--------|-----|------|---------|
698
+ | **JSON req/s** | 6,508 | 29,293 | 10,243 | 84,771 |
699
+ | **Dependencies** | 0 | 0 | 0 | 0 |
700
+ | **Features** | 54 | 54 | 54 | 54 |
701
+
702
+ Run benchmarks locally: `python benchmarks/benchmark.py --python`
703
+
704
+ ---
705
+
706
+ ## Cross-Framework Parity
707
+
708
+ Tina4 ships identical features across four languages — same architecture, same conventions, same 54 features:
709
+
710
+ | | Python | PHP | Ruby | Node.js |
711
+ |---|--------|-----|------|---------|
712
+ | **Package** | `tina4-python` | `tina4stack/tina4php` | `tina4ruby` | `tina4-nodejs` |
713
+ | **Tests** | 2,066 | 1,427 | 1,793 | 1,950 |
714
+ | **Default port** | 7145 | 7146 | 7147 | 7148 |
715
+
716
+ **7,236 tests** across all 4 frameworks. See [tina4.com](https://tina4.com).
700
717
 
701
718
  ---
702
719
 
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "tina4-python"
3
- version = "3.10.40"
4
- description = "Tina4 Python v3 Zero-dependency, lightweight web framework"
3
+ version = "3.10.41"
4
+ description = "Tina4 for Python — 54 built-in features, zero dependencies"
5
5
  authors = [
6
6
  {name = "Andre van Zuydam", email = "andrevanzuydam@gmail.com"}
7
7
  ]
@@ -1762,8 +1762,8 @@ async def dashboard(request, response):
1762
1762
 
1763
1763
  ## v3 Features Summary
1764
1764
 
1765
- - **38 built-in features**, zero third-party dependencies
1766
- - **1,633 tests** passing across all modules
1765
+ - **54 built-in features**, zero third-party dependencies
1766
+ - **2,066 tests** passing across all modules
1767
1767
  - **Production server auto-detect**: `tina4python serve --production` auto-installs uvicorn
1768
1768
  - **`tina4python generate`**: model, route, migration, middleware scaffolding
1769
1769
  - **Database**: 5 engines (SQLite, PostgreSQL, MySQL, MSSQL, Firebird), query caching (`TINA4_DB_CACHE=true`, `cache_stats()`, `cache_clear()`)
@@ -325,7 +325,6 @@ class ORM(metaclass=ORMMeta):
325
325
  pk_value: Primary key value.
326
326
  include: List of relationship names to eager-load.
327
327
  """
328
- db = cls._get_db()
329
328
  pk = cls._get_pk()
330
329
  table = cls._get_table()
331
330
  pk_col = cls.field_mapping.get(pk, cls._fields[pk].column)
@@ -334,13 +333,7 @@ class ORM(metaclass=ORMMeta):
334
333
  if cls.soft_delete:
335
334
  sql += " AND deleted_at IS NULL"
336
335
 
337
- row = db.fetch_one(sql, [pk_value])
338
- if row is None:
339
- return None
340
- instance = cls(row)
341
- if include:
342
- cls._eager_load([instance], include)
343
- return instance
336
+ return cls.select_one(sql, [pk_value], include=include)
344
337
 
345
338
  @classmethod
346
339
  def find(cls, pk_value, include: list[str] = None):
@@ -395,6 +388,12 @@ class ORM(metaclass=ORMMeta):
395
388
  cls._eager_load(instances, include)
396
389
  return instances, result.count
397
390
 
391
+ @classmethod
392
+ def select_one(cls, sql: str, params: list = None, include: list[str] = None):
393
+ """Return a single ORM instance for a raw SQL query, or None if no rows match."""
394
+ instances, _ = cls.select(sql, params, limit=1, offset=0, include=include)
395
+ return instances[0] if instances else None
396
+
398
397
  @classmethod
399
398
  def where(cls, filter_sql: str, params: list = None, limit: int = 20, offset: int = 0,
400
399
  include: list[str] = None):