Introduction: Python Web Server for Your Raspberry Pi

Picture of Python Web Server for Your Raspberry Pi

Note: If you want only a web server that doesn't require Python, check out this tutorial I made for a super easy web server for the Raspberry Pi.

You know some basic Python or you want to learn some and you want to make a website, a web server, a web crawler, etc. - But where do you start? Services like Heliohost or Vlexofree are great for free Python website hosting, but they are not always reliable, have a position queue, or have too much restriction for your project. So you have a Raspberry Pi and Instructables.com and you find my tutorial that describes just what you are looking for. I'll teach you how to set up and use a simple web server framework called Flask along with a basic idea about what you can do with your new Python-based web server.

Step 1: Installing Raspbian

Picture of Installing Raspbian

Raspbian is a distribution of Debian, a Linux operating system. Raspbian is the most common OS for your Raspberry Pi.

1) To download Raspbian, go to http://www.raspberrypi.org/downloads/ and download Raspbian via either torrent or direct download.

2) Extract the zip file (Right click & click extract for windows; Right click and click Open with > Archive Utility for mac).

3) Plug in your SD card for your Raspberry Pi into your computer.

4) Copy the Raspbian files to your SD card. I have tried mounting them using Win32DiskImager but I had no success with that.

5) Set up your Raspberry Pi by plugging it into a power source, attaching the Ethernet cable (Internet cable), connecting it to a TV (AV or HDMI; Also an audio cable if you are using AV), attaching a mouse, and attaching a keyboard.

6) Go through the setup process

7) Type 'startx' and hit Enter if you want to launch the desktop mode (Don't use desktop mode when you are running your website as it will use more power and available resources)

8) If you are in desktop mode, you can test to see if your internet works by opening your browser. If you are still in terminal mode, then you can test your internet by typing 'ping google.com' and hitting Enter.

This tutorial is more easily accomplished in desktop mode. To do terminal commands in desktop mode, open the terminal via the explorer bar's icon that looks like an empty monitor.

Step 2: Installing Flask

Picture of Installing Flask

Pip is a common package installer. We will use this to get Flask. You will need an internet connection.

In the terminal, type the following:

sudo apt-get install python-pip

Hit enter and then type the following:

sudo pip install Flask

Remember, this is case-sensitive!

With this you get a WSGI compliant web framework, a web server, and a templating engine (Jina2 templates).

Step 3: Making Your First Python Web Page

Picture of Making Your First Python Web Page

First, make a new folder in /home/pi and call it whatever you want. For this tutorial I will called it 'website'. Then, make a file called hello.py. You can make a hello.txt and then change the .txt to .py. Open this Python file with one of the text editors that comes with Raspbian.

If you go to the Flask website, as of 3/31/15, you will first see the following example code:

from flask import Flask
app = Flask(__name__)

@app.route("/") def hello():

return "Hello World!"

if __name__ == "__main__":

app.run(host='0.0.0.0')

So let's go through what this means.

from flask import Flask
The first line imports the Flask library. This allows Python to use commands from the Flask library.

app = Flask(__name__)

This second line gives a name to your application. __name__ is a bland and default name. It only works if you are using the default modules (Libraries). If you want to give your application a custom name, replace __name__ with 'YourApplicationName' - Of course, change what is in the apostrophes. If you are importing this Python script from another application, you would want to set __name__ to your module (Source file) name. If you still use __name__, then Python will automatically set it to __main__ when it runs.


@app.route("/") def hello():

return "Hello World!"

This is the bread and butter of your Python web server. @app.route("/") defines where a page is. With only a "/" as the path, "Hello World!" will be returned to the home page whenever someone tries to access it. def hello(): describes what is called a function. Anything that is indented under that function will be part of what happens when someone accesses the homepage. You can't start your function name with a number!


if __name__ == "__main__":

app.run()

As I said before, __name__ will automatically be read as __main__ when Python runs the script. So it is saying that if __name__ == "__main__" then run the app. Remember that app is set to __name__, which is the application!

Adding more to what is printed to a page

To add more to what is returned when someone accesses a page, you can write entire Python scripts in the def hello(): function! Try starting out with some basic things like math functions and concatenating numbers with strings. Here is a basic example of what you can put in your def hello(): function:

printedText = "Hello World! This is a basic Python script that concatenates the integer "+str(5)+" with the rest of this string!"

printedTextLen = "The length of the previous sentence is "+str(len(printedText))+" characters."

return printedText, "
", printedTextLen

The "
"
is a line break written in HTML format. It would be the same as if you were to hit Enter on your keyboard in a text editor. A web browser will see this as HTML and automatically make a line break.

Step 4: You're Done! (Kind Of)

Picture of You're Done! (Kind Of)

You can now start your Python web server. Simply type in the terminal:

cd /home/pi/website

