20

I am trying to do something that I assume is very simple, but since I am fairly new to Python I haven't been able to find out how. I need to execute a function in my Python script when a URL is called.

For example, I would visit the following URL in my browser (192.168.0.10 being the IP of the computer I am running the script on, and 8080 being the port of choice).

http://192.168.0.10:8080/captureImage

When this URL is visited, I would like to perform an action in my Python script, in this case execute a function I made.

I know this might be fairly simple, but I haven't been able to find out how this can be done. I would appreciate any help!

Lazze
  • 323
  • 2
  • 7
  • 17
  • To start with, you'll need a web server. Do you already have a web server installed and running on that computer? – Robᵩ Oct 17 '13 at 19:02
  • if u r using windows this link might work http://stackoverflow.com/questions/3179657/python-webbrowser-question – Thothadri Rajesh Oct 17 '13 at 19:28
  • 1
    I think you misunderstood me. I would like the Python script to act as sort of a web server, except I don't need to serve any files. I need to be able to execute a function when a client visits a URL on the server. – Lazze Oct 17 '13 at 20:39

2 Answers2

25

This is indeed very simple to do in python:

import SocketServer
from BaseHTTPServer import BaseHTTPRequestHandler

def some_function():
    print "some_function got called"

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/captureImage':
            # Insert your code here
            some_function()

        self.send_response(200)

httpd = SocketServer.TCPServer(("", 8080), MyHandler)
httpd.serve_forever()

Depending on where you want to go from here, you might want to checkout the documentation for BaseHttpServer, or look into a more full featured web framework like Django.

Nathan Jhaveri
  • 1,834
  • 1
  • 15
  • 17
  • That is exactly what I was looking for, thank you! However, I am running into another problem. When I start the script with your code, the web server stops the rest of the script from executing. This is a problem since I need to execute a function from my script when the URL is called. How would I go about fixing that? – Lazze Oct 18 '13 at 12:37
  • @Lazze - I updated the example to include a function call, does that help? To clarify, is the issue that you want the webserver to only handle one request and then shut down? Or is the problem that there is code after the httpd.serve_forever() line that never runs? (in that case, you can just move the httd.server_forever() line down to the end of your script) – Nathan Jhaveri Oct 18 '13 at 16:03
  • There is code that never runs after the serve_forever(). I will try moving it to the bottom of my script when I get home, will report back. Thank you for the help thus far! – Lazze Oct 18 '13 at 18:04
  • @Lazze Keep in mind that a python script executes top to bottom, line by line. Since serve_forever enters a loop, you'll have to break out of it (you can call self.shutdown() to stop the server) at some point. If you want to call a function, like I did with "some_function", make sure that function definition is before the code that calls it. Feel free to update the post with you code or create a new question if you want me to take a look at your code. – Nathan Jhaveri Oct 18 '13 at 19:28
  • What if I have another loop in my code that never finishes? Would placing the server_forever() in the bottom of my code still work then? – Lazze Oct 18 '13 at 21:02
  • @Lazze - If you have a loop that never finishes, code after that point will never run. If you never call serve_forever(), then the webserver will never run. You can look into using threads, or something like twisted if you want to do multiple things simultaneously, but that will be a lot more complicated. I'd say post your code and we can go from there. – Nathan Jhaveri Oct 18 '13 at 21:10
  • I have posted another question, that way it will hopefully help others too. You can find it here: http://stackoverflow.com/questions/19468020/run-server-alongside-infinite-loop-in-python – Lazze Oct 19 '13 at 15:59
  • can I get request or path parameters in above example.? – viveksinghggits Nov 30 '18 at 13:06
1

One robust way of accomplishing what you need is to use a Python web framework, Flask (http://flask.pocoo.org/). There are Youtube videos that do a good job of explaining Flask basics (https://www.youtube.com/watch?v=ZVGwqnjOKjk).

Here's an example from my motion detector that texts me when my cat is waiting by the door. All that needs to be done to trigger this code is for an HTTP request at the address (in my case) http://192.168.1.112:5000/cat_detected

   from flask import Flask
   import smtplib
   import time


   def email(from_address, to_address, email_subject, email_message):
       server = smtplib.SMTP('smtp.gmail.com:587')
       server.ehlo()
       server.starttls()
       server.login(username, password)
       # For character type new-lines, change the header to read: "Content-Type: text/plain". Use the double \r\n.
       # For HTML style tags for your new-lines, change the header to read:  "Content-Type: text/html".  Use line-breaks <br>.
       headers = "\r\n".join(["from: " + from_address, "subject: " + email_subject,
                       "to: " + to_address,
                       "mime-version: 1.0",
                       "content-type: text/plain"])
       message = headers + '\r\n' + email_message
       server.sendmail(from_address, to_address, message)
       server.quit()
       return time.strftime('%Y-%m-%d, %H:%M:%S')


   app = Flask(__name__)


   @app.route('/cat_detected', methods=['GET'])
   def cat_detected():
       fromaddr = 'CAT ALERT'
       admin_addrs_list = [['YourPhoneNumber@tmomail.net', 'Mark']]  # Use your carrier's format for sending text messages via email.
       for y in admin_addrs_list:
           email(fromaddr, y[0], 'CAT ALERT', 'Carbon life-form standing by the door.')
       print('Email on its way!', time.strftime('%Y-%m-%d, %H:%M:%S'))
       return 'Email Sent!'

   if __name__ == '__main__':
       username = 'yourGmailUserName@gmail.com'
       password = 'yourGmailPassword'
       app.run(host='0.0.0.0', threaded=True)
Markacho
  • 292
  • 2
  • 5