Python Network Programming: David M. Beazley
Python Network Programming: David M. Beazley
Python Network Programming: David M. Beazley
David M. Beazley
http://www.dabeaz.com
1. Network Fundamentals 4
2. Client Programming 32
3. Internet Data Handling 49
4. Web Programming Basics 65
5. Advanced Networks 93
Introduction
Support Files
• Course exercises:
http://www.dabeaz.com/python/pythonnetwork.zip
1
Python Networking
This Course
• This course focuses on the essential details of
network programming that all Python
programmers should probably know
• Low-level programming with sockets
• High-level client modules
• How to deal with common data encodings
• Simple web programming (HTTP)
• Simple distributed computing
Copyright (C) 2010, http://www.dabeaz.com 1- 4
2
Standard Library
• We will only cover modules supported by the
Python standard library
• These come with Python by default
• Keep in mind, much more functionality can be
found in third-party modules
• Will give links to notable third-party libraries as
appropriate
Prerequisites
3
Section 1
Network Fundamentals
The Problem
• Communication between computers
Network
4
Two Main Issues
• Addressing
• Specifying a remote computer and service
• Data transport
• Moving bits back and forth
Network Addressing
• Machines have a hostname and IP address
• Programs/services have port numbers
foo.bar.com
205.172.13.4
port 80
5
Standard Ports
• Ports for common services are preassigned
21 FTP
22 SSH
23 Telnet
25 SMTP (Mail)
80 HTTP (Web)
110 POP3 (Mail)
119 NNTP (News)
443 HTTPS (web)
Using netstat
• Use 'netstat' to view active network connections
shell % netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:imaps *:* LISTEN
tcp 0 0 *:pop3s *:* LISTEN
tcp 0 0 localhost:mysql *:* LISTEN
tcp 0 0 *:pop3 *:* LISTEN
tcp 0 0 *:imap2 *:* LISTEN
tcp 0 0 *:8880 *:* LISTEN
tcp 0 0 *:www *:* LISTEN
tcp 0 0 192.168.119.139:domain *:* LISTEN
tcp 0 0 localhost:domain *:* LISTEN
tcp 0 0 *:ssh *:* LISTEN
...
6
Connections
• Each endpoint of a network connection is always
represented by a host and port #
• In Python you write it out as a tuple (host,port)
("www.python.org",80)
("205.172.13.4",443)
Client/Server Concept
• Each endpoint is a running program
• Servers wait for incoming connections and
provide a service (e.g., web, mail, etc.)
• Clients make connections to servers
Client Server
www.bar.com
205.172.13.4
7
Request/Response Cycle
• Most network programs use a request/
response model based on messages
• Client sends a request message (e.g., HTTP)
GET /index.html HTTP/1.0
<HTML>
...
Using Telnet
• As a debugging aid, telnet can be used to
directly communicate with many services
telnet hostname portnum
• Example:
shell % telnet www.python.org 80
Trying 82.94.237.218...
Connected to www.python.org.
type this Escape character is '^]'.
and press GET /index.html HTTP/1.0
return a few
times HTTP/1.1 200 OK
Date: Mon, 31 Mar 2008 13:34:03 GMT
Server: Apache/2.2.3 (Debian) DAV/2 SVN/1.4.2
mod_ssl/2.2.3 OpenSSL/0.9.8c
...
8
Data Transport
• There are two basic types of communication
• Streams (TCP): Computers establish a
connection with each other and read/write data
in a continuous stream of bytes---like a file. This
is the most common.
• Datagrams (UDP): Computers send discrete
packets (or messages) to each other. Each
packet contains a collection of bytes, but each
packet is separate and self-contained.
Sockets
• Programming abstraction for network code
• Socket: A communication endpoint
socket socket
network
9
Socket Basics
• To create a socket
import socket
s = socket.socket(addr_family, type)
• Address families
socket.AF_INET Internet protocol (IPv4)
socket.AF_INET6 Internet protocol (IPv6)
• Socket types
socket.SOCK_STREAM Connection based stream (TCP)
socket.SOCK_DGRAM Datagrams (UDP)
• Example:
from socket import *
s = socket(AF_INET,SOCK_STREAM)
Socket Types
• Almost all code will use one of following
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s = socket(AF_INET, SOCK_DGRAM)
10
Using a Socket
• Creating a socket is only the first step
s = socket(AF_INET, SOCK_STREAM)
TCP Client
• How to make an outgoing connection
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.connect(("www.python.org",80)) # Connect
s.send("GET /index.html HTTP/1.0\n\n") # Send request
data = s.recv(10000) # Get response
s.close()
11
Exercise 1.1
Time : 10 Minutes
Server Implementation
12
TCP Server
• A simple server
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
TCP Server
• Address binding
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
binds the socket to
s.listen(5) a specific address
while True:
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
13
TCP Server
• Start listening for connections
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000)) Tells operating system to
s.listen(5)
while True:
start listening for
c,a = s.accept() connections on the socket
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
• s.listen(backlog)
• backlog is # of pending connections to allow
• Note: not related to max number of clients
Copyright (C) 2010, http://www.dabeaz.com 1- 21
TCP Server
• Accepting a new connection
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept() Accept a new client connection
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
14
TCP Server
• Client socket and address
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
Accept returns a pair (client_socket,addr)
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
<socket._socketobject ("104.23.11.4",27743)
object at 0x3be30>
This is the network/port
This is a new socket address of the client that
that's used for data connected
TCP Server
• Sending data
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0]) Send data to client
c.close()
15
TCP Server
• Closing the connection
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close() Close client connection
TCP Server
• Waiting for the next connection
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept() Wait for next connection
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
16
Exercise 1.2
Time : 20 Minutes
Advanced Sockets
• Socket programming is often a mess
• Huge number of options
• Many corner cases
• Many failure modes/reliability issues
• Will briefly cover a few critical issues
17
Partial Reads/Writes
• Be aware that reading/writing to a socket
may involve partial data transfer
• send() returns actual bytes sent
• recv() length is only a maximum limit
>>> len(data)
1000000
>>> s.send(data)
37722 Sent partial data
>>>
Partial Reads/Writes
• Be aware that for TCP, the data stream is
continuous---no concept of records, etc.
# Client
...
s.send(data)
s.send(moredata)
...
18
Sending All Data
• To wait until all data is sent, use sendall()
s.sendall(data)
End of Data
• How to tell if there is no more data?
• recv() will return empty string
>>> s.recv(1000)
''
>>>
19
Data Reassembly
• Receivers often need to reassemble
messages from a series of small chunks
• Here is a programming template for that
fragments = [] # List of chunks
while not done:
chunk = s.recv(maxsize) # Get a chunk
if not chunk:
break # EOF. No more data
fragments.append(chunk)
Timeouts
• Most socket operations block indefinitely
• Can set an optional timeout
s = socket(AF_INET, SOCK_STREAM)
...
s.settimeout(5.0) # Timeout of 5 seconds
...
• Disabling timeouts
s.settimeout(None)
20
Non-blocking Sockets
• Instead of timeouts, can set non-blocking
>>> s.setblocking(False)
Socket Options
• Sockets have a large number of parameters
• Can be set using s.setsockopt()
• Example: Reusing the port number
>>> s.bind(("",9000))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in bind
socket.error: (48, 'Address already in use')
>>> s.setsockopt(socket.SOL_SOCKET,
... socket.SO_REUSEADDR, 1)
>>> s.bind(("",9000))
>>>
21
Sockets as Files
• Sometimes it is easier to work with sockets
represented as a "file" object
f = s.makefile()
Sockets as Files
• Commentary : From personal experience,
putting a file-like layer over a socket rarely
works as well in practice as it sounds in theory.
• Tricky resource management (must manage
both the socket and file independently)
• It's easy to write programs that mysteriously
"freeze up" or don't operate quite like you
would expect.
22
Exercise 1.3
Time : 15 Minutes
23
UDP : Datagrams
DATA DATA DATA
UDP Server
• A simple datagram server
from socket import *
s = socket(AF_INET,SOCK_DGRAM) Create datagram socket
s.bind(("",10000)) Bind to a specific port
while True:
data, addr = s.recvfrom(maxsize) Wait for a message
resp = "Get off my lawn!"
s.sendto(resp,addr) Send response
(optional)
• No "connection" is established
• It just sends and receives packets
Copyright (C) 2010, http://www.dabeaz.com 1- 42
24
UDP Client
• Sending a datagram to a server
from socket import *
s = socket(AF_INET,SOCK_DGRAM) Create datagram socket
25
Raw Sockets
• If you have root/admin access, can gain direct
access to raw network packets
• Depends on the system
• Example: Linux packet sniffing
s = socket(AF_PACKET, SOCK_DGRAM)
s.bind(("eth0",0x0800)) # Sniff IP packets
while True:
msg,addr = s.recvfrom(4096) # get a packet
...
browser
web Port 80
web
web
browser
26
Sockets and Concurrency
• Each client gets its own socket on server
# server code
clients
s = socket(AF_INET, SOCK_STREAM) server
...
while True:
c,a = s.accept()
... browser
web a connection
point for clients
web
web client data
transmitted
browser
on a different
socket
browser
web Port 80
web
connect accept()
web
browser web
send()/recv()
browser
Copyright (C) 2010, http://www.dabeaz.com 1- 48
27
Sockets and Concurrency
• To manage multiple clients,
• Server must always be ready to accept
new connections
• Must allow each client to operate
independently (each may be performing
different tasks on the server)
• Will briefly outline the common solutions
Threaded Server
• Each client is handled by a separate thread
import threading
from socket import *
def handle_client(c):
... whatever ...
c.close()
return
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
t = threading.Thread(target=handle_client,
args=(c,))
28
Forking Server (Unix)
• Each client is handled by a subprocess
import os
from socket import *
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
if os.fork() == 0:
# Child process. Manage client
...
c.close()
os._exit(0)
else:
# Parent process. Clean up and go
# back to wait for more connections
c.close()
Asynchronous Server
• Server handles all clients in an event loop
import select
from socket import *
s = socket(AF_INET,SOCK_STREAM)
...
clients = [] # List of all active client sockets
while True:
# Look for activity on any of my sockets
input,output,err = select.select(s+clients,
clients, clients)
# Process all sockets with input
for i in input:
...
# Process all sockets ready for output
for o in output:
...
29
Utility Functions
• Get the hostname of the local machine
>>> socket.gethostname()
'foo.bar.com'
>>>
Omissions
• socket module has hundreds of obscure
socket control options, flags, etc.
• Many more utility functions
• IPv6 (Supported, but new and hairy)
• Other socket types (SOCK_RAW, etc.)
• More on concurrent programming (covered in
advanced course)
30
Discussion
• It is often unnecessary to directly use sockets
• Other library modules simplify use
• However, those modules assume some
knowledge of the basic concepts (addresses,
ports, TCP, UDP, etc.)
• Will see more in the next few sections...
31
Section 2
Client Programming
Overview
32
urllib Module
• A high level module that allows clients to
connect a variety of internet services
• HTTP
• HTTPS
• FTP
• Local files
• Works with typical URLs on the web...
Copyright (C) 2010, http://www.dabeaz.com 2- 3
urllib Module
• Open a web page: urlopen()
>>> import urllib
>>> u = urllib.urlopen("http://www.python/org/index.html")
>>> data = u.read()
>>> print data
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ...
...
>>>
33
urllib protocols
• Supported protocols
u = urllib.urlopen("http://www.foo.com")
u = urllib.urlopen("https://www.foo.com/private")
u = urllib.urlopen("ftp://ftp.foo.com/README")
u = urllib.urlopen("file:///Users/beazley/blah.txt")
HTML Forms
• One use of urllib is to automate forms
34
HTML Forms
• Within the form, you will find an action and
named parameters for the form fields
<FORM ACTION="/subscribe" METHOD="POST">
Your name: <INPUT type="text" name="name" size="30"><br>
Your email: <INPUT type="text" name="email" size="30"><br>
<INPUT type="submit" name="submit-button" value="Subscribe">
• Action (a URL)
http://somedomain.com/subscribe
• Parameters:
name
email
Web Services
• Another use of urllib is to access web services
• Downloading maps
• Stock quotes
• Email messages
• Most of these are controlled and accessed in
the same manner as a form
• There is a particular request and expected set
of parameters for different operations
35
Parameter Encoding
• urlencode()
• Takes a dictionary of fields and creates a
URL-encoded string of parameters
fields = {
'name' : 'Dave',
'email' : '[email protected]'
}
parms = urllib.urlencode(fields)
• Sample result
>>> parms
'name=Dave&email=dave%40dabeaz.com'
>>>
Sending Parameters
• Case 1 : GET Requests
<FORM ACTION="/subscribe" METHOD="GET">
Your name: <INPUT type="text" name="name" size="30"><br>
Your email: <INPUT type="text" name="email" size="30"><br>
<INPUT type="submit" name="submit-button" value="Subscribe">
• Example code:
fields = { ... }
parms = urllib.urlencode(fields)
u = urllib.urlopen("http://somedomain.com/subscribe?"+parms)
http://somedomain.com/subscribe?name=Dave&email=dave%40dabeaz.com
36
Sending Parameters
• Case 2 : POST Requests
<FORM ACTION="/subscribe" METHOD="POST">
Your name: <INPUT type="text" name="name" size="30"><br>
Your email: <INPUT type="text" name="email" size="30"><br>
<INPUT type="submit" name="submit-button" value="Subscribe">
• Example code:
fields = { ... }
parms = urllib.urlencode(fields)
u = urllib.urlopen("http://somedomain.com/subscribe", parms)
Response Data
• To read response data, treat the result of
urlopen() as a file object
>>> u = urllib.urlopen("http://www.python.org")
>>> data = u.read()
>>>
37
Response Headers
• HTTP headers are retrieved using .info()
>>> u = urllib.urlopen("http://www.python.org")
>>> headers = u.info()
>>> headers
<httplib.HTTPMessage instance at 0x1118828>
>>> headers.keys()
['content-length', 'accept-ranges', 'server',
'last-modified', 'connection', 'etag', 'date',
'content-type']
>>> headers['content-length']
'13597'
>>> headers['content-type']
'text/html'
>>>
• A dictionary-like object
Copyright (C) 2010, http://www.dabeaz.com 2- 13
Response Status
• urlopen() ignores HTTP status codes (i.e.,
errors are silently ignored)
• Can manually check the response code
u = urllib.urlopen("http://www.python.org/java")
if u.code == 200:
# success
...
elif u.code == 404:
# Not found!
...
elif u.code == 403:
# Forbidden
...
38
Exercise 2.1
Time : 15 Minutes
urllib Limitations
39
urllib2 Module
urllib2 Example
• urllib2 provides urlopen() as before
>>> import urllib2
>>> u = urllib2.urlopen("http://www.python.org/index.html")
>>> data = u.read()
>>>
40
urllib2 Requests
• Requests are now objects
>>> r = urllib2.Request("http://www.python.org")
>>> u = urllib2.urlopen(r)
>>> data = u.read()
r = urllib2.Request("http://somedomain.com/subscribe",
urllib.urlencode(data))
u = urllib2.urlopen(r)
response = u.read()
41
Request Headers
• Adding/Modifying client HTTP headers
headers = {
'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 7.0;
Windows NT 5.1; .NET CLR 2.0.50727)'
}
r = urllib2.Request("http://somedomain.com/",
headers=headers)
u = urllib2.urlopen(r)
response = u.read()
• Catching an error
try:
u = urllib2.urlopen(url)
except urllib2.HTTPError,e:
code = e.code # HTTP error code
42
urllib2 Openers
• The function urlopen() is an "opener"
• It knows how to open a connection, interact
with the server, and return a response.
• It only has a few basic features---it does not
know how to deal with cookies and passwords
• However, you can make your own opener
objects with these features enabled
urllib2 build_opener()
• build_opener() makes an custom opener
# Make a URL opener with cookie support
opener = urllib2.build_opener(
urllib2.HTTPCookieProcessor()
)
u = opener.open("http://www.python.org/index.html")
43
Example : Login Cookies
fields = {
'txtUsername' : 'dave',
'txtPassword' : '12345',
'submit_login' : 'Log In'
}
opener = urllib2.build_opener(
urllib2.HTTPCookieProcessor()
)
request = urllib2.Request(
"http://somedomain.com/login.asp",
urllib.urlencode(fields))
# Login
u = opener.open(request)
resp = u.read()
Discussion
44
Exercise 2.2
Time : 15 Minutes
Password: guido456
Limitations
• urllib and urllib2 are useful for fetching files
• However, neither module provides support for
more advanced operations
• Examples:
• Uploading to an FTP server
• File-upload via HTTP Post
• Other HTTP methods (e.g., HEAD, PUT)
Copyright (C) 2010, http://www.dabeaz.com 2- 28
45
ftplib
• A module for interacting with FTP servers
• Example : Capture a directory listing
>>> import ftplib
>>> f = ftplib.FTP("ftp.gnu.org","anonymous",
... "[email protected]")
>>> files = []
>>> f.retrlines("LIST",files.append)
'226 Directory send OK.'
>>> len(files)
15
>>> files[0]
'-rw-r--r-- 1 0 0 1765 Feb 20 16:47 README'
>>>
import ftplib
ftp_serv = ftplib.FTP(host,username,password)
46
httplib
• A module for implementing the client side of an
HTTP connection
import httplib
c = httplib.HTTPConnection("www.python.org",80)
c.putrequest("HEAD","/tut/tut.html")
c.putheader("Someheader","Somevalue")
c.endheaders()
r = c.getresponse()
data = r.read()
c.close()
smtplib
• A module for sending email messages
import smtplib
serv = smtplib.SMTP()
serv.connect()
msg = """\
From: [email protected]
To: [email protected]
Subject: Get off my lawn!
serv.sendmail("[email protected]",['[email protected]'],msg)
47
Exercise 2.3
Time : 15 Minutes
48
Section 3
Overview
49
CSV Files
• Comma Separated Values
Elwood,Blues,"1060 W Addison,Chicago 60637",110
McGurn,Jack,"4902 N Broadway,Chicago 60640",200
Parsing HTML
50
Parsing HTML
• Define a class that inherits from HTMLParser
and define a set of methods that respond to
different document features
from HTMLParser import HTMLParser
class MyParser(HTMLParser):
def handle_starttag(self,tag,attrs):
...
def handle_data(self,data):
...
def handle_endtag(self,tag):
...
Running a Parser
• To run the parser, you create a parser object
and feed it some data
# Fetch a web page
import urllib
u = urllib.urlopen("http://www.example.com")
data = u.read()
51
HTML Example
• An example: Gather all links
from HTMLParser import HTMLParser
class GatherLinks(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.links = []
def handle_starttag(self,tag,attrs):
if tag == 'a':
for name,value in attrs:
if name == 'href':
self.links.append(value)
HTML Example
• Running the parser
>>> parser = GatherLinks()
>>> import urllib
>>> data = urllib.urlopen("http://www.python.org").read()
>>> parser.feed(data)
>>> for x in parser.links:
... print x
/search/
/about
/news/
/doc/
/download/
...
>>>
52
XML Parsing with SAX
53
SAX Parsing
• Define a special handler class
import xml.sax
class MyHandler(xml.sax.ContentHandler):
def startDocument(self):
print "Document start"
def startElement(self,name,attrs):
print "Start:", name
def characters(self,text):
print "Characters:", text
def endElement(self,name):
print "End:", name
SAX Parsing
• To parse a document, you create an instance
of the handler and give it to the parser
# Create the handler object
hand = MyHandler()
54
Exercise 3.1
Time : 15 Minutes
55
etree Parsing Basics
• Parsing a document
from xml.etree.ElementTree import parse
doc = parse("recipe.xml")
56
Obtaining Elements
<?xml version="1.0" encoding="iso-8859-1"?>
<recipe>
<title>Famous Guacamole</title>
<description>
A southwest favorite!
</description>
<ingredients>
<item num="2">Large avocados, chopped</item>
doc =chopped</item>
<item num="1">Tomato, parse("recipe.xml")
desc_elem = doc.find("description")
<item num="1/2" units="C">White onion, chopped</item>
<item num="1" units="tbl">Fresh squeezed lemon juice</item>
desc_text = desc_elem.text
<item num="1">Jalapeno pepper, diced</item>
or
<item num="1" units="tbl">Fresh cilantro, minced</item>
<item num="3" units="tsp">Sea Salt</item>
doc = parse("recipe.xml")
<item num="6" units="bottles">Ice-cold beer</item>
</ingredients> desc_text = doc.findtext("description")
<directions>
Combine all ingredients and hand whisk to desired consistency.
Serve and enjoy with ice-cold beers.
</directions>
</recipe>
57
Element Attributes
<?xml version="1.0" encoding="iso-8859-1"?>
<recipe>
<title>Famous Guacamole</title>
<description>
A southwest favorite!
</description>
<ingredients>
<item num="2">Large avocados, chopped</item>
for item
<item in doc.findall("ingredients/item"):
num="1">Tomato, chopped</item>
num
<item = item.get("num")
num="1/2" units="C">White onion, chopped</item>
<item num="1"
units units="tbl">Fresh squeezed lemon juice</item>
= item.get("units")
<item num="1">Jalapeno pepper, diced</item>
<item num="1" units="tbl">Fresh cilantro, minced</item>
<item num="3" units="tsp">Sea Salt</item>
<item num="6" units="bottles">Ice-cold beer</item>
</ingredients>
<directions>
Combine all ingredients and hand whisk to desired consistency.
Serve and enjoy with ice-cold beers.
</directions>
</recipe>
Search Wildcards
• Specifying a wildcard for an element name
items = doc.findall("*/item")
items = doc.findall("ingredients/*")
58
Search Wildcards
• Wildcard for multiple nesting levels (//)
items = doc.findall("//item")
• More examples
<?xml version="1.0"?>
<top>
<a>
<b>
<c>text</c> c = doc.findall("//c")
</b> c = doc.findall("a//c")
</a>
</top>
cElementTree
• There is a C implementation of the library
that is significantly faster
import xml.etree.cElementTree
doc = xml.etree.cElementTree.parse("data.xml")
59
Tree Modification
• ElementTree allows modifications to be
made to the document structure
• To add a new child to a parent node
node.append(child)
Tree Output
• If you modify a document, it can be rewritten
• There is a method to write XML
doc = xml.etree.ElementTree.parse("input.xml")
# Make modifications to doc
...
# Write modified document back to a file
f = open("output.xml","w")
doc.write(f)
60
Iterative Parsing
• An alternative parsing interface
from xml.etree.ElementTree import iterparse
parse = iterparse("file.xml", ('start','end'))
Iterative Parsing
• If you combine iterative parsing and tree
modification together, you can process
large XML documents with almost no
memory overhead
• Programming interface is significantly easier
to use than a similar approach using SAX
• General idea : Simply throw away the
elements no longer needed during parsing
61
Iterative Parsing
• Programming pattern
from xml.etree.ElementTree import iterparse
parser = iterparse("file.xml",('start','end'))
Exercise 3.2
Time : 15 Minutes
62
JSON
• Javascript Object Notation
• A data encoding commonly used on the
web when interacting with Javascript
• Sometime preferred over XML because it's
less verbose and faster to parse
• Syntax is almost identical to a Python dict
63
Processing JSON Data
• Parsing a JSON document
import json
doc = json.load(open("recipe.json"))
Exercise 3.3
Time : 15 Minutes
64
Section 4
Introduction
65
Overview
Disclaimer
• Web programming is a huge topic that
could span an entire multi-day class
• It might mean different things
• Building an entire website
• Implementing a web service
• Our focus is on some basic mechanisms
found in the Python standard library that all
Python programmers should know about
66
HTTP Explained
• HTTP is the underlying protocol of the web
• Consists of requests and responses
GET /index.html
67
HTTP Responses
• Server sends back a response
HTTP/1.1 200 OK
Date: Thu, 26 Apr 2007 19:54:01 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) DAV/2 SVN/1.1.4 mod_python/3.1.3 Pyt
Last-Modified: Thu, 26 Apr 2007 18:40:24 GMT
Accept-Ranges: bytes
Content-Length: 14315
Connection: close
Content-Type: text/html
<HTML>
...
HTTP Protocol
• There are a small number of request types
GET
POST
HEAD
PUT
68
Content Encoding
• Content is described by these header fields:
Content-type:
Content-length:
• Example:
Content-type: image/jpeg
Content-length: 12422
Payload Packaging
• Responses must follow this formatting
Headers
...
Content-type: image/jpeg
Content-length: 12422
...
Content
(12422 bytes)
69
Exercise 4.1
Time : 10 Minutes
Role of Python
• Most web-related Python programming
pertains to the operation of the server
GET /index.html
70
Typical Python Tasks
Content Generation
• It is often overlooked, but Python is a useful
tool for simply creating static web pages
• Example : Taking various pages of content,
adding elements, and applying a common
format across all of them.
• Web server simply delivers all of the generated
content as normal files
71
Example : Page Templates
• Create a page "template" file
<html>
<body>
<table width=700>
<tr><td>
Your Logo : Navigation Links
<hr>
</td></tr>
Note the <tr><td>
special $content
$variable <hr>
<em>Copyright (C) 2008</em>
</td></tr>
</table>
</body>
</html>
# Go make content
page = make_content()
72
Commentary
Exercise 4.2
Time : 10 Minutes
73
HTTP Servers
• Python comes with libraries that implement
simple self-contained web servers
• Very useful for testing or special situations
where you want web service, but don't want
to install something larger (e.g., Apache)
• Not high performance, sometimes "good
enough" is just that
74
Exercise 4.3
Time : 10 Minutes
75
CGI Scripting
• Common Gateway Interface
• A common protocol used by existing web
servers to run server-side scripts, plugins
• Example: Running Python, Perl, Ruby scripts
under Apache, etc.
• Classically associated with form processing,
but that's far from the only application
CGI Example
• A web-page might have a form on it
76
CGI Example
• Forms have submitted fields or parameters
<FORM ACTION="/cgi-bin/subscribe.py" METHOD="POST">
Your name: <INPUT type="text" name="name" size="30"><br>
Your email: <INPUT type="text" name="email" size="30"><br>
<INPUT type="submit" name="submit-button" value="Subscribe">
CGI Example
• Request encoding looks like this:
Request POST /cgi-bin/subscribe.py HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS
Accept: text/xml,application/xml,application/xhtml
Accept-Language: en-us,en;q=0.5
...
Query name=David+Beazley&email=dave%40dabeaz.com&submit-
String button=Subscribe HTTP/1.1
77
CGI Mechanics
• CGI was originally implemented as a scheme
for launching processing scripts as a subprocess
to a web server
/cgi-bin/subscribe.py
HTTP Server
Python
request and carry out
subscribe.py
some kind of action
78
CGI Query Variables
• For GET requests, an env. variable is used
query = os.environ['QUERY_STRING']
cgi Module
• A utility library for decoding requests
• Major feature: Getting the passed parameters
#!/usr/bin/env python
# subscribe.py
import cgi
form = cgi.FieldStorage() Parse parameters
# Get various field values
name = form.getvalue('name')
email = form.getvalue('email')
79
CGI Responses
• CGI scripts respond by simply printing
response headers and the raw content
name = form.getvalue('name')
email = form.getvalue('email')
... do some kind of processing ...
# Output a response
print "Status: 200 OK"
print "Content-type: text/html"
print
print "<html><head><title>Success!</title></head><body>"
print "Hello %s, your email is %s" % (name,email)
print "</body>"
80
CGI Commentary
• There are many more minor details (consult
a reference on CGI programming)
• The basic idea is simple
• Server runs a script
• Script receives inputs from
environment variables and stdin
• Script produces output on stdout
• It's old-school, but sometimes it's all you get
Copyright (C) 2010, http://www.dabeaz.com 4- 33
Exercise 4.4
Time : 25 Minutes
81
WSGI
• Web Services Gateway Interface (WSGI)
• This is a standardized interface for creating
Python web services
• Allows one to create code that can run under a
wide variety of web servers and frameworks as
long as they also support WSGI (and most do)
• So, what is WSGI?
Copyright (C) 2010, http://www.dabeaz.com 4- 35
WSGI Interface
• WSGI is an application programming interface
loosely based on CGI programming
• In CGI, there are just two basic features
• Getting values of inputs (env variables)
• Producing output by printing
• WSGI takes this concept and repackages it into
a more modular form
82
WSGI Example
• With WSGI, you write an "application"
• An application is just a function (or callable)
def hello_app(environ, start_response):
status = "200 OK"
response_headers = [ ('Content-type','text/plain')]
response = []
start_response(status,response_headers)
response.append("Hello World\n")
response.append("You requested :"+environ['PATH_INFO]')
return response
WSGI Applications
• Applications always receive just two inputs
def hello_app(environ, start_response):
status = "200 OK"
response_headers = [ ('Content-type','text/plain')]
response = []
start_response(status,response_headers)
response.append("Hello World\n")
response.append("You requested :"+environ['PATH_INFO]')
return response
83
WSGI Environment
• The environment contains CGI variables
def hello_app(environ, start_response):
status = "200 OK"
response_headers = [ ('Content-type','text/plain')]
response = []
environ['REQUEST_METHOD']
environ['SCRIPT_NAME']
start_response(status,response_headers)
environ['PATH_INFO']
response.append("Hello World\n")
environ['QUERY_STRING']
response.append("You requested :"+environ['PATH_INFO]')
environ['CONTENT_TYPE']
return response
environ['CONTENT_LENGTH']
environ['SERVER_NAME']
...
WSGI Environment
• Environment also contains some WSGI variables
def hello_app(environ, start_response):
status = "200 OK"
response_headers = [ ('Content-type','text/plain')]
response = []
environ['wsgi.input']
environ['wsgi.errors']
start_response(status,response_headers)
environ['wsgi.url_scheme']
response.append("Hello World\n")
environ['wsgi.multithread']
response.append("You requested :"+environ['PATH_INFO]')
environ['wsgi.multiprocess']
return response
...
84
Processing WSGI Inputs
• Parsing of query strings is similar to CGI
import cgi
def sample_app(environ,start_response):
fields = cgi.FieldStorage(environ['wsgi.input'],
environ=environ)
# fields now has the CGI query variables
...
WSGI Responses
• The second argument is a function that is called
to initiate a response
def hello_app(environ, start_response):
status = "200 OK"
response_headers = [ ('Content-type','text/plain')]
response = []
start_response(status,response_headers)
response.append("Hello World\n")
response.append("You requested :"+environ['PATH_INFO]')
return response
85
WSGI Responses
WSGI Content
• Content is returned as a sequence of byte strings
def hello_app(environ, start_response):
status = "200 OK"
response_headers = [ ('Content-type','text/plain')]
response = []
start_response(status,response_headers)
response.append("Hello World\n")
response.append("You requested :"+environ['PATH_INFO]')
return response
86
WSGI Content Encoding
• WSGI applications must always produce bytes
• If working with Unicode, it must be encoded
def hello_app(environ, start_response):
status = "200 OK"
response_headers = [ ('Content-type','text/html')]
start_response(status,response_headers)
return [u"That's a spicy Jalape\u00f1o".encode('utf-8')]
WSGI Deployment
• The main point of WSGI is to simplify
deployment of web applications
• You will notice that the interface depends on
no third party libraries, no objects, or even any
standard library modules
• That is intentional. WSGI apps are supposed to
be small self-contained units that plug into
other environments
87
WSGI Deployment
• Running a simple stand-alone WSGI server
from wsgiref import simple_server
httpd = simple_server.make_server("",8080,hello_app)
httpd.serve_forever()
def hello_app(environ,start_response):
...
import wsgiref.handlers
wsgiref.handlers.CGIHandler().run(hello_app)
88
Exercise 4.5
Time : 20 Minutes
Customized HTTP
89
Customized HTTP
• Example: A Hello World Server
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
class HelloHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/hello':
self.send_response(200,"OK")
self.send_header('Content-type','text/plain')
self.end_headers()
self.wfile.write("""<HTML>
<HEAD><TITLE>Hello</TITLE></HEAD>
<BODY>Hello World!</BODY></HTML>""")
serv = HTTPServer(("",8080),HelloHandler)
serv.serve_forever()
Customized HTTP
• A more complex server
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
...
def do_POST(self): Redefine the behavior of the
... server by defining code for
def do_HEAD(self): all of the standard HTTP
... request types
def do_PUT(self):
...
serv = HTTPServer(("",8080),MyHandler)
serv.serve_forever()
90
Exercise 4.6
Time : 15 Minutes
Web Frameworks
• Python has a huge number of web frameworks
• Zope
• Django
• Turbogears
• Pylons
• CherryPy
• Google App Engine
• Frankly, there are too many to list here..
Copyright (C) 2010, http://www.dabeaz.com 4- 54
91
Web Frameworks
• Web frameworks build upon previous concepts
• Provide additional support for
• Form processing
• Cookies/sessions
• Database integration
• Content management
• Usually require their own training course
Copyright (C) 2010, http://www.dabeaz.com 4- 55
Commentary
• If you're building small self-contained
components or middleware for use on the
web, you're probably better off with WSGI
• The programming interface is minimal
• The components you create will be self-
contained if you're careful with your design
• Since WSGI is an official part of Python,
virtually all web frameworks will support it
92
Section 5
Advanced Networking
Overview
93
Problem with Sockets
SocketServer
94
SocketServer Example
• To use SocketServer, you define handler
objects using classes
• Example: A time server
import SocketServer
import time
class TimeHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.request.sendall(time.ctime()+"\n")
serv = SocketServer.TCPServer(("",8000),TimeHandler)
serv.serve_forever()
SocketServer Example
• Handler Class
import SocketServer Server is implemented
import time by a handler class
class TimeHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.request.sendall(time.ctime()+"\n")
serv = SocketServer.TCPServer(("",8000),TimeHandler)
serv.serve_forever()
95
SocketServer Example
• Handler Class Must inherit from
import SocketServer BaseRequestHandler
import time
class TimeHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.request.sendall(time.ctime())
serv = SocketServer.TCPServer(("",8000),TimeHandler)
serv.serve_forever()
SocketServer Example
• handle() method
import SocketServer
Define handle()
import time
to implement the
server action
class TimeHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.request.sendall(time.ctime())
serv = SocketServer.TCPServer(("",8000),TimeHandler)
serv.serve_forever()
96
SocketServer Example
• Client socket connection
import SocketServer
import time
class TimeHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.request.sendall(time.ctime())
serv = SocketServer.TCPServer(("",8000),TimeHandler)
Socket object
serv.serve_forever()
for client connection
SocketServer Example
• Creating and running the server
import SocketServer
import time
serv = SocketServer.TCPServer(("",8000),TimeHandler)
serv.serve_forever()
Runs the server
forever
97
Execution Model
• Server runs in a loop waiting for requests
• On each connection, the server creates a
new instantiation of the handler class
• The handle() method is invoked to handle
the logic of communicating with the client
• When handle() returns, the connection is
closed and the handler instance is destroyed
Exercise 5.1
Time : 15 Minutes
98
Big Picture
• A major goal of SocketServer is to simplify
the task of plugging different server handler
objects into different kinds of server
implementations
• For example, servers with different
implementations of concurrency, extra
security features, etc.
Concurrent Servers
• SocketServer supports different kinds of
concurrency implementations
TCPServer - Synchronous TCP server (one client)
ForkingTCPServer - Forking server (multiple clients)
ThreadingTCPServer - Threaded server (multiple clients)
serv = SocketServer.ThreadingTCPServer(("",8000),TimeHandler)
serv.serve_forever()
99
Server Mixin Classes
• SocketServer defines these mixin classes
ForkingMixIn
ThreadingMixIn
serv = ThreadedHTTPServer(("",8080),
SimpleHTTPRequestHandler)
Server Subclassing
• SocketServer objects are also subclassed to
provide additional customization
• Example: Security/Firewalls
class RestrictedTCPServer(TCPServer):
# Restrict connections to loopback interface
def verify_request(self,request,addr):
host, port = addr
if host != '127.0.0.1':
return False
else:
return True
serv = RestrictedTCPServer(("",8080),TimeHandler)
serv.serve_forever()
100
Exercise 5.2
Time : 15 Minutes
Distributed Computing
• It is relatively simple to build Python
applications that span multiple machines or
operate on clusters
101
Discussion
• Keep in mind: Python is a "slow" interpreted
programming language
• So, we're not necessarily talking about high
performance computing in Python (e.g.,
number crunching, etc.)
• However, Python can serve as a very useful
distributed scripting environment for
controlling things on different systems
XML-RPC
102
Simple XML-RPC
• How to create a stand-alone server
from SimpleXMLRPCServer import SimpleXMLRPCServer
def add(x,y):
return x+y
s = SimpleXMLRPCServer(("",8080))
s.register_function(add)
s.serve_forever()
Simple XML-RPC
• Adding multiple functions
from SimpleXMLRPCServer import SimpleXMLRPCServer
s = SimpleXMLRPCServer(("",8080))
s.register_function(add)
s.register_function(foo)
s.register_function(bar)
s.serve_forever()
s = SimpleXMLRPCServer(("",8080))
obj = SomeObject()
s.register_instance(obj)
s.serve_forever()
103
XML-RPC Commentary
104
Exercise 5.3
Time : 15 Minutes
105
pickle Module
• A module for serializing objects
• Serializing an object onto a "file"
import pickle
...
pickle.dump(someobj,f)
Pickling to Strings
• Pickle can also turn objects into byte strings
import pickle
# Convert to a string
s = pickle.dumps(someobj, protocol)
...
# Load from a string
someobj = pickle.loads(s)
106
Example
• Using pickle with XML-RPC
# addserv.py
import pickle
def add(px,py):
x = pickle.loads(px)
y = pickle.loads(py)
return pickle.dumps(x+y)
Example
• Passing Python objects from the client
>>> import pickle
>>> import xmlrpclib
>>> serv = xmlrpclib.ServerProxy("http://localhost:15000")
>>> a = [1,2,3]
>>> b = [4,5]
>>> r = serv.add(pickle.dumps(a),pickle.dumps(b))
>>> c = pickle.loads(r)
>>> c
[1, 2, 3, 4, 5]
>>>
107
Miscellaneous Comments
• Pickle is really only useful if used in a Python-
only environment
• Would not use if you need to communicate
to other programming languages
• There are also security concerns
• Never use pickle with untrusted clients
(malformed pickles can be used to execute
arbitrary system commands)
Exercise 5.4
Time : 15 Minutes
108
multiprocessing
• Python 2.6/3.0 include a new library module
(multiprocessing) that can be used for
different forms of distributed computation
• It is a substantial module that also addresses
interprocess communication, parallel
computing, worker pools, etc.
• Will only show a few network features here
Connections
• Creating a dedicated connection between
two Python interpreter processes
• Listener (server) process
from multiprocessing.connection import Listener
serv = Listener(("",16000),authkey="12345")
c = serv.accept()
• Client process
from multiprocessing.connection import Client
c = Client(("servername",16000),authkey="12345")
109
Connection Use
• Connections allow bidirectional message
passing of arbitrary Python objects
Example
• Example server using multiprocessing
# addserv.py
def add(x,y):
return x+y
110
Example
• Client connection with multiprocessing
>>> from multiprocessing.connection import Client
>>> client = Client(("",16000),authkey="12345")
>>> a = [1,2,3]
>>> b = [4,5]
>>> client.send((a,b))
>>> c = client.recv()
>>> c
[1, 2, 3, 4, 5]
>>>
Commentary
• Multiprocessing module already does the
work related to pickling, error handling, etc.
• Can use it as the foundation for something
more advanced
• There are many more features of
multiprocessing not shown here (e.g.,
features related to distributed objects,
parallel processing, etc.)
111
Commentary
What about...
• CORBA? SOAP? Others?
• There are third party libraries for this
• Honestly, most Python programmers aren't
into big heavyweight distributed object
systems like this (too much trauma)
• However, if you're into distributed objects,
you should probably look at the Pyro project
(http://pyro.sourceforge.net)
112
Network Wrap-up
• Have covered the basics of network support
that's bundled with Python (standard lib)
• Possible directions from here...
• Concurrent programming techniques
(often needed for server implementation)
• Parallel computing (scientific computing)
• Web frameworks
Copyright (C) 2010, http://www.dabeaz.com 5- 41
Exercise 5.5
Time : 15 Minutes
113
Python Network Programming Index Django, 4-54
dump() function, pickle module, 5-27
dumps() function, pickle module, 5-28
A
E
accept() method, of sockets, 1-19, 1-22
Address binding, TCP server, 1-20 ElementTree module, modifying document
Addressing, network, 1-4 structure, 3-23
Asynchronous network server, 1-52 ElementTree module, performance, 3-22
ElementTree module, xml.etree package, 3-14
B ElementTree, attributes, 3-19
ElementTree, incremental XML parsing, 3-25
BaseRequestHandler, SocketServer module, 5-5 ElementTree, wildcards, 3-20
bind() method, of sockets, 1-19, 1-20, 1-42 ElementTree, writing XML, 3-24
Browser, emulating in HTTP requests, 2-21 End of file, of sockets, 1-32
build_opener() function, urllib2 module, 2-24 environ variable, os module, 4-28
Error handling, HTTP requests, 2-22
C
F
cElementTree module, 3-22
cgi module, 4-30 FieldStorage object, cgi module, 4-30
CGI scripting, 4-23, 4-24, 4-25, 4-26, 4-27 File upload, via urllib, 2-28
CGI scripting, and WSGI, 4-48 Files, creating from a socket, 1-37
CGI scripting, creating a response, 4-31, 4-32 Forking server, 1-51
CGI scripting, environment variables, 4-28 ForkingMixIn class, SocketServer module, 5-15
CGI scripting, I/O model, 4-28 ForkingTCPServer, SocketServer module, 5-14
CGI scripting, parsing query variables, 4-30 ForkingUDPServer, SocketServer module, 5-14
CGI scripting, query string, 4-26 Form data, posting in an HTTP request, 2-10,
CGI scripting, query variables, 4-29 2-11, 2-20
CherryPy, 4-54 FTP server, interacting with, 2-29
Client objects, multiprocessing module, 5-34 FTP, uploading files to a server, 2-30
Client/Server programming, 1-8 ftplib module, 2-29
close() method, of sockets, 1-16, 1-25
Concurrency, and socket programming, 1-46 G
connect() method, of sockets, 1-16
Connections, network, 1-7 gethostbyaddr() function, socket module, 1-53
Content encoding, HTTP responses, 4-9 gethostbyname() function, socket module, 1-53
Cookie handling and HTTP requests, 2-25 gethostname() function, socket module, 1-53
Cookies, and urllib2 module, 2-17 Google AppEngine, 4-54
CORBA, 5-40
Creating custom openers for HTTP requests, 2-24
csv module, 3-3 H
D Hostname, 1-4
Hostname, obtaining, 1-53
HTML, parsing of, 3-4, 3-7
Datagram, 1-43 HTMLParser module, 3-5, 3-7
Distributed computing, 5-18, 5-19
HTTP cookies, 2-25 O
HTTP protocol, 4-5
HTTP request, with cookie handling, 2-25
HTTP status code, obtaining with urllib, 2-14 Objects, serialization of, 5-26
HTTP, client-side protocol, 2-31 Opener objects, urllib2 module, 2-23
HTTP, methods, 4-8 OpenSSL, 2-5
HTTP, request structure, 4-6
HTTP, response codes, 4-8 P
HTTP, response content encoding, 4-9
HTTP, response structure, 4-7, 4-10, 4-12
Parsing HTML, 3-7
httplib module, 2-31
Parsing, JSON, 3-29
Parsing, of HTML, 3-5
I pickle module, 5-27
POST method, of HTTP requests, 2-6, 2-7
Interprocess communication, 1-44 Posting form data, HTTP requests, 2-10, 2-11,
IP address, 1-4 2-20
IPC, 1-44 Pylons, 4-54
IPv4 socket, 1-13
IPv6 socket, 1-13 Q
JSON, 3-29 R
json module, 3-31
Raw Sockets, 1-45
L recv() method, of sockets, 1-16
recvfrom() method, of sockets, 1-42, 1-43
Limitations, of urllib module, 2-28 Request objects, urllib2 module, 2-19
listen() method, of sockets, 1-19, 1-21 Request-response cycle, network programming,
Listener objects, multiprocessing module, 5-34 1-9
load() function, pickle module, 5-27 RFC-2822 headers, 4-6
loads() function, pickle module, 5-28
S
M
sax module, xml package, 3-11
makefile() method, of sockets, 1-37 select module, 1-52
multiprocessing module, 5-33 select() function, select module, 1-52
send() method, of sockets, 1-16, 1-24
sendall() method, of sockets, 1-31
N Sending email, 2-32
sendto() method, of sockets, 1-42, 1-43
netstat, 1-6 Serialization, of Python objects, 5-26
Network addresses, 1-4, 1-7 serve_forever() method, SocketServer, 5-5
Network programming, client-server concept, 1-8 setsockopt() method, of sockets, 1-36
Network programming, standard port settimeout() method, of sockets, 1-34
assignments, 1-5 SimpleXMLRPCServer module, 5-21
simple_server module, wsgiref package, 4-46, UDPServer, SocketServer module, 5-14
4-47 Unix domain sockets, 1-44
smtplib module, 2-32 Uploading files, to an FTP server, 2-30
SOAP, 5-40 URL, parameter encoding, 2-6, 2-7
socket module, 1-13 urlencode() function, urllib module, 2-9
socket() function, socket module, 1-13 urllib module, 2-3
Socket, using for server or client, 1-15 urllib module, limitations, 2-28
Socket, wrapping with a file object, 1-37 urllib2 module, 2-17
Sockets, 1-12, 1-13 urllib2 module, error handling, 2-22
Sockets, and concurrency, 1-46 urllib2 module, Request objects, 2-19
Sockets, asynchronous server, 1-52 urlopen() function, obtaining response headers,
Sockets, end of file indication, 1-32 2-13
Sockets, forking server example, 1-51 urlopen() function, obtaining status code, 2-14
Sockets, partial reads and writes, 1-29 urlopen() function, reading responses, 2-12
Sockets, setting a timeout, 1-34 urlopen() function, urllib module, 2-4
Sockets, setting options, 1-36 urlopen() function, urllib2 module, 2-18
Sockets, threaded server, 1-50 urlopen(), posting form data, 2-10, 2-11, 2-20
SocketServer module, 5-4 urlopen(), supported protocols, 2-5
SocketServer, subclassing, 5-16 User-agent, setting in HTTP requests, 2-21
Standard port assignments, 1-5
V
T
viewing open network connections, 1-6
TCP, 1-13, 1-14
TCP, accepting new connections, 1-22 W
TCP, address binding, 1-20
TCP, client example, 1-16
TCP, communication with client, 1-23 Web frameworks, 4-54, 4-55
TCP, example with SocketServer module, 5-5 Web programming, and WSGI, 4-35, 4-36
TCP, listening for connections, 1-21 Web programming, CGI scripting, 4-23, 4-24,
TCP, server example, 1-19 4-25, 4-26, 4-27
TCPServer, SocketServer module, 5-10 Web services, 2-8
Telnet, using with network applications, 1-10 Webdav, 2-28
Threaded network server, 1-50 WSGI, 4-36
ThreadingMixIn class, SocketServer module, WSGI (Web Services Gateway Interface), 4-35
5-15 WSGI, and CGI environment variables, 4-39
ThreadingTCPServer, SocketServer module, 5-14 WSGI, and wsgi.* variables, 4-40
ThreadingUDPServer, SocketServer module, 5-14 WSGI, application inputs, 4-38
Threads, and network servers, 1-50 WSGI, applications, 4-37
Timeout, on sockets, 1-34 WSGI, parsing query string, 4-41
Turbogears, 4-54 WSGI, producing content, 4-44
Twisted framework, 1-52 WSGI, response encoding, 4-45
WSGI, responses, 4-42
WSGI, running a stand-alone server, 4-46, 4-47
U WSGI, running applications within a CGI script,
4-48
UDP, 1-13, 1-41 WWW, see HTTP, 4-5
UDP, client example, 1-43
UDP, server example, 1-42
X
Zope, 4-54