Fully featured framework for fast, easy and documented API development with Flask

Overview

Flask RestPlus

Build status Code coverage Documentation status License Supported Python versions Join the chat at https://gitter.im/noirbizarre/flask-restplus

IMPORTANT NOTICE:

This project has been forked to Flask-RESTX and will be maintained by by the python-restx organization. Flask-RESTPlus should be considered unmaintained.

The community has decided to fork the project due to lack of response from the original author @noirbizarre. We have been discussing this eventuality for almost a year.

Things evolved a bit since that discussion and a few of us have been granted maintainers access to the github project, but only the original author has access rights on the PyPi project. As such, we been unable to make any actual releases. To prevent this project from dying out, we have forked it to continue development and to support our users.

Flask-RESTPlus is an extension for Flask that adds support for quickly building REST APIs. Flask-RESTPlus encourages best practices with minimal setup. If you are familiar with Flask, Flask-RESTPlus should be easy to pick up. It provides a coherent collection of decorators and tools to describe your API and expose its documentation properly using Swagger.

Compatibility

Flask-RestPlus requires Python 2.7 or 3.4+.

Installation

You can install Flask-Restplus with pip:

$ pip install flask-restplus

or with easy_install:

$ easy_install flask-restplus

Quick start

With Flask-Restplus, you only import the api instance to route and document your endpoints.

from flask import Flask
from flask_restplus import Api, Resource, fields

app = Flask(__name__)
api = Api(app, version='1.0', title='TodoMVC API',
    description='A simple TodoMVC API',
)

ns = api.namespace('todos', description='TODO operations')

todo = api.model('Todo', {
    'id': fields.Integer(readOnly=True, description='The task unique identifier'),
    'task': fields.String(required=True, description='The task details')
})


class TodoDAO(object):
    def __init__(self):
        self.counter = 0
        self.todos = []

    def get(self, id):
        for todo in self.todos:
            if todo['id'] == id:
                return todo
        api.abort(404, "Todo {} doesn't exist".format(id))

    def create(self, data):
        todo = data
        todo['id'] = self.counter = self.counter + 1
        self.todos.append(todo)
        return todo

    def update(self, id, data):
        todo = self.get(id)
        todo.update(data)
        return todo

    def delete(self, id):
        todo = self.get(id)
        self.todos.remove(todo)


DAO = TodoDAO()
DAO.create({'task': 'Build an API'})
DAO.create({'task': '?????'})
DAO.create({'task': 'profit!'})


@ns.route('/')
class TodoList(Resource):
    '''Shows a list of all todos, and lets you POST to add new tasks'''
    @ns.doc('list_todos')
    @ns.marshal_list_with(todo)
    def get(self):
        '''List all tasks'''
        return DAO.todos

    @ns.doc('create_todo')
    @ns.expect(todo)
    @ns.marshal_with(todo, code=201)
    def post(self):
        '''Create a new task'''
        return DAO.create(api.payload), 201


@ns.route('/<int:id>')
@ns.response(404, 'Todo not found')
@ns.param('id', 'The task identifier')
class Todo(Resource):
    '''Show a single todo item and lets you delete them'''
    @ns.doc('get_todo')
    @ns.marshal_with(todo)
    def get(self, id):
        '''Fetch a given resource'''
        return DAO.get(id)

    @ns.doc('delete_todo')
    @ns.response(204, 'Todo deleted')
    def delete(self, id):
        '''Delete a task given its identifier'''
        DAO.delete(id)
        return '', 204

    @ns.expect(todo)
    @ns.marshal_with(todo)
    def put(self, id):
        '''Update a task given its identifier'''
        return DAO.update(id, api.payload)


if __name__ == '__main__':
    app.run(debug=True)

Contributors

Flask-RESTPlus is brought to you by @noirbizarre. Since early 2019 @SteadBytes, @a-luna, @j5awry, @ziirish volunteered to help @noirbizarre keep the project up and running. Of course everyone is welcome to contribute and we will be happy to review your PR's or answer to your issues.

Documentation

The documentation is hosted on Read the Docs

Contribution

Want to contribute! That's awesome! Check out CONTRIBUTING.rst!

Comments
  • App runs locally but returns 500 error on Heroku

    App runs locally but returns 500 error on Heroku

    There doesn't seem to be any documentation on deploying to Heroku with flask-restplus. I've just deployed an app and am getting the following: Error: INTERNAL SERVER ERROR.

    My Procfile is set to web: gunicorn app:app and my app is set as api = Api(app), app.wsgi_app = ProxyFix(app.wsgi_app), and app = Flask(__name__), respectively. Anyone have any suggestions?

    opened by rah-ool 38
  • AttributeError: Api does not have __schema__ attribute

    AttributeError: Api does not have __schema__ attribute

    Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information.

    Flask (0.11.1) flask-restplus (0.9.2) Flask-Script (2.0.5)

    [2016-08-17 15:07:57,503] ERROR in app: Exception on /mailang/api/v1/swagger.json [GET] Traceback (most recent call last): File "E:\Python27\lib\site-packages\flask\app.py", line 1639, in full_dispatch_request rv = self.dispatch_request() File "E:\Python27\lib\site-packages\flask\app.py", line 1625, in dispatch_request return self.view_functionsrule.endpoint File "E:\Python27\lib\site-packages\flask_restplus\api.py", line 310, in wrapper resp = resource(_args, *_kwargs) File "E:\Python27\lib\site-packages\flask\views.py", line 84, in view return self.dispatch_request(_args, *_kwargs) File "E:\Python27\lib\site-packages\flask_restplus\resource.py", line 44, in dispatch_request resp = meth(_args, *_kwargs) File "E:\Python27\lib\site-packages\flask_restplus\api.py", line 751, in get return self.api.schema File "E:\Python27\lib\site-packages\flask_restplus\api.py", line 206, in getattr raise AttributeError('Api does not have {0} attribute'.format(name)) AttributeError: Api does not have schema attribute 127.0.0.1 - - [17/Aug/2016 15:07:57] "GET /mailang/api/v1/swagger.json HTTP/1.1" 500 -

    Need more feedback 
    opened by 984958198 25
  • Refactor for accepting Marshmallow and other marshaling libraries

    Refactor for accepting Marshmallow and other marshaling libraries

    This is less of an issue and more of an intent to implement :shipit:

    Result

    The result of this work should be these two main things:

    • It should be possible to build alternative request parsing implementations.
    • It should be possible to use Marshmallow as easily as the current request parsing implementation.

    I intend to try doing this without losing backward compatibility of public APIs, so that most applications can update without having to rewrite their marshaling implementations. No promises of course about the internal API.

    Planning

    My plan of attack is as follows (may later be filled out with "subtasks"):

    • [ ] Design initial additions/changes to the public API through a simple "sample app"

      I'm simultaneously building a real world product with RestPlus and Marshmallow (hacked in) for my employer @l1ndanl. This should help a ton, since I can my experiences and "wish list" from that to design the public API.

      This implementation might be useful later for testing the implementation, but it shouldn't be set in stone. Implementation details may have to change the actual public API.

    • [ ] Locate and split out all touch points of the internal APIs with request parsing

      Before I design the abstraction layer I'd like to make sure I know exactly what the internal API needs to be able to do and where it's used. This will require some more extensive knowledge of RestPlus internals and since these uses will have to be split out anyway eventually, doing this before designing the abstraction should make it a lot easier for me.

    • [ ] Design the abstraction layer

    • [ ] Implement the abstraction layer for the "legacy" request parsing

    • [ ] Implement an abstraction layer for Marshmallow and/or webargs

    Methodology

    I'll obviously be developing in my own fork of RestPlus in a special branch, that can then eventually be merged through a PR.

    I'm also very interested in suggestions/ideas/insider info/similar projects + shows of support 🎉 .

    Related reading...

    • https://github.com/noirbizarre/flask-restplus/issues/410
    • https://github.com/noirbizarre/flask-restplus/issues/317
    • https://github.com/noirbizarre/flask-restplus/issues/9
    • The warning on this page: http://flask-restplus.readthedocs.io/en/stable/parsing.html
    opened by martijnarts 24
  • Support vendor fields

    Support vendor fields

    Swagger allow to add custom/vendor fields at every level: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#vendorExtensions

    flask-restplus should support declaring vendor fields.

    @Kelvinm you said in #44 that you have some local modification on the subject. Do you mind to share them ?

    enhancement 
    opened by noirbizarre 22
  • Fix ambiguity error with Polymorphism candidates (isinstance() problem)

    Fix ambiguity error with Polymorphism candidates (isinstance() problem)

    Right now Polymorphism fails when using something like this (models in sqlalchemy):

    models:

    class Product(BaseModel):
    	discr = Column(String)
    
    	__mapper_args__ = {
    		'polymorphic_on': discr,
            'polymorphic_identity': "product"
    	}
    
    class VegetableProduct(Product):
    	name = Column(String)
    
        __mapper_args__ = {
    		'polymorphic_identity': "vegetable"
    	}
    
    class DairyProduct(VegetableProduct):
        __mapper_args__ = {
    		'polymorphic_identity': "dairy"
    	}
    

    mapper:

    resource_product = api.model("Product", {
    	'discr': fields.String
    })
    
    product_mapper = {
    	VegetableProduct: api.inherit("Vegetable", resource_product, { 'name': fields.String }),
    	DairyProduct: api.inherit("Dairy", resource_product, { 'name': fields.String }),
    }
    
    resource_result = api.model("ResourceResult", {
    	'products': fields.List(fields.Polymorphism(product_mapper))
    })
    

    This sparkles error here:

    https://github.com/noirbizarre/flask-restplus/blob/master/flask_restplus/fields.py#L682

    Because candidates will be: VegetableProduct and DairyProduct, since isinstance() will return True for both classes (I personally surprised it works like this)

    But actually it should be only DairyProduct

    Checking by __class__.__name__ removes this error and it works as intended.

    I hope my quick fix did not break anything, I'm eager to update it if I don't know, more elegant solution is needed.

    opened by idchlife 18
  • Splitting up API library into multiple files

    Splitting up API library into multiple files

    I've tried several different ways to split up the API files into separate python source but have come up empty. I love the additions to flask-restplus but it appears that only the classes within the main python file are seen. Is there a good example of how to do this? In Flask-Restful it was a bit simpler as you could just add the resource and point to a different python file that got imported.

    help wanted 
    opened by kinabalu 16
  • Defining varaible keys in case of nested field model

    Defining varaible keys in case of nested field model

    	"preview": {
    		"9:16": {
    			"thumbnail": "",
    			"video": ""
    		}, "16:9": {
    			"thumbnail": "",
    			"video": ""
    		}, "1:1": {
    			"thumbnail": "",
    			"video": ""
    		}
    	}
    

    I have the above data coming in the request for which I want to create a model. I tried implementing wildcard fields but didn't get any success. In the above case, the aspect ratio is dynamic and can be anything but will always be in *:* format. In case that is coming, thumbnail and video are in nested modal with required= true.

    Any leads would be appreciated. Thanks in advance!

    enhancement in progress 
    opened by knowBalpreet 15
  • [proposal] better support for security requirements

    [proposal] better support for security requirements

    What I'm proposing, and willing to implement and contribute is a SecurityRequirement class, possibly with subclasses like OAuth2SecurityRequirement. defining an api with these requirements would look like this:

    oauth2_req = OAuth2SecurityRequirement(name="needsuser", scopes=["scope1", "scope2"], flow="implicit", authorization_uri="http://example.com/authorize")
    apikey_req = ApiKeyRequirement(name="apikey", param_name="key", in="query")
    
    to require either one of these api requirements api-wide, you'd pass an array of instances to the API constructor.
    
    
    ```python
    Api(title="my apy", version="v1", security_requirements=[
        apikey_req,
        oauth2_req("scope1")
    ])
    

    Note that oauth2 requirement instances are callable, so you can pass in required scopes.

    I'd be very much willing to implementthis and contribute the code back to this project if you're interested.

    enhancement 
    opened by bigblind 14
  • Enable OAuth2 Implicit Flow authentication round-trip in Swagger UI

    Enable OAuth2 Implicit Flow authentication round-trip in Swagger UI

    The swagger-ui project contains a oauth2-redirect.html file which provides a credential trampoline. Vendor it in, and place the external url to this file in swagger-ui.html.

    The OAuth2 authentication loop is run in a popup window/tab. The IDP will redirect back to the oauth2RedirectUrl with an access_token provided in the #hash-fragment of the url. Javascript running inside 'oauth2-redirect.html' pushes the access_token back to the parent which created the window/tab, before closing the tab.

    Enables use-case in #544 without adding another config param.

    Usage:

    app.config.SWAGGER_UI_OAUTH_CLIENT_ID = 'MyClientId'
    app.config.SWAGGER_UI_OAUTH_REALM = '-'
    app.config.SWAGGER_UI_OAUTH_APP_NAME = 'Demo'
    api = Api(
        app,
        title='Demo',
        security={'OAuth2': ['read', 'write']},
        authorizations={
            'OAuth2': {
                'type': 'oauth2',
                'flow': 'implicit',
                'authorizationUrl': 'https://example.auth0.com/authorize?audience=https://app.example.com',
                'clientId': Auth().client_id,
                'scopes': {
                    'openid': 'Get ID token',
                    'profile': 'Get identity',
                }
            }
        }
    )
    
    opened by ellieayla 13
  • How do I do post a batch of resources?

    How do I do post a batch of resources?

    Hi, Thanks for this great library. I had a question about batch posts. I have lots of data coming in through our api for a particular resource and it's expensive to send each datum individually. How do I do batch posts in one request while integrating with the restplus architecture? If you could point me to some examples, I would be grateful.

    Thanks, Rajiv

    question 
    opened by RAbraham 12
  • Namespace tags without attached resources are not hidden from the documentation

    Namespace tags without attached resources are not hidden from the documentation

    Docs say that:

    Namespace tags without attached resources will be hidden automatically from the documentation.

    Which is not not true. Steps to reproduce:

    1. Create a namespace, that has a single resource implemented by class
    2. Add the following annotation @my_namespace.route('/endpoint', doc=False)
    3. Swagger UI will have an empty entry for the namespace
    Needed: Feedback 
    opened by lextiz 12
  • Download 100K records in csv format

    Download 100K records in csv format

    Hi,

    Can you give an example of how to download huge amount of data in csf format from browser/python code? I have something similar to the following right now but it obviously doesnt work. Also, I am not sure how to stream data into the client-side temporary file in small chunks of 10K instead of choking the whole pipe with 100k+ records.

    import pandas as pd
    from datetime import datetime
    from dateutil.relativedelta import relativedelta
    from typing import Any
    from typing_extensions import Required
    from flask import request
    from flask_restx import Namespace, Resource, fields
    from db import prod_db
    
    @api.route('/daily_order_book')
    class DailyOrderBook(Resource):
        @api.doc('get_daily_order_book')
        @api.marshal_with(daily_order_book_model)
        @api.produces(mimetypes="application/vnd.ms-excel")
        def get(self):
            '''This method retrieves daily order book.'''
            today: datetime = datetime.today() 
            yesterday: datetime = today - relativedelta(days=1)
            sql: str = f'''
            select * from daily_order_book'
            '''
    
            df: pd.DataFrame = prod_db.read(sql=sql)
            csv: Any = df.to_csv()
    
            return csv
    
    opened by kaushik1979 1
  • got_request_exception signal repeat execution

    got_request_exception signal repeat execution

    if debug=True or propagate_exceptions=True got_request_exception signal repeat execution, This statement can be avoided by moving it to the back of the judgment

    #api.py line610
    def handle_error(self, e):
        got_request_exception.send(current_app._get_current_object(), exception=e)
        if not isinstance(e, HTTPException) and current_app.propagate_exceptions:
            exc_type, exc_value, tb = sys.exc_info()
            if exc_value is e:
                raise
            else:
                raise e
    
    
    bug 
    opened by VieteChen 0
  • Setting jwt_token in head does not show in cUrl

    Setting jwt_token in head does not show in cUrl

    Hi guys i'm using the decorator @jwt_token() in my namespace therefore when i authenticate in the swagger the header does not shown in cUrl, and my response is 401, i'm setting in Api() the authentication but the header is not sent

    swagger = Api(
        title='Ágil Web Documentação',
        version='',
        description='Api de Testes',
        prefix='',
        doc='/docs',
        security='apiKey',
        authorizations={
            'apikey': {
                'type': 'apiKey',
                'in': 'header',
                'name': 'Authorization',
                'description': "Type in the *'Value'* input box below: **'Bearer &lt;JWT&gt;'**, where JWT is the token"
            }
        },
    )
    
    client_ns = Namespace('clients', description=Test', path='/',
                            decorators=[jwt_required()])
    

    image

    bug 
    opened by danilocastelhano1 0
  • Documentation suggestions

    Documentation suggestions

    As I was reading part of the documentation, I found a missing apostrophe in the documentation of the Api class.

    In addition, I'm suggesting adding a jump link in the contributing document and smoothing out a sentence.

    opened by Chris-May 0
  • How to use swagger with a old flask project.

    How to use swagger with a old flask project.

    I have system that is build with two API one is mine and another is third-part maintaned. How can I add swagger without modify the source of the third-part software.

    I build a POC in the source below: PoC

    simple_page.py

    # Pure flask page
    from flask import Blueprint, render_template, abort
    from jinja2 import TemplateNotFound
    
    simple_page = Blueprint('simple_page', __name__,
                            template_folder='templates')
    
    @simple_page.route('/', defaults={'page': 'index'})
    @simple_page.route('/<page>')
    def show(page):
        try:
            return render_template('%s.html' % page)
        except TemplateNotFound:
            abort(418)
    

    other_page.py

    #restplus based artecture
    from flask import Blueprint, render_template, abort, Flask
    from jinja2 import TemplateNotFound
    app = Flask(__name__)
    
    other_page = Blueprint('other_page', __name__)
    
    from flask_restplus import Api, Resource, fields
    
    api = Api(other_page, version='1.0', title='Todo API',
        description='A simple TODO API', doc='/doc/', template_folder='templates',
    )
    
    
    @api.route('/')
    class TodoSimple(Resource):
        def get(self):
            try:
                return render_template('other_page.html')
            except TemplateNotFound:
                abort(418)
    

    simple.py

    from flask import Flask
    from simple_page import simple_page
    from other_page import other_page
    from flask_restplus import Api
    
    app = Flask(__name__)
    api = Api(simple_page, doc='/doc/')
    
    
    app.register_blueprint(simple_page)
    #app.register_blueprint(simple_page, url_prefix='/simple_page')
    app.register_blueprint(other_page, url_prefix='/other_page')
    app.run()
    

    with this I get the doc page but a message "No operations defined in spec!". Screen Shot 2021-07-02 at 6 35 50 PM

    And the rest_plus page I get the documentation normal.

    opened by engFelipeMonteiro 0
Goblet is an easy-to-use framework that enables developers to quickly spin up fully featured REST APIs with python on GCP

GOBLET Goblet is a framework for writing serverless rest apis in python in google cloud. It allows you to quickly create and deploy python apis backed

Austen 78 Dec 27, 2022
Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs

chisel Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs. Here are its fea

Craig Hobbs 2 Dec 2, 2021
Daniel Vaz Gaspar 4k Jan 8, 2023
Flask-Potion is a RESTful API framework for Flask and SQLAlchemy, Peewee or MongoEngine

Flask-Potion Description Flask-Potion is a powerful Flask extension for building RESTful JSON APIs. Potion features include validation, model resource

DTU Biosustain 491 Dec 8, 2022
Flask-Potion is a RESTful API framework for Flask and SQLAlchemy, Peewee or MongoEngine

Flask-Potion Description Flask-Potion is a powerful Flask extension for building RESTful JSON APIs. Potion features include validation, model resource

DTU Biosustain 484 Feb 3, 2021
Pyrin is an application framework built on top of Flask micro-framework to make life easier for developers who want to develop an enterprise application using Flask

Pyrin A rich, fast, performant and easy to use application framework to build apps using Flask on top of it. Pyrin is an application framework built o

Mohamad Nobakht 10 Jan 25, 2022
Appier is an object-oriented Python web framework built for super fast app development.

Joyful Python Web App development Appier is an object-oriented Python web framework built for super fast app development. It's as lightweight as possi

Hive Solutions 122 Dec 22, 2022
Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints.

Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints. check parameters and generate API documents automatically. Flask Sugar是一个基于flask,pyddantic,类型注解的API框架, 可以检查参数并自动生成API文档

null 162 Dec 26, 2022
TinyAPI - 🔹 A fast & easy and lightweight WSGI Framework for Python

TinyAPI - ?? A fast & easy and lightweight WSGI Framework for Python

xArty 3 Apr 8, 2022
FastAPI framework, high performance, easy to learn, fast to code, ready for production

FastAPI framework, high performance, easy to learn, fast to code, ready for production Documentation: https://fastapi.tiangolo.com Source Code: https:

Sebastián Ramírez 53k Jan 2, 2023
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Jan 8, 2023
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Dec 28, 2022
Free and open source full-stack enterprise framework for agile development of secure database-driven web-based applications, written and programmable in Python.

Readme web2py is a free open source full-stack framework for rapid development of fast, scalable, secure and portable database-driven web-based applic

null 2k Dec 31, 2022
APIFlask is a lightweight Python web API framework based on Flask and marshmallow-code projects

APIFlask APIFlask is a lightweight Python web API framework based on Flask and marshmallow-code projects. It's easy to use, highly customizable, ORM/O

Grey Li 705 Jan 4, 2023
A public API written in Python using the Flask web framework to determine the direction of a road sign using AI

python-public-API This repository is a public API for solving the problem of the final of the AIIJC competition. The task is to create an AI for the c

Lev 1 Nov 8, 2021
A minimal, extensible, fast and productive API framework for Python 3.

molten A minimal, extensible, fast and productive API framework for Python 3. Changelog: https://moltenframework.com/changelog.html Community: https:/

Bogdan Popa 980 Nov 28, 2022
Bionic is Python Framework for crafting beautiful, fast user experiences for web and is free and open source

Bionic is fast. It's powered core python without any extra dependencies. Bionic offers stateful hot reload, allowing you to make changes to your code and see the results instantly without restarting your app or losing its state.

 ⚓ 0 Mar 5, 2022
A boilerplate Flask API for a Fullstack Project with some additional packages and configuration prebuilt. ⚙

Flask Boilerplate to quickly get started with production grade flask application with some additional packages and configuration prebuilt.

Yasser Tahiri 32 Dec 24, 2022
Swagger/OpenAPI First framework for Python on top of Flask with automatic endpoint validation & OAuth2 support

Connexion Connexion is a framework that automagically handles HTTP requests based on OpenAPI Specification (formerly known as Swagger Spec) of your AP

Zalando SE 4.2k Jan 7, 2023