Skip to content

Commit 061552f

Browse files
authored
[feature][python-flask] Add CORS support to python-flask server (#8472)
* Add CORS support to python-flask server generator * Documentation update and CORS support for other generators using the same base class * Trivial sample changes
1 parent 64f5dc8 commit 061552f

File tree

14 files changed

+66
-3
lines changed

14 files changed

+66
-3
lines changed

docs/generators/python-aiohttp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
1212
|defaultController|default controller| |default_controller|
1313
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
1414
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
15+
|featureCORS|use flask-cors for handling CORS requests| |false|
1516
|legacyDiscriminatorBehavior|Set to true for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
1617
|packageName|python package name (convention: snake_case).| |openapi_server|
1718
|packageVersion|python package version.| |1.0.0|

docs/generators/python-blueplanet.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
1212
|defaultController|default controller| |default_controller|
1313
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
1414
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
15+
|featureCORS|use flask-cors for handling CORS requests| |false|
1516
|legacyDiscriminatorBehavior|Set to true for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
1617
|packageName|python package name (convention: snake_case).| |openapi_server|
1718
|packageVersion|python package version.| |1.0.0|

docs/generators/python-flask.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
1212
|defaultController|default controller| |default_controller|
1313
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
1414
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
15+
|featureCORS|use flask-cors for handling CORS requests| |false|
1516
|legacyDiscriminatorBehavior|Set to true for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
1617
|packageName|python package name (convention: snake_case).| |openapi_server|
1718
|packageVersion|python package version.| |1.0.0|

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonConnexionServerCodegen.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public abstract class AbstractPythonConnexionServerCodegen extends DefaultCodege
4949
public static final String CONTROLLER_PACKAGE = "controllerPackage";
5050
public static final String DEFAULT_CONTROLLER = "defaultController";
5151
public static final String SUPPORT_PYTHON2 = "supportPython2";
52+
public static final String FEATURE_CORS = "featureCORS";
5253
// nose is a python testing framework, we use pytest if USE_NOSE is unset
5354
public static final String USE_NOSE = "useNose";
5455
public static final String PYTHON_SRC_ROOT = "pythonSrcRoot";
@@ -61,6 +62,7 @@ public abstract class AbstractPythonConnexionServerCodegen extends DefaultCodege
6162
protected String defaultController;
6263
protected Map<Character, String> regexModifiers;
6364
protected boolean fixBodyName;
65+
protected boolean featureCORS = Boolean.FALSE;
6466
protected boolean useNose = Boolean.FALSE;
6567
protected String pythonSrcRoot;
6668

@@ -165,6 +167,8 @@ public AbstractPythonConnexionServerCodegen(String templateDirectory, boolean fi
165167
defaultValue("false"));
166168
cliOptions.add(new CliOption("serverPort", "TCP port to listen to in app.run").
167169
defaultValue("8080"));
170+
cliOptions.add(CliOption.newBoolean(FEATURE_CORS, "use flask-cors for handling CORS requests").
171+
defaultValue(Boolean.FALSE.toString()));
168172
cliOptions.add(CliOption.newBoolean(USE_NOSE, "use the nose test framework").
169173
defaultValue(Boolean.FALSE.toString()));
170174
cliOptions.add(new CliOption(PYTHON_SRC_ROOT, "put python sources in this subdirectory of output folder (defaults to \"\" for). Use this for src/ layout.").
@@ -213,6 +217,9 @@ public void processOpts() {
213217
additionalProperties.put(SUPPORT_PYTHON2, Boolean.TRUE);
214218
typeMapping.put("long", "long");
215219
}
220+
if (additionalProperties.containsKey(FEATURE_CORS)) {
221+
setFeatureCORS((String) additionalProperties.get(FEATURE_CORS));
222+
}
216223
if (additionalProperties.containsKey(USE_NOSE)) {
217224
setUseNose((String) additionalProperties.get(USE_NOSE));
218225
}
@@ -236,6 +243,10 @@ public void processOpts() {
236243
controllerPackage = packageName + "." + controllerPackage;
237244
}
238245

246+
public void setFeatureCORS(String val) {
247+
this.featureCORS = Boolean.valueOf(val);
248+
}
249+
239250
public void setUseNose(String val) {
240251
this.useNose = Boolean.valueOf(val);
241252
}

modules/openapi-generator/src/main/resources/python-aiohttp/__init__main.mustache

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import os
22
import connexion
3-
3+
{{#featureCORS}}
4+
import aiohttp_cors
5+
{{/featureCORS}}
46

57
def main():
68
options = {
@@ -12,4 +14,20 @@ def main():
1214
arguments={'title': '{{appName}}'},
1315
pythonic_params=True,
1416
pass_context_arg_name='request')
17+
18+
{{#featureCORS}}
19+
# Enable CORS for all origins.
20+
cors = aiohttp_cors.setup(app.app, defaults={
21+
"*": aiohttp_cors.ResourceOptions(
22+
allow_credentials=True,
23+
expose_headers="*",
24+
allow_headers="*",
25+
)
26+
})
27+
28+
# Register all routers for CORS.
29+
for route in list(app.app.router.routes()):
30+
cors.add(route)
31+
32+
{{/featureCORS}}
1533
app.run(port={{serverPort}})

modules/openapi-generator/src/main/resources/python-aiohttp/requirements.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ connexion[aiohttp,swagger-ui] <= 2.3.0; python_version=="3.5" or python_version=
77
werkzeug == 0.16.1; python_version=="3.5" or python_version=="3.4"
88
swagger-ui-bundle == 0.0.6
99
aiohttp_jinja2 == 1.2.0
10+
{{#featureCORS}}
11+
aiohttp_cors >= 0.7.0
12+
{{/featureCORS}}

modules/openapi-generator/src/main/resources/python-blueplanet/app/requirements.mustache

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ setuptools >= 21.0.0
77
bp2hookutil==3.3.0
88
plansdk
99
twigjack
10+
{{#featureCORS}}
11+
# should support both Python 2 and Python 3
12+
flask-cors >= 3.0.10
13+
{{/featureCORS}}

modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/__main__.mustache

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
{{/supportPython2}}
77

88
import connexion
9+
{{#featureCORS}}
10+
from flask_cors import CORS
11+
{{/featureCORS}}
912

1013
from {{packageName}} import encoder
1114

@@ -14,6 +17,12 @@ def main():
1417
app = connexion.App(__name__, specification_dir='./swagger/')
1518
app.app.json_encoder = encoder.JSONEncoder
1619
app.add_api('swagger.yaml', arguments={'title': '{{appName}}'})
20+
21+
{{#featureCORS}}
22+
# add CORS support
23+
CORS(app.app)
24+
25+
{{/featureCORS}}
1726
app.run(port={{serverPort}})
1827

1928

modules/openapi-generator/src/main/resources/python-flask/__main__.mustache

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
{{/supportPython2}}
77

88
import connexion
9+
{{#featureCORS}}
10+
from flask_cors import CORS
11+
{{/featureCORS}}
912

1013
from {{packageName}} import encoder
1114

@@ -16,6 +19,12 @@ def main():
1619
app.add_api('openapi.yaml',
1720
arguments={'title': '{{appName}}'},
1821
pythonic_params=True)
22+
23+
{{#featureCORS}}
24+
# add CORS support
25+
CORS(app.app)
26+
27+
{{/featureCORS}}
1928
app.run(port={{serverPort}})
2029

2130

modules/openapi-generator/src/main/resources/python-flask/requirements.mustache

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ connexion[swagger-ui] == 2.4.0; python_version<="2.7"
1010
werkzeug == 0.16.1; python_version=="3.5" or python_version=="3.4"
1111
swagger-ui-bundle >= 0.0.2
1212
python_dateutil >= 2.6.0
13+
{{#featureCORS}}
14+
# should support both Python 2 and Python 3
15+
flask-cors >= 3.0.10
16+
{{/featureCORS}}
1317
{{#supportPython2}}
1418
typing >= 3.5.2.2
1519
# For specs with timestamps, pyyaml 5.3 broke connexion's spec parsing in python 2.

samples/server/petstore/python-aiohttp-srclayout/src/openapi_server/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
22
import connexion
33

4-
54
def main():
65
options = {
76
"swagger_ui": True
@@ -12,4 +11,5 @@ def main():
1211
arguments={'title': 'OpenAPI Petstore'},
1312
pythonic_params=True,
1413
pass_context_arg_name='request')
14+
1515
app.run(port=8080)

samples/server/petstore/python-aiohttp/openapi_server/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
22
import connexion
33

4-
54
def main():
65
options = {
76
"swagger_ui": True
@@ -12,4 +11,5 @@ def main():
1211
arguments={'title': 'OpenAPI Petstore'},
1312
pythonic_params=True,
1413
pass_context_arg_name='request')
14+
1515
app.run(port=8080)

samples/server/petstore/python-blueplanet/app/openapi_server/__main__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def main():
99
app = connexion.App(__name__, specification_dir='./swagger/')
1010
app.app.json_encoder = encoder.JSONEncoder
1111
app.add_api('swagger.yaml', arguments={'title': 'OpenAPI Petstore'})
12+
1213
app.run(port=8080)
1314

1415

samples/server/petstore/python-flask/openapi_server/__main__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def main():
1111
app.add_api('openapi.yaml',
1212
arguments={'title': 'OpenAPI Petstore'},
1313
pythonic_params=True)
14+
1415
app.run(port=8080)
1516

1617

0 commit comments

Comments
 (0)