3333from flask_migrate import Migrate
3434from flask_marshmallow import Marshmallow
3535from flask_oidc import OpenIDConnect
36+ from flask_smorest import Api
3637
3738__version__ = pkg_resources .get_distribution ('mrmat-python-api-flask' ).version
3839db = SQLAlchemy ()
3940ma = Marshmallow ()
4041migrate = Migrate ()
4142oidc = OpenIDConnect ()
43+ api = Api ()
4244
4345dictConfig ({
4446 'version' : 1 ,
@@ -77,7 +79,11 @@ def create_app(config_override=None, instance_path=None):
7779 Returns: an initialised Flask app object
7880
7981 """
80- app = Flask (__name__ , instance_relative_config = True , instance_path = instance_path )
82+ app = Flask (__name__ ,
83+ static_url_path = '' ,
84+ static_folder = 'static' ,
85+ instance_relative_config = True ,
86+ instance_path = instance_path )
8187
8288 #
8389 # Set configuration defaults. If a config file is present then load it. If we have overrides, apply them
@@ -88,6 +94,20 @@ def create_app(config_override=None, instance_path=None):
8894 app .config .setdefault ('SQLALCHEMY_TRACK_MODIFICATIONS' , False )
8995 app .config .setdefault ('OIDC_USER_INFO_ENABLED' , True )
9096 app .config .setdefault ('OIDC_RESOURCE_SERVER_ONLY' , True )
97+ app .config .setdefault ('API_TITLE' , 'MrMat :: Python :: API :: Flask' )
98+ app .config .setdefault ('API_VERSION' , __version__ )
99+ app .config .setdefault ('OPENAPI_VERSION' , '3.0.2' )
100+ app .config .setdefault ('OPENAPI_URL_PREFIX' , '/apidoc' )
101+ app .config .setdefault ('OPENAPI_JSON_PATH' , 'openapi.json' )
102+ app .config .setdefault ('OPENAPI_SWAGGER_UI_PATH' , 'swagger' )
103+ app .config .setdefault ('OPENAPI_SWAGGER_UI_URL' , 'https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/' )
104+ app .config .setdefault ('OPENAPI_REDOC_PATH' , 'redoc' )
105+ app .config .setdefault ('OPENAPI_REDOC_URL' , 'https://rebilly.github.io/ReDoc/releases/latest/redoc.min.js' )
106+ app .config .setdefault ('OPENAPI_RAPIDOC_PATH' , 'rapidoc' )
107+ app .config .setdefault ('OPENAPI_RAPIDOC_URL' , 'https://unpkg.com/rapidoc/dist/rapidoc-min.js' )
108+ #app.config.setdefault('OPENAPI_SWAGGER_UI_CONFIG', {
109+ # 'oauth2RedirectUrl': 'http://localhost:5000/apidoc/swagger/oauth2-redirect'
110+ #})
91111 if 'FLASK_CONFIG' in os .environ and os .path .exists (os .path .expanduser (os .environ ['FLASK_CONFIG' ])):
92112 app .config .from_json (os .path .expanduser (os .environ ['FLASK_CONFIG' ]))
93113 if config_override is not None :
@@ -113,6 +133,7 @@ def create_app(config_override=None, instance_path=None):
113133 db .init_app (app )
114134 migrate .init_app (app , db )
115135 ma .init_app (app )
136+ api .init_app (app )
116137 if 'OIDC_CLIENT_SECRETS' in app .config .keys ():
117138 oidc .init_app (app )
118139 else :
@@ -121,15 +142,45 @@ def create_app(config_override=None, instance_path=None):
121142 #
122143 # Import and register our APIs here
123144
124- from mrmat_python_api_flask .apis .healthz import bp as api_healthz # pylint: disable=import-outside-toplevel
145+ from mrmat_python_api_flask .apis .healthz import api_healthz # pylint: disable=import-outside-toplevel
125146 from mrmat_python_api_flask .apis .greeting .v1 import api_greeting_v1 # pylint: disable=import-outside-toplevel
126147 from mrmat_python_api_flask .apis .greeting .v2 import api_greeting_v2 # pylint: disable=import-outside-toplevel
127148 from mrmat_python_api_flask .apis .greeting .v3 import api_greeting_v3 # pylint: disable=import-outside-toplevel
128149 from mrmat_python_api_flask .apis .resource .v1 import api_resource_v1 # pylint: disable=import-outside-toplevel
129- app .register_blueprint (api_healthz , url_prefix = '/healthz' )
130- app .register_blueprint (api_greeting_v1 , url_prefix = '/api/greeting/v1' )
131- app .register_blueprint (api_greeting_v2 , url_prefix = '/api/greeting/v2' )
132- app .register_blueprint (api_greeting_v3 , url_prefix = '/api/greeting/v3' )
133- app .register_blueprint (api_resource_v1 , url_prefix = '/api/resource/v1' )
150+ api .register_blueprint (api_healthz , url_prefix = '/healthz' )
151+ api .register_blueprint (api_greeting_v1 , url_prefix = '/api/greeting/v1' )
152+ api .register_blueprint (api_greeting_v2 , url_prefix = '/api/greeting/v2' )
153+ api .register_blueprint (api_greeting_v3 , url_prefix = '/api/greeting/v3' )
154+ api .register_blueprint (api_resource_v1 , url_prefix = '/api/resource/v1' )
155+
156+ #
157+ # If OAuth2 is in use, register our usage
158+
159+ api .spec .components .security_scheme ('mrmat_keycloak' ,
160+ {'type' : 'oauth2' ,
161+ 'description' : 'This API uses OAuth 2' ,
162+ 'flows' : {
163+ 'clientCredentials' : {
164+ 'tokenUrl' : 'https://keycloak.mrmat.org/auth/realms/master/protocol/openid-connect/token' ,
165+ 'scopes' : {
166+ 'mrmat-python-api-flask-resource-read' : 'Allows reading objects '
167+ 'in the Resource API' ,
168+ 'mrmat-python-api-flask-resource-write' : 'Allows creating/modifying'
169+ ' and deleting objects '
170+ 'in the Resource API'
171+ }
172+ },
173+ 'authorizationCode' : {
174+ 'authorizationUrl' : 'https://keycloak.mrmat.org/auth/realms/master/protocol/openid-connect/auth' ,
175+ 'tokenUrl' : 'https://keycloak.mrmat.org/auth/realms/master/protocol/openid-connect/token' ,
176+ 'scopes' : {
177+ 'mrmat-python-api-flask-resource-read' : 'Allows reading objects '
178+ 'in the Resource API' ,
179+ 'mrmat-python-api-flask-resource-write' : 'Allows creating/modifying'
180+ ' and deleting objects '
181+ 'in the Resource API'
182+ }
183+ }
184+ }})
134185
135186 return app
0 commit comments