Using a python variable in HTML

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
RobinMosedale
Posts: 40
Joined: Fri Jul 26, 2019 9:40 pm

Using a python variable in HTML

Post by RobinMosedale » Sat Mar 20, 2021 6:39 pm

Does micropython support using a python variable in HTML

I've tried <% thisvariablestring %>
which mearely prints 'thisvariablestring'
and """+thisvariablestring+"""
which reports variable not defined probably because it expects java source

Robin

marcidy
Posts: 133
Joined: Sat Dec 12, 2020 11:07 pm

Re: Using a python variable in HTML

Post by marcidy » Sun Mar 21, 2021 7:39 pm

Micropython can run an http server, which can serve HTML to a web browser client.

You can use micropython on the server side to manipulate a page before it is sent, but once you send the page from the server to the client, only the client can change the data with the tools the client has. The client can request more data, for example over a websocket, but only the client can manipulate the page in the browser.

The Web browser cannot use python variables, it has no concept of a python interpreter. Web browsers have javascript interpreters. The server cannot do anything to influence what the client does after sending the page. It can only manipulate the page before it is sent, or send more data to the client at the client's request. The client has to do something to request more data.

All that being said, I'm not clear what you doing. Please elaborate fully on what tools / packages you are using, and a simple code example of what you are trying to do, and I or someone else might be able to help. there currently is not enough information in your post to make any specific recommendation.

RobinMosedale
Posts: 40
Joined: Fri Jul 26, 2019 9:40 pm

Re: Using a python variable in HTML

Post by RobinMosedale » Mon Mar 22, 2021 7:37 pm

Thank you, I'm aware of the static nature of HTML. It is after all a simple text mark up coding.

It's a simple issue, which if I confess would be better implemented on the client's server with Java, but it seems a lot of effort for such a simple thing.

These are snippets from the code that works, most of the usual socket setup stuff works and would be a distraction so reams of code have been removed (which works fine)
So the static HTML is in the variable 'hdr'

the code is instigated from a get or more properly an android Webview LoadUrl(local ip address/apikey/disable)

Code: Select all


import usocket as soc
import network
import _thread as th
from network import WLAN
import camera
import time
import esp
from machine import Pin
import gc
from Wifi.Sta import Sta
import utime
import machine
import ntptime
import urequests
import json

#esp.osdebug(False)
esp.osdebug(True)
version="18a derived from v18 21 March 2021"



hdr = {
   
  # start page for disable
  # URL: /apikey/disable
  'disable': """HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8

<html>
<head>
<title>Test Page</title>
   <meta content="width=device-width; initial-scale=1.0;max-scale=1.0;user-scalable=0;">
</head>
<body>

  <center>
    <h1>Test Page</h1>
    <h1>Alarm Disabled</h1>
    <img src="/apikey/live" width=360 height= 270 />
  </center>
</body>
</html>

"""
#other elements have been removed as irrelevant

}
# part of a function ignore indent
   s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
   s.setsockopt(soc.SOL_SOCKET, soc.SO_REUSEADDR, 1)
   a = ('0.0.0.0', 80)
   s.bind(a)
   s.listen(2)  # queue at most 2 clients
  

def port1(cs, rq):
   global inhibit_time
   global current_time
   rqp = rq[1].split('/')
   if rqp[1] == 'apikey': # Must have /apikey/<REQ>
      if rqp[2] =='disable':         
         print("Alarm Disabled for 10 minutes")
         disable=True
         current_time=utime.time()
         inhibit_time=current_time+600
         cs.send(b'%s' % hdr['disable'])
         clean_up(cs)
      
     etc..................
     


   wlan = network.WLAN(network.STA_IF)
   
   wlan.config(dhcp_hostname='esptest')
   wlan.ifconfig(('192.168.1.144', '255.255.255.0', '192.168.1.254', '192.168.1.254'))
   time.sleep(2)
   print("Scanning network")
   
   
   print("Connecting")
   wlan.connect(topssid,"pwdxxx")

followed by all the usual waiting and timeout recovery
 
 # allll initialisation stuff............................... removed
     inhibit_time = 0
     current_time=0
     inhibit_time=utime.time()
     current_time=utime.time()
     
     #srv setup code removed
     
     th.start_new_thread(srv, (0,))
     th.start_new_thread(srv, (0,))

     # schedule 1 server for port 81
     th.start_new_thread(srv, (1,))

     srv(2)
     
However, if I introduce a simple string variable 'disable_status'

and initialise it in the initialisation part:-

Code: Select all

disable_status='Enabled'
Then introduce it in the socket replying element port1:

Code: Select all

def port1(cs, rq):
   global inhibit_time
   global current_time
   global disable_status
   rqp = rq[1].split('/')
   if rqp[1] == 'apikey': # Must have /apikey/<REQ>
      if rqp[2] =='disable':         
         print("Alarm Disabled for 10 minutes")
         disable=True
         disable_status='Disabled'
         current_time=utime.time()
         inhibit_time=current_time+600
         cs.send(b'%s' % hdr['disable'])
         clean_up(cs)
      
     etc..................
and then reference it in the sent HTML

Code: Select all

hdr = {
   
  # start page for disable
  # URL: /apikey/disable
  'disable': """HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8

<html>
<head>
<title>Test Page</title>
   <meta content="width=device-width; initial-scale=1.0;max-scale=1.0;user-scalable=0;">
</head>
<body>

  <center>
    <h1>Test Page</h1>
    <h1><% disable_status %></h1>
    <h1><"""+ disable_status +"""></h1>
    <img src="/apikey/live" width=360 height= 270 />
  </center>
</body>
</html>

"""
}
The first
<h1><% disable_status %></h1>
merely prints 'disable_status'
the second reports 'variable not found'

I'm no HTML guru, prefer Kotlin for Android so Java is painfully rusty, so just wished to have a simple text status sent on a client 'get'

Above seem to OK with standard Python

No great shakes, I can cludge something else

Robin

marcidy
Posts: 133
Joined: Sat Dec 12, 2020 11:07 pm

Re: Using a python variable in HTML

Post by marcidy » Mon Mar 22, 2021 9:38 pm

Code: Select all

"<% variable %>"
is templating syntax and requires a templating engine.

Code: Select all

"""...""" + variable """ ... """

requires variable to be in scope when the string is created. Using format syntax might make more sense.

Code: Select all

# declare the format string, note the braces.
hdr['disable'] = """ ... lots of stuff {} with lots more stuff"""


#use it somewhere else with a local variable
def f():
    variable = 'some value'
    filled_string = hdr['disable'].format(variable)  # filled_string now is " ... lots of stuff some value with logs more stuff"""

RobinMosedale
Posts: 40
Joined: Fri Jul 26, 2019 9:40 pm

Re: Using a python variable in HTML

Post by RobinMosedale » Wed Mar 24, 2021 12:50 am

Thank you Mark. You've recognised just how inexperienced I am with html.
Certainly give it a try but was leaning towards issuing gets that the holst replies with different pages. This is much better

RobinMosedale
Posts: 40
Joined: Fri Jul 26, 2019 9:40 pm

Re: Using a python variable in HTML

Post by RobinMosedale » Wed Mar 24, 2021 3:55 pm

That worked perfectly, thank you very much

Post Reply