使用Microdot在Micropython中构建物联网Web服务器

文章目录

  • Microdot一个可以在micropytho中搭建物联网web服务器的框架
  • 安装
  • 开始
  • 一个简单的Microdot网络服务器
  • 与CPython一起跑步
  • 使用 MicroPython 运行
  • 定义路由
  • 选择 HTTP 方法
  • 在 URL 路径中包含动态组件
  • 请求处理程序之前和之后
  • 错误处理程序
  • 挂载子应用程序
  • 关闭服务器
  • 请求对象
  • 请求属性
  • JSON 有效负载
  • 网址编码的表单数据
  • 访问原始请求正文
  • Cookies
  • “g”对象
  • 特定于请求的后请求处理程序
  • 请求限制
  • 反应
  • 响应的三个部分
  • JSON 响应
  • 重 定向
  • 文件响应
  • 流式处理响应
  • 更改默认响应内容类型
  • 设置cookies
  • 并发
  • 核心扩展
  • 异步异步支持
  • 呈现 HTML 模板
  • 使用 u模板引擎
  • 使用金贾引擎
  • 维护安全的用户会话
  • 跨域资源共享
  • 网络套接字支持
  • 异步网络套接字
  • HTTPS 支持
  • 测试客户端
  • 异步测试客户端
  • 在生产 Web 服务器上部署
  • 使用 WSGI Web 服务器
  • 使用 ASGI 网络服务器
  • [API 参考]([API Reference — Microdot documentation](https://microdot.readthedocs.io/en/latest/api.html#microdot-module))
  • Microdot一个可以在micropytho中搭建物联网web服务器的框架

    micordot英文官网

    只要是支持micropython的设备都可以使用它

    什么是Microdot?Microdot是一个受Flask启发的简约Python Web框架,旨在运行在 资源有限的系统,例如微控制器(esp32,esp8266)。它在标准上运行 Python和MicroPython。

    [项目需要的所需的Microdot源文件代码](miguelgrinberg/microdot: The impossibly small web framework for Python and MicroPython. (github.com))

    安装

    对于标准的Python(CPython)项目,Microdot及其所有核心扩展 可安装:pip

    pip install microdot
    

    对于MicroPython,如果该选项可用,您可以使用它安装它, 但推荐的方法是手动复制 microdot.py 和任何 所需的可选扩展名源文件从 GitHub 存储库到您的设备中,可能在将它们编译为 .mpy 文件之后。这些源文件也可以冻结并合并到自定义MicroPython固件中。upip

    开始

    本节以非正式的方式介绍Microdot的主要功能。为 详细的参考信息,请参阅 API 参考。

    一个简单的Microdot网络服务器

    以下是简单 Web 服务器的示例:

    from microdot import Microdot
    
    app = Microdot()
    
    @app.route('/')
    def index(request):
        return 'Hello, world!'
    
    app.run(host='0.0.0.0', port=5000, debug=False, ssl=None)
    

    脚本导入类并创建 来自它的应用程序实例。

    应用程序实例提供了一个route装饰器,用于定义一个或多个路由,根据需要 应用。

    route()装饰器将 URL 的路径部分作为 参数,并将其映射到修饰函数,以便调用该函数 当客户端请求 URL 时。该函数将对象作为参数传递,该参数提供 访问客户端传递的信息。返回的值由 函数作为响应发送回客户端。

    run()该方法启动应用程序的 Web 端口 5000 上的服务器(或在参数中传递的端口号)。这 方法在等待来自客户端的连接时阻止。

    与CPython一起跑步

    必需的Microdot源文件 microdot.py
    所需的外部依赖项 没有
    例子 hello.py

    使用 CPython 时,您可以通过运行脚本来启动 Web 服务器 定义并运行应用程序实例:

    python main.py
    

    在脚本运行时,您可以打开 Web 浏览器并导航到 http://localhost:5000/,这是 Microdot Web 的默认地址 服务器。从同一网络中的其他计算机,使用 IP 地址或 运行脚本的计算机的主机名,而不是 。localhost

    使用 MicroPython 运行

    必需的Microdot源文件 microdot.py
    所需的外部依赖项 没有
    例子 hello.pygpio.py

    使用MicroPython时,您可以上传包含Web的 main.py 文件 服务器代码与 microdot.py 一起发送到您的设备。MicroPython 将 设备通电时自动运行 main.py,因此Web服务器 将自动启动。可以在端口 5000 上访问该应用程序,网址为 设备的 IP 地址。如上所述,可以通过将参数传递给方法来更改端口。port``run()

    注意

    Microdot 不配置其所在设备的网络接口 正在运行。如果您的设备需要建立网络连接 前进,例如到 Wi-Fi 接入点,这必须在之前进行配置 调用该方法。run()

    定义路由

    ``修饰器用于关联 应用程序 URL,其中包含处理它的函数。唯一必需的参数 装饰器是 URL 的路径部分。

    以下示例为应用程序的根 URL 创建路由:

    @app.route('/')
    def index(request):
        return 'Hello, world!'
    

    当客户端请求根 URL(例如,http://localhost:5000/)时, Microdot 将调用该函数,并为其传递一个``对象。函数的返回值 是发送到客户端的响应。index()

    下面是另一个示例,该示例包含包含两个组件的 URL 的路由 在其路径中:

    @app.route('/users/active')
    def active_users(request):
        return 'Active users: Susan, Joe, and Bob'
    

    映射到此路由的完整 URL http://localhost:5000/users/active

    一个应用程序可以包含多个路由。Microdot使用 用于确定要为每个传入调用的正确路由函数的 URL 请求。

    选择 HTTP 方法

    上面显示的所有示例路由都与请求相关联。但 应用程序通常需要为其他 HTTP 方法定义路由,例如 、 和 。装饰器采用可选参数,应用程序可以在其中提供 路由应在给定路径上关联的 HTTP 方法。GET``POST``PUT``PATCH``DELETE``route()``methods

    以下示例定义在同一函数中处理和请求的路由:GET``POST

    @app.route('/invoices', methods=['GET', 'POST'])
    def invoices(request):
        if request.method == 'GET':
            return 'get invoices'
        elif request.method == 'POST':
            return 'create an invoice'
    

    在上述情况下,单个 URL 用于处理多个 HTTP 方法,可能需要为每个 HTTP 方法编写一个单独的函数。 上面的示例可以使用两个路由实现,如下所示:

    @app.route('/invoices', methods=['GET'])
    def get_invoices(request):
        return 'get invoices'
    
    @app.route('/invoices', methods=['POST'])
    def create_invoice(request):
        return 'create an invoice'
    

    Microdot 还提供 ](https://microdot.readthedocs.io/en/latest/api.html#microdot.Microdot.get)、[](https://microdot.readthedocs.io/en/latest/api.html#microdot.Microdot.put)[、 和``修饰器快捷方式。这 上面的两个示例路由可以用它们更简洁地编写:

    @app.get('/invoices')
    def get_invoices(request):
        return 'get invoices'
    
    @app.post('/invoices')
    def create_invoice(request):
        return 'create an invoice'
    

    在 URL 路径中包含动态组件

    上面显示的示例都使用硬编码的 URL 路径。Microdot还支持 路径中具有动态组件的路由的定义。例如 以下路由将路径遵循模式 *http://localhost:5000/users/<用户名>*的所有 URL 与函数相关联:get_user()

    @app.get('/users/<username>')
    def get_user(request, username):
        return 'User: ' + username
    

    如示例中所示,括在尖括号中的路径组件 被认为是动态的。Microdot接受 URL 该部分的任何值 路径,并将收到的值作为参数传递给函数之后的参数 请求对象。

    路由不限于单个动态组件。以下路线显示 如何在路径中包含多个动态组件:

    @app.get('/users/<firstname>/<lastname>')
    def get_user(request, firstname, lastname):
        return 'User: ' + firstname + ' ' + lastname
    

    默认情况下,动态路径组件被视为字符串。一个明确的 类型可以指定为前缀,与动态组件名称分隔 一个冒号。以下路由有两个声明为整数的动态组件 和字符串分别:

    @app.get('/users/<int:id>/<string:username>')
    def get_user(request, id, username):
        return 'User: ' + username + ' (' + str(id) + ')'
    

    如果将动态路径组件定义为整数,则传递给 路由函数也是一个整数。如果客户端发送的值不是 URL路径相应部分中的整数,则URL将不会 匹配,则不会调用路由。

    可以使用特殊类型将路径的其余部分捕获为 单个参数:path

    @app.get('/tests/<path:path>')
    def get_test(request, path):
        return 'Test: ' + path
    

    对于大多数控件,该类型允许应用程序提供 动态组件的自定义正则表达式。下一个示例定义 仅匹配以大写或小写开头的用户名的路由 字母,后跟一系列字母或数字:re

    @app.get('/users/<re:[a-zA-Z][a-zA-Z0-9]*:username>')
    def get_user(request, username):
        return 'User: ' + username
    

    注意

    动态路径组件作为关键字参数传递给路由函数, 因此,函数参数的名称必须与 路径规范。

    请求处理程序之前和之后

    应用程序通常需要在 请求已处理。示例包括身份验证和/或授权 客户端,打开与数据库的连接,或检查请求的 可以从缓存中获取资源。``装饰器寄存器 在将请求分派给路由函数之前要调用的函数。

    下面的示例注册一个 before 请求处理程序,该处理程序可确保 客户端在处理请求之前进行身份验证:

    @app.before_request
    def authenticate(request):
        user = authorize(request)
        if not user:
            return 'Unauthorized', 401
        request.g.user = user
    

    在请求处理程序将请求对象作为参数接收之前。如果 函数返回一个值,Microdot 将其作为响应发送给客户端,并且 不调用路由函数。这在请求处理程序之前给出了 在必要时拦截请求的权力。上面的例子使用了这个 防止未经授权的用户访问所请求的技术 资源。

    调用向装饰器注册``的请求处理程序后 在路由函数返回响应之后。他们的目的是执行任何 常见的关闭或清理任务。下一个示例显示了之前的组合 并在请求处理程序打印请求所需的时间之后 处理:

    @app.before_request
    def start_timer(request):
        request.g.start_time = time.time()
    
    @app.after_request
    def end_timer(request, response):
        duration = time.time() - request.g.start_time
        print(f'Request took {duration:0.2f} seconds')
    

    请求处理程序接收请求和响应对象作为参数之后。 该函数可以返回修改后的响应对象以替换原始对象。如果 该函数不返回值,则原始响应对象为 使用。

    仅对成功的请求调用 after 请求处理程序。``装饰器可用于注册在错误后调用的函数 发生。该函数接收请求和错误响应,并且 预期返回更新的响应对象。

    注意

    request.g 对象是一个特殊的对象,它允许 之前和之后的请求处理程序,以及 SA 路由函数 在请求的生命周期内共享数据。

    错误处理程序

    当在处理请求期间发生错误时,Microdot 确保 客户端收到相应的错误响应。一些常见错误 Microdot 自动处理的是:

  • 400 表示格式错误的请求。
  • 404 表示未定义的 URL。
  • 405 表示已定义的 URL,但不用于请求的 HTTP 方法。
  • 413 表示大于允许大小的请求。
  • 当应用程序引发异常时为 500。
  • 虽然上述错误完全符合 HTTP 规范,但 应用程序可能希望为它们提供自定义响应。``装饰器寄存器 用于响应特定错误代码的函数。以下示例显示 404 错误的自定义错误处理程序:

    @app.errorhandler(404)
    def not_found(request):
        return {'error': 'resource not found'}, 404
    

    装饰器有第二种形式,其中它采用 异常类作为参数。然后,Microdot将在以下情况下调用处理程序: 异常是引发给定类的实例。下一个示例 提供除以零错误的自定义响应:errorhandler()

    @app.errorhandler(ZeroDivisionError)
    def division_by_zero(request, exception):
        return {'error': 'division by zero'}, 500
    

    当引发的异常类未定义错误处理程序时,但 它的一个或多个基类会这样做,Microdot 会尝试调用 最具体的处理程序。

    挂载子应用程序

    小型Microdot应用程序可以写入单个源文件,但这 对于超过特定大小的应用程序,不是最佳选择。要做到 更简单的编写大型应用程序,Microdot 支持 可以“装载”到较大应用程序上的子应用程序,可能使用 应用于其所有路由的通用 URL 前缀。

    例如,考虑一个 customers.py 实现 对客户的操作:

    from microdot import Microdot
    
    customers_app = Microdot()
    
    @customers_app.get('/')
    def get_customers(request):
        # return all customers
    
    @customers_app.post('/')
    def new_customer(request):
        # create a new customer
    

    以同样的方式,orders.py 子应用程序在 客户订单:

    from microdot import Microdot
    
    orders_app = Microdot()
    
    @orders_app.get('/')
    def get_orders(request):
        # return all orders
    
    @orders_app.post('/')
    def new_order(request):
        # create a new order
    

    现在存储在 main.py 中的主应用程序可以导入和挂载 用于构建组合应用程序的子应用程序:

    from microdot import Microdot
    from customers import customers_app
    from orders import orders_app
    
    def create_app():
        app = Microdot()
        app.mount(customers_app, url_prefix='/customers')
        app.mount(orders_app, url_prefix='/orders')
        return app
    
    app = create_app()
    app.run()
    

    生成的应用程序将具有在 /customers/ 上可用的客户终结点和在 /orders/ 上可用的订单终结点。

    注意

    在请求之前、请求之后和错误处理程序中定义的 子应用程序也会在挂载时复制到主应用程序。 一旦安装在主应用程序中,这些处理程序将应用于 整个应用程序,而不仅仅是它们所在的子应用程序 创建。

    关闭服务器

    Web 服务器设计为永久运行,并且经常通过发送它们来停止 中断信号。但是有一种优雅地停止服务器的方法 有时很有用,尤其是在测试环境中。Microdot提供了一种可以调用``的方法 在处理路由期间,当 请求完成。下一个示例演示如何使用此功能:

    @app.get('/shutdown')
    def shutdown(request):
        request.app.shutdown()
        return 'The server is shutting down...'
    

    请求对象

    对象``封装所有信息 由客户端传递。它作为参数传递给路由处理程序,以及 到 请求之前、请求之后和错误处理程序。

    请求属性

    请求对象提供对请求属性的访问,包括:

  • method: 请求的 HTTP 方法.
  • path: 请求的路径.
  • args: The query string parameters of the request, as a MultiDict object.
  • headers: The headers of the request, as a dictionary.
  • cookies: The cookies that the client sent with the request, as a dictionary.
  • content_type: The content type specified by the client, or None if no content type was specified.
  • content_length: The content length of the request, or 0 if no content length was specified.
  • client_addr: The network address of the client, as a tuple (host, port).
  • app: The application instance that created the request.
  • JSON 有效负载

    当客户端发送正文中包含 JSON 数据的请求时, 应用程序可以使用该``属性访问解析的 JSON 数据。以下示例演示如何 要使用此属性:

    @app.post('/customers')
    def create_customer(request):
        customer = request.json
        # do something with customer
        return {'success': True}
    

    注意

    客户端必须将标头设置为 要填充的请求对象的属性。Content-Type``application/json``json

    网址编码的表单数据

    请求对象还支持通过属性提交](https://microdot.readthedocs.io/en/latest/api.html#microdot.Request.form)标准 HTML 表单,该属性显示表单数据 作为[对象。例:

    @app.route('/', methods=['GET', 'POST'])
    def index(req):
        name = 'Unknown'
        if req.method == 'POST':
            name = req.form.get('name')
        return f'Hello {name}'
    

    注意

    仅当标头由 客户端到 。表单提交使用 当前不支持内容类型。Content-Type``application/x-www-form-urlencoded``multipart/form-data

    访问原始请求正文

    对于既不需要 JSON 数据也不需要表单数据的情况,``request 属性返回整个正文 作为字节序列的请求。

    如果预期的正文太大而无法放入内存,则应用程序可以使用``请求属性来读取正文 内容作为类似文件的对象。

    Cookies

    客户端发送的 Cookie 通过请求对象的属性提供`` 字典形式。

    “g”对象

    有时应用程序需要在请求的生存期内存储数据,因此 它可以在请求处理程序之前或之后与 路由功能。请求对象提供用于此目的的属性``。

    在以下示例中,请求处理程序之前 授权客户端并存储用户名,以便路由函数可以 使用它:

    @app.before_request
    def authorize(request):
        username = authenticate_user(request)
        if not username:
            return 'Unauthorized', 401
        request.g.username = username
    
    @app.get('/')
    def index(request):
        return f'Hello, {request.g.username}!'
    

    特定于请求的后请求处理程序

    有时应用程序需要对响应对象执行操作, 在发送到客户端之前,例如设置或删除 cookie。一个好的 用于此选项的选项是定义特定于请求的请求处理程序 使用``装饰器。 在路由后由 Microdot 调用请求处理程序后特定于请求 函数返回和所有应用程序的后请求处理程序 叫。

    下一个示例演示如何使用特定于请求的 Cookie 进行更新 在路由函数中定义的请求处理程序之后:

    @app.post('/logout')
    def logout(request):
        @request.after_request
        def reset_session(request, response):
            response.set_cookie('session', '', http_only=True)
            return response
    
        return 'Logged out'
    

    请求限制

    为了帮助防止恶意攻击,Microdot 提供了一些配置选项 要限制接受的信息量,请执行以下操作:

  • max_content_length:这 请求正文接受的最大大小(以字节为单位)。当客户端发送 大于此值的请求,服务器将以 413 错误进行响应。 默认值为 16KB。
  • max_body_length:最大值 在属性中](https://microdot.readthedocs.io/en/latest/api.html#microdot.Request.body)加载的大小,在 字节。正文大于此大小但更小的请求 比设置的大小只能通过属性[访问。默认值也是 16KB。max_content_length
  • max_readline:允许的最大值 请求行的大小(以字节为单位)。默认值为 2KB。
  • 以下示例将应用程序配置为接受请求 最大 1MB 的有效负载,但可防止大于 8KB 的请求 正在加载到内存中:

    Request.max_content_length = 1024 * 1024
    Request.max_body_length = 8 * 1024
    

    反应

    从路由函数返回的一个或多个值由 Microdot,用于构建发送到客户端的响应。以下 部分介绍支持的不同类型的响应。

    响应的三个部分

    路由函数可以返回一个、两个或三个值。第一个或唯一的值是 始终在响应正文中返回到客户端:

    @app.get('/')
    def index(request):
        return 'Hello, World!'
    

    在上面的示例中,Microdot 发出标准 200 状态代码响应,并且 插入必要的标头。

    应用程序可以提供自己的状态代码作为从 返回的第二个值 路线。下面的示例返回 202 状态代码:

    @app.get('/')
    def index(request):
        return 'Hello, World!', 202
    

    应用程序还可以返回第三个值,一个带有附加值的字典 添加到或替换 Microdot 提供的默认标头的标头。 下一个示例返回 HTML 响应,而不是默认文本响应:

    @app.get('/')
    def index(request):
        return '<h1>Hello, World!</h1>', 202, {'Content-Type': 'text/html'}
    

    如果应用程序需要返回自定义标头,但不需要更改 默认状态代码,然后它可以返回两个值,省略 stauts 法典:

    @app.get('/')
    def index(request):
        return '<h1>Hello, World!</h1>', {'Content-Type': 'text/html'}
    

    应用程序还可以返回对象`` 将响应的所有详细信息作为单个值包含在内。

    JSON 响应

    如果应用程序需要返回包含 JSON 格式数据的响应,它可以 返回字典或列表作为第一个值,Microdot 将 自动将响应格式化为 JSON。

    例:

    @app.get('/')
    def index(request):
        return {'hello': 'world'}
    

    注意

    自动添加设置为 的标头 到响应。Content-Type``application/json

    重 定向

    该``函数是一个帮助程序 创建重定向响应:

    from microdot import redirect
    
    @app.get('/')
    def index(request):
        return redirect('/about')
    

    文件响应

    该``函数构建响应 文件的对象:

    from microdot import send_file
    
    @app.get('/')
    def index(request):
        return send_file('/static/index.html')
    

    可以在参数中将建议的缓存持续时间返回给客户端:max_age

    from microdot import send_file
    
    @app.get('/')
    def image(request):
        return send_file('/static/image.jpg', max_age=3600)  # in seconds
    

    注意

    与其他 Web 框架不同,Microdot 不会自动配置 路由以提供静态文件。以下是可以 添加到应用程序中以从静态目录提供静态文件 该项目:

    @app.route('/static/<path:path>')
    def static(request, path):
        if '..' in path:
            # directory traversal is not allowed
            return 'Not found', 404
        return send_file('static/' + path, max_age=86400)
    

    流式处理响应

    应用程序可以选择 通过返回生成器返回以块形式生成的响应。这 下面的示例返回斐波那契数列中低于 100 的所有数字:

    @app.get('/fibonacci')
    def fibonacci(request):
        def generate_fibonacci():
            a, b = 0, 1
            while a < 100:
                yield str(a) + '\n'
                a, b = b, a + b
    
        return generate_fibonacci()
    

    更改默认响应内容类型

    默认情况下,Microdot 对以下响应使用内容类型: 未显式包含标头。应用程序可以更改 通过在属性中](https://microdot.readthedocs.io/en/latest/api.html#microdot.Response.default_content_type)设置所需的内容类型来默认设置 的[类。text/plain``Content-Type

    下面的示例将应用程序配置为用作 默认内容类型:text/html

    from microdot import Response
    
    Response.default_content_type = 'text/html'
    

    设置cookies

    许多 Web 应用程序依赖于 cookie 来维护客户端之间的状态 请求。可以在响应中使用标头设置 Cookie, 但由于这是一种常见的做法,Microdot 在响应中提供了该方法`` 对象,将格式正确的 Cookie 标头添加到响应中。Set-Cookie

    鉴于路由函数通常不直接与响应一起工作 对象,建议设置 cookie 的方法是在特定于请求的后请求处理程序中执行此操作。

    例:

    @app.get('/')
    def index(request):
        @request.after_request
        def set_cookie(request, response):
            response.set_cookie('name', 'value')
            return response
    
        return 'Hello, World!'
    

    另一种选择是直接在路由函数中创建响应对象:

    @app.get('/')
    def index(request):
        response = Response('Hello, World!')
        response.set_cookie('name', 'value')
        return response
    

    注意

    标准 Cookie 不提供足够的隐私和安全控制,因此 切勿在其中存储敏感信息,除非您要添加其他信息 加密或加密签名等保护机制。会话扩展实现已签名 防止恶意行为者篡改的 Cookie。

    并发

    默认情况下,Microdot 以同步(单线程)模式运行。但是,如果 该模块可用,每个请求都将在 单独的线程和请求将同时处理。threading

    请注意,大多数微控制器板支持非常有限形式的 不适合并发请求处理的多线程。为 因此,不建议在微控制器平台上使用线程模块。

    micropython_asyncio扩展 提供更强大的并发选项,即使在低端也受支持 MicroPython 板。

    核心扩展

    Microdot 是一个高度可扩展的 Web 应用程序框架。扩展 本节中描述的内容作为 Microdot 项目的一部分进行维护,并且 可以从同一源代码存储库获取。

    异步异步支持

    兼容性 CPython & MicroPython
    必需的Microdot源文件 microdot.pymicrodot_asyncio.py
    所需的外部依赖项 CPython:无MicroPython: uasyncio
    例子 hello_async.py

    Microdot 可以扩展为使用基于包的异步编程模型。从包中导入[类时,异步服务器](https://microdot.readthedocs.io/en/latest/api.html#microdot_asyncio.Microdot) ,处理程序可以定义为协程。`asynciomicrodot_asyncio`

    下面的示例使用协程进行并发:asyncio

    from microdot_asyncio import Microdot
    
    app = Microdot()
    
    @app.route('/')
    async def hello(request):
        return 'Hello, world!'
    
    app.run()
    

    呈现 HTML 模板

    许多 Web 应用程序使用 HTML 模板将内容呈现给客户端。 Microdot 包括使用 CPython 上的 utemplate 包渲染模板的扩展,以及 MicroPython,并且仅在 Jinja 上 CPython。

    使用 u模板引擎

    兼容性 CPython & MicroPython
    必需的Microdot源文件 microdot.pymicrodot_utemplate.py
    所需的外部依赖项 utemplate
    例子 hello.pyhello_utemplate_async.py

    函数是`` 用于使用 uTemplate 引擎呈现 HTML 模板。第一个参数是 相对于模板目录的模板文件名,默认情况下为模板。任何其他参数都将传递到模板 引擎用作参数。

    例:

    from microdot_utemplate import render_template
    
    @app.get('/')
    def index(req):
        return render_template('index.html')
    

    加载模板的默认位置是模板子目录。可以使用以下``函数更改此位置:

    from microdot_utemplate import init_templates
    
    init_templates('my_templates')
    

    使用金贾引擎

    兼容性 仅限CPython
    必需的Microdot源文件 microdot.pymicrodot_jinja.py
    所需的外部依赖项 金贾2
    例子 hello.py

    使用``该功能 使用 Jinja 引擎渲染 HTML 模板。第一个参数是 模板文件名,相对于模板目录,即模板由 违约。任何其他参数都将传递到要使用的模板引擎 作为参数。

    例:

    from microdot_jinja import render_template
    
    @app.get('/')
    def index(req):
        return render_template('index.html')
    

    加载模板的默认位置是模板子目录。可以使用以下``函数更改此位置:

    from microdot_jinja import init_templates
    
    init_templates('my_templates')
    

    注意

    Jinja扩展与MicroPython不兼容。

    维护安全的用户会话

    兼容性 CPython & MicroPython
    必需的Microdot源文件 microdot.pymicrodot_session.py
    所需的外部依赖项 CPython: PyJWTMicroPython: jwt.py, hmac
    例子 login.py

    会话扩展为应用程序提供了一种安全的方式来维护 用户会话。会话作为签名的 cookie 存储在客户端的 浏览器,采用 JSON Web 令牌 (JWT) 格式。

    要使用用户会话,应用程序首先必须配置密钥 这将用于对会话 Cookie 进行签名。非常重要的是,这 密钥是保密的。拥有此密钥的攻击者可以生成 包含任何内容的有效用户会话 Cookie。

    要设置密钥,请使用以下函数:set_session_secret_key

    from microdot_session import set_session_secret_key
    
    set_session_secret_key('top-secret!')
    

    使用 to 和函数 在路由处理程序中分别检索、存储和删除会话数据。 提供装饰器 作为在路由处理程序开始时检索会话的便捷方法。get_session``update_session``delete_session``with_session

    例:

    from microdot import Microdot
    from microdot_session import set_session_secret_key, with_session, \
        update_session, delete_session
    
    app = Microdot()
    set_session_secret_key('top-secret')
    
    @app.route('/', methods=['GET', 'POST'])
    @with_session
    def index(req, session):
        username = session.get('username')
        if req.method == 'POST':
            username = req.form.get('username')
            update_session(req, {'username': username})
            return redirect('/')
        if username is None:
            return 'Not logged in'
        else:
            return 'Logged in as ' + username
    
    @app.post('/logout')
    def logout(req):
        delete_session(req)
        return redirect('/')
    

    跨域资源共享

    兼容性 CPython & MicroPython
    必需的Microdot源文件 microdot.pymicrodot_cors.py
    所需的外部依赖项 没有
    例子 cors.py

    CORS 扩展支持跨域资源共享 (科尔斯)。CORS是一个 允许在不同源上运行的 Web 应用程序访问的机制 彼此的资源。例如,在 上运行的 Web 应用程序可以从 访问 中的资源。https://example.com``https://api.example.com

    若要启用 CORS 支持,请创建类的``实例并配置所需的选项。 例:

    from microdot import Microdot
    from microdot_cors import CORS
    
    app = Microdot()
    cors = CORS(app, allowed_origins=['https://example.com'],
                allow_credentials=True)
    

    网络套接字支持

    兼容性 CPython & MicroPython
    必需的Microdot源文件 microdot.pymicrodot_websocket.py
    所需的外部依赖项 没有
    例子 echo.pyecho_wsgi.py

    WebSocket 扩展为应用程序提供了一种处理 WebSocket 的方法 请求。[](https://microdot.readthedocs.io/en/latest/api.html#microdot_websocket.with_websocket)装饰者 用于将路由处理程序标记为 WebSocket 处理程序。处理程序接收 一个 WebSocket 对象作为第二个参数。WebSocket 对象分别提供发送和接收消息的 和 方法。`send()receive()`

    例:

    @app.route('/echo')
    @with_websocket
    def echo(request, ws):
        while True:
            message = ws.receive()
            ws.send(message)
    

    注意

    不受支持的microdot_websocket_alt.py模块,具有相同的 接口,也提供了。此模块使用本机 WebSocket 支持 在MicroPython中,它为WebREPL提供支持,并且可能会提供更好的 MicroPython 低端板的性能。此模块不兼容 与CPython。

    异步网络套接字

    兼容性 CPython & MicroPython
    必需的Microdot源文件 microdot.pymicrodot_asyncio.pymicrodot_websocket.pymicrodot_asyncio_websocket.py
    所需的外部依赖项 CPython:无MicroPython: uasyncio
    例子 echo_async.py

    此扩展与同步 WebSocket 扩展具有相同的接口, 但 AND 方法是异步的。receive()``send()

    注意

    不受支持的microdot_asgi_websocket.py模块,具有相同的 接口,也提供了。使用 ASGI 支持时,必须使用此模块而不是microdot_asyncio_websocket.py。echo_asgi.py示例演示如何使用此模块。

    HTTPS 支持

    兼容性 CPython & MicroPython
    必需的Microdot源文件 microdot.pymicrodot_ssl.py
    例子 hello_tls.pyhello_async_tls.py

    该函数接受一个可选参数,通过该参数 可以传递初始化的对象。MicroPython 目前没有 有一个实现,所以模块提供 可用于创建上下文的基本实现。run()``ssl``SSLContext``SSLContext``microdot_ssl

    例:

    from microdot import Microdot
    from microdot_ssl import create_ssl_context
    
    app = Microdot()
    
    @app.route('/')
    def index(req):
        return 'Hello, World!'
    
    sslctx = create_ssl_context('cert.der', 'key.der')
    app.run(port=4443, debug=True, ssl=sslctx)
    

    注意

    该模块仅适用于MicroPython。在以下情况下使用时 CPython,此模块创建一个标准实例。microdot_ssl``SSLContext

    注意

    MicroPython 的库目前不支持 TLS,因此 此功能不适用于该上的异步应用程序 平台。完全支持 CPython 的库。uasyncio``asyncio

    测试客户端

    兼容性 CPython & MicroPython
    必需的Microdot源文件 microdot.pymicrodot_test_client.py
    所需的外部依赖项 没有

    Microdot 测试客户端是一个实用程序类,可在测试期间用于 将请求发送到应用程序中。

    例:

    from microdot import Microdot
    from microdot_test_client import TestClient
    
    app = Microdot()
    
    @app.route('/')
    def index(req):
        return 'Hello, World!'
    
    def test_app():
        client = TestClient(app)
        response = client.get('/')
        assert response.text == 'Hello, World!'
    

    有关更多详细信息,请参阅该``类的文档。

    异步测试客户端

    兼容性 CPython & MicroPython
    必需的Microdot源文件 microdot.pymicrodot_asyncio.pymicrodot_test_client.pymicrodot_asyncio_test_client.py
    所需的外部依赖项 没有

    与``类相似 以上,但用于异步应用程序。

    用法示例:

    from microdot_asyncio_test_client import TestClient
    
    async def test_app():
        client = TestClient(app)
        response = await client.get('/')
        assert response.text == 'Hello, World!'
    

    有关详细信息,请参阅 。``

    在生产 Web 服务器上部署

    该类创建自己的简单 Web 服务器。这足以让 使用MicroPython部署的应用程序,但是当使用CPython时,它可能很有用 使用单独的、经过实战考验的 Web 服务器。为了满足这一需求,Microdot 提供实现 WSGI 和 ASGI 协议的扩展。Microdot

    使用 WSGI Web 服务器

    兼容性 仅限CPython
    必需的Microdot源文件 microdot.pymicrodot_wsgi.py
    所需的外部依赖项 WSGI Web 服务器,例如 Gunicorn。
    例子 hello_wsgi.py

    该模块提供了一个扩展类 实现WSGI协议,可以与兼容的WSGI网络服务器一起使用 比如Gunicorn或uWSGI。microdot_wsgi``Microdot

    要使用 WSGI Web 服务器,应用程序必须从模块导入``类:microdot_wsgi

    from microdot_wsgi import Microdot
    
    app = Microdot()
    
    @app.route('/')
    def index(req):
        return 'Hello, World!'
    

    从此类创建的应用程序实例是 WSGI 应用程序 可以与任何投诉WSGI网络服务器一起使用。如果上述应用 存储在名为 test.py 的文件中,则以下命令运行 使用Gunicorn Web服务器的Web应用程序:app

    gunicorn test:app
    

    使用 ASGI 网络服务器

    兼容性 仅限CPython
    必需的Microdot源文件 microdot.pymicrodot_asyncio.pymicrodot_asgi.py
    所需的外部依赖项 一个 ASGI Web 服务器,例如 Uvicorn。
    例子 hello_asgi.py

    该模块提供了一个扩展类 实现 ASGI 协议,并可与兼容的 ASGI 服务器一起使用,例如 作为Uvicorn。microdot_asgi``Microdot

    要使用 ASGI Web 服务器,应用程序必须从模块导入``类:microdot_asgi

    from microdot_asgi import Microdot
    
    app = Microdot()
    
    @app.route('/')
    async def index(req):
        return 'Hello, World!'
    

    从此类创建的应用程序实例是 ASGI 应用程序 可以与任何投诉的ASGI网络服务器一起使用。如果上述应用 存储在名为 test.py 的文件中,则以下命令运行 使用 Uvicorn Web 服务器的 Web 应用程序:app

    uvicorn test:app
    

    [API 参考](API Reference — Microdot documentation)

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用Microdot在Micropython中构建物联网Web服务器

    发表评论