Others
Backend API Routes
除了你的前端应用,Reflex 还使用 FastAPI 后端来为你的应用提供服务。
要向后端 API 添加额外的端点,您可以使用 app.add_api_route
并添加一个返回 JSON 的路由。
async def api_test(item_id: int):
return {"my_result": item_id}
app = rx.App()
app.api.add_api_route("/items/{item_id}", api_test)
Now you can access the endpoint at localhost:8000/items/23
and get the result.
这对于创建一个可用于除 Reflex 应用之外其他目的的后端 API 非常有用。
Reserved Routes
后端的一些路由是为 Reflex 运行时保留的,除非你清楚自己在做什么,否则不应覆盖它们。
localhost:8000/ping/
: You can use this route to check the health of the backend.- The expected return is
"pong"
- The expected return is
localhost:8000/_event
: the frontend will use this route to notify the backend that an event occurred.- Overriding this route will break the event communication
localhost:8000/_upload
: This route is used for the upload of file when usingrx.upload()
.
Client-storage
You can use the browser's local storage to persist state between sessions. This allows user preferences, authentication cookies, other bits of information to be stored on the client and accessed from different browser tabs.
A client-side storage var looks and acts like a normal str
var, except the default value is either rx.Cookie
or rx.LocalStorage
depending on where the value should be stored. The key name will be based on the var name, but this can be overridden by passing name="my_custom_name"
as a keyword argument.
class ClientStorageState(rx.State):
my_cookie: str = rx.Cookie("")
my_local_storage: str = rx.LocalStorage("")
custom_cookie: str = rx.Cookie(
name="CustomNamedCookie", max_age=3600
)
def client_storage_example():
return rx.vstack(
rx.hstack(
rx.text("my_cookie"),
rx.input(
value=ClientStorageState.my_cookie,
on_change=ClientStorageState.set_my_cookie,
),
),
rx.hstack(
rx.text("my_local_storage"),
rx.input(
value=ClientStorageState.my_local_storage,
on_change=ClientStorageState.set_my_local_storage,
),
),
rx.hstack(
rx.text("custom_cookie"),
rx.input(
value=ClientStorageState.custom_cookie,
on_change=ClientStorageState.set_custom_cookie,
),
),
)
详见:https://reflex.dev/docs/api-reference/browser-storage/
State Utility Methods
The state object has several methods and attributes that return information about the current page, session, or state.
Router Attributes
self.router
属性包含多个子属性,提供各种信息:
-
router.page
: 关于当前页面和路由的数据host
: 当前页面(前端)提供服务的主机名和端口。path
: 当前页面的路径(对于动态页面,此路径将包含 slug)raw_path
: 浏览器中显示的页面路径(包括参数和动态值)full_path
: 前缀为host
的path
full_raw_path
: 前缀为host
的raw_path
params
: 与请求相关的查询参数字典
-
router.session
: 当前会话的数据client_token
: 与当前标签页 token 关联的 UUID。Each tab has a unique token.session_id
: 与客户端 WebSocket 连接关联的 ID。Each tab has a unique session ID.client_ip
: 客户端的 IP 地址。许多用户可能共享同一个 IP 地址。
-
router.headers
:与 WebSocket 连接关联的常见 header 选择。这些值仅在重新建立 WebSocket 连接时(例如,在页面刷新期间)才会更改。所有其他标头可在字典self.router_data.headers
中找到。host
: 提供 WebSocket 服务的主机名和端口(后端)。
Lifespan Tasks 生命周期任务
Lifespan Tasks 是后端服务器运行时执行的 coroutines。它们对于设置应用的初始全局状态、运行周期性任务以及在服务器关闭时清理资源非常有用。
Tasks
任何异步协程都可以用作 Lifespan Tasks。它将在后端启动时开始运行,并持续运行直到返回或因服务器关闭而被取消。
长时间运行的任务应捕获 asyncio.CancelledError
以执行任何必要的清理操作。
async def long_running_task(foo, bar):
print(f"Starting {foo} {bar} task")
some_api = SomeApi(foo)
try:
while True:
updates = some_api.poll_for_updates()
other_api.push_changes(updates, bar)
await asyncio.sleep(
5
) # add some polling delay to avoid running too often
except asyncio.CancelledError:
some_api.close() # clean up the API if needed
print("Task was stopped")
Register the Task
要注册一个生命周期任务,请使用 app.register_lifespan_task(coro_func, **kwargs)
。注册期间指定的任何关键字参数都将传递给任务。
如果任务接受特殊参数 app
,它将是与应用程序关联的 FastAPI
对象的实例。
app = rx.App()
app.register_lifespan_task(
long_running_task, foo=42, bar=os.environ["BAR_PARAM"]
)
Context Managers
生命周期任务也可以定义为 async contextmanagers(异步上下文管理器)。这对于设置和拆除资源非常有用,并且其行为类似于 ASGI 生命周期协议(ASGI lifespan protocol)。
代码在第一个 yield
之前的部分将在后端启动时运行。当后端关闭时, yield
之后的代码将运行以进行清理。以下是一个从 FastAPI 文档中借用并修改以适应此接口的示例。
from contextlib import asynccontextmanager
def fake_answer_to_everything_ml_model(x: float):
return x * 42
ml_models = {}
@asynccontextmanager
async def setup_model(app: FastAPI):
# Load the ML model
ml_models[
"answer_to_everything"
] = fake_answer_to_everything_ml_model
yield
# Clean up the ML models and release the resources
ml_models.clear()
...
app = rx.App()
app.register_lifespan_task(setup_model)
Other Methods
reset
:将所有变量设置为给定状态(包括子状态)的默认值。get_value
:返回变量的值而不跟踪其变化。这在序列化时非常有用,因为跟踪包装器被视为不可序列化。dict
:返回所有状态变量(及子状态)作为字典。这在页面首次加载并需要“水合”后发送到客户端时内部使用。
Special Attributes
dirty_vars
:自上次状态发送至客户端以来,所有已修改变量名的集合。内部使用此集合来确定在处理事件后,哪些变量需要发送给客户端。