tina4-python 3.10.11__tar.gz → 3.10.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.
- {tina4_python-3.10.11 → tina4_python-3.10.13}/PKG-INFO +1 -1
- {tina4_python-3.10.11 → tina4_python-3.10.13}/pyproject.toml +1 -1
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/core/server.py +4 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/orm/model.py +9 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/websocket/backplane.py +96 -3
- {tina4_python-3.10.11 → tina4_python-3.10.13}/.gitignore +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/README.md +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/CLAUDE.md +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/HtmlElement.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/Testing.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/ai/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/api/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/auth/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/cache/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/cli/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/container/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/core/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/core/cache.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/core/constants.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/core/events.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/core/middleware.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/core/request.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/core/response.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/core/router.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/crud/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/database/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/database/adapter.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/database/connection.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/database/firebird.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/database/mssql.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/database/mysql.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/database/odbc.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/database/postgres.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/database/sqlite.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/debug/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/debug/error_overlay.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/dev_admin/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/dev_reload.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/dotenv/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/frond/FROND.md +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/frond/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/frond/engine.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/auth/meta.json +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/database/meta.json +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/error-overlay/meta.json +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/orm/meta.json +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/queue/meta.json +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/rest-api/meta.json +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/templates/meta.json +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/graphql/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/i18n/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/messenger/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/migration/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/migration/runner.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/orm/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/orm/fields.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/css/tina4.css +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/css/tina4.min.css +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/favicon.ico +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/images/logo.svg +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/js/frond.min.js +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/js/tina4.min.js +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/js/tina4js.min.js +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/swagger/index.html +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/query_builder/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/queue/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/queue_backends/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/queue_backends/kafka_backend.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/queue_backends/mongo_backend.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_alerts.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_badges.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_buttons.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_cards.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_forms.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_grid.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_modals.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_nav.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_reset.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_tables.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_typography.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_utilities.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/_variables.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/base.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/colors.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/scss/tina4css/tina4.scss +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/seeder/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/service/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/session/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/session_handlers/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/session_handlers/mongodb_handler.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/session_handlers/redis_handler.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/session_handlers/valkey_handler.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/swagger/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/components/crud.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/docker/python/Dockerfile +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/docker/uv/Dockerfile +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/errors/302.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/errors/401.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/errors/403.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/errors/404.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/errors/500.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/errors/502.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/errors/503.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/errors/base.twig +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/frontend/README.md +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/readme.md +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/test_client/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/validator/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/websocket/__init__.py +0 -0
- {tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/wsdl/__init__.py +0 -0
|
@@ -966,6 +966,10 @@ async def app(scope: dict, receive, send):
|
|
|
966
966
|
ttl = int(os.environ.get("TINA4_SESSION_TTL", "3600"))
|
|
967
967
|
samesite = os.environ.get("TINA4_SESSION_SAMESITE", "Lax")
|
|
968
968
|
response.header("set-cookie", f"tina4_session={sid}; Path=/; HttpOnly; SameSite={samesite}; Max-Age={ttl}")
|
|
969
|
+
# Probabilistic garbage collection (~1% of requests)
|
|
970
|
+
import random
|
|
971
|
+
if random.randint(1, 100) == 1:
|
|
972
|
+
request.session.gc()
|
|
969
973
|
except Exception:
|
|
970
974
|
pass
|
|
971
975
|
|
|
@@ -240,6 +240,9 @@ class ORM(metaclass=ORMMeta):
|
|
|
240
240
|
if result.last_id and pk in self._fields:
|
|
241
241
|
setattr(self, pk, result.last_id)
|
|
242
242
|
|
|
243
|
+
# ORM save is a discrete unit of work — always commit
|
|
244
|
+
db.commit()
|
|
245
|
+
|
|
243
246
|
# Invalidate cached queries and relationship cache
|
|
244
247
|
self.clear_cache()
|
|
245
248
|
self._rel_cache = {}
|
|
@@ -264,6 +267,9 @@ class ORM(metaclass=ORMMeta):
|
|
|
264
267
|
else:
|
|
265
268
|
db.delete(table, f"{pk_db_col} = ?", [pk_value])
|
|
266
269
|
|
|
270
|
+
# ORM delete is a discrete unit of work — always commit
|
|
271
|
+
db.commit()
|
|
272
|
+
|
|
267
273
|
def force_delete(self):
|
|
268
274
|
"""Hard delete, even if soft delete is enabled."""
|
|
269
275
|
db = self._get_db()
|
|
@@ -276,6 +282,7 @@ class ORM(metaclass=ORMMeta):
|
|
|
276
282
|
raise ValueError("Cannot delete: no primary key value")
|
|
277
283
|
|
|
278
284
|
db.delete(table, f"{pk_db_col} = ?", [pk_value])
|
|
285
|
+
db.commit()
|
|
279
286
|
|
|
280
287
|
def restore(self):
|
|
281
288
|
"""Restore a soft-deleted record."""
|
|
@@ -290,6 +297,7 @@ class ORM(metaclass=ORMMeta):
|
|
|
290
297
|
|
|
291
298
|
db.update(table, {"deleted_at": None}, f"{pk_db_col} = ?", [pk_value])
|
|
292
299
|
self.deleted_at = None
|
|
300
|
+
db.commit()
|
|
293
301
|
|
|
294
302
|
# ── Finders ─────────────────────────────────────────────────
|
|
295
303
|
|
|
@@ -497,6 +505,7 @@ class ORM(metaclass=ORMMeta):
|
|
|
497
505
|
sql = SQLTranslator.auto_increment_syntax(sql, engine)
|
|
498
506
|
|
|
499
507
|
db.execute(sql)
|
|
508
|
+
db.commit()
|
|
500
509
|
return True
|
|
501
510
|
|
|
502
511
|
# ── Cached Queries ────────────────────────────────────────
|
|
@@ -100,6 +100,101 @@ class RedisBackplane(WebSocketBackplane):
|
|
|
100
100
|
logger.info("RedisBackplane closed")
|
|
101
101
|
|
|
102
102
|
|
|
103
|
+
class NATSBackplane(WebSocketBackplane):
|
|
104
|
+
"""NATS pub/sub backplane.
|
|
105
|
+
|
|
106
|
+
Requires the ``nats-py`` package (``pip install nats-py``). The import is
|
|
107
|
+
deferred so the rest of Tina4 works fine without it installed.
|
|
108
|
+
|
|
109
|
+
NATS is async-native, so we run an asyncio event loop in a background
|
|
110
|
+
thread for the subscription listener.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
def __init__(self, url: str | None = None):
|
|
114
|
+
try:
|
|
115
|
+
import nats # noqa: F401
|
|
116
|
+
except ImportError:
|
|
117
|
+
raise ImportError(
|
|
118
|
+
"The 'nats-py' package is required for NATSBackplane. "
|
|
119
|
+
"Install it with: pip install nats-py"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
self._url = url or os.environ.get(
|
|
123
|
+
"TINA4_WS_BACKPLANE_URL", "nats://localhost:4222"
|
|
124
|
+
)
|
|
125
|
+
self._nc = None
|
|
126
|
+
self._subs: dict[str, object] = {}
|
|
127
|
+
self._loop = None
|
|
128
|
+
self._thread = None
|
|
129
|
+
self._running = True
|
|
130
|
+
self._connect()
|
|
131
|
+
logger.info("NATSBackplane connected to %s", self._url)
|
|
132
|
+
|
|
133
|
+
def _connect(self):
|
|
134
|
+
"""Connect to NATS in a background event loop."""
|
|
135
|
+
import asyncio
|
|
136
|
+
import nats
|
|
137
|
+
|
|
138
|
+
self._loop = asyncio.new_event_loop()
|
|
139
|
+
|
|
140
|
+
async def _do_connect():
|
|
141
|
+
self._nc = await nats.connect(self._url)
|
|
142
|
+
|
|
143
|
+
self._loop.run_until_complete(_do_connect())
|
|
144
|
+
|
|
145
|
+
# Run the event loop in a background thread for subscriptions
|
|
146
|
+
self._thread = threading.Thread(
|
|
147
|
+
target=self._loop.run_forever, daemon=True
|
|
148
|
+
)
|
|
149
|
+
self._thread.start()
|
|
150
|
+
|
|
151
|
+
def publish(self, channel: str, message: str) -> None:
|
|
152
|
+
import asyncio
|
|
153
|
+
|
|
154
|
+
async def _pub():
|
|
155
|
+
await self._nc.publish(channel, message.encode())
|
|
156
|
+
|
|
157
|
+
asyncio.run_coroutine_threadsafe(_pub(), self._loop).result(timeout=5)
|
|
158
|
+
|
|
159
|
+
def subscribe(self, channel: str, callback) -> None:
|
|
160
|
+
import asyncio
|
|
161
|
+
|
|
162
|
+
async def _sub():
|
|
163
|
+
async def handler(msg):
|
|
164
|
+
callback(msg.data.decode())
|
|
165
|
+
|
|
166
|
+
sub = await self._nc.subscribe(channel, cb=handler)
|
|
167
|
+
self._subs[channel] = sub
|
|
168
|
+
|
|
169
|
+
asyncio.run_coroutine_threadsafe(_sub(), self._loop).result(timeout=5)
|
|
170
|
+
logger.info("NATSBackplane subscribed to channel '%s'", channel)
|
|
171
|
+
|
|
172
|
+
def unsubscribe(self, channel: str) -> None:
|
|
173
|
+
import asyncio
|
|
174
|
+
|
|
175
|
+
sub = self._subs.pop(channel, None)
|
|
176
|
+
if sub:
|
|
177
|
+
asyncio.run_coroutine_threadsafe(
|
|
178
|
+
sub.unsubscribe(), self._loop
|
|
179
|
+
).result(timeout=5)
|
|
180
|
+
logger.info("NATSBackplane unsubscribed from channel '%s'", channel)
|
|
181
|
+
|
|
182
|
+
def close(self) -> None:
|
|
183
|
+
import asyncio
|
|
184
|
+
|
|
185
|
+
self._running = False
|
|
186
|
+
if self._nc:
|
|
187
|
+
asyncio.run_coroutine_threadsafe(
|
|
188
|
+
self._nc.close(), self._loop
|
|
189
|
+
).result(timeout=5)
|
|
190
|
+
if self._loop:
|
|
191
|
+
self._loop.call_soon_threadsafe(self._loop.stop)
|
|
192
|
+
if self._thread:
|
|
193
|
+
self._thread.join(timeout=2)
|
|
194
|
+
self._subs.clear()
|
|
195
|
+
logger.info("NATSBackplane closed")
|
|
196
|
+
|
|
197
|
+
|
|
103
198
|
def create_backplane(url: str | None = None) -> WebSocketBackplane | None:
|
|
104
199
|
"""Factory that reads TINA4_WS_BACKPLANE and returns the appropriate
|
|
105
200
|
backplane instance, or *None* if no backplane is configured.
|
|
@@ -112,9 +207,7 @@ def create_backplane(url: str | None = None) -> WebSocketBackplane | None:
|
|
|
112
207
|
if backend == "redis":
|
|
113
208
|
return RedisBackplane(url=url)
|
|
114
209
|
elif backend == "nats":
|
|
115
|
-
|
|
116
|
-
"NATS backplane is on the roadmap but not yet implemented."
|
|
117
|
-
)
|
|
210
|
+
return NATSBackplane(url=url)
|
|
118
211
|
elif backend == "":
|
|
119
212
|
return None
|
|
120
213
|
else:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/images/tina4-logo-icon.webp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/public/swagger/oauth2-redirect.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/queue_backends/rabbitmq_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/session_handlers/mongodb_handler.py
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/session_handlers/redis_handler.py
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/session_handlers/valkey_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/docker/distroless/Dockerfile
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/docker/poetry/Dockerfile
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/templates/docker/python/Dockerfile
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/af/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/af/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/en/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/en/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/es/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/es/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/fr/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/fr/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/ja/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/ja/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/zh/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.10.11 → tina4_python-3.10.13}/tina4_python/translations/zh/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|