python hello.py

'cd' means 'Change Directory'. It will change the terminal directory to /home/pi/website. /website/ is the website folder you created earlier. Using the keyword python in the beginning of a terminal statement automatically switches to the Python interpreter. Saying hello.py after that makes the Python interpreter run hello.py, your hello world script.

Now go to a different computer on the SAME network as the Raspberry Pi and try typing in one of the following into your web address bar:

http://0.0.0.0:5000/

http://raspberrypi:5000/

http://YourRaspberryPi'sIPAddressHere:5000/

The last one is probably going to work. To get your Raspberry Pi's LOCAL IP address, NOT your PUBLIC IP address, you must go into terminal and type in the following:

sudo ifconfig

You will get something returned like what is shown in the above picture. Your local IP address will be what follows inet addr. You can also try logging into your router to find your Raspberry Pi's local IP address.

Step 5: Returning HTML Files

Picture of Returning HTML Files

So, I'm guessing you're a little overwhelmed about all of the programming but a little underwhelmed about what you get out of it. Guess what, you don't need to write your pages in Python! You can keep it simple and use the Jinja2 template program that already comes with Flask. This will allow you to drag-and-drop your HTML, CSS, and web-scripting files into a folder and you DON'T need to edit them for Python! So let's start off with a basic HTML page with some basic styling.

<html>

<head>

<title>My Python Website!</title>
</head>

<body>

<h1><font size="6" color="red" face="verdana">Welcome to my Python-based website!</font></h1>

<p><b><i><font size="3" color="gray" face="verdana">This is my first Python-based website that is running on my Raspberry Pi!</font></i></b></p>

</body>

</html>

See how simple HTML is? It is a VERY easy language to learn because it is much like english! So save that as whatever you want, but make sure that it has .html, not .txt. Now make a folder in the same directory as your Python files and call it templates . Make sure that templates is spelled WITHOUT capitalization and that is includes an 's' at the end. The exact spelling must be templates . Place your HTML file in the templates folder. Then REPLACE your hello.py file with the following code.

from flask import Flask

from flask import render_template

app = Flask(__name__)

@app.route('/')

def mypysite(name=None):

return render_template('index.html')

if __name__ == "__main__":

app.run('0.0.0.0')


So go to your terminal and use cd (Change directory) to navigate to your website folder as you did before. Type python hello.py to run your server. Open up the website on a different computer on the SAME network and you will see that index.html will run! index.html is the HTML file I wrote above.

Step 6: Making It LIVE!

Picture of Making It LIVE!

You've made your Python website and it was pretty easy, wasn't it? Well now it is time to go live!

First, log into your router. To do this, do one of the following:

For Windows: Hold the WinKey+R and type in 'cmd'. Hit enter and you have your command prompt. Type 'ipconfig' and hit enter. Look for your Default Gateway. Mine is 10.0.0.1, but yours might be something like 192.168.1.1 or 192.168.1.254 .

For Mac: On your mac bar, click the Apple button and then System Preferences. Select Network under Internet and Wireless. Select your connected network. Click the TCP/IP tab and your router's IP will be displayed below.

For linux (Maybe mac): Open terminal and type the following: route -n | grep 'UG[ \t]' | awk '{print $2}' (Or just copy/paste it). It will return ONLY your default gateway (Router IP address). Tell me if I am wrong that this also works for mac.

Now that you have your router's IP address, type it into your browser and hit enter. You will probably get a log in form. Usually, the log in is admin:password or admin:admin. You will need to consult with your network administrator if you are not the administrator. For more information about finding your router's log in information, go to Portforward.com's password list OR look for it on one of the sides of your router.

Once you've logged into your router, try to navigate to your portforwarding section. This will be different for all routers. Portforward.com may also help with this. Once there, you want to click something along the lines of "Add Service". Below is the information you want to fill out. If you have extra boxes, try leaving them blank or adding what you think is the necessary information. If you don't have to fill out all of the information I provide, then try with what you can.

Information for portforwarding:

Service Name: HTTP

Service Type: TCP/UDP (Sometimes listed as 'Both')

Server IPv4 Address: Your Raspberry Pi's LOCAL IP address. You found this in previous steps.

Server IPv6 Address: You don't need this as of today. You may need this in the future with the need for more IP addresses.

Starter Port: 5000

End Port: 5000

Finally, you can click SAVE!

Step 7: Getting a Dynamic DNS

Picture of Getting a Dynamic DNS

Some bad news: Your IP changes once in a while. You will have to change everything you worked on to match every new IP you get. To stop this, I recommend getting a dynamic DNS. Setting your IP to reserved will not entirely fix your problem. You can Google 'Free Dynamic DNS' and you will get loads of great ddns services. I, however, prefer RaspCTL's DDNS service. It is free, specific for the Raspberry Pi (Although it doesn't make a difference for what you use it for), and it is very QUICK and EASY to sign up and use.

