Skip to content

Instantly share code, notes, and snippets.

@norambna
Last active May 31, 2023 23:07
Show Gist options
  • Save norambna/bee7430f0dd1b275074e4d2ce5fd3a5f to your computer and use it in GitHub Desktop.
Save norambna/bee7430f0dd1b275074e4d2ce5fd3a5f to your computer and use it in GitHub Desktop.
CRUD REST API sample
import logging
import sys
from logging.handlers import TimedRotatingFileHandler
from uuid import uuid4
import bottle
import waitress
from bottle import get, post, delete, put, request, response, route, template
from requestlogger import ApacheFormatter, WSGILogger
'''
CRUD REST API sample based on: https://www.simplifiedpython.net/python-rest-api-example/
Bottle: Web Framework
https://pypi.org/project/bottle/
Waitress: Pure-Python WSGI server
https://pypi.org/project/waitress/
wsgi-request-logger: Logging for WSGI Applications that imitates Apache's log format
https://pypi.org/project/wsgi-request-logger/
'''
needed_keys = ("name", "country", "department")
data_dict = {
"933d3aeb-30bc-469a-970c-a469470e8363": {"name": "Sam", "country": "USA", "department": "Finance"},
"d00418cc-850a-4d36-8c44-9137a6e9bf0a": {"name": "Sarah", "country": "Canada", "department": "Marketing"},
"6878a5a9-b8b7-40de-bd57-09d06315338f": {"name": "Juan", "country": "Mexico", "department": "Production"},
"7987dfc2-1d14-4947-996b-12f6801900bb": {"name": "Juan", "country": "Argentina", "department": "IT"},
}
banned_list = ("Huey", "Dewey", "Louie")
@route("/")
def index():
return "Hello World"
@route("/multiply/<a>/<b>/")
def multiply(a, b): # sample usage of 'template'
try:
result = float(a) * float(b)
return template("{{a}} multiplied by {{b}} is <b>{{result}}</b>", a=a, b=b, result=result)
except ValueError:
response.status = 400
return "I can only multiply two float numbers!"
@get("/list")
def list_all():
return data_dict
@get("/search/<name>")
def search(name):
results = {key: value for key, value in data_dict.items() if value["name"] == name}
return results
@post("/add")
def add():
payload = request.json
if not (all(key in payload for key in needed_keys) and len(payload) == 3):
response.status = 400
return f"All these keys and just these keys must be present: {', '.join(needed_keys)}"
if payload["name"] in banned_list:
response.status = 400
return f"{payload['name']} has been banned!"
employee_id = str(uuid4())
data_dict[employee_id] = payload
return data_dict
@delete("/delete/<employee_id>")
def delete(employee_id):
if employee_id not in data_dict:
response.status = 400
return f"Employee ID {employee_id} was not found"
del data_dict[employee_id]
return data_dict
@put("/update/<employee_id>")
def update(employee_id):
payload = request.json
if employee_id not in data_dict:
response.status = 400
return f"Employee ID {employee_id} was not found"
if not all(key in needed_keys for key in payload.keys()):
response.status = 400
return f"You can only update any of these keys: {', '.join(needed_keys)}"
for key in payload.keys():
data_dict[employee_id][key] = payload[key]
return data_dict
logging_handlers = [logging.StreamHandler(sys.stdout), TimedRotatingFileHandler("access.log", "d", 7)]
logger = WSGILogger(bottle.default_app(), logging_handlers, ApacheFormatter(), propagate=False)
if __name__ == "__main__":
waitress.serve(logger, host="0.0.0.0", port=8080)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment