From 85d4e146a9e59e87f799633f29ba9bfec783a481 Mon Sep 17 00:00:00 2001 From: Colleen Kaku Date: Thu, 18 Feb 2021 18:28:44 -0800 Subject: [PATCH] completed wsgi calculator project --- calculator.py | 93 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 25 deletions(-) diff --git a/calculator.py b/calculator.py index a46affd..674b26e 100644 --- a/calculator.py +++ b/calculator.py @@ -40,45 +40,88 @@ """ - +import traceback + +def index(*args): + """ Returns a howto for the calculator application""" + howto = """ +

How To Use WSGI Calculator

+

Examples

+ To add integers: http://localhost:8080/add/23/42
+ To subtract integers: http://localhost:8080/subtract/23/42
+ To multiply: http://localhost:8080/multiply/3/5
+ To divide: http://localhost:8080/divide/22/11
+ """ + return howto def add(*args): """ Returns a STRING with the sum of the arguments """ + args = [int(i) for i in args] + return str(sum(args)) + +def subtract(*args): + """ Returns a STRING with the subtraction of the arguments """ + diff = int(args[0]) - int(args[1]) + return str(diff) - # TODO: Fill sum with the correct value, based on the - # args provided. - sum = "0" +def multiply(*args): + """ Returns a STRING with the product of the arguments """ + product = int(args[0]) * int(args[1]) + return str(product) - return sum +def divide(*args): + """ Returns a STRING with the division of the arguments """ + quotient = int(args[0]) / int(args[1]) + return str(int(quotient)) -# TODO: Add functions for handling more arithmetic operations. def resolve_path(path): """ Should return two values: a callable and an iterable of arguments. """ - - # TODO: Provide correct values for func and args. The - # examples provide the correct *syntax*, but you should - # determine the actual values of func and args using the - # path. - func = add - args = ['25', '32'] - + funcs = { + '': index, + 'add':add, + 'subtract':subtract, + 'multiply':multiply, + 'divide':divide, + } + path = path.strip('/').split('/') + func_name = path[0] + args = path[1:] + try: + func = funcs[func_name] + except KeyError: + raise NameError return func, args def application(environ, start_response): - # TODO: Your application code from the book database - # work here as well! Remember that your application must - # invoke start_response(status, headers) and also return - # the body of the response in BYTE encoding. - # - # TODO (bonus): Add error handling for a user attempting - # to divide by zero. - pass + headers = [('Content-type', 'text/html')] + try: + path = environ.get('PATH_INFO', None) + if path is None: + raise NameError + func, args = resolve_path(path) + body = func(*args) + status = "200 OK" + except NameError: + status = "404 Not Found" + body = "404 Not Found" + except ZeroDivisionError: + status = "400 Bad Request" + body = "400 Bad Request: Division by Zero" + except Exception: + status = "500 Internal Server Error" + body = "500 Internal Server Error" + print(traceback.format_exc()) + finally: + headers.append(('Content-length', str(len(body)))) + start_response(status, headers) + return [body.encode('utf8')] + if __name__ == '__main__': - # TODO: Insert the same boilerplate wsgiref simple - # server creation that you used in the book database. - pass + from wsgiref.simple_server import make_server + srv = make_server('localhost', 8080, application) + srv.serve_forever()