1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
import os, sys; sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
from pattern.server import App
from pattern.server import static
from pattern.server import HTTPError
# The pattern.server module allows you to run a pure-Python web server.
# It is built on CherryPy and inspired by Flask and bottle.py.
# This example demonstrates a basic web app.
# At the bottom of the script is a call to app.run().
# So, to start the web server, run this script.
# If you make any changes to the script and save it,
# the server automatically restarts to reflect the changes.
# If the server is running in "production mode", i.e., app.run(debug=False),
# it will not restart automatically.
app = App(name="basic", static="static/")
# Here are some properties of the app.
# app.path yields the absolute path to the app folder.
# app.static yields the absolute path to the folder for static content.
print app.name
print app.path
print app.static
# The @app.route() decorator can be used to define a URL path handler.
# A path handler is simply a Python function that returns a string,
# which will be displayed in the browser.
# For example, visit http://127.0.0.1:8080/:
@app.route("/")
def index():
return "Hello world!"
# The index() function handles requests at http://127.0.0.1:8080/,
# but no other paths. If you'd visit http://127.0.0.1:8080/ponies,
# a 404 error will be raised, since there is no "/ponies" handler.
# The @app.error() decorator can be used to catch errors.
# In this case it prints out the error status and a traceback.
# The traceback will always be an empty string
# when you are running a production server, i.e., app.run(debug=False).
# You want to see errors during development, i.e., app.run(debug=True).
# You don't want to confront users with them when the app is live
# (or let hackers learn from them).
@app.error("404")
def error_404(error):
return "<h1>%s</h1>\n%s\n<pre>%s</pre>" % (
error.status,
error.message,
error.traceback
)
# URL handler functions can take positional arguments and keyword arguments.
# Positional arguments correspond to the URL path.
# Keyword arguments correspond to query parameters.
# The products() function below handles requests at http://127.0.0.1:8080/products/.
# Notice how it takes an "name" parameter, which is a subpath.
# When you browse http://127.0.0.1:8080/products/, name=None.
# When you browse http://127.0.0.1:8080/products/iphone, name="iphone".
# When you browse http://127.0.0.1:8080/products/iphone/reviews, a 404 error is raised.
@app.route("/products")
def products(name):
return (
"<html>",
"<head></head>",
"<body>View product: " + (name or "") + "</body>",
"</html>"
)
# To catch any kind of subpath, use Python's *path notation.
# For http://127.0.0.1:8080/products2/, path=().
# For http://127.0.0.1:8080/products2/iphone, path=("iphone",).
# For http://127.0.0.1:8080/products2/iphone/reviews, path=("iphone", "reviews")
@app.route("/products2")
def products2(*path):
#print path
if len(path) == 0:
return "product overview"
if len(path) == 1:
return "product %s detail page" % path[0]
if len(path) == 2 and path[1] == "reviews":
return "product reviews for %s" % path[0]
# Uncaught subpaths raise a 404 error.
raise HTTPError(404)
# You can also use keyword arguments.
# These correspond to query parameters (i.e., the "?x=y" part of a URL).
# Query parameters from HTML forms can be sent to the server by GET or POST.
# GET sends the parameters as part of the URL.
# POST sends the parameters in the background. They can hold longer strings.
# For example, browse to http://127.0.0.1:8080/review and fill in the form.
# Observe the URL when you click "submit".
# Observe how the data in <textarea name='text'> is passed to
# the function's optional "text" parameter:
@app.route("/review")
def review(text=""):
if text:
s = "You wrote: " + text
else:
s = ""
return (
s,
"<form method='get'>",
"<textarea name='text'></textarea>",
"<br><input type='submit'>",
"</form>"
)
# To accept any number of query parameters, use Python's **data notation.
# The keyword argument "data" will be a dictionary with all query parameters.
# Images, CSS, etc. can be placed in the static folder.
# Take a look in /01-basic/static. There's a "cat.jpg".
# Static files are accessible from the web, e.g.,
# http://127.0.0.1:8080/cat.jpg
# So, you can refer to them in HTML code:
# http://127.0.0.1:8080/cat
@app.route("/cat")
def cat():
return "<p>A cat.</p><img src='cat.jpg'>"
# http://127.0.0.1:8080/cat-alias.jpg
@app.route("/cat-alias.jpg")
def cat_alias():
return static("cat.jpg", root=app.static)
# That's it. There is lot more you can do, but the general idea is:
# 1) Create an App.
# 2) Register URL handlers with @app.route().
# 3) Start the server with app.run().
app.run("127.0.0.1", port=8080, debug=True)
|