MicroWebSrv

A micro HTTP Web server that supports WebSockets, html/python language templating and routing handlers, for MicroPython (used on Pycom modules & ESP32)


Project maintained by jczic Hosted on GitHub Pages — Theme by mattgraham

MicroWebSrv is a micro HTTP Web server that supports WebSockets, html/python language templating and routing handlers, for MicroPython (principally used on ESP32 and Pycom modules)

HC²

Very easy to integrate and very light with 3 files only :

Simple but effective :

Using microWebSrv main class :

Name Function
Constructor mws = MicroWebSrv(routeHandlers=None, port=80, bindIP='0.0.0.0', webPath="/flash/www")
Start Web server mws.Start(threaded=True)
Stop Web server mws.Stop()
Check if Web server is running mws.IsStarted()
Set URL location for not found page mws.SetNotFoundPageUrl(url=None)
Get mime type from file extention mws.GetMimeTypeFromFilename(filename)
Get handler function from route (routeHandler, routeArgs) = mws.GetRouteHandler(resUrl, method)
Callback function to enable and accept WebSockets mws.AcceptWebSocketCallback = _acptWS _acptWS(webSocket, httpClient) { }
Maximum length of memory allocated to receive WebSockets data (1024 by default) mws.MaxWebSocketRecvLen
New thread used for each WebSocket connection (True by default) mws.WebSocketThreaded
Escape string to HTML usage MicroWebSrv.HTMLEscape(s)

Basic example :

from microWebSrv import MicroWebSrv
mws = MicroWebSrv() # TCP port 80 and files in /flash/www
mws.Start()         # Starts server in a new thread

Using as captive portal :

# To intercept all not found queries and redirect it,
mws.SetNotFoundPageUrl("http://my-device.wifi")

Using route handlers example :


routeHandlers = [
  ( "relative_url_route_1", "METHOD", handlerFunc_1 ),
  ( "relative_url_route_2", "METHOD", handlerFunc_2 ),
  ( ... )
]
def handlerFunc_1(httpClient, httpResponse, routeArgs=None) :
  print("In HTTP handler 1")

def handlerFunc_2(httpClient, httpResponse, routeArgs=None) :
  print("In HTTP handler 2")

Using directly route handlers decorators example :

@MicroWebSrv.route('/get-test')
def handlerFuncGet(httpClient, httpResponse) :
  print("In GET-TEST HTTP")

@MicroWebSrv.route('/post-test', 'POST')
def handlerFuncPost(httpClient, httpResponse) :
  print("In POST-TEST HTTP")

Using variable routes example :

routeHandlers = [
  ( "/edit/<testid>/<testpath>", "GET", handlerFuncEdit ),
  ( ... )
]
def handlerFuncEdit(httpClient, httpResponse, routeArgs) :
  print("In EDIT HTTP variable route :")
  print(" - testid   = %s" % routeArgs['testid'])
  print(" - testpath = %s" % routeArgs['testpath'])

Or direclty with route handler decorator :

@MicroWebSrv.route('/edit/<testid>/<testpath>')
def handlerFuncEdit(httpClient, httpResponse, routeArgs) :
  print("In EDIT HTTP variable route :")
  print(" - testid   = %s" % routeArgs['testid'])
  print(" - testpath = %s" % routeArgs['testpath'])

Using httpClient class in a route handler function :

Name Function
Get MicroWebSrv class httpClient.GetServer()
Get client address as tuple httpClient.GetAddr()
Get client IP address httpClient.GetIPAddr()
Get client TCP port httpClient.GetPort()
Get client request method httpClient.GetRequestMethod()
Get client request total path httpClient.GetRequestTotalPath()
Get client request ressource path httpClient.GetRequestPath()
Get client request query string httpClient.GetRequestQueryString()
Get client request query parameters as list httpClient.GetRequestQueryParams()
Get client request headers as list httpClient.GetRequestHeaders()
Get client request content type httpClient.GetRequestContentType()
Get client request content length httpClient.GetRequestContentLength()
Get client request content httpClient.ReadRequestContent(size=None)
Get client request form data as list httpClient.ReadRequestPostedFormData()
Get client request as JSON object httpClient.ReadRequestContentAsJSON()

Using httpResponse class in a route handler function :

