You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
5.1 KiB
Python

from __future__ import print_function
from __future__ import unicode_literals
from builtins import str, bytes, dict, int
import os
import 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)