|
@@ -0,0 +1,749 @@
|
|
|
+# SOME DESCRIPTIVE TITLE.
|
|
|
+# Copyright (C) WangWeimin
|
|
|
+# This file is distributed under the same license as the PyWebIO package.
|
|
|
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
|
|
|
+#
|
|
|
+msgid ""
|
|
|
+msgstr ""
|
|
|
+"Project-Id-Version: PyWebIO 1.3.3\n"
|
|
|
+"Report-Msgid-Bugs-To: \n"
|
|
|
+"POT-Creation-Date: 2021-10-05 16:10+0800\n"
|
|
|
+"PO-Revision-Date: 2021-10-05 16:15+0800\n"
|
|
|
+"Last-Translator: WangWeimin <wang0.618@qq.com>\n"
|
|
|
+"Language: zh_CN\n"
|
|
|
+"Language-Team: \n"
|
|
|
+"Plural-Forms: nplurals=1; plural=0;\n"
|
|
|
+"MIME-Version: 1.0\n"
|
|
|
+"Content-Type: text/plain; charset=utf-8\n"
|
|
|
+"Content-Transfer-Encoding: 8bit\n"
|
|
|
+"Generated-By: Babel 2.8.0\n"
|
|
|
+"X-Generator: Poedit 3.0\n"
|
|
|
+
|
|
|
+#: ../../advanced.rst:2
|
|
|
+msgid "Advanced topic"
|
|
|
+msgstr "高级特性"
|
|
|
+
|
|
|
+#: ../../advanced.rst:4
|
|
|
+msgid "This section will introduce the advanced features of PyWebIO."
|
|
|
+msgstr "本部分介绍PyWebIO的高级特性。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:10
|
|
|
+msgid "Start multiple applications with start_server()"
|
|
|
+msgstr "使用start_server()启动多应用"
|
|
|
+
|
|
|
+#: ../../advanced.rst:12
|
|
|
+msgid ""
|
|
|
+"`start_server() <pywebio.platform.tornado.start_server>` accepts a function as "
|
|
|
+"PyWebIO application. In addition, `start_server() <pywebio.platform.tornado."
|
|
|
+"start_server>` also accepts a list of application function or a dictionary of it "
|
|
|
+"to start multiple applications. You can use `pywebio.session.go_app() <pywebio."
|
|
|
+"session.go_app>` or `put_link() <pywebio.output.put_link>` to jump between "
|
|
|
+"application::"
|
|
|
+msgstr ""
|
|
|
+"`start_server() <pywebio.platform.tornado.start_server>` 接收一个函数作为PyWebIO应"
|
|
|
+"用,另外, `start_server() <pywebio.platform.tornado.start_server>` 还支持传入函数"
|
|
|
+"列表或字典,从而启动多个PyWebIO应用,应用之间可以通过 `go_app() <pywebio.session."
|
|
|
+"go_app>` 或 `put_link() <pywebio.output.put_link>` 进行跳转::"
|
|
|
+
|
|
|
+#: ../../advanced.rst:17
|
|
|
+msgid ""
|
|
|
+"def task_1():\n"
|
|
|
+" put_text('task_1')\n"
|
|
|
+" put_buttons(['Go task 2'], [lambda: go_app('task_2')])\n"
|
|
|
+"\n"
|
|
|
+"def task_2():\n"
|
|
|
+" put_text('task_2')\n"
|
|
|
+" put_buttons(['Go task 1'], [lambda: go_app('task_1')])\n"
|
|
|
+"\n"
|
|
|
+"def index():\n"
|
|
|
+" put_link('Go task 1', app='task_1') # Use `app` parameter to specify the task "
|
|
|
+"name\n"
|
|
|
+" put_link('Go task 2', app='task_2')\n"
|
|
|
+"\n"
|
|
|
+"# equal to `start_server({'index': index, 'task_1': task_1, 'task_2': task_2})`\n"
|
|
|
+"start_server([index, task_1, task_2])"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:32
|
|
|
+msgid ""
|
|
|
+"When the first parameter of `start_server() <pywebio.platform.tornado."
|
|
|
+"start_server>` is a dictionary, whose key is application name and value is "
|
|
|
+"application function. When it is a list, PyWebIO will use function name as "
|
|
|
+"application name."
|
|
|
+msgstr ""
|
|
|
+"当 `start_server() <pywebio.platform.tornado.start_server>` 的第一个参数的类型为字"
|
|
|
+"典时,字典键为应用名,类型为列表时,函数名为应用名。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:35
|
|
|
+msgid ""
|
|
|
+"You can select which application to access through the ``app`` URL parameter (for "
|
|
|
+"example, visit ``http://host:port/?app=foo`` to access the ``foo`` application), "
|
|
|
+"By default, the ``index`` application is opened when no ``app`` URL parameter "
|
|
|
+"provided. When the ``index`` application doesn't exist, PyWebIO will provide a "
|
|
|
+"default index application."
|
|
|
+msgstr ""
|
|
|
+"可以通过 ``app`` URL参数选择要访问的应用(例如使用 ``http://host:port/?app=foo`` 来"
|
|
|
+"访问 ``foo`` 应用), 为提供了 ``app`` URL参数时默认使用运行 ``index`` 应用,当 "
|
|
|
+"``index`` 应用不存在时,PyWebIO会提供一个默认的索引页作为 ``index`` 应用。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:44
|
|
|
+msgid "Integration with web framework"
|
|
|
+msgstr "与Web框架整合"
|
|
|
+
|
|
|
+#: ../../advanced.rst:46
|
|
|
+msgid ""
|
|
|
+"The PyWebIO application can be integrated into an existing Python Web project, the "
|
|
|
+"PyWebIO application and the Web project share a web framework. PyWebIO currently "
|
|
|
+"supports integration with Flask, Tornado, Django, aiohttp and FastAPI(Starlette) "
|
|
|
+"web frameworks."
|
|
|
+msgstr ""
|
|
|
+"可以将PyWebIO应用集成到现有的Python Web项目中,PyWebIO应用与Web项目共用一个Web框"
|
|
|
+"架。目前支持与Flask、Tornado、Django、aiohttp和FastAPI(Starlette) Web框架的集成。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:50
|
|
|
+msgid "The integration methods of those web frameworks are as follows:"
|
|
|
+msgstr "不同Web框架的集成方法如下: "
|
|
|
+
|
|
|
+#: ../../advanced.rst:54
|
|
|
+msgid "Tornado"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:58
|
|
|
+msgid "**Tornado**"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:60
|
|
|
+msgid ""
|
|
|
+"Use `pywebio.platform.tornado.webio_handler()` to get the `WebSocketHandler "
|
|
|
+"<https://www.tornadoweb.org/en/stable/websocket.html#tornado.websocket."
|
|
|
+"WebSocketHandler>`_ class for running PyWebIO applications in Tornado::"
|
|
|
+msgstr ""
|
|
|
+"使用 `pywebio.platform.tornado.webio_handler()` 来获取在Tornado中运行PyWebIO应用的 "
|
|
|
+"`WebSocketHandler <https://www.tornadoweb.org/en/stable/websocket.html#tornado."
|
|
|
+"websocket.WebSocketHandler>`_ 类::"
|
|
|
+
|
|
|
+#: ../../advanced.rst:64
|
|
|
+msgid ""
|
|
|
+"import tornado.ioloop\n"
|
|
|
+"import tornado.web\n"
|
|
|
+"from pywebio.platform.tornado import webio_handler\n"
|
|
|
+"\n"
|
|
|
+"class MainHandler(tornado.web.RequestHandler):\n"
|
|
|
+" def get(self):\n"
|
|
|
+" self.write(\"Hello, world\")\n"
|
|
|
+"\n"
|
|
|
+"if __name__ == \"__main__\":\n"
|
|
|
+" application = tornado.web.Application([\n"
|
|
|
+" (r\"/\", MainHandler),\n"
|
|
|
+" (r\"/tool\", webio_handler(task_func)), # `task_func` is PyWebIO task "
|
|
|
+"function\n"
|
|
|
+" ])\n"
|
|
|
+" application.listen(port=80, address='localhost')\n"
|
|
|
+" tornado.ioloop.IOLoop.current().start()"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:81
|
|
|
+msgid ""
|
|
|
+"In above code, we add a routing rule to bind the ``WebSocketHandler`` of the "
|
|
|
+"PyWebIO application to the ``/tool`` path. After starting the Tornado server, you "
|
|
|
+"can visit ``http://localhost/tool`` to open the PyWebIO application."
|
|
|
+msgstr ""
|
|
|
+"以上代码将 PyWebIO 应用的 ``WebSocketHandler`` 绑定到了 ``/tool`` 路径下。 启动"
|
|
|
+"Tornado后,访问 ``http://localhost/tool``即可打开PyWebIO应用。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:86
|
|
|
+msgid ""
|
|
|
+"PyWebIO uses the WebSocket protocol to communicate with the browser in Tornado. If "
|
|
|
+"your Tornado application is behind a reverse proxy (such as Nginx), you may need "
|
|
|
+"to configure the reverse proxy to support the WebSocket protocol. :ref:`Here "
|
|
|
+"<nginx_ws_config>` is an example of Nginx WebSocket configuration."
|
|
|
+msgstr ""
|
|
|
+"当使用Tornado后端时,PyWebIO使用WebSocket协议和浏览器进行通讯,如果你的Tornado应用"
|
|
|
+"处在反向代理(比如Nginx)之后,可能需要特别配置反向代理来支持WebSocket协议,:ref:`这"
|
|
|
+"里 <nginx_ws_config>` 有一个Nginx配置WebSocket的例子。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:90
|
|
|
+msgid "Flask"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:94
|
|
|
+msgid "**Flask**"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:96
|
|
|
+msgid ""
|
|
|
+"Use `pywebio.platform.flask.webio_view()` to get the view function for running "
|
|
|
+"PyWebIO applications in Flask::"
|
|
|
+msgstr ""
|
|
|
+"使用 `pywebio.platform.flask.webio_view()` 来获取在Flask中运行PyWebIO应用的视图函"
|
|
|
+"数::"
|
|
|
+
|
|
|
+#: ../../advanced.rst:98
|
|
|
+msgid ""
|
|
|
+"from pywebio.platform.flask import webio_view\n"
|
|
|
+"from flask import Flask\n"
|
|
|
+"\n"
|
|
|
+"app = Flask(__name__)\n"
|
|
|
+"\n"
|
|
|
+"# `task_func` is PyWebIO task function\n"
|
|
|
+"app.add_url_rule('/tool', 'webio_view', webio_view(task_func),\n"
|
|
|
+" methods=['GET', 'POST', 'OPTIONS']) # need GET,POST and OPTIONS "
|
|
|
+"methods\n"
|
|
|
+"\n"
|
|
|
+"app.run(host='localhost', port=80)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:110
|
|
|
+msgid ""
|
|
|
+"In above code, we add a routing rule to bind the view function of the PyWebIO "
|
|
|
+"application to the ``/tool`` path. After starting the Flask application, visit "
|
|
|
+"``http://localhost/tool`` to open the PyWebIO application."
|
|
|
+msgstr ""
|
|
|
+"以上代码使用添加了一条路由规则将PyWebIO应用的视图函数绑定到 ``/tool`` 路径下。\n"
|
|
|
+"启动Flask应用后,访问 ``http://localhost/tool`` 即可打开PyWebIO应用"
|
|
|
+
|
|
|
+#: ../../advanced.rst:113
|
|
|
+msgid "Django"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:117
|
|
|
+msgid "**Django**"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:119
|
|
|
+msgid ""
|
|
|
+"Use `pywebio.platform.django.webio_view()` to get the view function for running "
|
|
|
+"PyWebIO applications in Django::"
|
|
|
+msgstr ""
|
|
|
+"使用 `pywebio.platform.django.webio_view()` 来获取在Django中运行PyWebIO应用的视图函"
|
|
|
+"数::"
|
|
|
+
|
|
|
+#: ../../advanced.rst:121
|
|
|
+msgid ""
|
|
|
+"# urls.py\n"
|
|
|
+"\n"
|
|
|
+"from django.urls import path\n"
|
|
|
+"from pywebio.platform.django import webio_view\n"
|
|
|
+"\n"
|
|
|
+"# `task_func` is PyWebIO task function\n"
|
|
|
+"webio_view_func = webio_view(task_func)\n"
|
|
|
+"\n"
|
|
|
+"urlpatterns = [\n"
|
|
|
+" path(r\"tool\", webio_view_func),\n"
|
|
|
+"]"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:134
|
|
|
+msgid ""
|
|
|
+"In above code, we add a routing rule to bind the view function of the PyWebIO "
|
|
|
+"application to the ``/tool`` path. After starting the Django server, visit "
|
|
|
+"``http://localhost/tool`` to open the PyWebIO application"
|
|
|
+msgstr ""
|
|
|
+"以上代码使用添加了一条路由规则将PyWebIO应用的视图函数绑定到 ``/tool`` 路径下。\n"
|
|
|
+"启动Django应用后,访问 ``http://localhost/tool`` 即可打开PyWebIO应用"
|
|
|
+
|
|
|
+#: ../../advanced.rst:137
|
|
|
+msgid "aiohttp"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:141
|
|
|
+msgid "**aiohttp**"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:143
|
|
|
+msgid ""
|
|
|
+"Use `pywebio.platform.aiohttp.webio_handler()` to get the `Request Handler "
|
|
|
+"<https://docs.aiohttp.org/en/stable/web_quickstart.html#aiohttp-web-handler>`_ "
|
|
|
+"coroutine for running PyWebIO applications in aiohttp::"
|
|
|
+msgstr ""
|
|
|
+"使用 `pywebio.platform.aiohttp.webio_handler()` 来获取在aiohttp中运行PyWebIO应用的 "
|
|
|
+"`Request Handler <https://docs.aiohttp.org/en/stable/web_quickstart.html#aiohttp-"
|
|
|
+"web-handler>`_ 协程::"
|
|
|
+
|
|
|
+#: ../../advanced.rst:147
|
|
|
+msgid ""
|
|
|
+"from aiohttp import web\n"
|
|
|
+"from pywebio.platform.aiohttp import webio_handler\n"
|
|
|
+"\n"
|
|
|
+"app = web.Application()\n"
|
|
|
+"# `task_func` is PyWebIO task function\n"
|
|
|
+"app.add_routes([web.get('/tool', webio_handler(task_func))])\n"
|
|
|
+"\n"
|
|
|
+"web.run_app(app, host='localhost', port=80)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:156
|
|
|
+msgid ""
|
|
|
+"After starting the aiohttp server, visit ``http://localhost/tool`` to open the "
|
|
|
+"PyWebIO application"
|
|
|
+msgstr "启动aiohttp应用后,访问 ``http://localhost/tool`` 即可打开PyWebIO应用"
|
|
|
+
|
|
|
+#: ../../advanced.rst:160
|
|
|
+msgid ""
|
|
|
+"PyWebIO uses the WebSocket protocol to communicate with the browser in aiohttp. If "
|
|
|
+"your aiohttp server is behind a reverse proxy (such as Nginx), you may need to "
|
|
|
+"configure the reverse proxy to support the WebSocket protocol. :ref:`Here "
|
|
|
+"<nginx_ws_config>` is an example of Nginx WebSocket configuration."
|
|
|
+msgstr ""
|
|
|
+"当使用aiohttp后端时,PyWebIO使用WebSocket协议和浏览器进行通讯,如果你的aiohttp应用"
|
|
|
+"处在反向代理(比如Nginx)之后,\n"
|
|
|
+"可能需要特别配置反向代理来支持WebSocket协议,:ref:`这里 <nginx_ws_config>` 有一个"
|
|
|
+"Nginx配置WebSocket的例子。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:165
|
|
|
+msgid "FastAPI/Starlette"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:169
|
|
|
+msgid "**FastAPI/Starlette**"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:171
|
|
|
+msgid ""
|
|
|
+"Use `pywebio.platform.fastapi.webio_routes()` to get the FastAPI/Starlette routes "
|
|
|
+"for running PyWebIO applications. You can mount the routes to your FastAPI/"
|
|
|
+"Starlette app."
|
|
|
+msgstr ""
|
|
|
+"使用 `pywebio.platform.fastapi.webio_routes()` 来获取在FastAPI/Starlette中运行"
|
|
|
+"PyWebIO应用的路由组件,你可以将其挂载在到FastAPI/Starlette应用中。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:174
|
|
|
+msgid "FastAPI::"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:176
|
|
|
+msgid ""
|
|
|
+"from fastapi import FastAPI\n"
|
|
|
+"from pywebio.platform.fastapi import webio_routes\n"
|
|
|
+"\n"
|
|
|
+"app = FastAPI()\n"
|
|
|
+"\n"
|
|
|
+"@app.get(\"/app\")\n"
|
|
|
+"def read_main():\n"
|
|
|
+" return {\"message\": \"Hello World from main app\"}\n"
|
|
|
+"\n"
|
|
|
+"# `task_func` is PyWebIO task function\n"
|
|
|
+"app.mount(\"/tool\", FastAPI(routes=webio_routes(task_func)))"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:188
|
|
|
+msgid "Starlette::"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:190
|
|
|
+msgid ""
|
|
|
+"from starlette.applications import Starlette\n"
|
|
|
+"from starlette.responses import JSONResponse\n"
|
|
|
+"from starlette.routing import Route, Mount\n"
|
|
|
+"from pywebio.platform.fastapi import webio_routes\n"
|
|
|
+"\n"
|
|
|
+"async def homepage(request):\n"
|
|
|
+" return JSONResponse({'hello': 'world'})\n"
|
|
|
+"\n"
|
|
|
+"app = Starlette(routes=[\n"
|
|
|
+" Route('/', homepage),\n"
|
|
|
+" Mount('/tool', routes=webio_routes(task_func)) # `task_func` is PyWebIO task "
|
|
|
+"function\n"
|
|
|
+"])"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:203
|
|
|
+msgid ""
|
|
|
+"After starting the server by using ``uvicorn <module>:app`` , visit ``http://"
|
|
|
+"localhost:8000/tool/`` to open the PyWebIO application"
|
|
|
+msgstr ""
|
|
|
+"使用 ``uvicorn <module>:app` 启动server后,访问 ``http://localhost:8000/tool/`` 即"
|
|
|
+"可打开PyWebIO应用"
|
|
|
+
|
|
|
+#: ../../advanced.rst:205
|
|
|
+msgid ""
|
|
|
+"See also: `FastAPI doc <https://fastapi.tiangolo.com/advanced/sub-applications/"
|
|
|
+">`_ , `Starlette doc <https://www.starlette.io/routing/#submounting-routes>`_"
|
|
|
+msgstr ""
|
|
|
+"参见: `FastAPI doc <https://fastapi.tiangolo.com/advanced/sub-applications/>`_ , "
|
|
|
+"`Starlette doc <https://www.starlette.io/routing/#submounting-routes>`_"
|
|
|
+
|
|
|
+#: ../../advanced.rst:209
|
|
|
+msgid ""
|
|
|
+"PyWebIO uses the WebSocket protocol to communicate with the browser in FastAPI/"
|
|
|
+"Starlette. If your server is behind a reverse proxy (such as Nginx), you may need "
|
|
|
+"to configure the reverse proxy to support the WebSocket protocol. :ref:`Here "
|
|
|
+"<nginx_ws_config>` is an example of Nginx WebSocket configuration."
|
|
|
+msgstr ""
|
|
|
+"当使用FastAPI或Starlette后端时,PyWebIO使用WebSocket协议和浏览器进行通讯,如果你的"
|
|
|
+"aiohttp应用处在反向代理(比如Nginx)之后,\n"
|
|
|
+"可能需要特别配置反向代理来支持WebSocket协议,:ref:`这里 <nginx_ws_config>` 有一个"
|
|
|
+"Nginx配置WebSocket的例子。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:217
|
|
|
+msgid "Notes"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:218
|
|
|
+msgid "**Deployment in production**"
|
|
|
+msgstr "**生产环境部署**"
|
|
|
+
|
|
|
+#: ../../advanced.rst:220
|
|
|
+msgid ""
|
|
|
+"In your production system, you may want to deploy the web applications with some "
|
|
|
+"WSGI/ASGI servers such as uWSGI, Gunicorn, and Uvicorn. Since PyWebIO applications "
|
|
|
+"store session state in memory of process, when you use HTTP-based sessions (Flask "
|
|
|
+"and Django) and spawn multiple workers to handle requests, the request may be "
|
|
|
+"dispatched to a process that does not hold the session to which the request "
|
|
|
+"belongs. So you can only start one worker to handle requests when using Flask or "
|
|
|
+"Django backend."
|
|
|
+msgstr ""
|
|
|
+"在生产环境中,你可能会使用一些 WSGI/ASGI 服务器(如 uWSGI、Gunicorn、Uvicorn)部署 "
|
|
|
+"Web 应用程序。由于 PyWebIO 应用程序会在进程中存储会话状态,当使用基于 HTTP 的会话"
|
|
|
+"(使用Flask 和 Django后端时)并生成多个进程来处理请求时,请求可能会被分发到错误的进"
|
|
|
+"程中。因此,在使用基于 HTTP 的会话时,只能启动一个进程来处理请求。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:225
|
|
|
+msgid ""
|
|
|
+"If you still want to use multiple processes to increase concurrency, one way is to "
|
|
|
+"use Uvicorn+FastAPI, or you can also start multiple Tornado/aiohttp processes and "
|
|
|
+"add external load balancer (such as HAProxy or nginx) before them. Those backends "
|
|
|
+"use the WebSocket protocol to communicate with the browser in PyWebIO, so there is "
|
|
|
+"no the issue as described above."
|
|
|
+msgstr ""
|
|
|
+"如果仍然希望使用多进程来提高并发,一种方式是使用 Uvicorn+FastAPI,或者你也可以启动"
|
|
|
+"多个Tornado/aiohttp进程,并在它们之前添加外部的负载均衡软件(如 HAProxy 或 "
|
|
|
+"nginx)。这些后端使用 WebSocket 协议与浏览器进行通信,所以不存在上述问题。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:229
|
|
|
+msgid "**Static resources Hosting**"
|
|
|
+msgstr "**PyWebIO静态资源的托管**"
|
|
|
+
|
|
|
+#: ../../advanced.rst:231
|
|
|
+msgid ""
|
|
|
+"By default, the front-end of PyWebIO gets required static resources from CDN. If "
|
|
|
+"you want to deploy PyWebIO applications in an offline environment, you need to "
|
|
|
+"host static files by yourself, and set the ``cdn`` parameter of ``webio_view()`` "
|
|
|
+"or ``webio_handler()`` to ``False``."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO默认使用CDN来获取前端的静态资源,如果要将PyWebIO应用部署到离线环境中,需要自"
|
|
|
+"行托管静态文件,\n"
|
|
|
+"并将 ``webio_view()`` 或 ``webio_handler()`` 的 ``cdn`` 参数设置为 ``False`` 。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:235
|
|
|
+msgid ""
|
|
|
+"When setting ``cdn=False`` , you need to host the static resources in the same "
|
|
|
+"directory as the PyWebIO application. In addition, you can also pass a string to "
|
|
|
+"``cdn`` parameter to directly set the URL of PyWebIO static resources directory."
|
|
|
+msgstr ""
|
|
|
+"``cdn=False`` 时需要将静态资源托管在和PyWebIO应用同级的目录下。\n"
|
|
|
+"同时,也可以通过 ``cdn`` 参数直接设置PyWebIO静态资源的URL目录。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:238
|
|
|
+msgid ""
|
|
|
+"The path of the static file of PyWebIO is stored in ``pywebio.STATIC_PATH``, you "
|
|
|
+"can use the command ``python3 -c \"import pywebio; print(pywebio.STATIC_PATH)\"`` "
|
|
|
+"to print it out."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO的静态文件的路径保存在 ``pywebio.STATIC_PATH`` 中,可使用命令 ``python3 -c "
|
|
|
+"\"import pywebio; print(pywebio.STATIC_PATH)\"`` 将其打印出来。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:243
|
|
|
+msgid ""
|
|
|
+"``start_server()`` and ``path_deploy()`` also support ``cdn`` parameter, if it is "
|
|
|
+"set to ``False``, the static resource will be hosted in local server "
|
|
|
+"automatically, without manual hosting."
|
|
|
+msgstr ""
|
|
|
+"使用 ``start_server()`` 启动的应用,如果将 ``cdn`` 参数设置为 ``False`` ,会自动启"
|
|
|
+"动一个本地的静态资源托管服务,无需手动托管。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:250
|
|
|
+msgid "Coroutine-based session"
|
|
|
+msgstr "基于协程的会话"
|
|
|
+
|
|
|
+#: ../../advanced.rst:251
|
|
|
+msgid ""
|
|
|
+"In most cases, you don’t need the coroutine-based session. All functions or "
|
|
|
+"methods in PyWebIO that are only used for coroutine sessions are specifically "
|
|
|
+"noted in the document."
|
|
|
+msgstr ""
|
|
|
+"在大部分情况下,你并不需要使用基于协程的会话。PyWebIO中所有仅用于协程会话的函数或方"
|
|
|
+"法都在文档中均有特别说明。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:254
|
|
|
+msgid ""
|
|
|
+"PyWebIO's session is based on thread by default. Each time a user opens a session "
|
|
|
+"connection to the server, PyWebIO will start a thread to run the task function. In "
|
|
|
+"addition to thread-based sessions, PyWebIO also provides coroutine-based sessions. "
|
|
|
+"Coroutine-based sessions accept coroutine functions as task functions."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO的会话实现默认是基于线程的,用户每打开一个和服务端的会话连接,PyWebIO会启动"
|
|
|
+"一个线程来运行任务函数。\n"
|
|
|
+"除了基于线程的会话,PyWebIO还提供了基于协程的会话。基于协程的会话接受协程函数作为任"
|
|
|
+"务函数。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:258
|
|
|
+msgid ""
|
|
|
+"The session based on the coroutine is a single-thread model, which means that all "
|
|
|
+"sessions run in a single thread. For IO-bound tasks, coroutines take up fewer "
|
|
|
+"resources than threads and have performance comparable to threads. In addition, "
|
|
|
+"the context switching of the coroutine is predictable, which can reduce the need "
|
|
|
+"for program synchronization and locking, and can effectively avoid most critical "
|
|
|
+"section problems."
|
|
|
+msgstr ""
|
|
|
+"基于协程的会话为单线程模型,所有会话都运行在一个线程内。对于IO密集型的任务,协程比"
|
|
|
+"线程占用更少的资源同时又拥有媲美于线程的性能。\n"
|
|
|
+"另外,协程的上下文切换具有可预测性,能够减少程序同步与加锁的需要,可以有效避免大多"
|
|
|
+"数临界区问题。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:264
|
|
|
+msgid "Using coroutine session"
|
|
|
+msgstr "使用协程会话"
|
|
|
+
|
|
|
+#: ../../advanced.rst:266
|
|
|
+msgid ""
|
|
|
+"To use coroutine-based session, you need to use the ``async`` keyword to declare "
|
|
|
+"the task function as a coroutine function, and use the ``await`` syntax to call "
|
|
|
+"the PyWebIO input function:"
|
|
|
+msgstr ""
|
|
|
+"要使用基于协程的会话,需要使用 ``async`` 关键字将任务函数声明为协程函数,并使用 "
|
|
|
+"``await`` 语法调用PyWebIO输入函数:"
|
|
|
+
|
|
|
+#: ../../advanced.rst:269
|
|
|
+#, python-format
|
|
|
+msgid ""
|
|
|
+" from pywebio.input import *\n"
|
|
|
+" from pywebio.output import *\n"
|
|
|
+" from pywebio import start_server\n"
|
|
|
+"\n"
|
|
|
+" async def say_hello():\n"
|
|
|
+" name = await input(\"what's your name?\")\n"
|
|
|
+" put_text('Hello, %s' % name)\n"
|
|
|
+"\n"
|
|
|
+" start_server(say_hello, auto_open_webbrowser=True)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:283
|
|
|
+msgid ""
|
|
|
+"In the coroutine task function, you can also use ``await`` to call other "
|
|
|
+"coroutines or (`awaitable objects <https://docs.python.org/3/library/asyncio-task."
|
|
|
+"html#asyncio-awaitables>`_) in the standard library `asyncio <https://docs.python."
|
|
|
+"org/3/library/asyncio.html>`_:"
|
|
|
+msgstr ""
|
|
|
+"在协程任务函数中,也可以使用 ``await`` 调用其他协程或标准库 `asyncio <https://docs."
|
|
|
+"python.org/3/library/asyncio.html>`_ 中的可等待对象( `awaitable objects <https://"
|
|
|
+"docs.python.org/3/library/asyncio-task.html#asyncio-awaitables>`_ ):"
|
|
|
+
|
|
|
+#: ../../advanced.rst:287
|
|
|
+msgid ""
|
|
|
+" import asyncio\n"
|
|
|
+" from pywebio import start_server\n"
|
|
|
+"\n"
|
|
|
+" async def hello_word():\n"
|
|
|
+" put_text('Hello ...')\n"
|
|
|
+" await asyncio.sleep(1) # await awaitable objects in asyncio\n"
|
|
|
+" put_text('... World!')\n"
|
|
|
+"\n"
|
|
|
+" async def main():\n"
|
|
|
+" await hello_word() # await coroutine\n"
|
|
|
+" put_text('Bye, bye')\n"
|
|
|
+"\n"
|
|
|
+" start_server(main, auto_open_webbrowser=True)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:306
|
|
|
+msgid ""
|
|
|
+"In coroutine-based session, all input functions defined in the :doc:`pywebio.input "
|
|
|
+"</input>` module need to use ``await`` syntax to get the return value. Forgetting "
|
|
|
+"to use ``await`` will be a common error when using coroutine-based session."
|
|
|
+msgstr ""
|
|
|
+"在基于协程的会话中, :doc:`pywebio.input </input>` 模块中的定义输入函数都需要使用 "
|
|
|
+"``await`` 语法来获取返回值,忘记使用 ``await`` 将会是在使用基于协程的会话时常出现的"
|
|
|
+"错误。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:309
|
|
|
+msgid ""
|
|
|
+"Other functions that need to use ``await`` syntax in the coroutine session are:"
|
|
|
+msgstr "其他在协程会话中也需要使用 ``await`` 语法来进行调用函数有:"
|
|
|
+
|
|
|
+#: ../../advanced.rst:311
|
|
|
+msgid ""
|
|
|
+"`pywebio.session.run_asyncio_coroutine(coro_obj) <pywebio.session."
|
|
|
+"run_asyncio_coroutine>`"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:312
|
|
|
+msgid "`pywebio.session.eval_js(expression) <pywebio.session.eval_js>`"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:316
|
|
|
+msgid ""
|
|
|
+"Although the PyWebIO coroutine session is compatible with the ``awaitable "
|
|
|
+"objects`` in the standard library ``asyncio``, the ``asyncio`` library is not "
|
|
|
+"compatible with the ``awaitable objects`` in the PyWebIO coroutine session."
|
|
|
+msgstr ""
|
|
|
+"虽然PyWebIO的协程会话兼容标准库 ``asyncio`` 中的 ``awaitable objects`` ,但 "
|
|
|
+"``asyncio`` 库不兼容PyWebIO协程会话中的 ``awaitable objects`` ."
|
|
|
+
|
|
|
+#: ../../advanced.rst:319
|
|
|
+msgid ""
|
|
|
+"That is to say, you can't pass PyWebIO ``awaitable objects`` to the ``asyncio`` "
|
|
|
+"functions that accept ``awaitable objects``. For example, the following calls are "
|
|
|
+"**not supported** ::"
|
|
|
+msgstr ""
|
|
|
+"也就是说,无法将PyWebIO中的 ``awaitable objects`` 传入 ``asyncio`` 中的接受 "
|
|
|
+"``awaitable objects`` 作为参数的函数中,比如如下调用是 **不被支持的** ::"
|
|
|
+
|
|
|
+#: ../../advanced.rst:322
|
|
|
+msgid ""
|
|
|
+"await asyncio.shield(pywebio.input())\n"
|
|
|
+"await asyncio.gather(asyncio.sleep(1), pywebio.session.eval_js('1+1'))\n"
|
|
|
+"task = asyncio.create_task(pywebio.input())"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:329
|
|
|
+msgid "Concurrency in coroutine-based sessions"
|
|
|
+msgstr "协程会话的并发"
|
|
|
+
|
|
|
+#: ../../advanced.rst:331
|
|
|
+msgid ""
|
|
|
+"In coroutine-based session, you can start new thread, but you cannot call PyWebIO "
|
|
|
+"interactive functions in it (`register_thread() <pywebio.session.register_thread>` "
|
|
|
+"is not available in coroutine session). But you can use `run_async(coro) <pywebio."
|
|
|
+"session.run_async>` to execute a coroutine object asynchronously, and PyWebIO "
|
|
|
+"interactive functions can be used in the new coroutine:"
|
|
|
+msgstr ""
|
|
|
+"在基于协程的会话中,你可以启动线程,但是无法在其中调用PyWebIO交互函数"
|
|
|
+"( `register_thread() <pywebio.session.register_thread>` 在协程会话中不可用)。\n"
|
|
|
+"但你可以使用 `run_async(coro) <pywebio.session.run_async>` 来异步执行一个协程对象,"
|
|
|
+"新协程内可以使用PyWebIO交互函数:"
|
|
|
+
|
|
|
+#: ../../advanced.rst:336
|
|
|
+msgid ""
|
|
|
+" from pywebio import start_server\n"
|
|
|
+" from pywebio.session import run_async\n"
|
|
|
+"\n"
|
|
|
+" async def counter(n):\n"
|
|
|
+" for i in range(n):\n"
|
|
|
+" put_text(i)\n"
|
|
|
+" await asyncio.sleep(1)\n"
|
|
|
+"\n"
|
|
|
+" async def main():\n"
|
|
|
+" run_async(counter(10))\n"
|
|
|
+" put_text('Main coroutine function exited.')\n"
|
|
|
+"\n"
|
|
|
+"\n"
|
|
|
+" start_server(main, auto_open_webbrowser=True)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:355
|
|
|
+msgid ""
|
|
|
+"`run_async(coro) <pywebio.session.run_async>` returns a `TaskHandler <pywebio."
|
|
|
+"session.coroutinebased.TaskHandler>`, which can be used to query the running "
|
|
|
+"status of the coroutine or close the coroutine."
|
|
|
+msgstr ""
|
|
|
+"`run_async(coro) <pywebio.session.run_async>` 返回一个 `TaskHandler <pywebio."
|
|
|
+"session.coroutinebased.TaskHandler>` ,通过该 `TaskHandler <pywebio.session."
|
|
|
+"coroutinebased.TaskHandler>` 可以查询协程运行状态和关闭协程。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:359
|
|
|
+msgid "Close of session"
|
|
|
+msgstr "会话的结束"
|
|
|
+
|
|
|
+#: ../../advanced.rst:361
|
|
|
+msgid ""
|
|
|
+"Similar to thread-based session, when user close the browser page, the session "
|
|
|
+"will be closed."
|
|
|
+msgstr "和基于线程的会话一样,当用户关闭浏览器页面后,会话也随之关闭。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:363
|
|
|
+msgid ""
|
|
|
+"After the browser page closed, PyWebIO input function calls that have not yet "
|
|
|
+"returned in the current session will cause `SessionClosedException <pywebio."
|
|
|
+"exceptions.SessionClosedException>`, and subsequent calls to PyWebIO interactive "
|
|
|
+"functions will cause `SessionNotFoundException <pywebio.exceptions."
|
|
|
+"SessionNotFoundException>` or `SessionClosedException <pywebio.exceptions."
|
|
|
+"SessionClosedException>`."
|
|
|
+msgstr ""
|
|
|
+"浏览器页面关闭后,当前会话内还未返回的PyWebIO输入函数调用将抛出 "
|
|
|
+"`SessionClosedException <pywebio.exceptions.SessionClosedException>` 异常,之后对于"
|
|
|
+"PyWebIO交互函数的调用将会产生 `SessionNotFoundException <pywebio.exceptions."
|
|
|
+"SessionNotFoundException>` 或 `SessionClosedException <pywebio.exceptions."
|
|
|
+"SessionClosedException>` 异常。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:368
|
|
|
+msgid ""
|
|
|
+"`defer_call(func) <pywebio.session.defer_call>` also available in coroutine "
|
|
|
+"session."
|
|
|
+msgstr ""
|
|
|
+"协程会话也同样支持使用 `defer_call(func) <pywebio.session.defer_call>` 来设置会话结"
|
|
|
+"束时需要调用的函数。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:373
|
|
|
+msgid "Integration with Web Framework"
|
|
|
+msgstr "协程会话与Web框架集成"
|
|
|
+
|
|
|
+#: ../../advanced.rst:375
|
|
|
+msgid ""
|
|
|
+"The PyWebIO application that using coroutine-based session can also be integrated "
|
|
|
+"to the web framework."
|
|
|
+msgstr ""
|
|
|
+"基于协程的会话同样可以与Web框架进行集成,只需要在原来传入任务函数的地方改为传入协程"
|
|
|
+"函数即可。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:377
|
|
|
+msgid ""
|
|
|
+"However, there are some limitations when using coroutine-based sessions to "
|
|
|
+"integrate into Flask or Django:"
|
|
|
+msgstr "但当前在使用基于协程的会话集成进Flask或Django时,存在一些限制:"
|
|
|
+
|
|
|
+#: ../../advanced.rst:379
|
|
|
+msgid ""
|
|
|
+"First, when ``await`` the coroutine objects/awaitable objects in the ``asyncio`` "
|
|
|
+"module, you need to use `run_asyncio_coroutine() <pywebio.session."
|
|
|
+"run_asyncio_coroutine>` to wrap the coroutine object."
|
|
|
+msgstr ""
|
|
|
+"一是协程函数内还无法直接通过 ``await`` 直接等待asyncio库中的协程对象,目前需要使用 "
|
|
|
+"`run_asyncio_coroutine() <pywebio.session.run_asyncio_coroutine>` 进行包装。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:382
|
|
|
+msgid ""
|
|
|
+"Secondly, you need to start a new thread to run the event loop before starting a "
|
|
|
+"Flask/Django server."
|
|
|
+msgstr ""
|
|
|
+"二是,在启动Flask/Django这类基于线程的服务器之前需要启动一个单独的线程来运行事件循"
|
|
|
+"环。"
|
|
|
+
|
|
|
+#: ../../advanced.rst:384
|
|
|
+msgid "Example of coroutine-based session integration into Flask:"
|
|
|
+msgstr "使用基于协程的会话集成进Flask的示例:"
|
|
|
+
|
|
|
+#: ../../advanced.rst:386
|
|
|
+msgid ""
|
|
|
+" import asyncio\n"
|
|
|
+" import threading\n"
|
|
|
+" from flask import Flask, send_from_directory\n"
|
|
|
+" from pywebio import STATIC_PATH\n"
|
|
|
+" from pywebio.output import *\n"
|
|
|
+" from pywebio.platform.flask import webio_view\n"
|
|
|
+" from pywebio.platform import run_event_loop\n"
|
|
|
+" from pywebio.session import run_asyncio_coroutine\n"
|
|
|
+"\n"
|
|
|
+" async def hello_word():\n"
|
|
|
+" put_text('Hello ...')\n"
|
|
|
+" await run_asyncio_coroutine(asyncio.sleep(1)) # can't just \"await asyncio."
|
|
|
+"sleep(1)\"\n"
|
|
|
+" put_text('... World!')\n"
|
|
|
+"\n"
|
|
|
+" app = Flask(__name__)\n"
|
|
|
+" app.add_url_rule('/hello', 'webio_view', webio_view(hello_word),\n"
|
|
|
+" methods=['GET', 'POST', 'OPTIONS'])\n"
|
|
|
+"\n"
|
|
|
+" # thread to run event loop\n"
|
|
|
+" threading.Thread(target=run_event_loop, daemon=True).start()\n"
|
|
|
+" app.run(host='localhost', port=80)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../advanced.rst:411
|
|
|
+msgid ""
|
|
|
+"Finally, coroutine-based session is not available in the script mode. You always "
|
|
|
+"need to use ``start_server()`` to run coroutine task function or integrate it to a "
|
|
|
+"web framework."
|
|
|
+msgstr ""
|
|
|
+"最后,使用PyWebIO编写的协程函数不支持Script模式,总是需要使用 ``start_server`` 来启"
|
|
|
+"动一个服务或者集成进Web框架来调用。"
|