Giter Site home page Giter Site logo

kemingy / flaskerk Goto Github PK

View Code? Open in Web Editor NEW
26.0 3.0 2.0 331 KB

A flask extension for api doc and validation of request&response.

Home Page: https://kemingy.github.io/flaskerk

License: MIT License

Python 90.47% HTML 8.15% Makefile 1.37%
flask flask-extensions openapi validation redoc

flaskerk's Introduction

Flaskerk

Build Status GitHub PyPI - Python Version

Provide OpenAPI document and validation for flask service.

Mainly built for Machine Learning Model services.

If you're using Falcon, check my another library Falibrary.

Attention

I've created a new library named SpecTree. It supports all the features of Flaskerk, but with a better interface. Give it a try! This library may be archived in the future.

Features

  • Generate API document with Redoc UI or Swagger UI ๐Ÿ˜‹
  • Less boilerplate code, annotations are really easy-to-use โœจ
  • Validate query, JSON data, response data with pydantic ๐Ÿ˜‰
  • Better HTTP exceptions for API services (default & customized) (JSON instead of HTML) ๐Ÿ˜ฌ

Quick Start

install with pip install flaskerk (Python 3.6+)

Simple demo

from flask import Flask, request, jsonify
from flaskerk import Flaskerk
from pydantic import BaseModel

class Query(BaseModel):
    text: str

app = Flask(__name__)
api = Flaskerk()

@app.route('/api/classify')
@api.validate(query=Query)
def classify():
    print(request.query)
    return jsonify(label=0)

if __name__ == "__main__":
    api.register(app)
    app.run()

Changes you need to make:

  • create model with pydantic
  • decorate the route function with Flaskerk.validate()
  • specify which part you need in validate
    • query (args in url)
    • data (JSON data from request)
    • resp (response) this will be transformed to JSON data after validation
    • x (HTTP Exceptions list)
    • tags (tags for this API route)
  • register to Flask application

After that, this library will help you validate the incoming request and provide API document in /docs.

Parameters in Flaskerk.validate Corresponding parameters in Flask
query request.query
data request.json_data
resp \
x \

For more details, check the document.

More feature

from flask import Flask, request
from pydantic import BaseModel, Schema
from random import random
from flaskerk import Flaskerk, HTTPException

app = Flask(__name__)
api = Flaskerk(
    title='Demo Service',
    version='1.0',
    ui='swagger',
)

class Query(BaseModel):
    text: str

class Response(BaseModel):
    label: int
    score: float = Schema(
        ...,
        gt=0,
        lt=1,
    )

class Data(BaseModel):
    uid: str
    limit: int
    vip: bool

e233 = HTTPException(code=233, msg='lucky for you')

@app.route('/api/predict/<string(length=2):source>/<string(length=2):target>', methods=['POST'])
@api.validate(query=Query, data=Data, resp=Response, x=[e233], tags=['model'])
def predict(source, target):
    """
    predict demo

    demo for `query`, `data`, `resp`, `x`
    """
    print(f'=> from {source} to {target}')  # path
    print(f'Data: {request.json_data}')  # Data
    print(f'Query: {request.query}')  # Query
    if random() < 0.5:
        e233.abort('bad luck')
    return Response(label=int(10 * random()), score=random())

if __name__ == '__main__':
    api.register(app)
    app.run()

try it with http POST ':5000/api/predict/zh/en?text=hello' uid=0b01001001 limit=5 vip=true

Open the docs in http://127.0.0.1:5000/docs .

For more examples, check examples.

FAQ

Can I just do the validation without generating API document?

Sure. If you don't register it to Flask application, there won't be document routes.

flaskerk's People

Contributors

kemingy avatar mtizima avatar twelvelabs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

mtizima assem-ch

flaskerk's Issues

422 status code message

By default, if the user has any pydantic.BaseModel data, this API will have a 422 exception.

But if the user has defined a 422 exception, the message may be overwritten.

same route with multiple methods are not display in swagger

Hi I was playing around with flaskerk and found if you have a method
@app.route('/cars', methods=['GET'])
@api.validate(resp=Cars)
def get_cars() -> Cars:
# return Car(**cars[0])
# return {'data': [Car(**x).to_json() for x in cars]}
# return Cars(cars=[Car(**x) for x in cars])
# return cars
return Cars(cars=cars)

@app.route('/cars', methods=['POST'])
@api.validate(resp=Car, data=Car)
def post_cars() -> Car:
data = request.json_data
return Car(name=data.name, price=data.price, desc=data.desc)

in swagger will display only one (last one) , I fix in the code in base.py in line 103 or 104
instead of just
routes = {}
I put this
if path not in routes.keys():
routes[path] = {}

and it worked

Support for tags and change Swagger layout

Hello,

First, I have to say that I love the work that you guys are doing with this library. I was already thinking in create validation and automatic OpenAPI documentation similar to what FastAPI is doing.

I have two requests for the current status of Flaskerk.

  1. I would like to change the layout of the Swagger docs in the configs. Since I want to use the "BaseLayout" instead of the "StandaloneLayout". I could achieve this by creating a custom template folder, changing the swagger.html file and passing "template_folder" parameter in the constructor, but would be great to be able to choose between different layouts directly in the config.

  2. We need a way to support tags. If you take a look in the code below you will see my current implementation.

from flask import Flask, request, jsonify
from flaskerk import Flaskerk
from pydantic import BaseModel
import os

class Query(BaseModel):
    text: str

app = Flask(__name__)
api = Flaskerk(
    title='Demo Service',
    version='1.0',
    ui='swagger',
    template_folder=os.path.join(os.getcwd(), "templates_api")
)

@app.route('/api/first')
@api.validate(query=Query, tags=["first"])
def first():
    print(request.query)
    return jsonify(label=0)

@app.route('/api/second')
@api.validate(query=Query, tags=["second"])
def second():
    print(request.query)
    return jsonify(label=0)

if __name__ == "__main__":
    api.register(app)
    app.run()

Then in the base.py you should change the validate function for:

def validate(self, query=None, data=None, resp=None, x=[], tags=[]):

Add tags to the validate_request.

# register tags
validate_request.tags = tags

and finally, add them to the spec.

if hasattr(func, 'tags'):                    
    spec['tags'] = func.tags

Add some test

Currently, this project is tested with examples. Of course, this is not a suitable way.

Here is the list that should be tested:

  • flaskerk.utils.parse_url for every converter with and without args
  • flaskerk.exception.HTTPException default and customized exceptions
  • Query, Data, Response, Exception in flaskerk.base.Flaskerk.validate
  • change default config for flaskerk.base.Flaskerk

Unable to customize HTTP status code when validating response data

I'm trying out flaskerk and attempting to define an endpoint that creates a resource and returns a HTTP 201 Created response. I typically return the newly created resource in the response body for those types of endpoints.

It looks like the current implementation supports customizing the successful response code by raising an HTTPException with a 2xx code, but this doesn't appear to work in combination with a response schema (I think this was raised in #26). It's also a little unintuitive to me to use exceptions as a way of signaling a successful action. Would you be open to a PR that added an optional resp_code (or perhaps status... whatever you prefer) kwarg to the validate decorator? Something like so:

@app.route("/users", methods=["POST"])
@api.validate(data=User, resp=User, resp_code=201)
def create_user():
    # create the user...
    return user, 201

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.