From 7eb3fa26ba6c77c2e1b886876c6cf2e6f188e0a2 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Sun, 19 Apr 2020 14:32:37 +0200 Subject: [PATCH 01/11] use prance library to get bundled OAS --- Pipfile.lock | 78 +++++++++++++++++++--------- pyms/flask/services/swagger.py | 13 ++++- setup.py | 2 + tests/swagger.yaml | 4 +- tests/swagger_for_tests/swagger.yaml | 4 +- 5 files changed, 72 insertions(+), 29 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 617b21d..321b594 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -259,6 +259,13 @@ ], "version": "==3.2.1" }, + "prance": { + "hashes": [ + "sha256:1f88df76d8d642efac1243801d39d9348bbb7530311270adbd7305ec45e077ac", + "sha256:e1ab67ec984c94b94e32bf17a2d6f35960db8b1ee248efea9f00ebaa1fcea1af" + ], + "version": "==0.18.2" + }, "prometheus-client": { "hashes": [ "sha256:71cd24a2b3eb335cb800c7159f423df1bd4dcd5171b234be15e3f31ec9f622da" @@ -293,19 +300,19 @@ }, "pyyaml": { "hashes": [ - "sha256:059b2ee3194d718896c0ad077dd8c043e5e909d9180f387ce42012662a4946d6", - "sha256:1cf708e2ac57f3aabc87405f04b86354f66799c8e62c28c5fc5f88b5521b2dbf", - "sha256:24521fa2890642614558b492b473bee0ac1f8057a7263156b02e8b14c88ce6f5", - "sha256:4fee71aa5bc6ed9d5f116327c04273e25ae31a3020386916905767ec4fc5317e", - "sha256:70024e02197337533eef7b85b068212420f950319cc8c580261963aefc75f811", - "sha256:74782fbd4d4f87ff04159e986886931456a1894c61229be9eaf4de6f6e44b99e", - "sha256:940532b111b1952befd7db542c370887a8611660d2b9becff75d39355303d82d", - "sha256:cb1f2f5e426dc9f07a7681419fe39cee823bb74f723f36f70399123f439e9b20", - "sha256:dbbb2379c19ed6042e8f11f2a2c66d39cceb8aeace421bfc29d085d93eda3689", - "sha256:e3a057b7a64f1222b56e47bcff5e4b94c4f61faac04c7c4ecb1985e18caa3994", - "sha256:e9f45bd5b92c7974e59bcd2dcc8631a6b6cc380a904725fce7bc08872e691615" + "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", + "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", + "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", + "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", + "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", + "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", + "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", + "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", + "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", + "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", + "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" ], - "version": "==5.3" + "version": "==5.3.1" }, "requests": { "hashes": [ @@ -314,6 +321,14 @@ ], "version": "==2.23.0" }, + "semver": { + "hashes": [ + "sha256:095c3cba6d5433f21451101463b22cf831fe6996fcc8a603407fd8bea54f116b", + "sha256:723be40c74b6468861e0e3dbb80a41fc3b171a2a45bf956c245304773dc06055" + ], + "index": "pypi", + "version": "==2.9.1" + }, "six": { "hashes": [ "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", @@ -798,6 +813,13 @@ ], "version": "==0.13.1" }, + "prance": { + "hashes": [ + "sha256:1f88df76d8d642efac1243801d39d9348bbb7530311270adbd7305ec45e077ac", + "sha256:e1ab67ec984c94b94e32bf17a2d6f35960db8b1ee248efea9f00ebaa1fcea1af" + ], + "version": "==0.18.2" + }, "protobuf": { "hashes": [ "sha256:0bae429443cc4748be2aadfdaf9633297cfaeb24a9a02d0ab15849175ce90fab", @@ -906,19 +928,19 @@ }, "pyyaml": { "hashes": [ - "sha256:059b2ee3194d718896c0ad077dd8c043e5e909d9180f387ce42012662a4946d6", - "sha256:1cf708e2ac57f3aabc87405f04b86354f66799c8e62c28c5fc5f88b5521b2dbf", - "sha256:24521fa2890642614558b492b473bee0ac1f8057a7263156b02e8b14c88ce6f5", - "sha256:4fee71aa5bc6ed9d5f116327c04273e25ae31a3020386916905767ec4fc5317e", - "sha256:70024e02197337533eef7b85b068212420f950319cc8c580261963aefc75f811", - "sha256:74782fbd4d4f87ff04159e986886931456a1894c61229be9eaf4de6f6e44b99e", - "sha256:940532b111b1952befd7db542c370887a8611660d2b9becff75d39355303d82d", - "sha256:cb1f2f5e426dc9f07a7681419fe39cee823bb74f723f36f70399123f439e9b20", - "sha256:dbbb2379c19ed6042e8f11f2a2c66d39cceb8aeace421bfc29d085d93eda3689", - "sha256:e3a057b7a64f1222b56e47bcff5e4b94c4f61faac04c7c4ecb1985e18caa3994", - "sha256:e9f45bd5b92c7974e59bcd2dcc8631a6b6cc380a904725fce7bc08872e691615" + "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", + "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", + "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", + "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", + "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", + "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", + "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", + "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", + "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", + "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", + "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" ], - "version": "==5.3" + "version": "==5.3.1" }, "requests": { "hashes": [ @@ -934,6 +956,14 @@ ], "version": "==1.7.0" }, + "semver": { + "hashes": [ + "sha256:095c3cba6d5433f21451101463b22cf831fe6996fcc8a603407fd8bea54f116b", + "sha256:723be40c74b6468861e0e3dbb80a41fc3b171a2a45bf956c245304773dc06055" + ], + "index": "pypi", + "version": "==2.9.1" + }, "six": { "hashes": [ "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", diff --git a/pyms/flask/services/swagger.py b/pyms/flask/services/swagger.py index 7268f73..73ab1c3 100644 --- a/pyms/flask/services/swagger.py +++ b/pyms/flask/services/swagger.py @@ -1,8 +1,12 @@ import os +from pathlib import Path +from typing import Dict, Any import connexion from connexion.resolver import RestyResolver +import prance + from pyms.exceptions import AttrDoesNotExistException from pyms.flask.services.driver import DriverService from pyms.utils import check_package_exists @@ -40,6 +44,13 @@ def _get_application_root(config): application_root = "/" return application_root + @staticmethod + def get_bundled_specs(main_file: Path) -> Dict[str, Any]: + parser = prance.ResolvingParser(str(main_file.absolute()), + lazy=True, backend='openapi-spec-validator') + parser.parse() + return parser.specification + def init_app(self, config, path): """ Initialize Connexion App. See more info in [Connexion Github](https://github.com/zalando/connexion) @@ -75,7 +86,7 @@ def init_app(self, config, path): resolver=RestyResolver(self.project_dir)) params = { - "specification": self.file, + "specification": self.get_bundled_specs(Path(os.path.join(specification_dir, self.file))), "arguments": {'title': config.APP_NAME}, "base_path": application_root, "options": {"swagger_url": self.url}, diff --git a/setup.py b/setup.py index d06303f..5b5094e 100644 --- a/setup.py +++ b/setup.py @@ -39,6 +39,8 @@ 'connexion[swagger-ui]>=2.6.0', 'swagger-ui-bundle>=0.0.6', 'anyconfig>=0.9.8', + 'semver>=2.9.1', + 'prance>=0.18.2', ] install_traces_requires = [ diff --git a/tests/swagger.yaml b/tests/swagger.yaml index 45c818f..1425201 100644 --- a/tests/swagger.yaml +++ b/tests/swagger.yaml @@ -38,9 +38,9 @@ paths: produces: - "application/json" responses: - 200: + "200": description: "Example" - 405: + "405": description: "Invalid input" x-swagger-router-controller: "tests.test_flask" externalDocs: diff --git a/tests/swagger_for_tests/swagger.yaml b/tests/swagger_for_tests/swagger.yaml index f389692..fbff310 100644 --- a/tests/swagger_for_tests/swagger.yaml +++ b/tests/swagger_for_tests/swagger.yaml @@ -38,9 +38,9 @@ paths: produces: - "application/json" responses: - 200: + "200": description: "Example" - 405: + "405": description: "Invalid input" x-swagger-router-controller: "tests.test_flask" externalDocs: From dd9349808e2f53cebb268b9f48375cdc1895f2c9 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Sun, 19 Apr 2020 15:37:20 +0200 Subject: [PATCH 02/11] fix pipfile.lock --- Pipfile.lock | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 6251a2e..e1b219e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -356,7 +356,6 @@ ], "version": "==2.23.0" }, -<<<<<<< HEAD "semver": { "hashes": [ "sha256:095c3cba6d5433f21451101463b22cf831fe6996fcc8a603407fd8bea54f116b", @@ -364,14 +363,13 @@ ], "index": "pypi", "version": "==2.9.1" -======= + }, "s3transfer": { "hashes": [ "sha256:2482b4259524933a022d59da830f51bd746db62f047d6eb213f2f8855dcb8a13", "sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db" ], "version": "==0.3.3" ->>>>>>> 4a13881616b3f3370df6ac34e6675725d671255f }, "six": { "hashes": [ @@ -1014,7 +1012,6 @@ ], "version": "==1.7.0" }, -<<<<<<< HEAD "semver": { "hashes": [ "sha256:095c3cba6d5433f21451101463b22cf831fe6996fcc8a603407fd8bea54f116b", @@ -1022,14 +1019,13 @@ ], "index": "pypi", "version": "==2.9.1" -======= + }, "safety": { "hashes": [ "sha256:05f77773bbab834502328b29ed013677aa53ed0c22b6e330aef7d2a7e1dfd838", "sha256:3016631e0dd17193d6cf12e8ed1af92df399585e8ee0e4b1300d9e7e32b54903" ], "version": "==1.8.7" ->>>>>>> 4a13881616b3f3370df6ac34e6675725d671255f }, "six": { "hashes": [ From 2a53adba166e98bdae5482692ad014c4d2bf64d7 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Sun, 19 Apr 2020 16:20:59 +0200 Subject: [PATCH 03/11] prevent import errors --- pyms/flask/services/swagger.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pyms/flask/services/swagger.py b/pyms/flask/services/swagger.py index 73ab1c3..65db243 100644 --- a/pyms/flask/services/swagger.py +++ b/pyms/flask/services/swagger.py @@ -5,7 +5,10 @@ import connexion from connexion.resolver import RestyResolver -import prance +try: + import prance +except ModuleNotFoundError: # pragma: no cover + prance = None from pyms.exceptions import AttrDoesNotExistException from pyms.flask.services.driver import DriverService @@ -86,7 +89,8 @@ def init_app(self, config, path): resolver=RestyResolver(self.project_dir)) params = { - "specification": self.get_bundled_specs(Path(os.path.join(specification_dir, self.file))), + "specification": self.get_bundled_specs( + Path(os.path.join(specification_dir, self.file))) if prance else self.file, "arguments": {'title': config.APP_NAME}, "base_path": application_root, "options": {"swagger_url": self.url}, From 91f1d228c04bf4cfbb22a450d2da82f938825ee9 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Tue, 21 Apr 2020 14:52:26 +0200 Subject: [PATCH 04/11] merge swagger into a single file --- pyms/cmd/main.py | 38 ++++++++++++++++++++++----- pyms/flask/services/swagger.py | 39 ++++++++++++++++++++++------ tests/swagger_for_tests/info.yaml | 6 +++++ tests/swagger_for_tests/swagger.yaml | 13 +++++++--- tests/test_cmd.py | 11 ++++++++ 5 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 tests/swagger_for_tests/info.yaml diff --git a/pyms/cmd/main.py b/pyms/cmd/main.py index cc174e0..841c60b 100755 --- a/pyms/cmd/main.py +++ b/pyms/cmd/main.py @@ -3,10 +3,12 @@ from __future__ import unicode_literals, print_function import argparse +import os import sys -from pyms.utils import check_package_exists, import_from from pyms.crypt.fernet import Crypt +from pyms.flask.services.swagger import merge_swagger_file +from pyms.utils import check_package_exists, import_from class Command: @@ -33,13 +35,23 @@ def __init__(self, *args, **kwargs): parser_create_key.add_argument("create_key", action='store_true', help='Generate a Key to encrypt strings in config') - parser_startproject = commands.add_parser('startproject', - help='Generate a project from https://github.com/python-microservices/microservices-template') - parser_startproject.add_argument("startproject", action='store_true', - help='Generate a project from https://github.com/python-microservices/microservices-template') + parser_startproject = commands.add_parser( + 'startproject', + help='Generate a project from https://github.com/python-microservices/microservices-template') + parser_startproject.add_argument( + "startproject", action='store_true', + help='Generate a project from https://github.com/python-microservices/microservices-template') + + parser_startproject.add_argument( + "-b", "--branch", + help='Select a branch from https://github.com/python-microservices/microservices-template') - parser_startproject.add_argument("-b", "--branch", - help='Select a branch from https://github.com/python-microservices/microservices-template') + parser_merge_swagger = commands.add_parser('merge-swagger', help='Merge swagger into a single file') + parser_merge_swagger.add_argument("merge_swagger", action='store_true', + help='Merge swagger into a single file') + parser_merge_swagger.add_argument( + "-f", "--file", default=os.path.join('project', 'swagger', 'swagger.yaml'), + help='Swagger file path') parser.add_argument("-v", "--verbose", default="", type=str, help="Verbose ") @@ -57,6 +69,11 @@ def __init__(self, *args, **kwargs): self.branch = args.branch except AttributeError: self.startproject = False + try: + self.merge_swagger = args.merge_swagger + self.file = args.file + except AttributeError: + self.merge_swagger = False self.verbose = len(args.verbose) if autorun: # pragma: no cover result = self.run() @@ -89,6 +106,13 @@ def run(self): cookiecutter = import_from("cookiecutter.main", "cookiecutter") cookiecutter('gh:python-microservices/cookiecutter-pyms', checkout=self.branch) self.print_ok("Created project OK") + if self.merge_swagger: + try: + merge_swagger_file(main_file=self.file) + self.print_ok("Swagger file generated [swagger-complete.yaml]") + except FileNotFoundError as ex: + self.print_error(ex.__str__()) + return False return True @staticmethod diff --git a/pyms/flask/services/swagger.py b/pyms/flask/services/swagger.py index 65db243..6169e73 100644 --- a/pyms/flask/services/swagger.py +++ b/pyms/flask/services/swagger.py @@ -7,6 +7,7 @@ try: import prance + from prance.util import formats, fs except ModuleNotFoundError: # pragma: no cover prance = None @@ -20,6 +21,35 @@ PROJECT_DIR = "project" +def get_bundled_specs(main_file: Path) -> Dict[str, Any]: + """ + Get bundled specs + :param main_file: Swagger file path + :return: + """ + parser = prance.ResolvingParser(str(main_file.absolute()), + lazy=True, backend='openapi-spec-validator') + parser.parse() + return parser.specification + + +def merge_swagger_file(main_file: str): + """ + Generate swagger into a single file + :param main_file: Swagger file path + :return: + """ + input_file = Path(main_file) + output_file = Path(input_file.parent, 'swagger-complete.yaml') + + contents = formats.serialize_spec( + specs=get_bundled_specs(input_file).__str__(), + filename=output_file) + fs.write_file(filename=output_file, + contents=contents, + encoding='utf-8') + + class Service(DriverService): """The parameters you can add to your config are: * **path:** The relative or absolute route to your swagger yaml file. The default value is the current directory @@ -47,13 +77,6 @@ def _get_application_root(config): application_root = "/" return application_root - @staticmethod - def get_bundled_specs(main_file: Path) -> Dict[str, Any]: - parser = prance.ResolvingParser(str(main_file.absolute()), - lazy=True, backend='openapi-spec-validator') - parser.parse() - return parser.specification - def init_app(self, config, path): """ Initialize Connexion App. See more info in [Connexion Github](https://github.com/zalando/connexion) @@ -89,7 +112,7 @@ def init_app(self, config, path): resolver=RestyResolver(self.project_dir)) params = { - "specification": self.get_bundled_specs( + "specification": get_bundled_specs( Path(os.path.join(specification_dir, self.file))) if prance else self.file, "arguments": {'title': config.APP_NAME}, "base_path": application_root, diff --git a/tests/swagger_for_tests/info.yaml b/tests/swagger_for_tests/info.yaml new file mode 100644 index 0000000..34551b3 --- /dev/null +++ b/tests/swagger_for_tests/info.yaml @@ -0,0 +1,6 @@ +--- +version: "1.0.0" +author: "API Team" +email: "apiteam@swagger.io" +url: "http://swagger.io" +... diff --git a/tests/swagger_for_tests/swagger.yaml b/tests/swagger_for_tests/swagger.yaml index fbff310..c4be461 100644 --- a/tests/swagger_for_tests/swagger.yaml +++ b/tests/swagger_for_tests/swagger.yaml @@ -2,11 +2,17 @@ swagger: "2.0" info: description: "This is a sample server Test server" - version: "1.0.0" + version: + $ref: 'info.yaml#/version' title: "Swagger Test list" termsOfService: "http://swagger.io/terms/" contact: - email: "apiteam@swagger.io" + name: + $ref: 'info.yaml#/author' + url: + $ref: 'info.yaml#/url' + email: + $ref: 'info.yaml#/email' license: name: "Apache 2.0" url: "http://www.apache.org/licenses/LICENSE-2.0.html" @@ -45,4 +51,5 @@ paths: x-swagger-router-controller: "tests.test_flask" externalDocs: description: "Find out more about Swagger" - url: "http://swagger.io" \ No newline at end of file + url: "http://swagger.io" +... \ No newline at end of file diff --git a/tests/test_cmd.py b/tests/test_cmd.py index c238788..42f7024 100644 --- a/tests/test_cmd.py +++ b/tests/test_cmd.py @@ -55,3 +55,14 @@ def test_startproject_error(self): with pytest.raises(PackageNotExists) as excinfo: cmd.run() assert "cookiecutter is not installed. try with pip install -U cookiecutter" in str(excinfo.value) + + def test_merge_swagger_ok(self): + arguments = ["merge-swagger", "--file", "tests/swagger_for_tests/swagger.yaml", ] + cmd = Command(arguments=arguments, autorun=False) + assert cmd.run() + os.remove("tests/swagger_for_tests/swagger-complete.yaml") + + def test_merge_swagger_error(self): + arguments = ["merge-swagger", ] + cmd = Command(arguments=arguments, autorun=False) + assert not cmd.run() From 42fba325c0dbcc5434c215d1d2961c44e8ad2eb4 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Tue, 21 Apr 2020 15:51:41 +0200 Subject: [PATCH 05/11] fix swagger file format --- pyms/flask/services/swagger.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyms/flask/services/swagger.py b/pyms/flask/services/swagger.py index 6169e73..524e2d9 100644 --- a/pyms/flask/services/swagger.py +++ b/pyms/flask/services/swagger.py @@ -43,8 +43,9 @@ def merge_swagger_file(main_file: str): output_file = Path(input_file.parent, 'swagger-complete.yaml') contents = formats.serialize_spec( - specs=get_bundled_specs(input_file).__str__(), - filename=output_file) + specs=get_bundled_specs(input_file), + filename=output_file, + ) fs.write_file(filename=output_file, contents=contents, encoding='utf-8') From 121cbd0f23875cea7eda4d4713f3447bc4efd570 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Tue, 21 Apr 2020 16:38:50 +0200 Subject: [PATCH 06/11] relaunch job --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index fb1907d..f708486 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ py_ms.egg-info/* pylintReport.txt .scannerwork/ - # Docker # Deploy From 813a7c0ad44e895a19a0699ef802efb4fbdd2460 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Tue, 21 Apr 2020 19:06:04 +0200 Subject: [PATCH 07/11] remove duplicate code --- pyms/flask/services/swagger.py | 7 ------- tests/test_cmd.py | 8 ++++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pyms/flask/services/swagger.py b/pyms/flask/services/swagger.py index 1dccdd7..524e2d9 100644 --- a/pyms/flask/services/swagger.py +++ b/pyms/flask/services/swagger.py @@ -78,13 +78,6 @@ def _get_application_root(config): application_root = "/" return application_root - @staticmethod - def get_bundled_specs(main_file: Path) -> Dict[str, Any]: - parser = prance.ResolvingParser(str(main_file.absolute()), - lazy=True, backend='openapi-spec-validator') - parser.parse() - return parser.specification - def init_app(self, config, path): """ Initialize Connexion App. See more info in [Connexion Github](https://github.com/zalando/connexion) diff --git a/tests/test_cmd.py b/tests/test_cmd.py index 42f7024..2890f57 100644 --- a/tests/test_cmd.py +++ b/tests/test_cmd.py @@ -1,6 +1,7 @@ """Test common rest operations wrapper. """ import os +from pathlib import Path import unittest from unittest.mock import patch @@ -9,6 +10,7 @@ from pyms.cmd import Command from pyms.exceptions import FileDoesNotExistException, PackageNotExists from pyms.crypt.fernet import Crypt +from pyms.flask.services.swagger import get_bundled_specs class TestCmd(unittest.TestCase): @@ -56,6 +58,12 @@ def test_startproject_error(self): cmd.run() assert "cookiecutter is not installed. try with pip install -U cookiecutter" in str(excinfo.value) + def test_get_bundled_specs(self): + specs = get_bundled_specs(Path("tests/swagger_for_tests/swagger.yaml")) + self.assertEqual(specs.get('swagger'), "2.0") + self.assertEqual(specs.get('info').get('version'), "1.0.0") + self.assertEqual(specs.get('info').get('contact').get('email'), "apiteam@swagger.io") + def test_merge_swagger_ok(self): arguments = ["merge-swagger", "--file", "tests/swagger_for_tests/swagger.yaml", ] cmd = Command(arguments=arguments, autorun=False) From 89cff9e91775a7808bfab2a60ac0881f28dc1ac4 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Tue, 21 Apr 2020 19:16:03 +0200 Subject: [PATCH 08/11] relaunch job --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f708486..fb1907d 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ py_ms.egg-info/* pylintReport.txt .scannerwork/ + # Docker # Deploy From 304d25ee79c549aeb43ec58e288b3a4457a8a9d8 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Wed, 22 Apr 2020 19:47:16 +0200 Subject: [PATCH 09/11] merge-swagger command doc --- docs/command_line.md | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/docs/command_line.md b/docs/command_line.md index 933099f..833d96d 100644 --- a/docs/command_line.md +++ b/docs/command_line.md @@ -8,7 +8,8 @@ pyms -h Show you a list of options and help instructions to use this command like: ```bash -usage: main.py [-h] [-v VERBOSE] {encrypt,create-key,startproject} ... +usage: main.py [-h] [-v VERBOSE] + {encrypt,create-key,startproject,merge-swagger} ... Python Microservices @@ -20,11 +21,12 @@ optional arguments: Commands: Available commands - {encrypt,create-key,startproject} + {encrypt,create-key,startproject,merge-swagger} encrypt Encrypt a string create-key Generate a Key to encrypt strings in config startproject Generate a project from https://github.com/python- microservices/microservices-template + merge-swagger Merge swagger into a single file ``` @@ -67,3 +69,28 @@ pyms encrypt 'mysql+mysqlconnector://important_user:****@localhost/my_schema' ``` See [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md) for more information + +## Merge swagger into a single file + +Command: + +```bash +pyms merge-swagger [-h] [-f FILE] +``` + +```bash +optional arguments: + -h, --help show this help message and exit + -f FILE, --file FILE Swagger file path +``` + +This command use [prance](https://github.com/jfinkhaeuser/prance) to validate the API specification and generate a single YAML file. Has an optional argument to indicate the main file path of the API specification. + +!!! warning + You must run first `pip install prance==0.18.2` + +```bash +pyms merge-swagger --file 'app/swagger/swagger.yaml' +>> Swagger file generated [swagger-complete.yaml] +>> OK +``` \ No newline at end of file From e7e6464f4955f081bba88735cf84a467fdd6659e Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Wed, 22 Apr 2020 22:20:27 +0200 Subject: [PATCH 10/11] fixes based on reviewer suggestions --- docs/command_line.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/command_line.md b/docs/command_line.md index 833d96d..2de7501 100644 --- a/docs/command_line.md +++ b/docs/command_line.md @@ -84,10 +84,7 @@ optional arguments: -f FILE, --file FILE Swagger file path ``` -This command use [prance](https://github.com/jfinkhaeuser/prance) to validate the API specification and generate a single YAML file. Has an optional argument to indicate the main file path of the API specification. - -!!! warning - You must run first `pip install prance==0.18.2` +This command uses [prance](https://github.com/jfinkhaeuser/prance) to validate the API specification and generate a single YAML file. It has an optional argument to indicate the main file path of the API specification. ```bash pyms merge-swagger --file 'app/swagger/swagger.yaml' From 4caa68f7181f418d984f406a185c8a6e787fd126 Mon Sep 17 00:00:00 2001 From: Fernando Arruza Date: Wed, 22 Apr 2020 22:32:16 +0200 Subject: [PATCH 11/11] relaunch job --- .gitignore | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitignore b/.gitignore index fb1907d..a7c80e9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ venv tmp *.sqlite3 - # Test&converage htmlcov/ coverage.xml @@ -18,9 +17,6 @@ py_ms.egg-info/* pylintReport.txt .scannerwork/ - -# Docker - # Deploy build/ dist/