EDIT: RaspCTL has shutdown. Refer to this thread for help setting up a DDNS for your Pi until I can update this tutorial: https://www.reddit.com/r/raspberry_pi/comments/5z7...

For RaspCTL, click Login on the top right corner of the page, click "Create an account", and sign up. You are in. Change your IP address on the RaspCTL dashboard to your PUBLIC IP address. To get this, go to Google and search "my ip address". Copy and paste that into your RaspCTL dashboard. To install RaspCTL onto your Raspberry Pi, type the following into the terminal:

wget debrepo.krenel.org/raspctl.asc

cat raspctl.asc | sudo apt-key add -

echo "deb http://debrepo.krenel.org/ raspctl main" | sudo tee /etc/apt/sources.list.d/raspctl.list

sudo aptitude update

sudo aptitude install raspctl-dynamicdns


This is to configure RaspCTL:

sudo $EDITOR /etc/raspctl/dynamic-dns.conf

UUID = YOUR-UUID-HERE


Now run this and you are done:

sudo raspctl-dynamicdns


Important note for RaspCTL: Right now the client (the program that updates your IP if changed) is launched EVERY HOUR by a cron script (see /etc/cron.hourly/*). If you need more frequent checks (let's say, every minute), send the owner of RaspCTL an email at: jcarreras@krenel.org

Test that it works by typing the following into terminal:

sudo apt-get install dnsutils -y

nslookup your-username-here.raspctl.com


Example of what you will get after the previous command:
nslookup ip.raspctl.com

[...] answer cutted [...]

Name: ip.raspctl.com

Address: 192.81.216.84


You're pretty much done! The server name you made on RaspCTL is your website address with a :5000 after it. Here is my current project I am working on:

http://tcserver.raspctl.com:5000/

Step 8: Remotely Accessing Your Pi

Picture of Remotely Accessing Your Pi

To remotely access your Raspberry Pi, you can get use Putty or FileZilla. Just put in your local IPv4 address, your port number (In this case is 22 for SSH), and your login info. You will need your login info after you connect when using putty. You'd use FileZilla for file transfers and Putty for doing what you'd do as if you were in the terminal on your Pi.

Step 9: Possibilities

Picture of Possibilities

You can make fully-functional websites, webcrawlers, personal clouds, etc. with your new Python website. With Python, you can also control your GPIO pins. I haven't tried this, but the sky is your limit!

Comments

dulllou (author)2017-03-26

Thanks for a great instructable but RaspCTL's domain just expired and got taken by others. Please note and update the instructable if possible, thanks :)

knexpert1700 (author)dulllou2017-03-26

Thanks, I will update the DDNS section when I have the time

DavidN311 (author)2017-02-27

HI I'm working through it right now, however I am having trouble with Step 7. So I have set up the Domain name on Dynamic DNs but I am slightly confused on how to Upload Files to the new website Or how to access the website at all. Complete noob any help would be appreciated ;)!

buteman (author)2016-12-24

Thanks for a great instructable.

I have been using xvnc4server and accessing my pi that way so I could run a script on it from my laptop to control a robot. The Pi is the brains on the robot.

It seriously reduces my internet speed on other kit. Can I incorporate my python code into the web server and access the Pi's GPIO through it?

rroderickk (author)2016-12-16

Hello friend how can you publish the website on the internet, how many users could you host at the same time ?, and how can you change the url to make it friendlier? I wait your answer: D

ivorykoder made it! (author)2016-10-09

Thanks for the a very handy minimalistic tutorial to get started for newbie (in RPi and Python) like me. I would like to point out that, before you are adding port forwarding for our raspberry's IP, you should ensure your RPi a static IP. Very small point though. Thanks once again!

papernapkinhead (author)2015-04-04

Thanks for the tutorial! One bit you may want to add is that you'll want to call app.run(host='0.0.0.0') vs. app.run() if you want other machines on the network to be able to access the page (at least I did). Also, the code snippets have some spacing issues which may cause trouble for folks copy/pasting. I'd suggest using a GitHub Gist if Instructables allows that sort of thing. Thanks again!!

I agree about code formatting for newbies. The article may include a note pointing out the code formatting issues.

kylovader (author)2016-02-06

Thank you for a great introduction on setting up a Python web server on Raspberry Pi!

elsep2003 (author)2015-04-02

I've just discovered flask, its a great. its perfect for what I need. Thank you.

mmanuel2 (author)2015-04-02

Thanks for this. Great starting point.

Quick suggestion: In Step 4, this URL http://localhost:5000/ will never work to access the Pi from another computer on the network. localhost always refers to the computer that is running the browser (your Mac or PC.)

knexpert1700 (author)mmanuel22015-04-02

Thanks