{"id":13541950,"url":"https://github.com/jczic/MicroWebSrv2","last_synced_at":"2025-04-02T09:33:08.226Z","repository":{"id":38714769,"uuid":"213262747","full_name":"jczic/MicroWebSrv2","owner":"jczic","description":"The last Micro Web Server for IoTs (MicroPython) or large servers (CPython), that supports WebSockets, routes, template engine and with really optimized architecture (mem allocations, async I/Os). Ready for ESP32, STM32 on Pyboard, Pycom's chipsets (WiPy, LoPy, ...). Robust, efficient and documented!","archived":false,"fork":false,"pushed_at":"2024-04-02T21:45:20.000Z","size":1068,"stargazers_count":661,"open_issues_count":54,"forks_count":97,"subscribers_count":29,"default_branch":"master","last_synced_at":"2024-10-11T13:23:05.652Z","etag":null,"topics":["async","asynchronous","cors","esp32","hc2","http","https","iot","micropython","microwebsrv","pyboard","pycom","routes","ssl","template-engine","web-server","websocket","websocket-server","websockets","wipy"],"latest_commit_sha":null,"homepage":"https://github.com/jczic/MicroWebSrv2","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jczic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-07T00:01:34.000Z","updated_at":"2024-10-11T07:15:16.000Z","dependencies_parsed_at":"2023-12-21T02:35:28.877Z","dependency_job_id":"13b418d1-cae9-4811-b41c-f3c2c45369ff","html_url":"https://github.com/jczic/MicroWebSrv2","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jczic%2FMicroWebSrv2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jczic%2FMicroWebSrv2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jczic%2FMicroWebSrv2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jczic%2FMicroWebSrv2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jczic","download_url":"https://codeload.github.com/jczic/MicroWebSrv2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222818707,"owners_count":17042228,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","asynchronous","cors","esp32","hc2","http","https","iot","micropython","microwebsrv","pyboard","pycom","routes","ssl","template-engine","web-server","websocket","websocket-server","websockets","wipy"],"created_at":"2024-08-01T10:00:59.273Z","updated_at":"2024-11-03T07:31:29.613Z","avatar_url":"https://github.com/jczic.png","language":"Python","funding_links":[],"categories":["Libraries","Frameworks for Micropython"],"sub_categories":["Communications","Others","More"],"readme":" \n\u003ch3\u003e\n  \u003cp align=\"center\"\u003e\n    Also check out the new ESP32 MPY-Jama free IDE below:\n  \u003c/p\u003e\n\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/jczic/ESP32-MPY-Jama\"\u003e\u003cimg src=\"https://github.com/jczic/ESP32-MPY-Jama/raw/master/img/ESP32%20MPY-Jama%20NEW.png\" alt=\"New microWebSrv2\" width=\"350\" valign=\"middle\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n![Release](https://img.shields.io/github/v/release/jczic/microwebsrv2?include_prereleases\u0026color=success)\n![Size](https://img.shields.io/github/languages/code-size/jczic/microwebsrv2?color=blue)\n![MicroPython](https://img.shields.io/badge/micropython-Ok-green.svg)\n![Python](https://img.shields.io/badge/python-Ok-green.svg)\n![License](https://img.shields.io/github/license/jczic/microwebsrv2?color=yellow)\n\n\u003cbr /\u003e\n\n**MicroWebSrv2** is the new powerful embedded Web Server for **MicroPython** and **CPython** that supports **route handlers**, modules like **WebSockets** or **PyhtmlTemplate** and a **lot of simultaneous requests** (in thousands!).\n\n**Fully asynchronous**, its connections and memory management are **very optimized** and **truly fast**.\n\nMostly used on **Pycom WiPy**, **ESP32**, **STM32** on **Pyboard**, ... **Robust** and **efficient**! (see [Features](#features))\n\n#### :small_orange_diamond: [Download the latest version (Zip)](https://github.com/jczic/MicroWebSrv2/archive/master.zip)\n\n\u003cbr /\u003e\n\n---\n\n```vhdl\n                _               __    __     _     __            ____  \n      _ __ ___ (_) ___ _ __ ___/ / /\\ \\ \\___| |__ / _\\_ ____   _|___ \\ \n     | '_ ` _ \\| |/ __| '__/ _ \\ \\/  \\/ / _ | '_ \\\\ \\| '__\\ \\ / / __) |\n     | | | | | | | (__| | | (_) \\  /\\  |  __| |_) _\\ | |   \\ V / / __/ \n     |_| |_| |_|_|\\___|_|  \\___/ \\/  \\/ \\___|_.__/\\__|_|    \\_/ |_____|  JC`zic \u0026 HC²\n\n\n```\n\n---\n\n\u003cbr /\u003e\n\n# :bookmark_tabs: \u0026nbsp;Table of contents\n\n- [**About**](#about)\n- [**Features**](#features)\n- [**Install**](#install)\n- [**Demo**](#demo)\n- [**Usage**](#usage)\n- [**Documentation**](#documentation)\n  - [**MicroWebSrv2 package**](#mws2-package)\n  - [**Working with microWebSrv2**](#working-with-mws2)\n    - [Asynchronous logic](#async-logic)\n    - [Configuring web server](#config-web-srv)\n      - [Default pages](#default-pages)\n      - [MIME types](#mime-types)\n    - [Starting web server](#start-web-srv)\n    - [Handling web routes](#handling-routes)\n    - [SSL/TLS security (HTTPS)](#ssl-security)\n  - [**About XAsyncSockets layer**](#xasyncsockets)\n  - [**MicroWebSrv2 Class**](#mws2-class)\n    - [Static Methods](#mws2-static-func)\n    - [Instance Methods](#mws2-func)\n    - [Properties](#mws2-prop)\n  - [**Web Routes**](#web-routes)\n    - [Route Processing](#route-process)\n    - [Route Arguments](#route-args)\n    - [Route Methods](#route-func)\n  - [**HttpRequest Class**](#request-class)\n    - [Instance Methods](#request-func)\n    - [Properties](#request-prop)\n  - [**HttpResponse Class**](#response-class)\n    - [Instance Methods](#response-func)\n    - [Properties](#response-prop)\n  - [**Additional modules**](#modules)\n    - [**WebSockets Module**](#websockets-mod)\n      - [Properties](#websockets-mod-prop)\n      - [WebSocket Class](#websocket-class)\n        - [Instance Methods](#websocket-func)\n        - [Properties](#websocket-prop)\n    - [**PyhtmlTemplate Module**](#pyhtmltemplate-mod)\n      - [Instance Methods](#pyhtmltemplate-func)\n      - [Properties](#pyhtmltemplate-prop)\n- [**Author**](#author)\n- [**License**](#license)\n\n---\n\n\u003ca name=\"about\"\u003e\u003c/a\u003e\n# :anger: \u0026nbsp;About\n\nThis project follows the embedded [MicroWebSrv](https://github.com/jczic/MicroWebSrv),\nwhich is mainly used on microcontrollers such as Pycom, ESP32 and STM32 on Pyboards.\n\nIn a need for scalability and to meet the IoT universe, **microWebSrv2** was developed as a new project\nand has been completely redesigned to be much more robust and efficient that its predecessor.\n\nInternal mechanisms works **directly at I/O level**, are fully asynchronous from end to end, and manages the memory in a highly optimized way.  \nAlso, architecture makes its integration very easy and the source code, **MIT licensed**, remains really small.\n\n---\n\n\u003ca name=\"features\"\u003e\u003c/a\u003e\n# :rocket: \u0026nbsp;Features\n\n- Embed **microWebSrv2** into your microcontrollers as a **powerful web server**.\n\n- Benefit from a fully **asynchronous architecture** that allows to process many **concurrent requests** very quickly.\n\n- Use multiple worker threads to **parallelize simultaneous processes**.\n\n- Adjust settings to **fine-tune resources usage** and sizing pre-allocated memory.\n\n- Load **additional modules** to extend the server's functionalities.\n\n- Customize the management of **centralized logs**.\n\n- Apply **SSL/TLS security layer** and certificate on web connections (https mode).\n\n- Define **web routes** with variable arguments in order to be able to process the targeted requests.\n\n- Receive any type of request such as ```GET```, ```HEAD```, ```POST```, ```PUT```, ```DELETE```, ```OPTIONS```, ```PATCH```, ...\n\n- Use the **route resolver** (from the path) and the **path builder** (from the route) for convenience.\n\n- Increase loading speed by automatically allowing web clients to **cache static files**.\n\n- Receive name/value pairs from **URL encoded forms**.\n\n- Send and receive **JSON** objects and use them to create a **RESTful API** style.\n\n- Play with **AjAX** requests to interact quickly with a web application.\n\n- Define the **origin** of resources and allow all values of **CORS** pre-flight requests.\n\n- Verify that a request is successfully **authenticated** by the **Basic** or **Bearer** method.\n\n- Reduce the number of persistent connections per web client with **keep-alive mode** support.\n\n- Respond to a request by using a **data stream** as content, sent with known length or in **chunked transfer-encoding**.\n\n- Use a file to respond to a request that will be treated as **on-the-fly content** or as an **attachment to download**.\n\n- Take advantage of the **WebSockets module** to exchange messages in real time via **WS or secured WSS** connection.\n\n- Create **.pyhtml pages** for an HTML rendering with integrated Python using the **PyhtmlTemplate module**.\n\n---\n\n\u003ca name=\"install\"\u003e\u003c/a\u003e\n# :electric_plug: \u0026nbsp;Install\n\n- **Solution 1** Run:\n\n```sh\n    pip3 install --user git+https://github.com/jczic/MicroWebSrv2.git#egg=MicroWebSrv2\n```\n\n- **Solution 2**, clone the [GitHub repository](https://github.com/jczic/MicroWebSrv2.git) from the terminal:\n\n```sh\n    git clone https://github.com/jczic/MicroWebSrv2.git\n```\n        and run:\n\n```sh\n    cd MicroWebSrv2 \u0026\u0026 pip install --user .\n```\n\n- **Solution 3**, download the [ZIP file](https://github.com/jczic/MicroWebSrv2/archive/master.zip) and extract it to a folder of your choice.\n\n---\n\n\u003ca name=\"demo\"\u003e\u003c/a\u003e\n# :vertical_traffic_light: \u0026nbsp;Demo\n\n1. **Start the example:**\n    ```sh\n    \u003e python3 main.py\n    ```\n    \n2. **Open your web browser at:**\n    - [http://localhost](http://localhost) to view the main page\n    - [http://localhost/test-redir](http://localhost/test-redir) to test a redirection\n    - [http://localhost/test-post](http://localhost/test-post) to test a POST form\n    - [http://localhost/wstest.html](http://localhost/wstest.html) to test the WebSockets page\n    - [http://localhost/wschat.html](http://localhost/wschat.html) to test the multi-users chat page\n    - [http://localhost/test.pyhtml](http://localhost/test.pyhtml) to test a pyhtml template page\n\n![WebSockets Chat](/img/wschat.png \"WebSockets Chat\")\n\n---\n\n\u003ca name=\"usage\"\u003e\u003c/a\u003e\n# :gear: \u0026nbsp;Usage\n\n```python\nfrom MicroWebSrv2 import *\nfrom time         import sleep\n\nmws2 = MicroWebSrv2()\nmws2.StartManaged()\n\n# Main program loop until keyboard interrupt,\ntry :\n    while True :\n        sleep(1)\nexcept KeyboardInterrupt :\n    mws2.Stop()\n```\n\n---\n\n\u003ca name=\"documentation\"\u003e\u003c/a\u003e\n# :books: \u0026nbsp;Documentation\n\n  \u003ca name=\"mws2-package\"\u003e\u003c/a\u003e\n  - ## MicroWebSrv2 package\n\n    The Python package comes with the following files:\n      - :small_red_triangle_down: **/MicroWebSrv2**\n        - :small_orange_diamond: \\_\\_init\\_\\_.py\n        - :small_orange_diamond: microWebSrv2.py\n        - :small_orange_diamond: webRoute.py\n        - :small_orange_diamond: httpRequest.py\n        - :small_orange_diamond: httpResponse.py\n        - :small_blue_diamond: **/libs**\n          - :small_orange_diamond: XAsyncSockets.py\n          - :small_orange_diamond: urlUtils.py\n        - :small_blue_diamond: **/mods**\n          - :small_orange_diamond: WebSockets.py\n          - :small_orange_diamond: PyhtmlTemplate.py\n\n    ---\n\n  \u003ca name=\"working-with-mws2\"\u003e\u003c/a\u003e\n  - ## Working with microWebSrv2\n\n    To work with **microWebSrv2**, you must first import the package as follows:\n    ```python\n    from MicroWebSrv2 import *\n    ```\n\n    There are 5 main elements with which you will work:\n      - Web server (see [MicroWebSrv2 class](#mws2-class))\n      - Routes (see [Web routes](#web-routes))\n      - Requests (see [HttpRequest class](#request-class))\n      - Responses (see [HttpResponse class](#response-class))\n      - Modules (see [Additional modules](#modules))\n\n    Now, you have everything you need to continue :sunglasses:\n\n    ---\n\n    \u003ca name=\"async-logic\"\u003e\u003c/a\u003e\n    - ### Asynchronous logic\n\n      **microWebSrv2** is based on a fully asynchronous I/Os logic.\n\n      This means that many requests and responses can be processed concurrently,\n      allowing other necessary processing at any time within a single thread.\n\n      In addition, it is possible to use several shared workers in order to\n      be able to parallelize processes that could be blocking.\n\n      Finally, memory buffers required for data processing are pre-allocated\n      as best as possible to maximize performance and prevent excessive memory requirements.\n\n      Thus, it is possible to maintain several thousand persistent connections but also,\n      to benefit from a low consumption of resources on embedded platforms.\n\n      \u003e **microWebSrv2** leans on the [XAsyncSockets](#xasyncsockets) layer.\n\n      ---\n\n    \u003ca name=\"config-web-srv\"\u003e\u003c/a\u003e\n    - ### Configuring web server\n\n      Before starting **microWebSrv2** to listen to web requests, it is important to configure it correctly.\n\n        - If you want to change the default server port or bind IP address, you must set the **BindAddress** property.\n          ```python\n          mws2.BindAddress = ('192.168.0.1', 12345)\n          ```\n\n        - If you want to define an another directory for web files, you must set the **RootPath** property.\n          ```python\n          mws2.RootPath = 'webfiles/root'\n          ```\n\n        - If you want a secure https web server, you must call the [**EnableSSL**](#mws2-enablessl) method.\n          ```python\n          mws2.EnableSSL(certFile='certificate.crt', keyFile='private-key.key')\n          ```\n\n        - If you want to redirect resources not found, you must set the **NotFoundURL** property.\n          ```python\n          mws2.NotFoundURL = '/'   # relative or absolute URL\n          ```\n\n        - If you want to set a pre-configured setting, you can call one of the following methods:\n            - [SetEmbeddedConfig](#mws2-setembeddedconfig)\n            - [SetLightConfig](#mws2-setlightconfig)\n            - [SetNormalConfig](#mws2-setnormalconfig) (default setting)\n            - [SetLargeConfig](#mws2-setlargeconfig)\n\n        - If you want to set your custom settings, you can adjust the following properties:\n            - [ConnQueueCapacity](#mws2-prop)\n            - [BufferSlotsCount](#mws2-prop)\n            - [BufferSlotSize](#mws2-prop)\n            - [KeepAllocBufferSlots](#mws2-prop)\n            - [MaxRequestContentLength](#mws2-prop)\n\n        - If you want to change the default timeout to wait for requests data, you must set the **RequestsTimeoutSec** property.\n          ```python\n          mws2.RequestsTimeoutSec = 10\n          ```\n\n        - If you want to intercept logs to process them, you must set the [**OnLogging**](#mws2-onlogging) callback.\n          ```python\n          def OnMWS2Logging(microWebSrv2, msg, msgType) :\n              print('Log from custom function: %s' % msg)\n\n          mws2.OnLogging = OnMWS2Logging\n          ```\n\n      ---\n\n      \u003ca name=\"default-pages\"\u003e\u003c/a\u003e\n      - ### Default pages\n\n        Default pages are used as resources when requested paths point to directories.\n\n        | Page filename |\n        |---------------|\n        | index.html    |\n        | index.htm     |\n        | default.html  |\n        | default.htm   |\n\n        \u003e It is possible to add new default pages globally by calling [**MicroWebSrv2.AddDefaultPage**](#mws2-adddefaultpage) static method.\n\n        ---\n\n      \u003ca name=\"mime-types\"\u003e\u003c/a\u003e\n      - ### MIME types\n\n        MIME types allow specific files as readable resources and that are transmitted with the corresponding content type.\n\n        | Filename extension | MIME type |\n        |--------------------|------------------------|\n        | .txt               | text/plain             |\n        | .htm               | text/html              |\n        | .html              | text/html              |\n        | .css               | text/css               |\n        | .csv               | text/csv               |\n        | .js                | application/javascript |\n        | .xml               | application/xml        |\n        | .xhtml             | application/xhtml+xml  |\n        | .json              | application/json       |\n        | .zip               | application/zip        |\n        | .pdf               | application/pdf        |\n        | .ts                | application/typescript |\n        | .woff              | font/woff              |\n        | .woff2             | font/woff2             |\n        | .ttf               | font/ttf               |\n        | .otf               | font/otf               |\n        | .jpg               | image/jpeg             |\n        | .jpeg              | image/jpeg             |\n        | .png               | image/png              |\n        | .gif               | image/gif              |\n        | .svg               | image/svg+xml          |\n        | .ico               | image/x-icon           |\n\n        \u003e It is possible to add new MIME types globally by calling [**MicroWebSrv2.AddMimeType**](#mws2-addmimetype) static method.\n\n      ---\n\n    \u003ca name=\"start-web-srv\"\u003e\u003c/a\u003e\n    - ### Starting web server\n\n      To start **microWebSrv2** server, you must use one of the following methods:\n\n        - **Start in a pool:**  \n          The web server uses an existing asynchronous pool.  \n          If you want to have more than one server, this is the right solution.  \n          \u003e For more documentation, see [**StartInPool(...)**](#mws2-startinpool) method.  \n          \u003e If you want details about pools, check the GitHub repository of [XAsyncSockets](https://github.com/jczic/XAsyncSockets) library.\n\n        - **Start in a managed pool:**  \n          The web server automatically creates a new managed asynchronous pool and uses it.  \n          If you only need one server without more specific code, this is the right solution.  \n          However, you will need to define some pool sizing parameters.  \n          In this mode, a call to ```mws2.Stop()``` will release the pool.  \n          \u003e For more documentation, see [**StartManaged(...)**](#mws2-startmanaged) method.\n\n      :cyclone: Example to start a dual http/https web server:\n      ```python\n      from MicroWebSrv2 import *\n      from time         import sleep\n\n      xasPool  = XAsyncSocketsPool()\n      srvHttp  = MicroWebSrv2()\n      srvHttps = MicroWebSrv2()\n\n      srvHttps.EnableSSL( certFile = 'SSL-Cert/openhc2.crt',\n                          keyFile  = 'SSL-Cert/openhc2.key' )\n\n      srvHttp .StartInPool(xasPool)\n      srvHttps.StartInPool(xasPool)\n      \n      xasPool.AsyncWaitEvents(threadsCount=1)\n\n      try :\n          while True :\n              sleep(1)\n      except KeyboardInterrupt :\n          srvHttp .Stop()\n          srvHttps.Stop()\n          xasPool .StopWaitEvents()\n      ```\n\n      ---\n\n    \u003ca name=\"handling-routes\"\u003e\u003c/a\u003e\n    - ### Handling web routes\n\n      **microWebSrv2** have an easy and efficient web route system.  \n      A simple handler function with a decorator allows you to process requests.\n\n      :cyclone: Example of a processing handler:\n      ```python\n      @WebRoute(GET, '/test')\n      def RequestTest(microWebSrv2, request) :\n          request.Response.ReturnOkJSON({\n              'ClientAddr' : request.UserAddress,\n              'Accept'     : request.Accept,\n              'UserAgent'  : request.UserAgent\n          })\n      ```\n      \u003e For more documentation, see [**Web Routes**](#web-routes) section.\n\n      ---\n\n    \u003ca name=\"ssl-security\"\u003e\u003c/a\u003e\n    - ### SSL/TLS security (HTTPS)\n\n      **microWebSrv2** allow web server to apply the SSL/TLS security layer.  \n      In this case, a certificate and its private key must be given (with an optional PEM file).\n\n      If you want to test https mode, uncomment the ```mws2.EnableSSL(...)``` call in ```main.py``` file.  \n      After restarting the demo program, open your browser at the following address:  \n      [https://localhost](https://localhost)\n\n      :warning: The **ssl library** must be implements ```SSLContext``` on Python version to support secured web server.\n\n    ---\n\n  \u003ca name=\"xasyncsockets\"\u003e\u003c/a\u003e\n  - ## About XAsyncSockets layer\n\n    **XAsyncSockets** is an efficient Python/MicroPython library of managed asynchronous sockets.  \n    \u003e Available under MIT license on GitHub (same author):  \n      [https://github.com/jczic/XAsyncSockets](https://github.com/jczic/XAsyncSockets)\n\n    **XAsyncSockets** layer provides the following features:\n      - Managed asynchronous sockets in a pool (up to thousands!)\n      - Works directly with I/O to receive and send very quickly\n      - Supports very large number of simultaneous TCP connections\n      - Supports concurrent synchronous processing operations if necessary (threaded)\n      - Implementation of TCP servers\n      - Implementation of TCP clients\n      - Implementation of UDP datagrams (sender and/or receiver)\n      - TCP client can event after a specified size of data or a text line received\n      - Each connections and receivings can waiting during a specified time\n      - The reasons of TCP client closures are returned\n      - Really robust, very fast and easy to use\n      - Compatible with MicroPython implementation (sockets layer, FiFo queue, perf counter)\n\n    ---\n\n  \u003ca name=\"mws2-class\"\u003e\u003c/a\u003e\n  - ## MicroWebSrv2 Class\n\n    **MicroWebSrv2** is the main class and is needed to create an instance of web server:\n    ```python\n    mws2 = MicroWebSrv2()\n    ```\n\n    ---\n\n    \u003ca name=\"mws2-static-func\"\u003e\u003c/a\u003e\n    - ### MicroWebSrv2 static methods\n\n      #### :arrow_forward: MicroWebSrv2.LoadModule(...)\n      ```python\n      @staticmethod\n      def LoadModule(modName)\n      # Loads a global and dedicated module for all instances of MicroWebSrv2.\n      #   - Returns the instantiated class of the module.\n      #     This instance can be used to configure global parameters and callbacks.\n      #   - \u003cmodName\u003e is the name of module and must be a not empty string.\n      # An exception will be raised if an error occurs.\n      ```\n\n      #### :arrow_forward: MicroWebSrv2.HTMLEscape(...)\n      ```python\n      @staticmethod\n      def HTMLEscape(s)\n      # Escapes HTML special characters of a text to use it in HTML code.\n      #   - Returns the escaped string of \u003cs\u003e.\n      #   - \u003cs\u003e is a text that must be escaped and must be a string.\n      # An exception can be raised if \u003cs\u003e is not correct.\n      ```\n\n      \u003ca name=\"mws2-adddefaultpage\"\u003e\u003c/a\u003e\n      #### :arrow_forward: MicroWebSrv2.AddDefaultPage(...)\n      ```python\n      @staticmethod\n      def AddDefaultPage(filename)\n      # Adds a new default page that it can be returned when a directory resource is requested.\n      # Default pages are searched by order in list and file must be found in the directory.\n      # Ex: AddDefaultPage('home.html')\n      #   - No return value.\n      #   - \u003cfilename\u003e is the name of page file that will be searched and must be a not empty string.\n      # An exception can be raised if \u003cfilename\u003e is not correct.\n      ```\n\n      \u003ca name=\"mws2-addmimetype\"\u003e\u003c/a\u003e\n      #### :arrow_forward: MicroWebSrv2.AddMimeType(...)\n      ```python\n      @staticmethod\n      def AddMimeType(ext, mimeType)\n      # Adds a new MIME type to support specified file type and response content type.\n      # Ex: AddMimeType('.tar', 'application/x-tar')\n      #   - No return value.\n      #   - \u003cext\u003e is the file extention including the dot and must be a not empty string.\n      #   - \u003cmimeType\u003e is the name of MIME type and must be a not empty string.\n      # An exception can be raised if arguments are not correct.\n      ```\n\n      #### :arrow_forward: MicroWebSrv2.GetMimeTypeFromFilename(...)\n      ```python\n      @staticmethod\n      def GetMimeTypeFromFilename(filename)\n      # Obtains the name of MIME type corresponding to a filename.\n      #   - Returns the name of MIME type found in string, returns None otherwise.\n      #   - \u003cfilename\u003e is a path to a file and must be a not empty string.\n      ```\n\n      ---\n\n    \u003ca name=\"mws2-func\"\u003e\u003c/a\u003e\n    - ### MicroWebSrv2 instance methods\n\n      \u003ca name=\"mws2-startinpool\"\u003e\u003c/a\u003e\n      #### :arrow_forward: mws2.StartInPool(...)\n      ```python\n      def StartInPool(self, asyncSocketsPool)\n      # Starts the web server in an existing asynchronous pool.\n      #   - No return value.\n      #   - \u003casyncSocketsPool\u003e is the asynchronous pool and must be an instantiated class of XAsyncSocketsPool.\n      # An exception will be raised if an error occurs.\n      ```\n\n      \u003ca name=\"mws2-startmanaged\"\u003e\u003c/a\u003e\n      #### :arrow_forward: mws2.StartManaged(...)\n      ```python\n      def StartManaged(self, parllProcCount=1, procStackSize=0)\n      # Starts the web server in a new and managed asynchronous pool.\n      #   - No return value.\n      #   - \u003cparllProcCount\u003e is the count of parallel processes and must be a positive integer or zero.\n      #   - \u003cprocStackSize\u003e is the stack size for each parallelized processes and must be a positive integer or zero.\n      # If \u003cparllProcCount\u003e is 0, the calling thread is used and blocked to process all http connections.\n      # If \u003cparllProcCount\u003e is 1, only one thread is reserved to process all http connections.\n      # If \u003cparllProcCount\u003e is greater than 1, multiple threads are reserved to share and process all http connections.\n      # If \u003cprocStackSize\u003e  is 0, the default stack size is used on CPython and a value of 8192 is used on MicroPython.\n      # A minimum value of 8*1024 is recommended for \u003cprocStackSize\u003e but on CPython, the minimum value must be of 32*1024.\n      # An exception will be raised if an error occurs.\n      ```\n\n      #### :arrow_forward: mws2.Stop(...)\n      ```python\n      def Stop(self)\n      # Stops the web server.\n      # If the server has started in managed mode, this automatically releases the asynchronous pool.\n      #   - No return value.\n      ```\n\n      #### :arrow_forward: mws2.Log(...)\n      ```python\n      def Log(self, msg, msgType)\n      # Logs the message of the specified type to the output or by calling the OnLogging callback.\n      #   - No return value.\n      #   - \u003cmsg\u003e is the message to log and will be converted to string.\n      #   - \u003cmsgType\u003e can take following values:\n      #      - MicroWebSrv2.DEBUG\n      #      - MicroWebSrv2.INFO\n      #      - MicroWebSrv2.WARNING\n      #      - MicroWebSrv2.ERROR\n      ```\n\n      #### :arrow_forward: mws2.ResolvePhysicalPath(...)\n      ```python\n      def ResolvePhysicalPath(self, urlPath)\n      # Resolves the specified relative URL path to the physical path.\n      #   - Returns the physical path found or None.\n      #   - \u003curlPath\u003e is the relative URL path to resolve and must be a not empty string.\n      # An exception can be raised if \u003curlPath\u003e is not correct.\n      ```\n\n      \u003ca name=\"mws2-enablessl\"\u003e\u003c/a\u003e\n      #### :arrow_forward: mws2.EnableSSL(...)\n      ```python\n      def EnableSSL(self, certFile, keyFile, caFile=None)\n      # Configures the web server to apply the SSL/TLS security layer (https).\n      # Warning, the ssl library must be implements SSLContext on Python version to support secured web server.\n      #   - No return value.\n      #   - \u003ccertFile\u003e is the path of the certificate file and must be a not empty string.\n      #   - \u003ckeyFile\u003e is the path of the private key file and must be a not empty string.\n      #   - \u003ccaFile\u003e is the path of a PEM file and must be a not empty string or None.\n      # If the web server port in BindAddress is 80 (default http), it automatically switches to port 443 (default https).\n      # An exception will be raised if an error occurs.\n      ```\n\n      #### :arrow_forward: mws2.DisableSSL(...)\n      ```python\n      def DisableSSL(self)\n      # Configures the web server as SSL/TLS web server (https).\n      #   - No return value.\n      # If the web server port in BindAddress is 443 (default https), it automatically switches to port 80 (default http).\n      # An exception can be raised if an error occurs.\n      ```\n\n      \u003ca name=\"mws2-setembeddedconfig\"\u003e\u003c/a\u003e\n      #### :arrow_forward: mws2.SetEmbeddedConfig(...)\n      ```python\n      def SetEmbeddedConfig(self)\n      # Configures the web server with optimized parameters for an embedded deployment.\n      #   - No return value.\n      # Parameters set:\n      #   - ConnQueueCapacity       = 8\n      #   - BufferSlotsCount        = 16\n      #   - BufferSlotSize          = 1024\n      #   - KeepAllocBufferSlots    = True\n      #   - MaxRequestContentLength = 16*1024\n      # An exception can be raised if an error occurs.\n      ```\n\n      \u003ca name=\"mws2-setlightconfig\"\u003e\u003c/a\u003e\n      #### :arrow_forward: mws2.SetLightConfig(...)\n      ```python\n      def SetLightConfig(self)\n      # Configures the web server with optimized parameters for a light deployment.\n      #   - No return value.\n      # Parameters set:\n      #   - ConnQueueCapacity       = 64\n      #   - BufferSlotsCount        = 128\n      #   - BufferSlotSize          = 1024\n      #   - KeepAllocBufferSlots    = True\n      #   - MaxRequestContentLength = 512*1024\n      # An exception can be raised if an error occurs.\n      ```\n\n      \u003ca name=\"mws2-setnormalconfig\"\u003e\u003c/a\u003e\n      #### :arrow_forward: mws2.SetNormalConfig(...)\n      ```python\n      def SetNormalConfig(self)\n      # Configures the web server with optimized parameters for a normal deployment.\n      # It is the default configuration when MicroWebSrv2 class is created.\n      #   - No return value.\n      # Parameters set:\n      #   - ConnQueueCapacity       = 256\n      #   - BufferSlotsCount        = 512\n      #   - BufferSlotSize          = 4*1024\n      #   - KeepAllocBufferSlots    = True\n      #   - MaxRequestContentLength = 2*1024*1024\n      # An exception can be raised if an error occurs.\n      ```\n\n      \u003ca name=\"mws2-setlargeconfig\"\u003e\u003c/a\u003e\n      #### :arrow_forward: mws2.SetLargeConfig(...)\n      ```python\n      def SetLargeConfig(self)\n      # Configures the web server with optimized parameters for a large deployment.\n      #   - No return value.\n      # Parameters set:\n      #   - ConnQueueCapacity       = 512\n      #   - BufferSlotsCount        = 2*1024\n      #   - BufferSlotSize          = 16*1024\n      #   - KeepAllocBufferSlots    = True\n      #   - MaxRequestContentLength = 8*1024*1024\n      # An exception can be raised if an error occurs.\n      ```\n\n      ---\n\n    \u003ca name=\"mws2-prop\"\u003e\u003c/a\u003e\n    - ### MicroWebSrv2 properties\n\n      | Name                      |                 Type                |           Get           |           Set           | Description                                                                          |\n      |---------------------------|:-----------------------------------:|:-----------------------:|:-----------------------:|--------------------------------------------------------------------------------------|\n      | `IsRunning`               |                 bool                | :ballot_box_with_check: |            -            | *Indicates that the server is running.*                                              |\n      | `ConnQueueCapacity`       |                 int                 | :ballot_box_with_check: | :ballot_box_with_check: | *Queue capacity of the TCP server (backlog).*                                        |\n      | `BufferSlotsCount`        |                 int                 | :ballot_box_with_check: | :ballot_box_with_check: | *Number of pre-allocated memory buffer slots.*                                       |\n      | `BufferSlotSize`          |                 int                 | :ballot_box_with_check: | :ballot_box_with_check: | *Size of each pre-allocated memory buffer slots.*                                    |\n      | `KeepAllocBufferSlots`    |                 bool                | :ballot_box_with_check: | :ballot_box_with_check: | *Maintains the allocation of memory buffer slots.*                                   |\n      | `MaxRequestContentLength` |                 int                 | :ballot_box_with_check: | :ballot_box_with_check: | *Maximum content length who can be processed by a request.*                          |\n      | `BindAddress`             |                tuple                | :ballot_box_with_check: | :ballot_box_with_check: | *Local bind address of the TCP server such as a tuple of `(str_ip_addr, int_port)`.* |\n      | `IsSSLEnabled`            |                 bool                | :ballot_box_with_check: |            -            | *Indicates that SSL/TLS security layer with certificate is currently enabled.*       |\n      | `RootPath`                |                 str                 | :ballot_box_with_check: | :ballot_box_with_check: | *Path of the root folder that contains the web files.*                               |\n      | `RequestsTimeoutSec`      |                 int                 | :ballot_box_with_check: | :ballot_box_with_check: | *Timeout in seconds to waiting the next data reception of requests.*                 |\n      | `NotFoundURL`             |             str or None             | :ballot_box_with_check: | :ballot_box_with_check: | *URL used to redirects requests not found.*                                          |\n      | `AllowAllOrigins`         |                 bool                | :ballot_box_with_check: | :ballot_box_with_check: | *Indicates that all resource origins of requests are allowed.*                       |\n      | `CORSAllowAll`            |                 bool                | :ballot_box_with_check: | :ballot_box_with_check: | *Allows all CORS values for the pre-flight requests (OPTIONS).*                      |\n      | `OnLogging`               | [callback](#mws2-onlogging) or None | :ballot_box_with_check: | :ballot_box_with_check: | *Callback function when the server logs information.*                                |\n\n      \u003e **Definition of the above callback functions:**\n\n      \u003ca name=\"mws2-onlogging\"\u003e\u003c/a\u003e\n      ```python\n      def OnLogging(microWebSrv2, msg, msgType)\n      # \u003cmicroWebSrv2\u003e is of type MicroWebSrv2\n      # \u003cmsg\u003e is of type str\n      # \u003cmsgType\u003e can take following values:\n      #    - MicroWebSrv2.DEBUG\n      #    - MicroWebSrv2.INFO\n      #    - MicroWebSrv2.WARNING\n      #    - MicroWebSrv2.ERROR\n      ```\n\n    ---\n\n  \u003ca name=\"web-routes\"\u003e\u003c/a\u003e\n  - ## Web Routes\n\n    Web routes allow you to define conditional access paths to\n    specific resources and react to corresponding http requests.  \n    They also provide the possibility of using freer\n    conditions that can be retrieved as input elements.\n\n    In **microWebSrv2**, a web route is composed by a **processing handler**,\n    a **requested method**, a **requested path** and an optional **name**.  \n    The requested path can also consist of variable parts that\n    can be retrieved as arguments.\n\n    Finally, during an http request, if the method and path match to a route,\n    the processing handler is called with the expected arguments.\n\n    ---\n\n    \u003ca name=\"route-process\"\u003e\u003c/a\u003e\n    - ### Route Processing\n\n      A route processing is an handler function decorated by the setting of the route.  \n      This setting uses the ```@WebRoute``` decorator whose definition is as follows:\n      ```python\n      @WebRoute(method, routePath, name=None)\n      # \u003cmethod\u003e is the http requested method and must be a not empty string.\n      # \u003croutePath\u003e is the http requested path and must be a not empty string.\n      # \u003cname\u003e is an optional route name and must be a string or None.\n      ```\n\n      The handler function definition is as follows:\n      ```python\n      @WebRoute(...)\n      def RequestHandler(microWebSrv2, request)\n      # \u003cmicroWebSrv2\u003e is of type MicroWebSrv2\n      # \u003crequest\u003e is of type HttpRequest\n      ```\n\n      The **method argument** can be a string but also one of the following constants:  \n      ```GET```, ```HEAD```, ```POST```, ```PUT```, ```DELETE```, ```OPTIONS```, ```PATCH```\n\n      The **routePath argument** must always starts by ```/``` and specifies the relative URL of the route.\n\n      \u003e Note that a route processing handler is **global** and can be called by any instance of MicroWebSrv2 class.\n\n      :cyclone: Example of processing handlers:\n      ```python\n      @WebRoute(GET, '/my-resource')\n      def RequestHandler1(microWebSrv2, request) :\n          pass\n      ```\n      ```python\n      @WebRoute(POST, '/test/virtual-page.html', 'myTestRoute')\n      def RequestHandler2(microWebSrv2, request) :\n          pass\n      ```\n      ```python\n      @WebRoute(OPTIONS, '/')\n      def RequestHandler3(microWebSrv2, request) :\n          pass\n      ```\n\n      ---\n\n    \u003ca name=\"route-args\"\u003e\u003c/a\u003e\n    - ### Route Arguments\n\n      It is possible to include route arguments that can be retrieved as input elements.  \n      These arguments are directly defined in the **requested path**\n      by naming and framing them with ```\u003c```and ```\u003e``` as follows:\n      ```python\n      @WebRoute(GET, '/users/\u003cid\u003e/profile/\u003cproperty\u003e')\n      ```\n      In this web route, two arguments are defined: ```id``` and ```property```.  \n      Thus, the route is variable and corresponds to the **requested path** from which any argument can be used.\n      ```python\n      '/users/123/profile/firstname'\n      ```\n\n      So, the handler function definition is extended as follows:\n      ```python\n      @WebRoute(...)\n      def RequestHandler(microWebSrv2, request, args)\n      # \u003cmicroWebSrv2\u003e is of type MicroWebSrv2\n      # \u003crequest\u003e is of type HttpRequest\n      # \u003cargs\u003e is a dictionary of route arguments\n      ```\n      Now, ```args``` can be used like ```args['id']``` or ```args['property']```.  \n      Note that values can be strings but also integers directly.\n\n      ---\n\n    \u003ca name=\"route-func\"\u003e\u003c/a\u003e\n    - ### Route Methods\n\n      #### :arrow_forward: RegisterRoute(...)\n      ```python\n      def RegisterRoute(handler, method, routePath, name=None)\n      # Registers a global web route directly, without decorator usage.\n      #   - No return value.\n      #   - \u003chandler\u003e is the route processing handler and must be a function (see above).\n      #   - \u003cmethod\u003e is the http requested method and must be a not empty string.\n      #   - \u003croutePath\u003e is the http requested path and must be a not empty string.\n      #   - \u003cname\u003e is an optional route name and must be a string or None.\n      # An exception can be raised if arguments are not correct.\n      ```\n\n      #### :arrow_forward: ResolveRoute(...)\n      ```python\n      def ResolveRoute(method, path)\n      # Resolves a web route using a method and a path.\n      #   - Returns a RouteResult class if no error occurred and route was found, returns None otherwise.\n      #   - \u003cmethod\u003e is an http method and must be of string type.\n      #   - \u003cpath\u003e is an http relative path and must be of string type.\n      ```\n      The **RouteResult** class exposes the following properties:\n\n      | Name        |        Type        |\n      |-------------|:------------------:|\n      | `Handler`   | processing handler |\n      | `Method`    |       string       |\n      | `RoutePath` |       string       |\n      | `Name`      |   string or None   |\n      | `Args`      |     dictionary     |\n\n      #### :arrow_forward: PathFromRoute(...)\n      ```python\n      def PathFromRoute(routeName, routeArgs={ })\n      # Constructs the relative path from the route name and route arguments.\n      #   - Returns a string that is the relative path.\n      #   - \u003crouteName\u003e is the name of the web route and must be a not empty string.\n      #   - \u003crouteArgs\u003e is a dictionary of needed argument names and values.\n      # An exception can be raised if arguments are not correct or route was not found.\n      ```\n\n    ---\n\n  \u003ca name=\"request-class\"\u003e\u003c/a\u003e\n  - ## HttpRequest Class\n\n    HttpRequest class represents a received http request by the web server.  \n    It can be obtained in web route handlers or in modules.  \n    It also allows you to process the response.\n\n    ---\n\n    \u003ca name=\"request-func\"\u003e\u003c/a\u003e\n    - ### HttpRequest instance methods\n\n      #### :arrow_forward: httpRequest.GetPostedURLEncodedForm(...)\n      ```python\n      def GetPostedURLEncodedForm(self)\n      # Obtains name/value pairs from an URL encoded form.\n      # The http request must have an URL encoded form content.\n      #   - Returns a dictionary of name/value pairs (string for both).\n      ```\n\n      #### :arrow_forward: httpRequest.GetPostedJSONObject(...)\n      ```python\n      def GetPostedJSONObject(self)\n      # Obtains the object posted in JSON format.\n      # The http request must have a JSON content.\n      #   - Returns any type of object or None.\n      ```\n\n      #### :arrow_forward: httpRequest.GetHeader(...)\n      ```python\n      def GetHeader(self, name)\n      # Obtains the value of an http request header.\n      #   - Returns always a string value.\n      #   - \u003cname\u003e must be a not empty string.\n      # An exception can be raised if \u003cname\u003e is not correct.\n      ```\n\n      #### :arrow_forward: httpRequest.CheckBasicAuth(...)\n      ```python\n      def CheckBasicAuth(self, username, password)\n      # Checks if the http request is authenticated with the \"Basic\" method.\n      #   - Returns True if the authentication is correct, returns False otherwise.\n      #   - \u003cusername\u003e must be a string.\n      #   - \u003cpassword\u003e must be a string.\n      # An exception can be raised if arguments are not correct.\n      ```\n\n      #### :arrow_forward: httpRequest.CheckBearerAuth(...)\n      ```python\n      def CheckBearerAuth(self, token)\n      # Checks if the http request is authenticated with the \"Bearer\" method.\n      #   - Returns True if authentication is correct, returns False otherwise.\n      #   - \u003ctoken\u003e is the session token and must be a string.\n      # An exception can be raised if \u003ctoken\u003e is not correct.\n      ```\n\n      ---\n\n    \u003ca name=\"request-prop\"\u003e\u003c/a\u003e\n    - ### HttpRequest properties\n\n      | Name              |               Type              |           Get           | Set | Description                                                                                 |\n      |-------------------|:-------------------------------:|:-----------------------:|:---:|---------------------------------------------------------------------------------------------|\n      | `UserAddress`     |              tuple              | :ballot_box_with_check: |  -  | *User remote address of the http connection such as a tuple of `(str_ip_addr, int_port)`.*  |\n      | `IsSSL`           |               bool              | :ballot_box_with_check: |  -  | *Indicates that the http connection is secured by SSL/TLS security layer with certificate.* |\n      | `HttpVer`         |               str               | :ballot_box_with_check: |  -  | *Version of the client protocol of the http connection.*                                    |\n      | `Method`          |               str               | :ballot_box_with_check: |  -  | *Name of the method transmitted with this request.*                                         |\n      | `Path`            |               str               | :ballot_box_with_check: |  -  | *Path of the resource transmitted with this request.*                                       |\n      | `QueryString`     |               str               | :ballot_box_with_check: |  -  | *Full query string transmitted with this request.*                                          |\n      | `QueryParams`     |               dict              | :ballot_box_with_check: |  -  | *Parameters of the query string transmitted with this request.*                             |\n      | `Host`            |               str               | :ballot_box_with_check: |  -  | *Hostname transmitted with this request.*                                                   |\n      | `Accept`          |               list              | :ballot_box_with_check: |  -  | *List of possible content types expected in response to this request.*                      |\n      | `AcceptEncodings` |               list              | :ballot_box_with_check: |  -  | *List of possible encodings expected in response to this request.*                          |\n      | `AcceptLanguages` |               list              | :ballot_box_with_check: |  -  | *List of possible languages expected in response to this request.                           |\n      | `Cookies`         |               list              | :ballot_box_with_check: |  -  | *List of cookies transmitted with this request.*                                            |\n      | `CacheControl`    |               str               | :ballot_box_with_check: |  -  | *Control of cache transmitted with this request.*                                           |\n      | `Referer`         |               str               | :ballot_box_with_check: |  -  | *Referer address transmitted with this request.*                                            |\n      | `ContentType`     |               str               | :ballot_box_with_check: |  -  | *Type of the content included in this request.*                                             |\n      | `ContentLength`   |               int               | :ballot_box_with_check: |  -  | *Length of the content included in this request.*                                           |\n      | `UserAgent`       |               str               | :ballot_box_with_check: |  -  | *Name of the client agent transmitted with this request.*                                   |\n      | `Authorization`   |               str               | :ballot_box_with_check: |  -  | *Authorization string transmitted with this request.*                                       |\n      | `Origin`          |               str               | :ballot_box_with_check: |  -  | *Address of the origin transmitted with this request.*                                      |\n      | `IsKeepAlive`     |               bool              | :ballot_box_with_check: |  -  | *Indicates that the http connection can be keep alive.*                                     |\n      | `IsUpgrade`       |               bool              | :ballot_box_with_check: |  -  | *Indicates that the http connection must be upgraded.*                                      |\n      | `Upgrade`         |               str               | :ballot_box_with_check: |  -  | *Upgrade string transmitted with this request.*                                             |\n      | `Content`         |        memoryview or None       | :ballot_box_with_check: |  -  | *Raw data of the content included in this request.*                                         |\n      | `Response`        | [HttpResponse](#response-class) | :ballot_box_with_check: |  -  | *Http response related to this connection.*                                                 |\n      | `XAsyncTCPClient` |         XAsyncTCPClient         | :ballot_box_with_check: |  -  | *Asynchronous TCP connection from the XAsyncSockets library.*                               |\n\n    ---\n\n  \u003ca name=\"response-class\"\u003e\u003c/a\u003e\n  - ## HttpResponse Class\n\n    HttpResponse class is used to manage the reponse of an http request.  \n    It can be obtained by the ```Response``` property of an instantiated HttpRequest.   \n\n    ---\n\n    \u003ca name=\"response-func\"\u003e\u003c/a\u003e\n    - ### HttpResponse instance methods\n\n      #### :arrow_forward: httpResponse.SetHeader(...)\n      ```python\n      def SetHeader(self, name, value)\n      # Set a header to the http response.\n      #   - No return value.\n      #   - \u003cname\u003e must be a not empty string.\n      #   - \u003cvalue\u003e may be anything but cannot be None.\n      # An exception can be raised if arguments are not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.SwitchingProtocols(...)\n      ```python\n      def SwitchingProtocols(self, upgrade)\n      # Sends a special http response to upgrade the connection.\n      #   - No return value.\n      #   - \u003cupgrade\u003e must be a not empty string.\n      # An exception can be raised if \u003cupgrade\u003e is not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnStream(...)\n      ```python\n      def ReturnStream(self, code, stream)\n      # Sends a stream content to the http response.\n      #   - No return value.\n      #   - \u003ccode\u003e is the http status code and must be a positive integer.\n      #   - \u003cstream\u003e must be a readable buffer protocol object.\n      # An exception can be raised if arguments are not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.Return(...)\n      ```python\n      def Return(self, code, content=None)\n      # Sends an http response with or without content.\n      #   - No return value.\n      #   - \u003ccode\u003e is the http status code and must be a positive integer.\n      #   - \u003ccontent\u003e must be a string or in bytes or convertible into bytes or None.\n      # An exception can be raised if arguments are not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnJSON(...)\n      ```python\n      def ReturnJSON(self, code, obj)\n      # Sends an http response with a JSON content.\n      #   - No return value.\n      #   - \u003ccode\u003e is the http status code and must be a positive integer.\n      #   - \u003cobj\u003e can be anything and will be serialized (stringify process).\n      # An exception can be raised if arguments are not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnOk(...)\n      ```python\n      def ReturnOk(self, content=None)\n      # Sends a success http response with or without content.\n      #   - No return value.\n      #   - \u003ccontent\u003e must be a string or in bytes or convertible into bytes or None.\n      # An exception can be raised if \u003ccontent\u003e is not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnOkJSON(...)\n      ```python\n      def ReturnOkJSON(self, obj)\n      # Sends a success http response with a JSON content.\n      #   - No return value.\n      #   - \u003cobj\u003e can be anything and will be serialized (stringify process).\n      # An exception can be raised if \u003cobj\u003e is not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnFile(...)\n      ```python\n      def ReturnFile(self, filename, attachmentName=None)\n      # Sends a file to the http response.\n      #   - No return value.\n      #   - \u003cfilename\u003e is the physical path of the file and must be a not empty string.\n      #   - \u003cattachmentName\u003e can be the name of the file to save, in string, or None.\n      #     If None, the user will see it \"on the fly\" in his browser, he will can save it otherwise.\n      # An exception can be raised if arguments are not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnNotModified(...)\n      ```python\n      def ReturnNotModified(self)\n      # Sends a not modified http response.\n      # Used in resources caching context.\n      #   - No return value.\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnRedirect(...)\n      ```python\n      def ReturnRedirect(self, location)\n      # Sends a temporary redirect http response.\n      # Used to move the user to a new url.\n      #   - No return value.\n      #   - \u003clocation\u003e is the relative or absolute URL and must be a not empty string.\n      # An exception can be raised if \u003clocation\u003e is not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnBadRequest(...)\n      ```python\n      def ReturnBadRequest(self)\n      # Sends a bad request http response.\n      # Used for user request error.\n      #   - No return value.\n\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnUnauthorized(...)\n      ```python\n      def ReturnUnauthorized(self, typeName, realm=None)\n      # Sends an unauthorized http response.\n      # Used if the user needs to authenticate.\n      #   - No return value.\n      #   - \u003ctypeName\u003e is the name of required authentication and must be a not empty string.\n      #   - \u003crealm\u003e is a name for the protected resource and can be a string or None.\n      # An exception can be raised if arguments are not correct.\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnForbidden(...)\n      ```python\n      def ReturnForbidden(self)\n      # Sends a forbidden http response.\n      # Used to indicate a denied access.\n      #   - No return value.\n\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnNotFound(...)\n      ```python\n      def ReturnNotFound(self)\n      # Sends a not found http response.\n      # Used to indicate that the resource does not exist.\n      #   - No return value.\n\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnMethodNotAllowed(...)\n      ```python\n      def ReturnMethodNotAllowed(self)\n      # Sends a method not allowed http response.\n      # Used if the method is not supported for resource.\n      #   - No return value.\n\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnEntityTooLarge(...)\n      ```python\n      def ReturnEntityTooLarge(self)\n      # Sends an entity too large http response.\n      # Used for an excessive content size.\n      #   - No return value.\n\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnInternalServerError(...)\n      ```python\n      def ReturnInternalServerError(self)\n      # Sends an internal server error http response.\n      # Used if an error has occurred.\n      #   - No return value.\n\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnNotImplemented(...)\n      ```python\n      def ReturnNotImplemented(self)\n      # Sends a not implemented http response.\n      # Used in case of a non-existent process of the resource.\n      #   - No return value.\n\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnServiceUnavailable(...)\n      ```python\n      def ReturnServiceUnavailable(self)\n      # Sends a service unavailable http response.\n      # Used if it is currently impossible to process the request.\n      #   - No return value.\n\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnBasicAuthRequired(...)\n      ```python\n      def ReturnBasicAuthRequired(self)\n      # Sends an http response to indicate that \"Basic\" authentication is required.\n      #   - No return value.\n\n      ```\n\n      #### :arrow_forward: httpResponse.ReturnBearerAuthRequired(...)\n      ```python\n      def ReturnBearerAuthRequired(self)\n      # Sends an http response to indicate that \"Bearer\" authentication is required.\n      #   - No return value.\n\n      ```\n\n      ---\n\n    \u003ca name=\"response-prop\"\u003e\u003c/a\u003e\n    - ### HttpResponse properties\n\n      | Name                       |              Type                    |           Get           |           Set           | Description                                                                                 |\n      |----------------------------|:------------------------------------:|:-----------------------:|:-----------------------:|---------------------------------------------------------------------------------------------|\n      | `Request`                  | [HttpRequest](#request-class)        | :ballot_box_with_check: |            -            | *Http request related to this response.*                                                    |\n      | `UserAddress`              |             tuple                    | :ballot_box_with_check: |            -            | *User remote address of the http connection such as a tuple of `(str_ip_addr, int_port)`.*  |\n      | `IsSSL`                    |              bool                    | :ballot_box_with_check: |            -            | *Indicates that the http connection is secured by SSL/TLS security layer with certificate.* |\n      | `AllowCaching`             |              bool                    | :ballot_box_with_check: | :ballot_box_with_check: | *Indicates to the user the possible caching of this response.*                              |\n      | `AccessControlAllowOrigin` |          str or None                 | :ballot_box_with_check: | :ballot_box_with_check: | *Indicates to the user the allowed resource origin.*                                        |\n      | `ContentType`              |          str or None                 | :ballot_box_with_check: | :ballot_box_with_check: | *Type of the content of this response.*                                                     |\n      | `ContentCharset`           |          str or None                 | :ballot_box_with_check: | :ballot_box_with_check: | *Encoding charset used for the content of this response.*                                   |\n      | `ContentLength`            |              int                     | :ballot_box_with_check: | :ballot_box_with_check: | *Length of the content of this response.*                                                   |\n      | `HeadersSent`              |              bool                    | :ballot_box_with_check: |            -            | *Indicates that response http headers was already sent.*                                    |\n      | `OnSent`                   | [callback](#response-onsent) or None | :ballot_box_with_check: | :ballot_box_with_check: | *Callback function when response is fully sent.*                                            |\n\n      \u003e **Definition of the above callback functions:**\n\n      \u003ca name=\"response-onsent\"\u003e\u003c/a\u003e\n      ```python\n      def OnSent(microWebSrv2, response)\n      # \u003cmicroWebSrv2\u003e is of type MicroWebSrv2\n      # \u003cresponse\u003e is of type HttpResponse\n      ```\n\n    ---\n\n  \u003ca name=\"modules\"\u003e\u003c/a\u003e\n  - ## Additional modules\n\n    **microWebSrv2** supports additional modules that can be called during the\n    processing of a web request and can then decide whether or not to intercept it.  \n    Modules can simply analyze http requests or responding to them so that\n    they cannot continue their normal pipe-line processing.\n\n    A module file must be placed in the \"```/mods```\" directory of the package\n    and must define a class of the same name.  \n    In addition, this class must implement the ```OnRequest(...)``` method\n    that will be called at each http request.\n\n    :cyclone: Example of a module named \"```TestMod.py```\":\n    ```python\n    class TestMod :\n\n        def OnRequest(self, microWebSrv2, request) :\n            print('TestMod: Request received from %s:%s' % request.UserAddress)\n    ```\n\n    ---\n\n    \u003ca name=\"websockets-mod\"\u003e\u003c/a\u003e\n    - ## WebSockets Module\n\n      **WebSockets module** must be loaded first by **microWebSrv2** to process WebSocket connections.  \n      These are fully managed asynchronous I/Os and really many connections can be processed.  \n      After module loaded, do not forget to assign the callback [OnWebSocketAccepted](#ws-mod-onwebsocketaccepted).  \n      If you need to select and process a sub-protocol, you must assign the callback [OnWebSocketProtocol](#ws-mod-onwebsocketprotocol).  \n      ```python\n      from MicroWebSrv2 import *\n\n      WS_CHAT_SUB_PROTOCOL = 'myGreatChat-v1'\n\n      def OnWebSocketProtocol(microWebSrv2, protocols) :\n          if WS_CHAT_SUB_PROTOCOL in protocols :\n              return WS_CHAT_SUB_PROTOCOL\n\n      def OnWebSocketAccepted(microWebSrv2, webSocket) :\n          print('New WebSocket (myGreatChat proto) accepted from %s:%s.' % webSocket.Request.UserAddress)\n\n      wsMod = MicroWebSrv2.LoadModule('WebSockets')\n      wsMod.OnWebSocketProtocol = OnWebSocketProtocol\n      wsMod.OnWebSocketAccepted = OnWebSocketAccepted\n      ```\n\n      ---\n    \n      \u003ca name=\"websockets-mod-prop\"\u003e\u003c/a\u003e\n      - ### WebSockets module properties\n\n        | Name                  |                   Type                          |           Get           |           Set           | Description                                                                    |\n        |-----------------------|:-----------------------------------------------:|:-----------------------:|:-----------------------:|--------------------------------------------------------------------------------|\n        | `OnWebSocketProtocol` | [callback](#ws-mod-onwebsocketprotocol) or None | :ballot_box_with_check: | :ballot_box_with_check: | *Callback function when a new WebSocket connection negociates a sub-protocol.* |\n        | `OnWebSocketAccepted` | [callback](#ws-mod-onwebsocketaccepted) or None | :ballot_box_with_check: | :ballot_box_with_check: | *Callback function when a new WebSocket connection is accepted.*               |\n\n        \u003e **Definition of the above callback functions:**\n\n        \u003ca name=\"ws-mod-onwebsocketprotocol\"\u003e\u003c/a\u003e\n        ```python\n        def OnWebSocketProtocol(microWebSrv2, protocols)\n        # \u003cmicroWebSrv2\u003e is of type MicroWebSrv2\n        # \u003cprotocols\u003e is a string list of proposed protocols\n        # RETURN: If you select a protocol, you must return it (the same as in the list)\n        ```\n\n        \u003ca name=\"ws-mod-onwebsocketaccepted\"\u003e\u003c/a\u003e\n        ```python\n        def OnWebSocketAccepted(microWebSrv2, webSocket)\n        # \u003cmicroWebSrv2\u003e is of type MicroWebSrv2\n        # \u003cwebSocket\u003e is of type WebSocket\n        ```\n\n        ---\n\n      \u003ca name=\"websocket-class\"\u003e\u003c/a\u003e\n      - ### WebSocket Class\n\n        WebSocket class is automatically instantiated by WebSockets module.  \n        A WebSocket can be obtained when a new connection is accepted in the callback [OnWebSocketAccepted](#ws-mod-onwebsocketaccepted).  \n        It is also important to assign WebSocket callbacks in order to receive the various events.  \n\n        ---\n\n        \u003ca name=\"websocket-func\"\u003e\u003c/a\u003e\n        - ### WebSocket instance methods\n\n          #### :arrow_forward: webSocket.SendTextMessage(...)\n          ```python\n          def SendTextMessage(self, msg)\n          # Sends a text message through the WebSocket.\n          #   - Returns True or False.\n          #   - \u003cmsg\u003e must be a not empty string.\n          # An exception can be raised if \u003cmsg\u003e is not correct.\n          ```\n\n          #### :arrow_forward: webSocket.SendBinaryMessage(...)\n          ```python\n          def SendBinaryMessage(self, msg)\n          # Sends a binary message through the WebSocket.\n          #   - Returns True or False.\n          #   - \u003cmsg\u003e must be in bytes or convertible into bytes and not empty.\n          # An exception can be raised if \u003cmsg\u003e is not correct.\n          ```\n\n          #### :arrow_forward: webSocket.Close(...)\n          ```python\n          def Close(self)\n          # Closes the WebSocket.\n          #   - No return value.\n          ```\n\n          ---\n\n        \u003ca name=\"websocket-prop\"\u003e\u003c/a\u003e\n        - ### WebSocket properties\n\n          | Name                   |                   Type                  |           Get           |           Set           | Description                                     |\n          |------------------------|:---------------------------------------:|:-----------------------:|:-----------------------:|-------------------------------------------------|\n          | `Request`              |     [ HttpRequest](#request-class)      | :ballot_box_with_check: |            -            | *Http request related to this connection.*      |\n          | `IsClosed`             |                   bool                  | :ballot_box_with_check: |            -            | *Indicates that connection is closed.*          |\n          | `WaitFrameTimeoutSec`  |                   int                   | :ballot_box_with_check: | :ballot_box_with_check: | *Timeout in seconds to waiting next frame.*     |\n          | `MaxRecvMessageLength` |               int or None               | :ballot_box_with_check: | :ballot_box_with_check: | *Maximum length of messages to receive.*        |\n          | `OnTextMessage`        |  [callback](#ws-ontextmessage) or None  | :ballot_box_with_check: | :ballot_box_with_check: | *Callback function to receive text messages.*   |\n          | `OnBinaryMessage`      | [callback](#ws-onbinarymessage) or None | :ballot_box_with_check: | :ballot_box_with_check: | *Callback function to receive binary messages.* |\n          | `OnClosed`             |     [callback](#ws-onclosed) or None    | :ballot_box_with_check: | :ballot_box_with_check: | *Callback function when connection is closed.*  |\n\n          \u003e **Definition of the above callback functions:**\n\n          \u003ca name=\"ws-ontextmessage\"\u003e\u003c/a\u003e\n          ```python\n          def OnTextMessage(webSocket, msg)\n          # \u003cwebSocket\u003e is of type WebSocket\n          # \u003cmsg\u003e is of type str\n          ```\n\n          \u003ca name=\"ws-onbinarymessage\"\u003e\u003c/a\u003e\n          ```python\n          def OnBinaryMessage(webSocket, msg)\n          # \u003cwebSocket\u003e is of type WebSocket\n          # \u003cmsg\u003e is of type memoryview\n          ```\n\n          \u003ca name=\"ws-onclosed\"\u003e\u003c/a\u003e\n          ```python\n          def OnClosed(webSocket)\n          # \u003cwebSocket\u003e is of type WebSocket\n          ```\n\n    ---\n\n    \u003ca name=\"pyhtmltemplate-mod\"\u003e\u003c/a\u003e\n    - ## PyhtmlTemplate Module\n\n      **PyhtmlTemplate module** must be loaded first by **microWebSrv2** to process **.pyhtml** pages.  \n      With it, you will be able to render HTML pages directly integrating Python/MicroPython language.  \n      ```python\n      from MicroWebSrv2 import *\n\n      pyhtmlTemplateMod = MicroWebSrv2.LoadModule('PyhtmlTemplate')\n      pyhtmlTemplateMod.ShowDebug = True\n      ```\n\n      In the pages **.pyhtml**, you must use the following instructions:\n\n      | Instruction | Code schema                                                               |\n      |:-----------:| ------------------------------------------------------------------------- |\n      | PY          | `{{ py }}` *Python code* `{{ end }}`                                      |\n      | IF          | `{{ if` *Python condition* `}}` *html bloc* `{{ end }}`                   |\n      | ELIF        | `{{ elif` *Python condition* `}}` *html bloc* `{{ end }}`                 |\n      | ELSE        | `{{ else }}` *html bloc* `{{ end }}`                                      |\n      | FOR         | `{{ for` *identifier* `in` *Python iterator* `}}` *html bloc* `{{ end }}` |\n      | Expression  | `{{` *Python expression* `}}`                                             |\n\n      :cyclone: See the **[test.pyhtml](https://github.com/jczic/MicroWebSrv2/blob/master/www/test.pyhtml)** page for the example:\n\n      ![Pyhtml Code](/img/pyhtml_code.png \"Pyhtml Code\")\n\n      ![Pyhtml Page](/img/pyhtml_page.png \"Pyhtml Page\")\n\n      ---\n\n      \u003ca name=\"pyhtmltemplate-func\"\u003e\u003c/a\u003e\n      - ### PyhtmlTemplate module instance methods\n\n        #### :arrow_forward: pyhtmlTemplateMod.SetGlobalVar(...)\n        ```python\n        def SetGlobalVar(self, globalVarName, globalVar)\n        # Defines a global variable accessible by all pyhtml pages.\n        #   - No return value.\n        #   - \u003cglobalVarName\u003e must be a not empty string.\n        #   - \u003cglobalVar\u003e must be an object or None.\n        # An exception can be raised if \u003cglobalVarName\u003e is not correct.\n        ```\n\n        #### :arrow_forward: pyhtmlTemplateMod.GetGlobalVar(...)\n        ```python\n        def GetGlobalVar(self, globalVarName)\n        # Retrieves a global variable accessible by all pyhtml pages.\n        #   - Returns an object or None.\n        #   - \u003cglobalVarName\u003e must be a not empty string.\n        # An exception can be raised if \u003cglobalVarName\u003e is not correct.\n        ```\n\n        ---\n\n      \u003ca name=\"pyhtmltemplate-prop\"\u003e\u003c/a\u003e\n      - ### PyhtmlTemplate module properties\n\n        | Name        |  Type  |           Get           |           Set           | Description                       |\n        |-------------|:------:|:-----------------------:|:-----------------------:|-----------------------------------|\n        | `ShowDebug` |  bool  | :ballot_box_with_check: | :ballot_box_with_check: | *Enables debugging on web pages.* |\n\n---\n\n\u003ca name=\"author\"\u003e\u003c/a\u003e\n## :wink: \u0026nbsp;Author\n\n  **Jean-Christophe Bos** (:fr:)\n  - GitHub: *[@jczic](https://github.com/jczic)*\n  - Email:  *\u003cjczic.bos@gmail.com\u003e*\n  - Profil: *[LinkedIn](https://www.linkedin.com/in/jczic)*\n  - Music:  *[SoundCloud](https://soundcloud.com/jczic/sets/electro-pulse)*\n            *[Spotify](https://open.spotify.com/album/5fUd57GcAIcdUn9NX3fviG)*\n            *[YouTube](https://www.youtube.com/playlist?list=PL9CsGuMbcLaU02VKS7jtR6LaDNpq7MZEq)*\n---\n\n\u003ca name=\"license\"\u003e\u003c/a\u003e\n## :eight_pointed_black_star: \u0026nbsp;License\n\n  - Copyright :copyright: 2019 [Jean-Christophe Bos](https://www.linkedin.com/in/jczic) \u0026 [HC²](https://www.hc2.fr).\n  - This project is [MIT](https://github.com/jczic/MicroWebSrv2/blob/master/LICENSE.md) licensed.\n\n---\n\n\u003cbr /\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjczic%2FMicroWebSrv2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjczic%2FMicroWebSrv2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjczic%2FMicroWebSrv2/lists"}