How to share files and web dev projects over your local network, using Python

Oct 7, 2013 • Karen


Alice and Bob are sitting at home, hacking on their laptops, each connected to their home wifi network. Alice is getting started with Django, and runs:

$ startproject mysite
$ cd mysite
$ python runserver 8080
Validating models...

0 errors found
October 07, 2013 - 17:12:31
Django version 1.5.4, using settings 'mysite.settings'
Development server is running at
Quit the server with CONTROL-C.

Alice opens her browser to look at her new Django website. Because of a previous web development project, localhost autocompletes to localhost:3000, which she accidentally tries to load. Her browser displays a connection refused error. Whoops, thinks Alice. My browser tried to get data from a port number that the Django built-in server application isn't listening to, and nothing else is listening to that port, so it refused the connection.


Alice corrects the port number, and when she visits localhost:8080 in her browser, she sees the default Django 'It works!' page.

"Hey, Bob!" Alice cries to her housemate in the other room, "Check out my awesome Django site!" She quickly pastes the localhost:8080 link into a chat window for Bob.

Bob clicks the link. "Alice, I'm not seeing your site. I just get a connection refused error."

"Oh, sorry, I gave you a link referring to localhost, which is a hostname for whatever computer requests it. It only works on my computer since I'm hosting the site. Let me send you a different link..." Alice sends Bob winterfell:8080, since winterfell is the name of her computer.

"That link didn't work either," replies Bob.

Alice is confused. She does some research, and comes across an article explaining that not only do computers have port numbers, they also have interfaces. She runs:

$ ifconfig

and gets back

eth1 Link encap:Ethernet HWaddr f0:de:f1:bf:61:75
      RX packets:0 errors:0 dropped:0 overruns:0 frame:0
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000
      RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
      Interrupt:20 Memory:f2500000-f2520000

lo Link encap:Local Loopback
      inet addr: Mask:
      inet6 addr: ::1/128 Scope:Host
      UP LOOPBACK RUNNING MTU:65536 Metric:1
      RX packets:64904 errors:0 dropped:0 overruns:0 frame:0
      TX packets:64904 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0
      RX bytes:13965657 (13.9 MB) TX bytes:13965657 (13.9 MB)

wlan1 Link encap:Ethernet HWaddr 60:d8:19:c7:0f:91
      inet addr: Bcast: Mask:
      inet6 addr: fe80::62d8:19ff:fec7:f91/64 Scope:Link
      RX packets:3800909 errors:0 dropped:0 overruns:0 frame:0
      TX packets:2102641 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000
      RX bytes:217109512 (217.1 MB) TX bytes:346745106 (346.7 MB)

Oh, thinks Alice, my computer has three interfaces listed here. eth1 must be my laptop's ethernet jack, which isn't plugged in right now. lo is probably localhost, which is only accessible inside my computer. And that means wlan1 is my wifi card, which I'm connecting to the Internet with right now.

Alice also reads that by default, the Django built-in webserver only serves on the 'localhost' (also known as interface. From this Alice surmises, Bob wasn't able to access my site because Django's web server is only listening to port 8080 on the localhost interface--my wifi card's interface doesn't have anything listening to port 8080.

Alice learns that she can change this default behavior by changing the IP address that her site is served on to

$ python runserver means that the server will listen to the given port (in this case 8080) on all interfaces, not just localhost.

Alice does this, then asks Bob to try the link again. He does.

"Cool, Alice! ...but isn't this built into Django?"

"Shush, it's in alpha."

Sharing the contents of any directory

The next day, Alice's friend Carol visits and she and Alice want to watch a movie together. The movie is on Carol's laptop, which has a small screen and mostly-broken speakers. Alice, on the other hand, has an excellent computer connected to a huge HD monitor and great sound system.

"Alice, I'd like to watch the movie on your computer, but I don't have a flash drive to easily move the movie file over," says Carol. "What should we do?"

Alice, who has been reading a bit more about Python and servers, says, "I know! Do you have Python installed on your laptop?"

Carol does, so Alice opens a terminal, cds into the directory where the movie file is, and runs

$ python -m SimpleHTTPServer 8080
Serving HTTP on port 8080 ...

Alice has previously learned that unlike the built-in Django web server, SimpleHTTPServer by default listens to all interfaces at whatever port you specify (or port 8000 if unspecified), so she does not have to provide for the IP address.

Alice then opens the video player program on her computer, finds the option to stream from a URL, and enters


into the URL field, where fuji is the name of Carol's laptop and awesome_movie.mp4 is the file name for the video.

Alice hits play, and after only a bit of buffering (for Alice and Bob's wifi router is quite fast and high quality) she and Carol happily settle down and watch the movie.