Skip to content

flask-smorest with subdomains and redoc #661

@welby-caseactive

Description

@welby-caseactive

I have this sample app

from flask import Flask, jsonify
from flask_smorest import Api, Blueprint as SmorestBlueprint

# Initialize Flask app
app = Flask(__name__, subdomain_matching=True)
app.url_map.default_subdomain = "docs"
app.config["API_TITLE"] = "My API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.2"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_REDOC_PATH"] = "/redoc"
app.config[
    "OPENAPI_REDOC_URL"
] = "https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js"
app.config[
    "SERVER_NAME"
] = "example.com:5000"  # Configure the server name to handle subdomains

# Initialize API
api = Api(app)

# Create 'account' and 'manage' blueprint
account_blp = SmorestBlueprint("account", "account")
manage_blp = SmorestBlueprint("manage", "manage")


@account_blp.route("/info", subdomain="account")
def account_info():
    return jsonify({"message": "Account Info"})


@manage_blp.route("/settings", subdomain="manage")
def manage_settings():
    return jsonify({"message": "Manage Settings"})


# Set up Redoc for each subdomain
redoc_html = """
<!DOCTYPE html>
<html>
  <head>
    <title>Redoc</title>
    <!-- needed for adaptive design -->
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700">
    <style>
      body {
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <redoc spec-url='/openapi.json'></redoc>
    <script src="https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js"> </script>
  </body>
</html>
"""


# Register blueprints with API
api.register_blueprint(account_blp, subdomain="account")
api.register_blueprint(manage_blp, subdomain="manage")

# print routes to see whats registered
for rule in app.url_map.iter_rules():
    methods = ",".join(rule.methods)
    print(f"{rule.endpoint:25s} {methods:20s} {rule.rule}")


if __name__ == "__main__":
    # Run the app on all interfaces to accept requests from subdomains
    app.run(debug=True, host="0.0.0.0", port=5000)

I added the entry below in /etc/hosts

127.0.0.1 account.example.com
127.0.0.1 manage.example.com
127.0.0.1 docs.example.com
  • http://account.example.com:5000/info works
  • http://manage.example.com:5000/settings works

http://docs.example.com:5000/redoc works but server URL for each endpoint is missing. Both endpoints starts with http://docs.example.com:5000

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions