FlaskPostmanTutorial

Flask API to Postman collection without Swagger

Create a Postman collection from a Flask app with blueprints and flask-jwt-extended, without flasgger, apispec or YAML docstrings. Real output included.

Flask doesn't generate API docs, which makes "export my Flask API to Postman" harder than it should be. Most guides tell you to install flasgger or apispec and describe every endpoint in YAML docstrings first. That's fine for a new project but a big job for an existing one.

routeman works the other way round: it reads the routes Flask actually serves and the fields your views actually use.

The app

A typical application factory with two blueprints, using flask-jwt-extended:

auth_bp = Blueprint("auth", __name__, url_prefix="/api/auth")

@auth_bp.post("/login")
def login():
    data = request.get_json()
    username = data["username"]
    password = data["password"]
    return jsonify(access_token=create_access_token(identity=username))

@auth_bp.post("/register")
def register():
    data = request.get_json()
    email = data["email"]
    password = data["password"]
    ...

bp = Blueprint("orders", __name__, url_prefix="/api/orders")

@bp.get("/")
@jwt_required()
def list_orders():
    page = request.args.get("page", 1, type=int)
    status = request.args.get("status")
    ...

@bp.post("/")
@jwt_required()
def create_order():
    data = request.get_json()
    product_id = int(data["product_id"])
    quantity = int(data.get("quantity", 1))
    note = data.get("note")
    ...

@bp.get("/<int:order_id>")
@jwt_required()
def get_order(order_id): ...

def create_app():
    app = Flask(__name__)
    JWTManager(app)
    app.register_blueprint(auth_bp)
    app.register_blueprint(bp)
    return app

There are no schemas or docstrings, just ordinary Flask code.

Generate

$ pip install routeman
$ routeman routes -a "app:create_app()"
POST    /api/auth/login           json: username, password
POST    /api/auth/register        json: email, password
GET     /api/orders/            ๐Ÿ”’
POST    /api/orders/            ๐Ÿ”’ json: product_id, quantity, note
GET     /api/orders/{order_id}  ๐Ÿ”’
5 routes, auth: bearer

$ routeman generate -a "app:create_app()"
โœ“ flask: 5 requests (3 POST, 2 GET)
โœ“ auth: bearer (login: POST /api/auth/login)
โœ“ wrote postman/shop-api.postman_collection.json
โœ“ wrote postman/shop-api.local.postman_environment.json
  done in 0.15s - import the files in Postman (File โ†’ Import)

Every body field above came from reading the view code: data["username"], data.get("quantity", 1) and so on. @jwt_required() marked the order routes as protected, and /api/auth/login was recognised as the login route.

What's inside the collection

  • Auth โ€บ Login sends {"username": "{{username}}", "password": "{{password}}"} from the environment, so you never paste credentials into the request. Its test script saves the returned access_token.
  • Auth โ€บ Register gets {"email": "user@example.com", "password": "Str0ngPassw0rd!"}, a password most validators accept.
  • Orders โ€บ List orders has page and status query parameters.
  • Orders โ€บ Create order sends {"product_id": 1, "quantity": 1, "note": "Sample text"}. The integers come from the int(...) casts. The description notes that the fields were inferred from the view code.
  • Orders โ€บ Get order uses {{order_id}}, typed as an integer from the <int:order_id> converter.

When you do have schemas

If your project uses marshmallow, flask-smorest (@blp.arguments(Schema)) or Pydantic models, routeman uses them for exact field types, required flags and allowed values. Flask-RESTful Resources and MethodView classes are supported too, with one request per HTTP method.

Other auth styles

  • Flask-Login (@login_required): session auth.
  • Flask-HTTPAuth: Basic or token auth.
  • Custom API key header: set type = "apikey" and header = "X-API-Key" in routeman.toml.

Configuration that sticks

$ routeman init

This asks for the app path, name and servers, then writes routeman.toml, so teammates and CI can run a bare routeman generate. Settings from .env are loaded before create_app() runs.

More details on the Flask page, or continue with how the token auto-save script works.

Try routeman on your project

$ pip install routeman
$ routeman generate

Read the docs โ†’ Ask a question