About Me
-
Mike Brown
-
Your Favorite Organizer
-
Python Backend + DevOps
-
Python Lead @ Excella Consulting
The Premise
I made a simple API last year
Let's rewrite it using some currently trending frameworks
The Input
{
"text": "mike made the coolest API",
"search": "sarcastic wonka"
}
The Output
The Original Code
Flask + Flask-API
https://github.com/tomchristie/flask-api
@app.route('/', methods = ['GET', 'POST'])
def giffer():
if request.method == 'POST':
data = request.data
gif_file = gif_factory.create(**data)
return send_file(gif_file)
else:
return get_guide_text()
gif_factory.create
-
Pull a gif image from the giphy API
-
Use moviepy to generate new gif with meme text
-
Save the file to the filesystem (sadface)
-
Return string path to the new gif file
The Contestants
-
Sanic - Asynchronous/Fast
-
Hug - Simplified/Self Documenting
Sanic
-
Flask-style API
-
Python 3 required
-
Async/Await syntax
-
"Faster than Node"
@app.route('/', methods = ['POST'])
async def giffer(request):
data = request.json
gif_file = await gif_factory.create(**data)
return file(gif_file, mime_type='image/gif')
class GifferView(HTTPMethodView):
def post(self, request):
data = request.json
gif_file = await gif_factory.create(**data)
return file(gif_file, mime_type='image/gif')
def get(self, request):
return create_guide_text()
app.add_route(GifferView.as_view(), '/')
Hug
-
Flask-style API
-
Python 3 required
-
Type Annotations
-
Autogenerated documentation
-
"make developing an API as simple as possible"
@hug.get('/', output=hug.output_format.pretty_json)
def giffer_get():
return print_guide()
@hug.post('/', output=hug.output_format.gif_image)
def giffer_post(data):
return gif_factory.create(**data)
{
"documentation": {
"handlers": {
"/": {
"GET": {
"examples": [
"http://localhost:8000/"
],
"outputs": {
"format": "JSON pretty printed and indented",
"content_type": "application/json"
}
},
"POST": {
"outputs": {
"format": "gif formatted image",
"content_type": "image/gif"
},
"inputs": {
"data": {
"type": "Basic text / string value"
}
}
}
}}}}
http://localhost:8000/documentation
@hug.get('/', output=hug.output_format.pretty_json)
def giffer_get():
return print_guide()
@hug.post('/', output=hug.output_format.gif_image)
# def giffer_post(data):
# return gif_factory.create(**data)
def giffer_post(search, text):
return gif_factory.create(search=search, text=text)
{
"documentation": {
"handlers": {
"/": {
"GET": {
"examples": [
"http://localhost:8000/"
],
"outputs": {
"format": "JSON pretty printed and indented",
"content_type": "application/json"
}
},
"POST": {
"outputs": {
"format": "gif formatted image",
"content_type": "image/gif"
},
"inputs": {
"search": {
"type": "Basic text / string value"
},
"text": {
"type": "Basic text / string value"
}
}
}}}}}
http://localhost:8000/documentation
@hug.type(extend=hug.types.text)
def input_search(value):
"""The search string for giphy"""
pass
@hug.type(extend=hug.types.text)
def input_text(value):
"""The text to display in the gif"""
pass
@hug.post('/', output=hug.output_format.gif_image)
# def giffer_post(search, text):
def giffer_post(search: input_search, text: input_text,
text_width: int=60):
return gif_factory.create(search=search, text=text,
text_width=text_width)
Type Annotations!
{
"documentation": {
"handlers": {
"/": {
"POST": {
"outputs": {
"format": "gif formatted image",
"content_type": "image/gif"
},
"inputs": {
"search": {
"type": "The search string for giphy"
},
"text": {
"type": "The text to display in the gif"
},
"text_width": {
"type": "int(x=0) -> integer\nint(x, base=10)",
"default": 60
}
},
}
}}}}
http://localhost:8000/documentation
Final Thoughts
Questions?
How To Make An API In 2017
By m3brown
How To Make An API In 2017
- 1,137