|
2 | 2 | from dataclasses import dataclass |
3 | 3 | from typing import Any, Callable, Generator, Type, TypeVar, cast |
4 | 4 |
|
5 | | -from flask import g |
| 5 | +from flask import g, request |
6 | 6 |
|
7 | 7 | import mesop.protos.ui_pb2 as pb |
| 8 | +from mesop.env.env import MESOP_WEBSOCKETS_ENABLED |
8 | 9 | from mesop.events import LoadEvent, MesopEvent |
9 | 10 | from mesop.exceptions import MesopDeveloperException, MesopUserException |
10 | 11 | from mesop.key import Key |
11 | 12 | from mesop.security.security_policy import SecurityPolicy |
12 | 13 | from mesop.utils.backoff import exponential_backoff |
| 14 | +from mesop.warn import warn |
13 | 15 |
|
14 | 16 | from .context import Context |
15 | 17 |
|
@@ -54,12 +56,25 @@ def __init__(self): |
54 | 56 | self._state_classes: list[type[Any]] = [] |
55 | 57 | self._loading_errors: list[pb.ServerError] = [] |
56 | 58 | self._has_served_traffic = False |
| 59 | + self._contexts = {} |
57 | 60 |
|
58 | 61 | def context(self) -> Context: |
| 62 | + if MESOP_WEBSOCKETS_ENABLED and hasattr(request, "sid"): |
| 63 | + # flask-socketio adds sid (session id) to the request object. |
| 64 | + sid = request.sid # type: ignore |
| 65 | + if sid not in self._contexts: |
| 66 | + self._contexts[sid] = self.create_context() |
| 67 | + return self._contexts[sid] |
59 | 68 | if "_mesop_context" not in g: |
60 | 69 | g._mesop_context = self.create_context() |
61 | 70 | return g._mesop_context |
62 | 71 |
|
| 72 | + def delete_context(self, sid: str) -> None: |
| 73 | + if sid in self._contexts: |
| 74 | + del self._contexts[sid] |
| 75 | + else: |
| 76 | + warn(f"Tried to delete context with sid={sid} that doesn't exist.") |
| 77 | + |
63 | 78 | def create_context(self) -> Context: |
64 | 79 | # If running in prod mode, *always* enable the has served traffic safety check. |
65 | 80 | # If running in debug mode, *disable* the has served traffic safety check. |
|
0 commit comments