Added style #15. Does this clarify REST?

This commit is contained in:
Crista Lopes
2013-09-23 20:35:59 -07:00
parent 177ed23c16
commit f9ae20233d
2 changed files with 143 additions and 0 deletions

35
15-restful/README.md Normal file
View File

@@ -0,0 +1,35 @@
Style #15
==============================
REST = REpresentational State Transfer (http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm)
REST is a style for network-based interactive applications that
underlies the Web. The example here doesn't go over the network, but
preserves the main contraints of REST, which are:
- Interactive: end-to-end between an active agent (e.g. a person) and a backend
- Separation between Client (user interface) and Server (data storage)
- Statelessness, as in client--stateless-server: every request from
client to server must contain all the information necessary for the
server to serve the request. The server cannot store
context of the interaction. Session state is on the client.
- Uniform interface: resources that are created and retrieved,
resource identifiers and hypermedia representation that is the
engine of application state
Additionally, the networked style has the following contraints, not shown here:
- Cache
- Layered system
- Code-on-demans
Possible names:
- RESTful
- Stateless Ping-Pong

108
15-restful/tf-15.py Normal file
View File

@@ -0,0 +1,108 @@
import re, string, sys
with open("../stop_words.txt") as f:
stops = set(f.read().split(",") + list(string.ascii_lowercase))
# The "database"
data = {}
# Internal functions of the "server"-side application
def error_state():
return "Something wrong", ["get", "default", None]
# The "server"-side application handlers
def quit_handler(args):
sys.exit("Goodbye cruel world...")
def default_get_handler(args):
rep = "What would you like to do?"
rep += "\n1 - Quit" + "\n2 - Upload file"
links = {"1" : ["post", "execution", None], "2" : ["get", "file_form", None]}
return rep, links
def upload_get_handler(args):
return "Name of file to upload?", ["post", "file"]
def upload_post_handler(args):
def create_data(filename):
if filename in data:
return
word_freqs = {}
print "Trying to open " + filename
with open(filename) as f:
for w in [x.lower() for x in re.split("[^a-zA-Z]+", f.read()) if len(x) > 0 and x.lower() not in stops]:
word_freqs[w] = word_freqs.get(w, 0) + 1
word_freqsl = word_freqs.items()
word_freqsl.sort(lambda x, y: cmp(y[1], x[1]))
data[filename] = word_freqsl
if args == None:
return error_state()
filename = args[0]
try:
create_data(filename)
except:
return error_state()
return word_get_handler([filename, 0])
def word_get_handler(args):
def get_word(filename, word_index):
if word_index < len(data[filename]):
return data[filename][word_index]
else:
return ("no more words", 0)
filename = args[0]; word_index = args[1]
word_info = get_word(filename, word_index)
rep = '\n#{0}: {1} - {2}'.format(word_index+1, word_info[0], word_info[1])
rep += "\n\nWhat would you like to do next?"
rep += "\n1 - Quit" + "\n2 - Upload file"
rep += "\n3 - See next most-frequently occurring word"
links = {"1" : ["post", "execution", None],
"2" : ["get", "file_form", None],
"3" : ["get", "word", [filename, word_index+1]]}
return rep, links
# Handler registration
handlers = {"post_execution" : quit_handler,
"get_default" : default_get_handler,
"get_file_form" : upload_get_handler,
"post_file" : upload_post_handler,
"get_word" : word_get_handler }
# The "server" core
def handle_request(verb, uri, args):
def handler_key(verb, uri):
return verb + "_" + uri
if handler_key(verb, uri) in handlers:
return handlers[handler_key(verb, uri)](args)
else:
return handlers[handler_key("get", "default")](args)
# A very simple client "browser"
def render_and_get_input(state_representation, links):
print state_representation
if type(links) is dict: # many possible next states
input = sys.stdin.readline().strip()
if input in links:
return links[input]
else:
return ["get", "default", None]
elif type(links) is list: # only one possible next state
if links[0] == "post": # get "form" data
input = sys.stdin.readline().strip()
links.append([input]) # add the data at the end
return links
else: # get action, don't get user input
return links
else:
return ["get", "default", None]
request = ["get", "default", None]
while True:
# "server"-side computation
state_representation, links = handle_request(*request)
# "client"-side computation
request = render_and_get_input(state_representation, links)