Name Function
Write switching protocols response httpResponse.WriteSwitchProto(upgrade, headers=None)
Write generic response httpResponse.WriteResponse(code, headers, contentType, contentCharset, content)
Write PyHTML rendered response page httpResponse.WriteResponsePyHTMLFile(filepath, headers=None, vars=None)
Write file directly as response httpResponse.WriteResponseFile(filepath, contentType=None, headers=None)
Write attached file as response httpResponse.WriteResponseFileAttachment(filepath, attachmentName, headers=None)
Write OK response httpResponse.WriteResponseOk(headers=None, contentType=None, contentCharset=None, content=None)
Write JSON object as OK response httpResponse.WriteResponseJSONOk(obj=None, headers=None)
Write redirect response httpResponse.WriteResponseRedirect(location)
Write error response httpResponse.WriteResponseError(code)
Write JSON object as error response httpResponse.WriteResponseJSONError(code, obj=None)
Write bad request response httpResponse.WriteResponseBadRequest()
Write forbidden response httpResponse.WriteResponseForbidden()
Write not found response httpResponse.WriteResponseNotFound()
Write method not allowed response httpResponse.WriteResponseMethodNotAllowed()
Write internal server error response httpResponse.WriteResponseInternalServerError()
Write not implemented response httpResponse.WriteResponseNotImplemented()

Using route handler function example :

def _httpHandlerTestPost(httpClient, httpResponse) :
  formData  = httpClient.ReadRequestPostedFormData()
  firstname = formData["firstname"]
  lastname  = formData["lastname"]
  content   = """\
  <!DOCTYPE html>
  <html>
    <head>
      <meta charset="UTF-8" />
      <title>TEST POST</title>
    </head>
    <body>
      <h1>TEST POST</h1>
      Firstname = %s<br />
      Lastname = %s<br />
    </body>
  </html>
  """ % ( MicroWebSrv.HTMLEscape(firstname),
          MicroWebSrv.HTMLEscape(lastname) )
  httpResponse.WriteResponseOk( headers         = None,
                                contentType     = "text/html",
                                contentCharset  = "UTF-8",
                                content         = content )

Known mime types (content types) :

File extension Mime type
.txt text/plain
.htm text/html
.html text/html
.css text/css
.csv text/csv
.js application/javascript
.xml application/xml
.xhtml application/xhtml+xml
.json application/json
.zip application/zip
.pdf application/pdf
.jpg image/jpeg
.jpeg image/jpeg
.png image/png
.gif image/gif
.svg image/svg+xml
.ico image/x-icon

Default index pages order (for http://hostname/) :

Filename
index.pyhtml
index.html
index.htm
default.pyhtml
default.html
default.htm

Using optional module microWebSocket to connect WebSockets :

Enable and accept WebSockets :

from microWebSrv import MicroWebSrv
mws = MicroWebSrv()                                    # TCP port 80 and files in /flash/www
mws.MaxWebSocketRecvLen     = 256                      # Default is set to 1024
mws.WebSocketThreaded       = False                    # WebSockets without new threads
mws.AcceptWebSocketCallback = _acceptWebSocketCallback # Function to receive WebSockets
mws.Start()                                            # Starts server in a new thread
Name Function
Callback function to receive text message ws.RecvTextCallback = func(webSocket, msg)
Callback function to receive binary data ws.RecvBinaryCallback = func(webSocket, data)
Callback function when connection was closed ws.ClosedCallback(webSocket)
Send a text message ws.SendText(msg)
Send a binary message ws.SendBinary(data)
Check connection state ws.IsClosed()
Close the connection ws.Close()

Basic example of callback functions :

def _acceptWebSocketCallback(webSocket, httpClient) :
  print("WS ACCEPT")
  webSocket.RecvTextCallback   = _recvTextCallback
  webSocket.RecvBinaryCallback = _recvBinaryCallback
  webSocket.ClosedCallback     = _closedCallback

def _recvTextCallback(webSocket, msg) :
  print("WS RECV TEXT : %s" % msg)
  webSocket.SendText("Reply for %s" % msg)

def _recvBinaryCallback(webSocket, data) :
  print("WS RECV DATA : %s" % data)

def _closedCallback(webSocket) :
  print("WS CLOSED")

Using optional module microWebTemplate for .pyhtml rendered pages :

Instruction Schema
PY *MicroPython code*
IF *html bloc*
ELIF *html bloc*
ELSE *html bloc*
FOR *html bloc*
INCLUDE ``
?   ``

Using :


  import machine
  from utime import sleep
  test = 123
  def testFunc(x) :
    return 2 * x

Using :


  <span>titi</span>

  <span>tata</span>

  <span>I like the number  !</span>

Using :


  <div>toto x 10 equal </div>
  <hr />

Using :


Example of a .pyhtml file :

<html>
  <head>
    <title>TEST PYHTML</title>
  </head>
  <body>
    <h1>BEGIN</h1>
    
      def _testFunction(x) :
        return "IN TEST FUNCTION %s" % x
    
    <div style="background-color: black; color: white;">
      
        This is an HTML test...<br />
        TOTO =  !<br />
        
          TOTO2 = 
        
        Ok good.<br />
      
    </div>
    <br />
    <br />
    
      IN IF (1)
    
      IN ELIF (2)
    
      IN ELIF (3)
    
      IN ELSE (4)
    
  </body>
</html>

By JC`zic for HC² ;’)

Keep it simple, stupid :+1: