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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions