{"id":2509,"library":"flask-restx","title":"Flask-RESTX","description":"Flask-RESTX is a powerful extension for Flask that adds support for quickly building REST APIs. It encourages best practices with minimal setup and provides automatic documentation via Swagger UI. As a community-driven fork of Flask-RESTPlus, it is actively maintained, currently at version 1.3.2, with a consistent release cadence addressing compatibility with newer Flask, Werkzeug, and Python versions.","status":"active","version":"1.3.2","language":"python","source_language":"en","source_url":"https://github.com/python-restx/flask-restx","tags":["flask","rest","api","swagger","openapi","documentation","restful","python"],"install":[{"cmd":"pip install flask-restx","lang":"bash","label":"Install Flask-RESTX"}],"dependencies":[{"reason":"Core web framework dependency for building REST APIs.","package":"Flask","optional":false},{"reason":"WSGI utility library, a core dependency of Flask, with specific compatibility requirements for Flask-RESTX.","package":"Werkzeug","optional":false}],"imports":[{"symbol":"Api","correct":"from flask_restx import Api"},{"symbol":"Resource","correct":"from flask_restx import Resource"},{"symbol":"fields","correct":"from flask_restx import fields"},{"symbol":"Namespace","correct":"from flask_restx import Namespace"},{"note":"While correct, `reqparse` is deprecated and will be removed in a future major version (2.0). Consider using alternatives like `api.model()` or `marshmallow` for request parsing.","symbol":"reqparse","correct":"from flask_restx import reqparse"},{"note":"Flask-RESTX is a fork of Flask-RESTPlus; imports must be updated from `flask_restplus` to `flask_restx`.","wrong":"from flask_restplus import Api","symbol":"Api","correct":"from flask_restx import Api"}],"quickstart":{"code":"from flask import Flask\nfrom flask_restx import Api, Resource, fields\n\napp = Flask(__name__)\napi = Api(app, version='1.0', title='Example API', description='A simple API example')\n\n# Define a namespace\nns = api.namespace('todos', description='TODO operations')\n\n# Define a model for request/response serialization\ntodo_model = ns.model('Todo', {\n    'id': fields.Integer(readonly=True, description='The task unique identifier'),\n    'task': fields.String(required=True, description='The task details')\n})\n\n# A simple in-memory data store\nclass TodoDAO:\n    def __init__(self):\n        self.counter = 0\n        self.todos = []\n\n    def get(self, id):\n        for todo in self.todos:\n            if todo['id'] == id:\n                return todo\n        ns.abort(404, \"Todo {} doesn't exist\".format(id))\n\n    def create(self, data):\n        todo = data\n        self.counter += 1\n        todo['id'] = self.counter\n        self.todos.append(todo)\n        return todo\n\n    def update(self, id, data):\n        todo = self.get(id)\n        todo.update(data)\n        return todo\n\n    def delete(self, id):\n        todo = self.get(id)\n        self.todos.remove(todo)\n\nDAO = TodoDAO()\nDAO.create({'task': 'Build an API'})\nDAO.create({'task': '?????'})\nDAO.create({'task': 'profit!'})\n\n@ns.route('/<int:id>')\n@ns.param('id', 'The task identifier')\nclass Todo(Resource):\n    @ns.doc('get_todo')\n    @ns.marshal_with(todo_model)\n    def get(self, id):\n        '''Fetch a single todo item'''\n        return DAO.get(id)\n\n    @ns.doc('update_todo')\n    @ns.expect(todo_model)\n    @ns.marshal_with(todo_model)\n    def put(self, id):\n        '''Update a todo item given its identifier'''\n        return DAO.update(id, api.payload)\n\n    @ns.doc('delete_todo')\n    @ns.response(204, 'Todo deleted')\n    def delete(self, id):\n        '''Delete a todo item given its identifier'''\n        DAO.delete(id)\n        return '', 204\n\n@ns.route('/')\nclass TodoList(Resource):\n    @ns.doc('list_todos')\n    @ns.marshal_list_with(todo_model)\n    def get(self):\n        '''List all todo items'''\n        return DAO.todos\n\n    @ns.doc('create_todo')\n    @ns.expect(todo_model)\n    @ns.marshal_with(todo_model, code=201)\n    def post(self):\n        '''Create a new todo item'''\n        return DAO.create(api.payload), 201\n\n\nif __name__ == '__main__':\n    app.run(debug=True)","lang":"python","description":"This quickstart demonstrates a basic Flask-RESTX application with a single API, a namespace, and a resource for managing 'todo' items. It includes defining a data model, handling GET, POST, PUT, and DELETE operations, and leverages Flask-RESTX's automatic Swagger UI documentation features."},"warnings":[{"fix":"Upgrade to `flask-restx` 1.3.0 or newer for Flask 2.x/3.x compatibility. For older `flask-restx` versions (<=0.4.0), pin Flask and Werkzeug to `<2.0.0`.","message":"Breaking changes related to Flask and Werkzeug versions. Prior to `flask-restx` 0.4.0, versions were incompatible with Flask/Werkzeug 2.0.0+. Version 0.4.0 pinned dependencies to `<2.0.0`. Versions 0.5.0 to <1.3.0 provided compatibility with Flask <3.0.0 by wrapping imports. `flask-restx` >=1.3.0 adds support for Flask >=3.0.0 and Flask >=2.0.0.","severity":"breaking","affected_versions":"<1.3.0"},{"fix":"Ensure your project uses Python 3.9 or higher. If using older Python versions, you must use an older `flask-restx` release (e.g., <1.0.1 for Python <3.7).","message":"Python version compatibility has changed. Support for Python <3.7 was dropped in versions 1.0.1 and 1.2.0. The current minimum Python version required is 3.9.","severity":"breaking","affected_versions":"<1.2.0"},{"fix":"Replace `reqparse.RequestParser()` with `api.model()` definitions and `@ns.expect()` decorator for request payload validation and documentation.","message":"The `reqparse` module is considered deprecated and is slated for removal in Flask-RESTX 2.0. While still functional, it is recommended to transition to `api.model()` for request validation and serialization, or integrate with other input/output validation libraries like Marshmallow.","severity":"deprecated","affected_versions":"All versions"},{"fix":"Use a global find/replace tool to change `flask_restplus` to `flask_restx` in Python files and `RESTPLUS_` to `RESTX_` in configuration settings.","message":"When migrating from `Flask-RESTPlus`, all imports from `flask_restplus` must be changed to `flask_restx`. Additionally, configuration options (e.g., `RESTPLUS_SWAGGER_UI_DOC_EXPANSION`) should be updated from `RESTPLUS_` prefixes to `RESTX_`.","severity":"gotcha","affected_versions":"All versions (for migration)"},{"fix":"Carefully configure `ProxyFix` and, if issues persist, consider serving the Swagger UI static assets manually and configuring `specs_url` or `doc` parameters in `Api` initialization.","message":"Deploying Flask-RESTX applications behind a reverse proxy (like Nginx) with `werkzeug.middleware.proxy_fix.ProxyFix` can lead to issues where the Swagger UI interface incorrectly assumes its base paths (e.g., `/swaggerui`, `/api/swagger.json`), even if the API itself functions correctly under the proxy. This often requires complex Nginx configurations or serving Swagger UI assets statically.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'1.3.2':52 'activ':47 'add':14 'address':58 'api':20,69 'automat':30 'best':23 'build':18 'cadenc':57 'communiti':38 'community-driven':37 'compat':59 'consist':55 'current':49 'document':31,72 'driven':39 'encourag':22 'extens':10 'flask':2,5,12,43,62,67 'flask-restplus':42 'flask-restx':1,4 'fork':40 'maintain':48 'minim':26 'newer':61 'openapi':71 'power':9 'practic':24 'provid':29 'python':65,74 'quick':17 'releas':56 'rest':19,68,73 'restplus':44 'restx':3,6 'setup':27 'support':15 'swagger':33,70 'ui':34 'version':51,66 'via':32 'werkzeug':63","created_at":"2026-04-11T01:31:07.747832+00:00","updated_at":"2026-04-16T15:07:51.331338+00:00","problems":[{"fix":"To resolve this, either downgrade Flask to a version below 3.0.0 (e.g., `pip install 'Flask<3.0.0'`) or update Flask-RESTX to version 1.2.0 or higher, which includes compatibility fixes for Flask 3.x.","cause":"This error occurs when using Flask-RESTX with Flask versions 3.0.0 or higher, because the 'flask.scaffold' module was moved or removed in newer Flask versions.","error":"ModuleNotFoundError: No module named 'flask.scaffold'"},{"fix":"Ensure you are applying `@ns.doc()` (where `ns` is a `Namespace` instance) to your `Resource` classes or their methods, or use `@api.route('/path')` directly on the `Api` instance for basic routes.","cause":"This error typically happens when attempting to use the `@api.doc()` decorator directly on the `api` instance imported from `flask_restx`, instead of applying it to a `Namespace` instance or a `Resource` class within a namespace.","error":"AttributeError: module 'flask_restx.api' has no attribute 'doc'"},{"fix":"Instead of `api.add_resource()`, define a `Namespace` and add your resource to it using `ns.add_resource()`, or use the `@api.route()` decorator on the `Api` instance for simple, non-namespaced resources.","cause":"Developers migrating from Flask-RESTful or older Flask-RESTPlus examples often try to use `api.add_resource()` directly on the `Api` object, but `flask-restx` primarily uses namespaces for resource registration, where `add_resource` is a method of the `Namespace` object.","error":"AttributeError: 'Api' object has no attribute 'add_resource'"},{"fix":"Ensure that your `Resource` methods explicitly return a dictionary, string, or a `flask.Response` object, which Flask-RESTX can then automatically serialize to JSON. If using classes as return types, they must be marshaled using `api.model` and `@marshal_with`.","cause":"This error occurs when a method in a `flask_restx.Resource` class returns an instance of a class or an unexpected type, rather than a dictionary, string, tuple, or Flask `Response` object that Flask-RESTX can serialize.","error":"TypeError: The view function did not return a valid response. The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a HelloWorld"},{"fix":"Update all import statements in your project from `from flask_restplus import ...` to `from flask_restx import ...`. You can often do this with a global search and replace in your IDE or a `sed` command.","cause":"This error indicates that the project is still attempting to import from the deprecated `flask_restplus` library after it has been migrated to `flask-restx`.","error":"ModuleNotFoundError: No module named 'flask_restplus'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.3.2","cli_name":"","cli_version":null,"type":"library","homepage":"https://flask-restx.readthedocs.io","github":"https://github.com/python-restx/flask-restx","docs":null,"changelog":null,"pypi":"https://pypi.org/project/flask-restx/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["web-framework"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-28","next_check":"2026-07-28","install_tag":null}}