Home

Awesome

<h3> <p align="center"> Also check out the new ESP32 MPY-Jama free IDE and the latest MicroWebSrv2 below: </p> </h3> <p align="center"> <a href="https://github.com/jczic/ESP32-MPY-Jama"><img src="https://github.com/jczic/ESP32-MPY-Jama/raw/master/img/ESP32%20MPY-Jama%20NEW.png" alt="New microWebSrv2" width="350" valign="middle"></a>                   <a href="https://github.com/jczic/MicroWebSrv2"><img src="microWebSrv2.png" alt="New microWebSrv2" width="350" valign="middle"></a> </p>
<br />

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. Now supports all variants of Pyboard D-series from the makers of Micropython)

HC²

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

Mini tuto in video by rdagger68 :

Simple but effective :

Using microWebSrv main class :

NameFunction
Constructormws = MicroWebSrv(routeHandlers=None, port=80, bindIP='0.0.0.0', webPath="/flash/www")
Start Web servermws.Start(threaded=True)
Stop Web servermws.Stop()
Check if Web server is runningmws.IsStarted()
Set URL location for not found pagemws.SetNotFoundPageUrl(url=None)
Get mime type from file extentionmws.GetMimeTypeFromFilename(filename)
Get handler function from route(routeHandler, routeArgs) = mws.GetRouteHandler(resUrl, method)
Callback function to enable and accept WebSocketsmws.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 usageMicroWebSrv.HTMLEscape(s)

Basic example :

from microWebSrv import MicroWebSrv
mws = MicroWebSrv()      # TCP port 80 and files in /flash/www
mws.Start(threaded=True) # 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 :

NameFunction
Get MicroWebSrv classhttpClient.GetServer()
Get client address as tuplehttpClient.GetAddr()
Get client IP addresshttpClient.GetIPAddr()
Get client TCP porthttpClient.GetPort()
Get client request methodhttpClient.GetRequestMethod()
Get client request total pathhttpClient.GetRequestTotalPath()
Get client request ressource pathhttpClient.GetRequestPath()
Get client request query stringhttpClient.GetRequestQueryString()
Get client request query parameters as listhttpClient.GetRequestQueryParams()
Get client request headers as listhttpClient.GetRequestHeaders()
Get client request content typehttpClient.GetRequestContentType()
Get client request content lengthhttpClient.GetRequestContentLength()
Get client request contenthttpClient.ReadRequestContent(size=None)
Get client request form data as listhttpClient.ReadRequestPostedFormData()
Get client request as JSON objecthttpClient.ReadRequestContentAsJSON()

Using httpResponse class in a route handler function :

NameFunction
Write switching protocols responsehttpResponse.WriteSwitchProto(upgrade, headers=None)
Write generic responsehttpResponse.WriteResponse(code, headers, contentType, contentCharset, content)
Write PyHTML rendered response pagehttpResponse.WriteResponsePyHTMLFile(filepath, headers=None, vars=None)
Write file directly as responsehttpResponse.WriteResponseFile(filepath, contentType=None, headers=None)
Write attached file as responsehttpResponse.WriteResponseFileAttachment(filepath, attachmentName, headers=None)
Write OK responsehttpResponse.WriteResponseOk(headers=None, contentType=None, contentCharset=None, content=None)
Write JSON object as OK responsehttpResponse.WriteResponseJSONOk(obj=None, headers=None)
Write redirect responsehttpResponse.WriteResponseRedirect(location)
Write error responsehttpResponse.WriteResponseError(code)
Write JSON object as error responsehttpResponse.WriteResponseJSONError(code, obj=None)
Write bad request responsehttpResponse.WriteResponseBadRequest()
Write forbidden responsehttpResponse.WriteResponseForbidden()
Write not found responsehttpResponse.WriteResponseNotFound()
Write method not allowed responsehttpResponse.WriteResponseMethodNotAllowed()
Write internal server error responsehttpResponse.WriteResponseInternalServerError()
Write not implemented responsehttpResponse.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 extensionMime type
.txttext/plain
.htmtext/html
.htmltext/html
.csstext/css
.csvtext/csv
.jsapplication/javascript
.xmlapplication/xml
.xhtmlapplication/xhtml+xml
.jsonapplication/json
.zipapplication/zip
.pdfapplication/pdf
.tsapplication/typescript
.wofffont/woff
.woff2font/woff2
.ttffont/ttf
.otffont/otf
.jpgimage/jpeg
.jpegimage/jpeg
.pngimage/png
.gifimage/gif
.svgimage/svg+xml
.icoimage/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(threaded=True)                               # Starts server in a new thread
NameFunction
Callback function to receive text messagews.RecvTextCallback = func(webSocket, msg)
Callback function to receive binary dataws.RecvBinaryCallback = func(webSocket, data)
Callback function when connection was closedws.ClosedCallback = func(webSocket)
Send a text messagews.SendText(msg)
Send a binary messagews.SendBinary(data)
Check connection statews.IsClosed()
Close the connectionws.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 :

InstructionSchema
PY{{ py }} MicroPython code {{ end }}
IF{{ if MicroPython condition }} html bloc {{ end }}
ELIF{{ elif MicroPython condition }} html bloc {{ end }}
ELSE{{ else }} html bloc {{ end }}
FOR{{ for identifier in MicroPython iterator }} html bloc {{ end }}
INCLUDE{{ include pyhtml_filename }}
?  {{ MicroPython expression }}

Using {{ py }} :

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

Using {{ if ... }} :

{{ if testFunc(5) <= 3 }}
  <span>titi</span>
{{ elif testFunc(10) >= 15 }}
  <span>tata</span>
{{ else }}
  <span>I like the number {{ test }} !</span>
{{ end }}

Using {{ for ... }} :

{{ for toto in range(testFunc(3)) }}
  <div>toto x 10 equal {{ toto * 10 }}</div>
  <hr />
{{ end }}

Using {{ include ... }} :

{{ include myTemplate.pyhtml }}

Example of a .pyhtml file :

<html>
  <head>
    <title>TEST PYHTML</title>
  </head>
  <body>
    <h1>BEGIN</h1>
    {{ py }}
      def _testFunction(x) :
        return "IN TEST FUNCTION %s" % x
    {{ end }}
    <div style="background-color: black; color: white;">
      {{ for toto in range(3) }}
        This is an HTML test...<br />
        TOTO = {{ toto + 1 }} !<br />
        {{ for toto2 in range(3) }}
          TOTO2 = {{ _testFunction(toto2) }}
        {{ end }}
        Ok good.<br />
      {{ end }}
    </div>
    {{ _testFunction(100) }}<br />
    <br />
    {{ if 2+5 < 3 }}
      IN IF (1)
    {{ elif 10+15 != 25 }}
      IN ELIF (2)
    {{ elif 10+15 == 25 }}
      IN ELIF (3)
    {{ else }}
      IN ELSE (4)
    {{ end }}
  </body>
</html>

<a name="author"></a>

:wink:  Author

Jean-Christophe Bos (:fr:)

By JC`zic for HC² ;')

Keep it simple, stupid :+1: