drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Running Python Scripts From A Html

Fri Aug 02, 2019 4:13 pm

Hi everyone, suppose its a simple enough question, i hope the answer is just as simple lol.

so i have a few python scripts on the pi which do differnt things.

i want to create a webpage local on the pi (with apache i suppose) that when a simple link is clicked it launchs and runs the script as if you had typed it in terminal.

any help with this ?


thanks

ghp
Posts: 1411
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Running Python Scripts From A Html

Fri Aug 02, 2019 5:18 pm

Look for a python based 'web server' like tornado (my favorite), flask, django. Then your web requests are directly handled inside a python environment.
If you want the html page to be public, then security issues might need a more complicated architecture.

gkreidl
Posts: 6097
Joined: Thu Jan 26, 2012 1:07 pm
Location: Germany

Re: Running Python Scripts From A Html

Fri Aug 02, 2019 5:56 pm

Kweb (Minimal Kiosk Browser) can do this without any supporting server (only from local HTML files)

But a Buster version is not available, yet.
Minimal Kiosk Browser (kweb)
Slim, fast webkit browser with support for audio+video+playlists+youtube+pdf+download
Optional fullscreen kiosk mode and command interface for embedded applications
Includes omxplayerGUI, an X front end for omxplayer

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Fri Aug 02, 2019 6:09 pm

so with the above i can create a html with a link to the .py and it will launch it ?

ghp
Posts: 1411
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Running Python Scripts From A Html

Fri Aug 02, 2019 6:24 pm

Tornado basic example is here. a form, a link. Run the code, use browser and localhost:8888 should bring up the sample page.

Code: Select all

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('<a href="%s">link to story 1</a>' %
                   self.reverse_url("story", "1"))

class MySampleHandler(tornado.web.RequestHandler):
    def get(self):
        self.set_header("Content-Type", "text/plain")
        self.write("You pressed sample link")

class MyFormHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("""<html>
                           <body>
                              <form action="/myform" method="POST">
                                   <input type="text" name="message">
                                   <input type="submit" value="Submit">
                              </form>
                           </body>
                           <a href="/sample">a sample link</a>
                       </html>""")

    def post(self):
        self.set_header("Content-Type", "text/plain")
        self.write("You wrote " + self.get_body_argument("message"))

def make_app():
    return tornado.web.Application([
        ( r"/", MyFormHandler),
        ( r"/myform", MyFormHandler),
        ( r"/sample", MySampleHandler),
        
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

User avatar
neilgl
Posts: 963
Joined: Sun Jan 26, 2014 8:36 pm
Location: Near Aston Martin factory

Re: Running Python Scripts From A Html

Fri Aug 02, 2019 6:58 pm

Yes you can use apache2 no problem.

gkreidl
Posts: 6097
Joined: Thu Jan 26, 2012 1:07 pm
Location: Germany

Re: Running Python Scripts From A Html

Fri Aug 02, 2019 8:46 pm

drifterf wrote:
Fri Aug 02, 2019 6:09 pm
so with the above i can create a html with a link to the .py and it will launch it ?
Yes. A link, a button, an Image (icon) or a web form with selectable arguments.
My desktop is a local web page running in kweb which gives access to all my important applications.

Image

Another example is a kweb interface to mumudvb to start and watch TV channels:
Image
Minimal Kiosk Browser (kweb)
Slim, fast webkit browser with support for audio+video+playlists+youtube+pdf+download
Optional fullscreen kiosk mode and command interface for embedded applications
Includes omxplayerGUI, an X front end for omxplayer

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 10:09 am

i get the following error, i have used pip install tornado

sudo python tornado1.py
Traceback (most recent call last):
File "tornado1.py", line 1, in <module>
import tornado.ioloop
File "/home/pi/tornado.py", line 1, in <module>
ImportError: No module named ioloop

ghp
Posts: 1411
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 10:22 am

unfortunately there is the python2-python3 confusion.
For python3, install and run with

# recommended, as Tornado 6.0 requires Python 3.5.2
sudo pip3 install tornado
python3 tornado1.py

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 10:41 am

ghp wrote:
Sat Aug 03, 2019 10:22 am
unfortunately there is the python2-python3 confusion.
For python3, install and run with

# recommended, as Tornado 6.0 requires Python 3.5.2
sudo pip3 install tornado
python3 tornado1.py
should of known that lol, much appreciated !!

how would i link the "a sample link" button to launch a .py script then ?

i would like seperate links for seperate py scripts

button 1 = /scripts/test.py
button 2 = /differntscripts/this.py

etc ?

thanks

ghp
Posts: 1411
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 11:03 am

Hello, in the Handler for the link, add
import subprocess

Good if the python script executes fast.

subprocess.run("python3 test1.py", shell=True)

For long running scripts, you should spawn the process.

pid = subprocess.Popen(["python3", "test1.py"]).pid
print(pid) # pid allows to terminate the process later.

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 11:14 am

thank you for your help again, something like i done below ?

i changed this part

def post(self):
import subprocess
self.set_header("Content-Type", "text/plain")
self.write("You wrote " + self.get_body_argument("message"))
subprocess.run("python3 test1.py", shell=True)


Code: Select all

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('<a href="%s">link to story 1</a>' %
                   self.reverse_url("story", "1"))

class MySampleHandler(tornado.web.RequestHandler):
    def get(self):
        self.set_header("Content-Type", "text/plain")
        self.write("You pressed sample link")

class MyFormHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("""<html>
                           <body>
                              <form action="/myform" method="POST">
                                   <input type="text" name="message">
                                   <input type="submit" value="Submit">
                              </form>
                           </body>
                           <a href="/sample">a sample link</a>
                       </html>""")

    def post(self):
        import subprocess 
        self.set_header("Content-Type", "text/plain")
        self.write("You wrote " + self.get_body_argument("message"))
        subprocess.run("python3 test1.py", shell=True)

def make_app():
    return tornado.web.Application([
        ( r"/", MyFormHandler),
        ( r"/myform", MyFormHandler),
        ( r"/sample", MySampleHandler),
        
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

ghp
Posts: 1411
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 4:03 pm

Hello, this handler MyFormHandler with its post method is dedicated to the form in the html.
Think you spotted the url mapping to the handlers in the code

Code: Select all

        ( r"/", MyFormHandler),
        ( r"/myform", MyFormHandler),
        ( r"/sample", MySampleHandler),
 
The method names correspond to the GET, POST, ... request names in the html-requests.

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 4:13 pm

thank you once again for helping but im new to this and still confused. could you show me a modified code that would launch a .py on clicking the link. hopefully then i can see what to change and why, thank you again

ghp
Posts: 1411
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 4:55 pm

The link in the html page <a href="/sample">a sample link</a> is using url "/sample".
The url resolution table in the code

Code: Select all

        ( r"/", MyFormHandler),
        ( r"/myform", MyFormHandler),
        ( r"/sample", MySampleHandler),
links /sample to MySampleHandler.
You know about http-requests: a link is a using a GET-request.
So using the link in the page forwards the request into the get-method of the MySampleHandler.

Conclusion: put this code subprocess.run("python3 test1.py", shell=True) into the MySampleHandler, get-method.

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 5:19 pm

once again im sorry, i currently now get this when i click the web button with the code i have attached.
pi@raspberrypi:~ $ sudo python html.py
WARNING:tornado.access:404 GET /favicon.ico (::1) 1.80ms
ERROR:tornado.application:Uncaught exception GET /sample (::1)
HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/sample', version='HTTP/1.1', remote_ip='::1')
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1590, in _execute
result = method(*self.path_args, **self.path_kwargs)
File "html.py", line 13, in get
subprocess.run("python3 test1.py", shell=True)
NameError: global name 'subprocess' is not defined
ERROR:tornado.access:500 GET /sample (::1) 13.06ms
this is my python script

Code: Select all

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('<a href="%s">link to story 1</a>' %
                   self.reverse_url("story", "1"))

class MySampleHandler(tornado.web.RequestHandler):
    def get(self):
        self.set_header("Content-Type", "text/plain")
        self.write("You pressed sample link")
        subprocess.run("python3 test1.py", shell=True)

class MyFormHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("""<html>
                           <body>
                              <form action="/myform" method="POST">
                                   <input type="text" name="message">
                                   <input type="submit" value="Submit">
                              </form>
                           </body>
                           <a href="/sample">a sample link</a>
                       </html>""")

    def post(self):
        self.set_header("Content-Type", "text/plain")
        self.write("You wrote " + self.get_body_argument("message"))

def make_app():
    return tornado.web.Application([
        ( r"/", MyFormHandler),
        ( r"/myform", MyFormHandler),
        ( r"/sample", MySampleHandler),
        
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sat Aug 03, 2019 5:51 pm

ok so i forgot to add import subprocess lol

but now i get this

Code: Select all

pi@raspberrypi:~ $ sudo python html.py
WARNING:tornado.access:404 GET /favicon.ico (::1) 2.13ms
ERROR:tornado.application:Uncaught exception GET /sample (::1)
HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/sample', version='HTTP/1.1', remote_ip='::1')
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1590, in _execute
    result = method(*self.path_args, **self.path_kwargs)
  File "html.py", line 14, in get
    subprocess.run("python test1.py", shell=True)
AttributeError: 'module' object has no attribute 'run'
ERROR:tornado.access:500 GET /sample (::1) 25.87ms

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sun Aug 04, 2019 6:24 am

ok,, i have been messing around and not can get a gpio to trigger from a web button so i will continue to mess around

i would like to thank everyone for the help !

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sun Aug 04, 2019 7:53 am

Hi everyone, sorry to bring my head back up after all your help lol

i am getting into the tornado stuff now and starting to understand it a bit more.

how would it be possible to open a .html file i have already created when the "Release Door" link is pressed?


the current code is below


Code: Select all

import tornado.ioloop
import tornado.web
import subprocess

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('<a href="%s">link to story 1</a>' %
                   self.reverse_url("story", "1"))

class MyOpenDoorHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("""Released The Door""")
        pid = subprocess.Popen(["python", "opendoor.py"]).pid
        print(pid)


class MyFormHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("""<html>
                           <body>
                           </body>
                           <a href="/opendoor">Release Door</a>
                      </html>""")

    def post(self):
        self.set_header("Content-Type", "text/plain")
        self.write("Door Released" + self.get_body_argument("message"))
        pid = subprocess.Popen(["python", "opendoor.py"]).pid
        print(pid)

def make_app():
    return tornado.web.Application([
        ( r"/", MyFormHandler),
        ( r"/myform", MyFormHandler),
        ( r"/opendoor", MyOpenDoorHandler), 
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8787)
    tornado.ioloop.IOLoop.current().start()

ghp
Posts: 1411
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Running Python Scripts From A Html

Sun Aug 04, 2019 8:30 am

how would it be possible to open a .html file i have already created when the "Release Door" link is pressed?
Static files can be handled with (drum fill) StaticFileHandler.

Code: Select all

    return tornado.web.Application([
        ( r"/", MyFormHandler           ),
        ( r"/myform", MyFormHandler       ),
        ( r"/sample", MySampleHandler         ),
        ( r"/success/?(.*)", tornado.web.StaticFileHandler, {"path": "html/success/" , "default_filename": "success.html"} ),
Place success.html in path ./html/success/.
With URL localhost:8888/success this file should be delivered. Or with localhost:8888/success/success.html.

Then in the request handler of your link, place a redirect as last statement.

Code: Select all

class MySampleHandler(tornado.web.RequestHandler):
    def get(self):
        print("MySampleHandler")
        ... some other actions ...        
        self.redirect("/success")
The regular expression "/success/?(.*)", matches "/success", "/success/", for both the default_filename applies. Or with "/success/success.html", the group (.*) applies and provides a file name for StaticFileHandler. See the StaticFileHndler docs for the details.

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sun Aug 04, 2019 8:45 am

thank you, i now get this error for some reason. have i done something wrong ?


File "server.py", line 19
pid = subprocess.Popen["python", "opendoor2.py"]).pid
^
SyntaxError: invalid syntax



Code: Select all

import tornado.ioloop
import tornado.web
import subprocess

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('<a href="%s">link to story 1</a>' %
                   self.reverse_url("story", "1"))

class MyOpenDoorHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("""Released The Door - Relay 1""")
        pid = subprocess.Popen(["python", "opendoor.py"]).pid
        print(pid)

class MyOpenDoor2Handler(tornado.web.RequestHandler):
    def get(self):
        print("Relay 2 Script")
        pid = subprocess.Popen["python", "opendoor2.py"]).pid
        print(pid)
        self.redirect("/success")

class MyFormHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("""<html>
                           <body>
                           </body>
                           <a href="/opendoor">Release Door</a>
                           <br>
                           <a href="/opendoor2">Release Door - Relay 2</a>
                      </html>""")

    def post(self):
        self.set_header("Content-Type", "text/plain")
        self.write("Door Released" + self.get_body_argument("message"))
        pid = subprocess.Popen(["python", "opendoor.py"]).pid
        print(pid)

def make_app():
    return tornado.web.Application([
        ( r"/", MyFormHandler),
        ( r"/myform", MyFormHandler),
        ( r"/opendoor", MyOpenDoorHandler), 
        ( r"/opendoor2/?(.*)", tornado.web.StaticFileHandler, {"path": "html/success/" , "default_filename": "success.html"} ),
    ])

if __name__ == "__main__":

ghp
Posts: 1411
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Running Python Scripts From A Html

Sun Aug 04, 2019 11:29 am

Brackets come in pairs.

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sun Aug 04, 2019 12:43 pm

ghp wrote:
Sun Aug 04, 2019 11:29 am
Brackets come in pairs.
thank you, im such a dumbass (should of put me contact lenses in lol)

this works great now except it dosent launch my .py script in the handler ?

it redirects to the page i require but dosent actually launch the .py script (opendoor2.py)

Code: Select all

                                                                                        
import tornado.ioloop
import tornado.web
import subprocess

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('<a href="%s">link to story 1</a>' %
                   self.reverse_url("story", "1"))

class MyOpenDoorHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("""Released The Door - Relay 1""")
        pid = subprocess.Popen(["python", "opendoor.py"]).pid
        print(pid)

class MyOpenDoor2Handler(tornado.web.RequestHandler):
    def get(self):
        self.write("""Released The Door - Relay 2""")
        pid = subprocess.Popen(["python", "opendoor2.py"]).pid
        print(pid)
        self.redirect("/opendoor2")

class MyFormHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("""<html>
                           <body>
                           </body>
                           <a href="/opendoor">Release Door</a>
                           <br>
                           <a href="/opendoor2">Release Door - Relay 2</a>
                      </html>""")

    def post(self):
        self.set_header("Content-Type", "text/plain")
        self.write("Door Released" + self.get_body_argument("message"))
        pid = subprocess.Popen(["python", "opendoor.py"]).pid
        print(pid)

def make_app():
    return tornado.web.Application([
        ( r"/", MyFormHandler),
        ( r"/myform", MyFormHandler),
        ( r"/opendoor", MyOpenDoorHandler), 
        ( r"/opendoor2/?(.*)", tornado.web.StaticFileHandler, {"path": "/home/pi/ACU/html/" , "default_filename": "index.html"} ),
        ( r"/opendoor2", MyOpenDoor2Handler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8787)

drifterf
Posts: 134
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Running Python Scripts From A Html

Sun Aug 04, 2019 3:16 pm

no one help with this ? so close but stuck at moment, been trying all day for something im sure is simple :(

ghp
Posts: 1411
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Running Python Scripts From A Html

Mon Aug 05, 2019 4:35 am

- the last line of code is missing tornado.ioloop.IOLoop.current().start()
- html code usually has links inside <body>... here goes the page ...</body>. Your page works unexpectedly.
- in the Popen, add ", shell=True". Or try using /usr/bin/python which is more precise.
- the url mappings contain r"/opendoor2/?(.*)" AND r"/opendoor2". So MyOpenDoor2Handler will not be called. Better tu use different names for the url.

When in doubt how to use the subprocess.Popen, then write a short script with these statements only and run this on its own.

Return to “Python”