diff --git a/bin/python-server-blueplanet-petstore.sh b/bin/python-server-blueplanet-petstore.sh new file mode 100755 index 000000000000..ece725e1c1b0 --- /dev/null +++ b/bin/python-server-blueplanet-petstore.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +SCRIPT="$0" +echo "# START SCRIPT: $SCRIPT" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar" + +if [ ! -f "$executable" ] +then + mvn -B clean package +fi + +generator=python-blueplanet +input=modules/openapi-generator/src/test/resources/2_0/petstore.yaml +out_folder=samples/server/petstore/$generator +resources=modules/openapi-generator/src/main/resources/$generator + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="generate -t $resources -i $input -g $generator -o $out_folder -Dservice $@" + +rm -rf $out_folder/.openapi* +rm -rf $out_folder/openapi_server +rm -rf $out_folder/tests* +rm $out_folder/README.md +rm $out_folder/requirements.txt +rm $out_folder/test-requirements.txt + +java $JAVA_OPTS -jar $executable $ags diff --git a/docs/generators.md b/docs/generators.md index 588bf946ca5f..d4f6a248f133 100644 --- a/docs/generators.md +++ b/docs/generators.md @@ -97,6 +97,7 @@ The following generators are available: - [php-symfony](generators/php-symfony.md) - [php-ze-ph](generators/php-ze-ph.md) - [python-aiohttp](generators/python-aiohttp.md) + - [python-blueplanet](generators/python-blueplanet.md) - [python-flask](generators/python-flask.md) - [ruby-on-rails](generators/ruby-on-rails.md) - [ruby-sinatra](generators/ruby-sinatra.md) diff --git a/docs/generators/python-blueplanet.md b/docs/generators/python-blueplanet.md new file mode 100644 index 000000000000..b5b9e8a05ef7 --- /dev/null +++ b/docs/generators/python-blueplanet.md @@ -0,0 +1,19 @@ + +--- +id: generator-opts-server-python-blueplanet +title: Config Options for python-blueplanet +sidebar_label: python-blueplanet +--- + +| Option | Description | Values | Default | +| ------ | ----------- | ------ | ------- | +|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| +|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| +|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| +|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| +|packageName|python package name (convention: snake_case).| |openapi_server| +|packageVersion|python package version.| |1.0.0| +|controllerPackage|controller package| |controllers| +|defaultController|default controller| |default_controller| +|supportPython2|support python2| |false| +|serverPort|TCP port to listen to in app.run| |8080| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonBluePlanetServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonBluePlanetServerCodegen.java new file mode 100755 index 000000000000..7a1599a4c32d --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonBluePlanetServerCodegen.java @@ -0,0 +1,239 @@ +/* + * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openapitools.codegen.languages; + +import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.SupportingFile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +public class PythonBluePlanetServerCodegen extends PythonAbstractConnexionServerCodegen { + private static final Logger LOGGER = LoggerFactory.getLogger(PythonBluePlanetServerCodegen.class); + + protected String modelDocPath = ""; + protected String modelTestPath = ""; + + public PythonBluePlanetServerCodegen() { + super("python-blueplanet", true); + testPackage = "tests"; + embeddedTemplateDir = templateDir = "python-blueplanet"; + } + + + /** + * Configures a friendly name for the generator. This will be used by the generator + * to select the library with the -g flag. + * + * @return the friendly name for the generator + */ + @Override + public String getName() { + return "python-blueplanet"; + } + + @Override + public void processOpts() { + super.processOpts(); + //apiTemplateFiles.clear(); + + if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) { + setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME)); + } else { + setPackageName("swagger_microservice"); + additionalProperties.put(CodegenConstants.PACKAGE_NAME, this.packageName); + } + if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) { + setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION)); + } else { + setPackageVersion("1.0.0"); + additionalProperties.put(CodegenConstants.PACKAGE_VERSION, this.packageVersion); + } + if (additionalProperties.containsKey(CONTROLLER_PACKAGE)) { + this.controllerPackage = additionalProperties.get(CONTROLLER_PACKAGE).toString(); + } else { + this.controllerPackage = "controllers"; + additionalProperties.put(CONTROLLER_PACKAGE, this.controllerPackage); + } + if (additionalProperties.containsKey(DEFAULT_CONTROLLER)) { + this.defaultController = additionalProperties.get(DEFAULT_CONTROLLER).toString(); + } else { + this.defaultController = "default_controller"; + additionalProperties.put(DEFAULT_CONTROLLER, this.defaultController); + } + if (Boolean.TRUE.equals(additionalProperties.get(SUPPORT_PYTHON2))) { + additionalProperties.put(SUPPORT_PYTHON2, Boolean.TRUE); + typeMapping.put("long", "long"); + } + + String APP_PATH = "app" + File.separatorChar; + String APP_PACKAGE_PATH = APP_PATH + packageName; + String TEST_PATH = APP_PACKAGE_PATH + File.separatorChar + "test"; + String MODEL_PATH = APP_PACKAGE_PATH + File.separatorChar + "models"; + String CONTROLLER_PATH = APP_PACKAGE_PATH + File.separatorChar + "controllers"; + String SOLUTION_PATH = "solution" + File.separatorChar; + String SWAGGER_PATH = APP_PACKAGE_PATH + File.separatorChar + "swagger"; + + // make solution and app src path available in mustache template + additionalProperties.put("appSrcPath", APP_PATH); + additionalProperties.put("solutionSrcPath", SOLUTION_PATH); + additionalProperties.put("modelDefinitionsSrcPath", modelDocPath); + + /* + * Supporting Files. You can write single files for the generator with the + * entire object tree available. If the input file has a suffix of `.mustache + * it will be processed by the template engine. Otherwise, it will be copied + */ + + // Root Directory + supportingFiles.add(new SupportingFile("Makefile.mustache", "", "Makefile")); + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt")); + + // App Directory + supportingFiles.add(new SupportingFile("app/Dockerfile.mustache", APP_PATH, "Dockerfile")); + supportingFiles.add(new SupportingFile("app/dockerignore.mustache", APP_PATH, ".dockerignore")); + supportingFiles.add(new SupportingFile("app/gitignore.mustache", APP_PATH, ".gitignore")); + supportingFiles.add(new SupportingFile("app/README.mustache", APP_PATH, "README.md")); + supportingFiles.add(new SupportingFile("app/requirements.mustache", APP_PATH, "requirements.txt")); + supportingFiles.add(new SupportingFile("app/setup.mustache", APP_PATH, "setup.py")); + supportingFiles.add(new SupportingFile("app/tox.mustache", APP_PATH, "tox.ini")); + supportingFiles.add(new SupportingFile("app/test-requirements.mustache", APP_PATH, "test-requirements.txt")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/__init__.mustache", APP_PACKAGE_PATH, "__init__.py")); + supportingFiles.add(new SupportingFile("app/{{packageName}}/__main__.mustache", APP_PACKAGE_PATH, "__main__.py")); + supportingFiles.add(new SupportingFile("app/{{packageName}}/encoder.mustache", APP_PACKAGE_PATH, "encoder.py")); + supportingFiles.add(new SupportingFile("app/{{packageName}}/util.mustache", APP_PACKAGE_PATH, "util.py")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/controllers/__init__.mustache", CONTROLLER_PATH, "__init__.py")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/models/__init__.mustache", MODEL_PATH, "__init__.py")); + supportingFiles.add(new SupportingFile("app/{{packageName}}/models/base_model_.mustache", MODEL_PATH, "base_model_.py")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/test/__init__.mustache", TEST_PATH, "__init__.py")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/swagger/swagger.mustache", SWAGGER_PATH, "swagger.yaml")); + + // Solution Directory + supportingFiles.add(new SupportingFile("solution/fig.mustache", SOLUTION_PATH, "fig.yml")); + + // Dynamically generated file definitions + modelTemplateFiles.remove("model.mustache", ".py"); + modelTemplateFiles.put("app/{{packageName}}/models/model.mustache", ".py"); + modelPackage = "app." + packageName + ".models"; + + apiTemplateFiles.remove("controller.mustache", ".py"); + apiTemplateFiles.put("app/{{packageName}}/controllers/controller.mustache", ".py"); + controllerPackage = "app." + packageName + ".controllers"; + + apiTestTemplateFiles().remove("controller_test.mustache", ".py"); + apiTestTemplateFiles.put("app/{{packageName}}/test/controller_test.mustache", ".py"); + testPackage = "app." + packageName + ".test"; + + // hack: Use ModelDoc to generate tosca files TODO: implement new Java class + modelDocPath = "model-definitions.types.tosca." + packageName; + modelDocTemplateFiles.put("model-definitions/types/tosca/{{packageName}}/{{model}}.mustache", ".tosca"); + + // hack: Use ModelTest to generate ui files TODO: implement new Java class + modelTestTemplateFiles.put("model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/create.mustache", "create.json"); + modelTestTemplateFiles.put("model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/high.mustache", "high.json"); + modelTestTemplateFiles.put("model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/low.mustache", "low.json"); + modelTestPath = "model-definitions" + File.separator + "types"; + } + + @Override + protected void addSupportingFiles() { + String APP_PATH = "app" + File.separatorChar; + String APP_PACKAGE_PATH = APP_PATH + packageName; + String TEST_PATH = APP_PACKAGE_PATH + File.separatorChar + "test"; + String MODEL_PATH = APP_PACKAGE_PATH + File.separatorChar + "models"; + String CONTROLLER_PATH = APP_PACKAGE_PATH + File.separatorChar + "controllers"; + String SOLUTION_PATH = "solution" + File.separatorChar; + String SWAGGER_PATH = APP_PACKAGE_PATH + File.separatorChar + "swagger"; + + // TODO: PythonAbstract should allow override + supportingFiles.clear(); + + // make solution and app src path available in mustache template + additionalProperties.put("appSrcPath", APP_PATH); + additionalProperties.put("solutionSrcPath", SOLUTION_PATH); + additionalProperties.put("modelDefinitionsSrcPath", modelDocPath); + + // Root Directory + supportingFiles.add(new SupportingFile("Makefile.mustache", "", "Makefile")); + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt")); + + // App Directory + supportingFiles.add(new SupportingFile("app/Dockerfile.mustache", APP_PATH, "Dockerfile")); + supportingFiles.add(new SupportingFile("app/dockerignore.mustache", APP_PATH, ".dockerignore")); + supportingFiles.add(new SupportingFile("app/gitignore.mustache", APP_PATH, ".gitignore")); + supportingFiles.add(new SupportingFile("app/README.mustache", APP_PATH, "README.md")); + supportingFiles.add(new SupportingFile("app/requirements.mustache", APP_PATH, "requirements.txt")); + supportingFiles.add(new SupportingFile("app/setup.mustache", APP_PATH, "setup.py")); + supportingFiles.add(new SupportingFile("app/tox.mustache", APP_PATH, "tox.ini")); + supportingFiles.add(new SupportingFile("app/test-requirements.mustache", APP_PATH, "test-requirements.txt")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/__init__.mustache", APP_PACKAGE_PATH, "__init__.py")); + supportingFiles.add(new SupportingFile("app/{{packageName}}/__main__.mustache", APP_PACKAGE_PATH, "__main__.py")); + supportingFiles.add(new SupportingFile("app/{{packageName}}/encoder.mustache", APP_PACKAGE_PATH, "encoder.py")); + supportingFiles.add(new SupportingFile("app/{{packageName}}/util.mustache", APP_PACKAGE_PATH, "util.py")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/controllers/__init__.mustache", CONTROLLER_PATH, "__init__.py")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/models/__init__.mustache", MODEL_PATH, "__init__.py")); + supportingFiles.add(new SupportingFile("app/{{packageName}}/models/base_model_.mustache", MODEL_PATH, "base_model_.py")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/test/__init__.mustache", TEST_PATH, "__init__.py")); + + supportingFiles.add(new SupportingFile("app/{{packageName}}/swagger/swagger.mustache", SWAGGER_PATH, "swagger.yaml")); + + // Solution Directory + supportingFiles.add(new SupportingFile("solution/fig.mustache", SOLUTION_PATH, "fig.yml")); + } + + @Override + public String modelDocFileFolder() { + return (outputFolder + File.separator + modelDocPath).replace('.', File.separatorChar); + } + + @Override + public String toModelDocFilename( String name ) { + return toModelName( name ) + "_ResourceType"; + } + + @Override + public String modelTestFileFolder() { + return outputFolder + File.separator + modelTestPath + File.separator + "ddui-views"; + } + + @Override + public String toModelTestFilename(String name) { + String resourceTypeFolder = packageName + ".resourceTypes." + toModelName(name) + File.separator; + return resourceTypeFolder; + } + + /** + * Location to write api files. You can use the apiPackage() as defined when the class is + * instantiated + */ + @Override + public String apiFileFolder() { + return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar); + } + +} diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index c5e741736314..1e1e65c5d1ea 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -75,6 +75,7 @@ org.openapitools.codegen.languages.PowerShellClientCodegen org.openapitools.codegen.languages.PythonClientCodegen org.openapitools.codegen.languages.PythonFlaskConnexionServerCodegen org.openapitools.codegen.languages.PythonAiohttpConnexionServerCodegen +org.openapitools.codegen.languages.PythonBluePlanetServerCodegen org.openapitools.codegen.languages.RClientCodegen org.openapitools.codegen.languages.RubyClientCodegen org.openapitools.codegen.languages.RubyOnRailsServerCodegen diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/Makefile.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/Makefile.mustache new file mode 100644 index 000000000000..3c81950b41e0 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/Makefile.mustache @@ -0,0 +1,51 @@ +HIDE ?= @ +PACKAGE := {{packageName}} +RELEASE := {{packageVersion}} +VENV := env +PYPI ?= 'https://pypi.blueplanet.com/simple' + +PWD ?= $(shell pwd) + +# Solution +VENDOR ?= path_to_your_repo +SOLUTION_RELEASE ?= $(shell solmaker version solution/fig.yml) +SOLUTION_NAME ?= $(shell solmaker name solution/fig.yml) +SOLUTION_IMAGE := $(VENDOR)/solution-$(SOLUTION_NAME) + +DOCKER_BUILD := docker build +DOCKER_IMAGE ?= $(VENDOR)/$(PACKAGE) +REGISTRY ?= registry.blueplanet.com +REMOTE_SERVER ?= bpadmin@10.10.10.10 + +SOLUTION := $(REGISTRY).$(VENDOR).$(SOLUTION_NAME):$(SOLUTION_RELEASE) + +.PHONY: app solution update upload-solution + +app: check-env + $(DOCKER_BUILD) --build-arg GLTOKEN=${GLTOKEN} -t $(REGISTRY)/$(DOCKER_IMAGE):$(RELEASE) -f app/Dockerfile ./app + +remote: + docker save $(REGISTRY)/$(DOCKER_IMAGE):$(RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + docker save $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + +push: + docker push $(REGISTRY)/$(DOCKER_IMAGE):$(RELEASE) + docker push $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) + +solution: check-env + $(docker rmi $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) && true) + solmaker build solution/fig.yml --vendor=$(VENDOR) --tag=$(SOLUTION_RELEASE) + +upload-solution: + docker save $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + +update: app solution + -ssh $(REMOTE_SERVER) 'solman "solution_purge -y $(SOLUTION)"' + docker save $(REGISTRY)/$(DOCKER_IMAGE):$(RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + docker save $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + -ssh $(REMOTE_SERVER) 'solman "solution_deploy $(SOLUTION)"' + +check-env: +ifndef GLTOKEN + $(error GLTOKEN is undefined) +endif diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/README.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/README.mustache new file mode 100644 index 000000000000..378755e355ac --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/README.mustache @@ -0,0 +1,59 @@ +# {{packageName}} Swagger-ui and Resource Types + +This project is an autogenerated microservice for Ciena's Blueplanet platform. + +## Overview + +Generated code can be used as: + +* Resource Type generation for Resource Adapter Development +* Resource Type generation for Service Template Development +* Microservice for swagger based NBI + +Make Targets: + +image: Create Docker image for use as BluePlanet microservice +solution: Create Solution image + +Resource Types are generated in model-definitions directory + +## Usage + +### Creating new release + +1. Update RELEASE property in Makefile +2. Update release(s) in [fig.yml](solution/fig.yml) +3. make image and solution + + ```bash + # building the image + make image + make solution + ``` + +### Iterative Development + +1. A helper target can be used for pushing image and solution to server + + ```bash + make update REMOTE_SERVER=bpadmin@10.10.10.10 + ``` + +This `make` target does the following: + +1. creates App and Solution image +2. purges solution from MCP remote +3. pushes solution and image to MCP remote +4. deploys solution + +### Local Usage + +To run the server locally: + +```bash +cd app +pip3 install -r requirements.txt +python3 -m swagger_server +``` + +and open your browser to [here](http://localhost:8080/{{packageName}}/ui/) diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/Dockerfile.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/Dockerfile.mustache new file mode 100644 index 000000000000..d96f8f2cc399 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/Dockerfile.mustache @@ -0,0 +1,43 @@ +{{#supportPython2}} +FROM python:2-alpine +{{/supportPython2}} +{{^supportPython2}} +FROM python:3-alpine +{{/supportPython2}} + +ARG GLTOKEN + +RUN apk add curl bash +ENV SHELL /bin/bash + +RUN mkdir /bp2 \ + && mkdir /bp2/data \ + && mkdir /bp2/log \ + && mkdir /bp2/src \ + && echo 'alias ll="ls -l"' >> ~/.bashrc +WORKDIR /bp2/src + +COPY requirements.txt /bp2/src + +{{#supportPython2}} +RUN pip install --extra-index-url https://GLTOKEN:$GLTOKEN@pypi.blueplanet.com/simple --no-cache-dir -r requirements.txt +{{/supportPython2}} +{{^supportPython2}} +RUN pip3 install --extra-index-url https://GLTOKEN:$GLTOKEN@pypi.blueplanet.com/simple --no-cache-dir -r requirements.txt +{{/supportPython2}} + +COPY . /bp2/src + +ENV SBIS=bpocore \ + SBI_bpocore_southbound-update=update_etc_hosts_multi_provider + +EXPOSE {{serverPort}} + +{{#supportPython2}} +ENTRYPOINT ["python"] +{{/supportPython2}} +{{^supportPython2}} +ENTRYPOINT ["python3"] +{{/supportPython2}} + +CMD ["-B", "-m", "{{packageName}}"] diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/README.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/README.mustache new file mode 100644 index 000000000000..b73b9e311b07 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/README.mustache @@ -0,0 +1,60 @@ +# Swagger generated server + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the +[OpenAPI-Spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This +is an example of building a swagger-enabled Flask server. + +This example uses the [Connexion](https://github.com/zalando/connexion) library on top of Flask. + +## Requirements +{{#supportPython2}} +Python 2.7+ +{{/supportPython2}} +{{^supportPython2}} +Python 3.5.2+ +{{/supportPython2}} + +## Usage +To run the server, please execute the following from the root directory: + +``` +{{#supportPython2}} +pip install -r requirements.txt +python -m {{packageName}} +{{/supportPython2}} +{{^supportPython2}} +pip3 install -r requirements.txt +python3 -m {{packageName}} +{{/supportPython2}} +``` + +and open your browser to here: + +``` +http://localhost:{{serverPort}}{{contextPath}}/ui/ +``` + +Your Swagger definition lives here: + +``` +http://localhost:{{serverPort}}{{contextPath}}/swagger.json +``` + +To launch the integration tests, use tox: +``` +sudo pip install tox +tox +``` + +## Running with Docker + +To run the server on a Docker container, please execute the following from the root directory: + +```bash +# building the image +docker build -t {{packageName}} . + +# starting up a container +docker run -p {{serverPort}}:{{serverPort}} {{packageName}} +``` \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/dockerignore.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/dockerignore.mustache new file mode 100644 index 000000000000..cdd823e64e7e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/dockerignore.mustache @@ -0,0 +1,72 @@ +.travis.yaml +.swagger-codegen-ignore +README.md +tox.ini +git_push.sh +test-requirements.txt +setup.py + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +venv/ +.python-version + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/gitignore.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/gitignore.mustache new file mode 100644 index 000000000000..a655050c2631 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/gitignore.mustache @@ -0,0 +1,64 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +venv/ +.python-version + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/requirements.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/requirements.mustache new file mode 100644 index 000000000000..d08b80acc5b3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/requirements.mustache @@ -0,0 +1,9 @@ +connexion == 1.1.15 +python_dateutil == 2.6.0 +{{#supportPython2}} +typing == 3.5.2.2 +{{/supportPython2}} +setuptools >= 21.0.0 +bp2hookutil==3.3.0 +plansdk +twigjack diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/setup.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/setup.mustache new file mode 100644 index 000000000000..56f8bc1ec176 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/setup.mustache @@ -0,0 +1,35 @@ +# coding: utf-8 + +import sys +from setuptools import setup, find_packages + +NAME = "{{packageName}}" +VERSION = "{{packageVersion}}" +{{#apiInfo}}{{#apis}}{{^hasMore}} +# To install the library, run the following +# +# python setup.py install +# +# prerequisite: setuptools +# http://pypi.python.org/pypi/setuptools + +REQUIRES = ["connexion"] + +setup( + name=NAME, + version=VERSION, + description="{{appName}}", + author_email="{{infoEmail}}", + url="{{packageUrl}}", + keywords=["Swagger", "{{appName}}"], + install_requires=REQUIRES, + packages=find_packages(), + package_data={'': ['swagger/swagger.yaml']}, + include_package_data=True, + entry_points={ + 'console_scripts': ['{{packageName}}={{packageName}}.__main__:main']}, + long_description="""\ + {{appDescription}} + """ +) +{{/hasMore}}{{/apis}}{{/apiInfo}} diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/test-requirements.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/test-requirements.mustache new file mode 100644 index 000000000000..7f8d96e6b40e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/test-requirements.mustache @@ -0,0 +1,6 @@ +flask_testing==0.6.1 +coverage>=4.0.3 +nose>=1.3.7 +pluggy>=0.3.1 +py>=1.4.31 +randomize>=0.13 diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/tox.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/tox.mustache new file mode 100644 index 000000000000..3efa994317d9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/tox.mustache @@ -0,0 +1,10 @@ +[tox] +envlist = {{#supportPython2}}py27, {{/supportPython2}}py35 + +[testenv] +deps=-r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +commands= + nosetests \ + [] \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/__init__.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/__init__.mustache new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/__main__.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/__main__.mustache new file mode 100644 index 000000000000..10756347223c --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/__main__.mustache @@ -0,0 +1,21 @@ +{{#supportPython2}} +#!/usr/bin/env python +{{/supportPython2}} +{{^supportPython2}} +#!/usr/bin/env python3 +{{/supportPython2}} + +import connexion + +from {{packageName}} import encoder + + +def main(): + app = connexion.App(__name__, specification_dir='./swagger/') + app.app.json_encoder = encoder.JSONEncoder + app.add_api('swagger.yaml', arguments={'title': '{{appName}}'}) + app.run(port={{serverPort}}) + + +if __name__ == '__main__': + main() diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/controllers/__init__.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/controllers/__init__.mustache new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/controllers/controller.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/controllers/controller.mustache new file mode 100644 index 000000000000..6fff6e4613f9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/controllers/controller.mustache @@ -0,0 +1,112 @@ +import connexion +import six + +{{#imports}}{{import}} # noqa: E501 +{{/imports}} +from {{packageName}} import util +{{#operations}} +{{#operation}} + + +def {{operationId}}({{#allParams}}{{paramName}}{{^required}}=None{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}): # noqa: E501 + """{{#summary}}{{.}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} + + {{#notes}}{{.}}{{/notes}} # noqa: E501 + + {{#allParams}} + :param {{paramName}}: {{description}} + {{^isContainer}} + {{#isPrimitiveType}} + :type {{paramName}}: {{#isString}}str{{/isString}}{{#isInteger}}int{{/isInteger}}{{#isLong}}int{{/isLong}}{{#isFloat}}float{{/isFloat}}{{#isDouble}}float{{/isDouble}}{{#isByteArray}}str{{/isByteArray}}{{#isBinary}}str{{/isBinary}}{{#isBoolean}}bool{{/isBoolean}}{{#isDate}}str{{/isDate}}{{#isDateTime}}str{{/isDateTime}} + {{/isPrimitiveType}} + {{#isUuid}} + :type {{paramName}}: {{#isString}}str{{/isString}}{{#isInteger}}int{{/isInteger}}{{#isLong}}int{{/isLong}}{{#isFloat}}float{{/isFloat}}{{#isDouble}}float{{/isDouble}}{{#isByteArray}}str{{/isByteArray}}{{#isBinary}}str{{/isBinary}}{{#isBoolean}}bool{{/isBoolean}}{{#isDate}}str{{/isDate}}{{#isDateTime}}str{{/isDateTime}} + {{/isUuid}} + {{^isPrimitiveType}} + {{#isFile}} + :type {{paramName}}: werkzeug.datastructures.FileStorage + {{/isFile}} + {{^isFile}} + {{^isUuid}} + :type {{paramName}}: dict | bytes + {{/isUuid}} + {{/isFile}} + {{/isPrimitiveType}} + {{/isContainer}} + {{#isListContainer}} + {{#items}} + {{#isPrimitiveType}} + :type {{paramName}}: List[{{#isString}}str{{/isString}}{{#isInteger}}int{{/isInteger}}{{#isLong}}int{{/isLong}}{{#isFloat}}float{{/isFloat}}{{#isDouble}}float{{/isDouble}}{{#isByteArray}}str{{/isByteArray}}{{#isBinary}}str{{/isBinary}}{{#isBoolean}}bool{{/isBoolean}}{{#isDate}}str{{/isDate}}{{#isDateTime}}str{{/isDateTime}}] + {{/isPrimitiveType}} + {{^isPrimitiveType}} + :type {{paramName}}: list | bytes + {{/isPrimitiveType}} + {{/items}} + {{/isListContainer}} + {{#isMapContainer}} + {{#items}} + {{#isPrimitiveType}} + :type {{paramName}}: Dict[str, {{#isString}}str{{/isString}}{{#isInteger}}int{{/isInteger}}{{#isLong}}int{{/isLong}}{{#isFloat}}float{{/isFloat}}{{#isDouble}}float{{/isDouble}}{{#isByteArray}}str{{/isByteArray}}{{#isBinary}}str{{/isBinary}}{{#isBoolean}}bool{{/isBoolean}}{{#isDate}}str{{/isDate}}{{#isDateTime}}str{{/isDateTime}}] + {{/isPrimitiveType}} + {{^isPrimitiveType}} + :type {{paramName}}: dict | bytes + {{/isPrimitiveType}} + {{/items}} + {{/isMapContainer}} + {{/allParams}} + + :rtype: {{#returnType}}{{.}}{{/returnType}}{{^returnType}}None{{/returnType}} + """ + {{#allParams}} + {{^isContainer}} + {{#isDate}} + {{paramName}} = util.deserialize_date({{paramName}}) + {{/isDate}} + {{#isDateTime}} + {{paramName}} = util.deserialize_datetime({{paramName}}) + {{/isDateTime}} + {{^isPrimitiveType}} + {{^isFile}} + {{^isUuid}} + if connexion.request.is_json: + {{paramName}} = {{baseType}}.from_dict(connexion.request.get_json()) # noqa: E501 + {{/isUuid}} + {{/isFile}} + {{/isPrimitiveType}} + {{/isContainer}} + {{#isListContainer}} + {{#items}} + {{#isDate}} + if connexion.request.is_json: + {{paramName}} = [util.deserialize_date(s) for s in connexion.request.get_json()] # noqa: E501 + {{/isDate}} + {{#isDateTime}} + if connexion.request.is_json: + {{paramName}} = [util.deserialize_datetime(s) for s in connexion.request.get_json()] # noqa: E501 + {{/isDateTime}} + {{#complexType}} + if connexion.request.is_json: + {{paramName}} = [{{complexType}}.from_dict(d) for d in connexion.request.get_json()] # noqa: E501 + {{/complexType}} + {{/items}} + {{/isListContainer}} + {{#isMapContainer}} + {{#items}} + {{#isDate}} + if connexion.request.is_json: + {{paramName}} = {k: util.deserialize_date(v) for k, v in six.iteritems(connexion.request.get_json())} # noqa: E501 + {{/isDate}} + {{#isDateTime}} + if connexion.request.is_json: + {{paramName}} = {k: util.deserialize_datetime(v) for k, v in six.iteritems(connexion.request.get_json())} # noqa: E501 + {{/isDateTime}} + {{#complexType}} + if connexion.request.is_json: + {{paramName}} = {k: {{baseType}}.from_dict(v) for k, v in six.iteritems(connexion.request.get_json())} # noqa: E501 + {{/complexType}} + {{/items}} + {{/isMapContainer}} + {{/allParams}} + return 'do some magic!' +{{/operation}} +{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/encoder.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/encoder.mustache new file mode 100644 index 000000000000..e303a0e41a76 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/encoder.mustache @@ -0,0 +1,20 @@ +from connexion.apps.flask_app import FlaskJSONEncoder +import six + +from {{modelPackage}}.base_model_ import Model + + +class JSONEncoder(FlaskJSONEncoder): + include_nulls = False + + def default(self, o): + if isinstance(o, Model): + dikt = {} + for attr, _ in six.iteritems(o.swagger_types): + value = getattr(o, attr) + if value is None and not self.include_nulls: + continue + attr = o.attribute_map[attr] + dikt[attr] = value + return dikt + return FlaskJSONEncoder.default(self, o) diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/models/__init__.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/models/__init__.mustache new file mode 100644 index 000000000000..98b56e3d1540 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/models/__init__.mustache @@ -0,0 +1,7 @@ +# coding: utf-8 + +# flake8: noqa +from __future__ import absolute_import +# import models into model package +{{#models}}{{#model}}from {{modelPackage}}.{{classFilename}} import {{classname}}{{/model}} +{{/models}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/models/base_model_.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/models/base_model_.mustache new file mode 100644 index 000000000000..54517a06d53a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/models/base_model_.mustache @@ -0,0 +1,73 @@ +import pprint + +import six +{{^supportPython2}} +import typing +{{/supportPython2}} + +from {{packageName}} import util +{{^supportPython2}} + +T = typing.TypeVar('T') +{{/supportPython2}} + + +class Model(object): + # swaggerTypes: The key is attribute name and the + # value is attribute type. + swagger_types = {} + + # attributeMap: The key is attribute name and the + # value is json key in definition. + attribute_map = {} + + @classmethod + def from_dict(cls{{^supportPython2}}: typing.Type[T]{{/supportPython2}}, dikt){{^supportPython2}} -> T{{/supportPython2}}: + """Returns the dict as a model""" + return util.deserialize_model(dikt, cls) + + def to_dict(self): + """Returns the model properties as a dict + + :rtype: dict + """ + result = {} + + for attr, _ in six.iteritems(self.swagger_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + + return result + + def to_str(self): + """Returns the string representation of the model + + :rtype: str + """ + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """Returns true if both objects are not equal""" + return not self == other diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/models/model.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/models/model.mustache new file mode 100644 index 000000000000..7bb398f9f738 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/models/model.mustache @@ -0,0 +1,161 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from {{modelPackage}}.base_model_ import Model +{{#imports}}{{import}} # noqa: F401,E501 +{{/imports}} +from {{packageName}} import util + + +{{#models}} +{{#model}} +class {{classname}}(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """{{#allowableValues}} + + """ + allowed enum values + """ +{{#enumVars}} + {{name}} = {{{value}}}{{^-last}} +{{/-last}} +{{/enumVars}}{{/allowableValues}} + + def __init__(self{{#vars}}, {{name}}{{^supportPython2}}: {{datatype}}{{/supportPython2}}={{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{/vars}}): # noqa: E501 + """{{classname}} - a model defined in Swagger + + {{#vars}} + :param {{name}}: The {{name}} of this {{classname}}. # noqa: E501 + :type {{name}}: {{datatype}} + {{/vars}} + """ + self.swagger_types = { +{{#vars}} + '{{name}}': {{{datatype}}}{{#hasMore}},{{/hasMore}} +{{/vars}} + } + + self.attribute_map = { +{{#vars}} + '{{name}}': '{{baseName}}'{{#hasMore}},{{/hasMore}} +{{/vars}} + } +{{#vars}}{{#-first}} +{{/-first}} + self._{{name}} = {{name}} +{{/vars}} + + @classmethod + def from_dict(cls, dikt){{^supportPython2}} -> '{{classname}}'{{/supportPython2}}: + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The {{name}} of this {{classname}}. # noqa: E501 + :rtype: {{classname}} + """ + return util.deserialize_model(dikt, cls){{#vars}}{{#-first}} + +{{/-first}} + @property + def {{name}}(self){{^supportPython2}} -> {{datatype}}{{/supportPython2}}: + """Gets the {{name}} of this {{classname}}. + + {{#description}} + {{{description}}} # noqa: E501 + {{/description}} + + :return: The {{name}} of this {{classname}}. + :rtype: {{datatype}} + """ + return self._{{name}} + + @{{name}}.setter + def {{name}}(self, {{name}}{{^supportPython2}}: {{datatype}}{{/supportPython2}}): + """Sets the {{name}} of this {{classname}}. + + {{#description}} + {{{description}}} # noqa: E501 + {{/description}} + + :param {{name}}: The {{name}} of this {{classname}}. + :type {{name}}: {{datatype}} + """ +{{#isEnum}} + allowed_values = [{{#allowableValues}}{{#values}}"{{{this}}}"{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501 +{{#isContainer}} +{{#isListContainer}} + if not set({{{name}}}).issubset(set(allowed_values)): + raise ValueError( + "Invalid values for `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501 + .format(", ".join(map(str, set({{{name}}}) - set(allowed_values))), # noqa: E501 + ", ".join(map(str, allowed_values))) + ) +{{/isListContainer}} +{{#isMapContainer}} + if not set({{{name}}}.keys()).issubset(set(allowed_values)): + raise ValueError( + "Invalid keys in `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501 + .format(", ".join(map(str, set({{{name}}}.keys()) - set(allowed_values))), # noqa: E501 + ", ".join(map(str, allowed_values))) + ) +{{/isMapContainer}} +{{/isContainer}} +{{^isContainer}} + if {{{name}}} not in allowed_values: + raise ValueError( + "Invalid value for `{{{name}}}` ({0}), must be one of {1}" + .format({{{name}}}, allowed_values) + ) +{{/isContainer}} +{{/isEnum}} +{{^isEnum}} +{{#required}} + if {{name}} is None: + raise ValueError("Invalid value for `{{name}}`, must not be `None`") # noqa: E501 +{{/required}} +{{#hasValidation}} +{{#maxLength}} + if {{name}} is not None and len({{name}}) > {{maxLength}}: + raise ValueError("Invalid value for `{{name}}`, length must be less than or equal to `{{maxLength}}`") # noqa: E501 +{{/maxLength}} +{{#minLength}} + if {{name}} is not None and len({{name}}) < {{minLength}}: + raise ValueError("Invalid value for `{{name}}`, length must be greater than or equal to `{{minLength}}`") # noqa: E501 +{{/minLength}} +{{#maximum}} + if {{name}} is not None and {{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: # noqa: E501 + raise ValueError("Invalid value for `{{name}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`") # noqa: E501 +{{/maximum}} +{{#minimum}} + if {{name}} is not None and {{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: # noqa: E501 + raise ValueError("Invalid value for `{{name}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`") # noqa: E501 +{{/minimum}} +{{#pattern}} + if {{name}} is not None and not re.search(r'{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501 + raise ValueError("Invalid value for `{{name}}`, must be a follow pattern or equal to `{{{pattern}}}`") # noqa: E501 +{{/pattern}} +{{#maxItems}} + if {{name}} is not None and len({{name}}) > {{maxItems}}: + raise ValueError("Invalid value for `{{name}}`, number of items must be less than or equal to `{{maxItems}}`") # noqa: E501 +{{/maxItems}} +{{#minItems}} + if {{name}} is not None and len({{name}}) < {{minItems}}: + raise ValueError("Invalid value for `{{name}}`, number of items must be greater than or equal to `{{minItems}}`") # noqa: E501 +{{/minItems}} +{{/hasValidation}} +{{/isEnum}} + + self._{{name}} = {{name}}{{^-last}} + +{{/-last}} +{{/vars}} + +{{/model}} +{{/models}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/swagger/swagger.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/swagger/swagger.mustache new file mode 100644 index 000000000000..51560926bba1 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/swagger/swagger.mustache @@ -0,0 +1 @@ +{{{swagger-yaml}}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/test/__init__.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/test/__init__.mustache new file mode 100644 index 000000000000..9cea80bc6302 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/test/__init__.mustache @@ -0,0 +1,16 @@ +import logging + +import connexion +from flask_testing import TestCase + +from {{packageName}}.encoder import JSONEncoder + + +class BaseTestCase(TestCase): + + def create_app(self): + logging.getLogger('connexion.operation').setLevel('ERROR') + app = connexion.App(__name__, specification_dir='../swagger/') + app.app.json_encoder = JSONEncoder + app.add_api('swagger.yaml') + return app.app diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/test/controller_test.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/test/controller_test.mustache new file mode 100644 index 000000000000..a41b12f2c210 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/test/controller_test.mustache @@ -0,0 +1,51 @@ +# coding: utf-8 + +from __future__ import absolute_import + +from flask import json +from six import BytesIO + +{{#imports}}{{import}} # noqa: E501 +{{/imports}} +from {{packageName}}.test import BaseTestCase + + +class {{#operations}}Test{{classname}}(BaseTestCase): + """{{classname}} integration test stubs""" + + {{#operation}} + def test_{{operationId}}(self): + """Test case for {{{operationId}}} + + {{{summary}}} + """ + {{#bodyParam}} + {{paramName}} = {{{example}}} + {{/bodyParam}} + {{#queryParams}} + {{#-first}}query_string = [{{/-first}}{{^-first}} {{/-first}}('{{paramName}}', {{{example}}}){{#hasMore}},{{/hasMore}}{{#-last}}]{{/-last}} + {{/queryParams}} + {{#headerParams}} + {{#-first}}headers = [{{/-first}}{{^-first}} {{/-first}}('{{paramName}}', {{{example}}}){{#hasMore}},{{/hasMore}}{{#-last}}]{{/-last}} + {{/headerParams}} + {{#formParams}} + {{#-first}}data = dict({{/-first}}{{^-first}} {{/-first}}{{paramName}}={{{example}}}{{#hasMore}},{{/hasMore}}{{#-last}}){{/-last}} + {{/formParams}} + response = self.client.open( + '{{#contextPath}}{{{.}}}{{/contextPath}}{{{path}}}'{{#pathParams}}{{#-first}}.format({{/-first}}{{paramName}}={{{example}}}{{#hasMore}}, {{/hasMore}}{{^hasMore}}){{/hasMore}}{{/pathParams}}, + method='{{httpMethod}}'{{#bodyParam}}, + data=json.dumps({{paramName}}){{^consumes}}, + content_type='application/json'{{/consumes}}{{/bodyParam}}{{#headerParams}}{{#-first}}, + headers=headers{{/-first}}{{/headerParams}}{{#formParams}}{{#-first}}, + data=data{{/-first}}{{/formParams}}{{#consumes}}{{#-first}}, + content_type='{{{mediaType}}}'{{/-first}}{{/consumes}}{{#queryParams}}{{#-first}}, + query_string=query_string{{/-first}}{{/queryParams}}) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + {{/operation}} +{{/operations}} + +if __name__ == '__main__': + import unittest + unittest.main() diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/util.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/util.mustache new file mode 100644 index 000000000000..527d1424c3d5 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/app/{{packageName}}/util.mustache @@ -0,0 +1,141 @@ +import datetime + +import six +import typing + + +def _deserialize(data, klass): + """Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if klass in six.integer_types or klass in (float, str, bool): + return _deserialize_primitive(data, klass) + elif klass == object: + return _deserialize_object(data) + elif klass == datetime.date: + return deserialize_date(data) + elif klass == datetime.datetime: + return deserialize_datetime(data) + elif type(klass) == typing.GenericMeta: + if klass.__extra__ == list: + return _deserialize_list(data, klass.__args__[0]) + if klass.__extra__ == dict: + return _deserialize_dict(data, klass.__args__[1]) + else: + return deserialize_model(data, klass) + + +def _deserialize_primitive(data, klass): + """Deserializes to primitive type. + + :param data: data to deserialize. + :param klass: class literal. + + :return: int, long, float, str, bool. + :rtype: int | long | float | str | bool + """ + try: + value = klass(data) + except UnicodeEncodeError: + value = six.u(data) + except TypeError: + value = data + return value + + +def _deserialize_object(value): + """Return a original value. + + :return: object. + """ + return value + + +def deserialize_date(string): + """Deserializes string to date. + + :param string: str. + :type string: str + :return: date. + :rtype: date + """ + try: + from dateutil.parser import parse + return parse(string).date() + except ImportError: + return string + + +def deserialize_datetime(string): + """Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :type string: str + :return: datetime. + :rtype: datetime + """ + try: + from dateutil.parser import parse + return parse(string) + except ImportError: + return string + + +def deserialize_model(data, klass): + """Deserializes list or dict to model. + + :param data: dict, list. + :type data: dict | list + :param klass: class literal. + :return: model object. + """ + instance = klass() + + if not instance.swagger_types: + return data + + for attr, attr_type in six.iteritems(instance.swagger_types): + if data is not None \ + and instance.attribute_map[attr] in data \ + and isinstance(data, (list, dict)): + value = data[instance.attribute_map[attr]] + setattr(instance, attr, _deserialize(value, attr_type)) + + return instance + + +def _deserialize_list(data, boxed_type): + """Deserializes a list and its elements. + + :param data: list to deserialize. + :type data: list + :param boxed_type: class literal. + + :return: deserialized list. + :rtype: list + """ + return [_deserialize(sub_data, boxed_type) + for sub_data in data] + + +def _deserialize_dict(data, boxed_type): + """Deserializes a dict and its elements. + + :param data: dict to deserialize. + :type data: dict + :param boxed_type: class literal. + + :return: deserialized dict. + :rtype: dict + """ + return {k: _deserialize(v, boxed_type) + for k, v in six.iteritems(data)} diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/create.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/create.mustache new file mode 100644 index 000000000000..178c67936e9f --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/create.mustache @@ -0,0 +1,23 @@ +{ + "type": "form", + "version": "2.0", + "cells": [{ + "label": "General", + "children": [ + {"model": "label"}, + {"model": "description"} + ] + },{ + "label": "Details", + "model": "properties", + "children": [ +{{#models}} +{{#model}} +{{#vars}} + {"model": "{{name}}" }, +{{/vars}} +{{/model}} +{{/models}} + ] + }] +} diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/high.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/high.mustache new file mode 100644 index 000000000000..5b261500f725 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/high.mustache @@ -0,0 +1,76 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "children": [{ + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "domain-by-product-renderer" + }, + "model": "productId" + } + ] + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "State", + "model": "orchState" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/low.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/low.mustache new file mode 100644 index 000000000000..fcfefc103482 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/ddui-views/{{packageName}}.resourceTypes.{{model}}/low.mustache @@ -0,0 +1,53 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/tosca/{{packageName}}/{{model}}.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/tosca/{{packageName}}/{{model}}.mustache new file mode 100644 index 000000000000..b3cfc28ffc6b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/model-definitions/types/tosca/{{packageName}}/{{model}}.mustache @@ -0,0 +1,73 @@ +{{#models}} +{{#model}} +"$schema" = "http://cyaninc.com/json-schemas/tosca-lite-v1/definition-module#" +title = "{{packageName}} {{classname}}" +package = {{packageName}} +version = "1.0" +description = "Defines a {{classname}}" +authors = ["F. Bar (foo@bar.baz)"] + +imports { + Root = tosca.resourceTypes.Root + {{#imports}} + {{.}} = {{packageName}}.resourceTypes.{{.}} + {{/imports}} +} +resourceTypes { + + {{classname}} { + title = {{classname}} + description = {{classname}} + derivedFrom = Root + properties { + {{#vars}} + {{name}} { + {{^isContainer}} + {{#isPrimitiveType}} + type = {{>prop_type}} + {{/isPrimitiveType}} + {{^isPrimitiveType}} + type = {{datatype}} + {{/isPrimitiveType}} + {{/isContainer}} + {{#isListContainer}} + type = array + {{#items}} + {{#isPrimitiveType}} + items.type = {{>prop_type}} + {{/isPrimitiveType}} + {{^isPrimitiveType}} + items.type = {{datatype}} + {{/isPrimitiveType}} + {{/items}} + {{/isListContainer}} + {{#isMapContainer}} + # TODO + {{/isMapContainer}} + description = "{{description}}" + {{#isEnum}} + enum = [{{#allowableValues}}{{#values}}"{{{this}}}"{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] + {{/isEnum}} + {{#required}} + optional = true + {{/required}} + {{^required}} + optional = false + {{/required}} + } + {{/vars}} + } + } +} + +serviceTemplates { + + {{classname}} { + title = {{classname}} + description = {{classname}} + implements = {{packageName}}.resourceTypes.{{classname}} + + } +} +{{/model}} +{{/models}} diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/prop_type.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/prop_type.mustache new file mode 100644 index 000000000000..60089c8c7e83 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/prop_type.mustache @@ -0,0 +1 @@ +{{#isString}}string{{/isString}}{{#isInteger}}integer{{/isInteger}}{{#isLong}}integer{{/isLong}}{{#isFloat}}integer{{/isFloat}}{{#isDouble}}integer{{/isDouble}}{{#isByteArray}}string{{/isByteArray}}{{#isBinary}}string{{/isBinary}}{{#isBoolean}}boolean{{/isBoolean}}{{#isDate}}string{{/isDate}}{{#isDateTime}}string{{/isDateTime}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/requirements.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/requirements.mustache new file mode 100644 index 000000000000..08a16baf59c1 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/requirements.mustache @@ -0,0 +1,2 @@ +--extra-index-url https://pypi.blueplanet.com/simple/ +solution-maker==0.1.6 diff --git a/modules/openapi-generator/src/main/resources/python-blueplanet/solution/fig.mustache b/modules/openapi-generator/src/main/resources/python-blueplanet/solution/fig.mustache new file mode 100644 index 000000000000..8de0cdfae463 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python-blueplanet/solution/fig.mustache @@ -0,0 +1,51 @@ + +# +# Ciena +# +# Copyright(c) 2016, Ciena, Inc. All rights reserved. +# + +# REFERENCES: +# =========================================================== +# +# "Fig file format for solutions": +# https://confluence.ciena.com/display/blueplanet/Fig+file+format+for+solutions +# + +__version__: 1 + +# Docker registry must be specified in this file. +# if only passed as the --registry argument to solmaker, +# solman will not find the images at deployment time. +# MAKE SURE it is aligned with the value in the Makefile +docker_registry: registry.blueplanet.com + +# this name is read by the Makefile and used to build various paths +solution_name: {{packageName}} + +# version is not read from this file, but coded in the Makefile +# the vendor and tag are provided by the Makefile as argumernts to solmaker +solution_version: {{packageVersion}} + +# ============ NOTE =============================================================================== +# The app image versions listed below are hard coded of course. +# Verify GIT commits against the respective image versions housed in bpdr.io ... to ensure +# you're getting what you want! bpdr.io repo for each app is listed. +# ================================================================================================= + +apps: + tapi-swagger: + # https://..../{{packageName}} + image: registry.blueplanet.com/blueplanet/{{packageName}}:{{packageVersion}} + volumes: + - /dev/log:/dev/log + environment: + - NBI_{{packageName}}_type=http + - NBI_{{packageName}}_port=8080 +app_bar: + System: + Documentation: + '{{packageName}} Swagger': + description: '{{packageName}} Swagger UI' + icon: 'orchestrate' + url: '/{{packageName}}/ui/#' diff --git a/samples/server/petstore/python-blueplanet/.openapi-generator-ignore b/samples/server/petstore/python-blueplanet/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/python-blueplanet/.openapi-generator/VERSION b/samples/server/petstore/python-blueplanet/.openapi-generator/VERSION new file mode 100644 index 000000000000..afa636560641 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/python-blueplanet/Makefile b/samples/server/petstore/python-blueplanet/Makefile new file mode 100644 index 000000000000..fec18ee48528 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/Makefile @@ -0,0 +1,51 @@ +HIDE ?= @ +PACKAGE := openapi_server +RELEASE := 1.0.0 +VENV := env +PYPI ?= 'https://pypi.blueplanet.com/simple' + +PWD ?= $(shell pwd) + +# Solution +VENDOR ?= path_to_your_repo +SOLUTION_RELEASE ?= $(shell solmaker version solution/fig.yml) +SOLUTION_NAME ?= $(shell solmaker name solution/fig.yml) +SOLUTION_IMAGE := $(VENDOR)/solution-$(SOLUTION_NAME) + +DOCKER_BUILD := docker build +DOCKER_IMAGE ?= $(VENDOR)/$(PACKAGE) +REGISTRY ?= registry.blueplanet.com +REMOTE_SERVER ?= bpadmin@10.10.10.10 + +SOLUTION := $(REGISTRY).$(VENDOR).$(SOLUTION_NAME):$(SOLUTION_RELEASE) + +.PHONY: app solution update upload-solution + +app: check-env + $(DOCKER_BUILD) --build-arg GLTOKEN=${GLTOKEN} -t $(REGISTRY)/$(DOCKER_IMAGE):$(RELEASE) -f app/Dockerfile ./app + +remote: + docker save $(REGISTRY)/$(DOCKER_IMAGE):$(RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + docker save $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + +push: + docker push $(REGISTRY)/$(DOCKER_IMAGE):$(RELEASE) + docker push $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) + +solution: check-env + $(docker rmi $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) && true) + solmaker build solution/fig.yml --vendor=$(VENDOR) --tag=$(SOLUTION_RELEASE) + +upload-solution: + docker save $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + +update: app solution + -ssh $(REMOTE_SERVER) 'solman "solution_purge -y $(SOLUTION)"' + docker save $(REGISTRY)/$(DOCKER_IMAGE):$(RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + docker save $(REGISTRY)/$(SOLUTION_IMAGE):$(SOLUTION_RELEASE) | bzip2 | pv | ssh $(REMOTE_SERVER) 'bunzip2 | docker load' + -ssh $(REMOTE_SERVER) 'solman "solution_deploy $(SOLUTION)"' + +check-env: +ifndef GLTOKEN + $(error GLTOKEN is undefined) +endif diff --git a/samples/server/petstore/python-blueplanet/README.md b/samples/server/petstore/python-blueplanet/README.md new file mode 100644 index 000000000000..a94ea0374837 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/README.md @@ -0,0 +1,59 @@ +# openapi_server Swagger-ui and Resource Types + +This project is an autogenerated microservice for Ciena's Blueplanet platform. + +## Overview + +Generated code can be used as: + +* Resource Type generation for Resource Adapter Development +* Resource Type generation for Service Template Development +* Microservice for swagger based NBI + +Make Targets: + +image: Create Docker image for use as BluePlanet microservice +solution: Create Solution image + +Resource Types are generated in model-definitions directory + +## Usage + +### Creating new release + +1. Update RELEASE property in Makefile +2. Update release(s) in [fig.yml](solution/fig.yml) +3. make image and solution + + ```bash + # building the image + make image + make solution + ``` + +### Iterative Development + +1. A helper target can be used for pushing image and solution to server + + ```bash + make update REMOTE_SERVER=bpadmin@10.10.10.10 + ``` + +This `make` target does the following: + +1. creates App and Solution image +2. purges solution from MCP remote +3. pushes solution and image to MCP remote +4. deploys solution + +### Local Usage + +To run the server locally: + +```bash +cd app +pip3 install -r requirements.txt +python3 -m swagger_server +``` + +and open your browser to [here](http://localhost:8080/openapi_server/ui/) diff --git a/samples/server/petstore/python-blueplanet/app/.dockerignore b/samples/server/petstore/python-blueplanet/app/.dockerignore new file mode 100644 index 000000000000..cdd823e64e7e --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/.dockerignore @@ -0,0 +1,72 @@ +.travis.yaml +.swagger-codegen-ignore +README.md +tox.ini +git_push.sh +test-requirements.txt +setup.py + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +venv/ +.python-version + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints diff --git a/samples/server/petstore/python-blueplanet/app/.gitignore b/samples/server/petstore/python-blueplanet/app/.gitignore new file mode 100644 index 000000000000..a655050c2631 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/.gitignore @@ -0,0 +1,64 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +venv/ +.python-version + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints diff --git a/samples/server/petstore/python-blueplanet/app/Dockerfile b/samples/server/petstore/python-blueplanet/app/Dockerfile new file mode 100644 index 000000000000..47f8a46f5610 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/Dockerfile @@ -0,0 +1,28 @@ +FROM python:3-alpine + +ARG GLTOKEN + +RUN apk add curl bash +ENV SHELL /bin/bash + +RUN mkdir /bp2 \ + && mkdir /bp2/data \ + && mkdir /bp2/log \ + && mkdir /bp2/src \ + && echo 'alias ll="ls -l"' >> ~/.bashrc +WORKDIR /bp2/src + +COPY requirements.txt /bp2/src + +RUN pip3 install --extra-index-url https://GLTOKEN:$GLTOKEN@pypi.blueplanet.com/simple --no-cache-dir -r requirements.txt + +COPY . /bp2/src + +ENV SBIS=bpocore \ + SBI_bpocore_southbound-update=update_etc_hosts_multi_provider + +EXPOSE 8080 + +ENTRYPOINT ["python3"] + +CMD ["-B", "-m", "openapi_server"] diff --git a/samples/server/petstore/python-blueplanet/app/README.md b/samples/server/petstore/python-blueplanet/app/README.md new file mode 100644 index 000000000000..722730320758 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/README.md @@ -0,0 +1,49 @@ +# Swagger generated server + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the +[OpenAPI-Spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This +is an example of building a swagger-enabled Flask server. + +This example uses the [Connexion](https://github.com/zalando/connexion) library on top of Flask. + +## Requirements +Python 3.5.2+ + +## Usage +To run the server, please execute the following from the root directory: + +``` +pip3 install -r requirements.txt +python3 -m openapi_server +``` + +and open your browser to here: + +``` +http://localhost:8080/v2/ui/ +``` + +Your Swagger definition lives here: + +``` +http://localhost:8080/v2/swagger.json +``` + +To launch the integration tests, use tox: +``` +sudo pip install tox +tox +``` + +## Running with Docker + +To run the server on a Docker container, please execute the following from the root directory: + +```bash +# building the image +docker build -t openapi_server . + +# starting up a container +docker run -p 8080:8080 openapi_server +``` \ No newline at end of file diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/__init__.py b/samples/server/petstore/python-blueplanet/app/openapi_server/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/__main__.py b/samples/server/petstore/python-blueplanet/app/openapi_server/__main__.py new file mode 100644 index 000000000000..a97eee0948a4 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/__main__.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 + +import connexion + +from openapi_server import encoder + + +def main(): + app = connexion.App(__name__, specification_dir='./swagger/') + app.app.json_encoder = encoder.JSONEncoder + app.add_api('swagger.yaml', arguments={'title': 'OpenAPI Petstore'}) + app.run(port=8080) + + +if __name__ == '__main__': + main() diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/__init__.py b/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/pet_controller.py b/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/pet_controller.py new file mode 100644 index 000000000000..8c47927bde67 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/pet_controller.py @@ -0,0 +1,124 @@ +import connexion +import six + +from app.openapi_server.models.api_response import ApiResponse # noqa: E501 +from app.openapi_server.models.pet import Pet # noqa: E501 +from openapi_server import util + + +def add_pet(body): # noqa: E501 + """Add a new pet to the store + + # noqa: E501 + + :param body: Pet object that needs to be added to the store + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = Pet.from_dict(connexion.request.get_json()) # noqa: E501 + return 'do some magic!' + + +def delete_pet(pet_id, api_key=None): # noqa: E501 + """Deletes a pet + + # noqa: E501 + + :param pet_id: Pet id to delete + :type pet_id: int + :param api_key: + :type api_key: str + + :rtype: None + """ + return 'do some magic!' + + +def find_pets_by_status(status): # noqa: E501 + """Finds Pets by status + + Multiple status values can be provided with comma separated strings # noqa: E501 + + :param status: Status values that need to be considered for filter + :type status: List[str] + + :rtype: List[Pet] + """ + return 'do some magic!' + + +def find_pets_by_tags(tags): # noqa: E501 + """Finds Pets by tags + + Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. # noqa: E501 + + :param tags: Tags to filter by + :type tags: List[str] + + :rtype: List[Pet] + """ + return 'do some magic!' + + +def get_pet_by_id(pet_id): # noqa: E501 + """Find pet by ID + + Returns a single pet # noqa: E501 + + :param pet_id: ID of pet to return + :type pet_id: int + + :rtype: Pet + """ + return 'do some magic!' + + +def update_pet(body): # noqa: E501 + """Update an existing pet + + # noqa: E501 + + :param body: Pet object that needs to be added to the store + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = Pet.from_dict(connexion.request.get_json()) # noqa: E501 + return 'do some magic!' + + +def update_pet_with_form(pet_id, name=None, status=None): # noqa: E501 + """Updates a pet in the store with form data + + # noqa: E501 + + :param pet_id: ID of pet that needs to be updated + :type pet_id: int + :param name: Updated name of the pet + :type name: str + :param status: Updated status of the pet + :type status: str + + :rtype: None + """ + return 'do some magic!' + + +def upload_file(pet_id, additional_metadata=None, file=None): # noqa: E501 + """uploads an image + + # noqa: E501 + + :param pet_id: ID of pet to update + :type pet_id: int + :param additional_metadata: Additional data to pass to server + :type additional_metadata: str + :param file: file to upload + :type file: str + + :rtype: ApiResponse + """ + return 'do some magic!' diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/store_controller.py b/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/store_controller.py new file mode 100644 index 000000000000..30e6bbd3a9a0 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/store_controller.py @@ -0,0 +1,57 @@ +import connexion +import six + +from app.openapi_server.models.order import Order # noqa: E501 +from openapi_server import util + + +def delete_order(order_id): # noqa: E501 + """Delete purchase order by ID + + For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors # noqa: E501 + + :param order_id: ID of the order that needs to be deleted + :type order_id: str + + :rtype: None + """ + return 'do some magic!' + + +def get_inventory(): # noqa: E501 + """Returns pet inventories by status + + Returns a map of status codes to quantities # noqa: E501 + + + :rtype: Dict[str, int] + """ + return 'do some magic!' + + +def get_order_by_id(order_id): # noqa: E501 + """Find purchase order by ID + + For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions # noqa: E501 + + :param order_id: ID of pet that needs to be fetched + :type order_id: int + + :rtype: Order + """ + return 'do some magic!' + + +def place_order(body): # noqa: E501 + """Place an order for a pet + + # noqa: E501 + + :param body: order placed for purchasing the pet + :type body: dict | bytes + + :rtype: Order + """ + if connexion.request.is_json: + body = Order.from_dict(connexion.request.get_json()) # noqa: E501 + return 'do some magic!' diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/user_controller.py b/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/user_controller.py new file mode 100644 index 000000000000..147f8d1cbb99 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/controllers/user_controller.py @@ -0,0 +1,119 @@ +import connexion +import six + +from app.openapi_server.models.user import User # noqa: E501 +from openapi_server import util + + +def create_user(body): # noqa: E501 + """Create user + + This can only be done by the logged in user. # noqa: E501 + + :param body: Created user object + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = User.from_dict(connexion.request.get_json()) # noqa: E501 + return 'do some magic!' + + +def create_users_with_array_input(body): # noqa: E501 + """Creates list of users with given input array + + # noqa: E501 + + :param body: List of user object + :type body: list | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = [User.from_dict(d) for d in connexion.request.get_json()] # noqa: E501 + return 'do some magic!' + + +def create_users_with_list_input(body): # noqa: E501 + """Creates list of users with given input array + + # noqa: E501 + + :param body: List of user object + :type body: list | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = [User.from_dict(d) for d in connexion.request.get_json()] # noqa: E501 + return 'do some magic!' + + +def delete_user(username): # noqa: E501 + """Delete user + + This can only be done by the logged in user. # noqa: E501 + + :param username: The name that needs to be deleted + :type username: str + + :rtype: None + """ + return 'do some magic!' + + +def get_user_by_name(username): # noqa: E501 + """Get user by user name + + # noqa: E501 + + :param username: The name that needs to be fetched. Use user1 for testing. + :type username: str + + :rtype: User + """ + return 'do some magic!' + + +def login_user(username, password): # noqa: E501 + """Logs user into the system + + # noqa: E501 + + :param username: The user name for login + :type username: str + :param password: The password for login in clear text + :type password: str + + :rtype: str + """ + return 'do some magic!' + + +def logout_user(): # noqa: E501 + """Logs out current logged in user session + + # noqa: E501 + + + :rtype: None + """ + return 'do some magic!' + + +def update_user(username, body): # noqa: E501 + """Updated user + + This can only be done by the logged in user. # noqa: E501 + + :param username: name that need to be deleted + :type username: str + :param body: Updated user object + :type body: dict | bytes + + :rtype: None + """ + if connexion.request.is_json: + body = User.from_dict(connexion.request.get_json()) # noqa: E501 + return 'do some magic!' diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/encoder.py b/samples/server/petstore/python-blueplanet/app/openapi_server/encoder.py new file mode 100644 index 000000000000..96da9553f37f --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/encoder.py @@ -0,0 +1,20 @@ +from connexion.apps.flask_app import FlaskJSONEncoder +import six + +from app.openapi_server.models.base_model_ import Model + + +class JSONEncoder(FlaskJSONEncoder): + include_nulls = False + + def default(self, o): + if isinstance(o, Model): + dikt = {} + for attr, _ in six.iteritems(o.swagger_types): + value = getattr(o, attr) + if value is None and not self.include_nulls: + continue + attr = o.attribute_map[attr] + dikt[attr] = value + return dikt + return FlaskJSONEncoder.default(self, o) diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/models/__init__.py b/samples/server/petstore/python-blueplanet/app/openapi_server/models/__init__.py new file mode 100644 index 000000000000..8a2ff884ed92 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/models/__init__.py @@ -0,0 +1,11 @@ +# coding: utf-8 + +# flake8: noqa +from __future__ import absolute_import +# import models into model package +from app.openapi_server.models.api_response import ApiResponse +from app.openapi_server.models.category import Category +from app.openapi_server.models.order import Order +from app.openapi_server.models.pet import Pet +from app.openapi_server.models.tag import Tag +from app.openapi_server.models.user import User diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/models/api_response.py b/samples/server/petstore/python-blueplanet/app/openapi_server/models/api_response.py new file mode 100644 index 000000000000..9c876ad632c4 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/models/api_response.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from app.openapi_server.models.base_model_ import Model +from openapi_server import util + + +class ApiResponse(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + def __init__(self, code: int=None, type: str=None, message: str=None): # noqa: E501 + """ApiResponse - a model defined in Swagger + + :param code: The code of this ApiResponse. # noqa: E501 + :type code: int + :param type: The type of this ApiResponse. # noqa: E501 + :type type: str + :param message: The message of this ApiResponse. # noqa: E501 + :type message: str + """ + self.swagger_types = { + 'code': int, + 'type': str, + 'message': str + } + + self.attribute_map = { + 'code': 'code', + 'type': 'type', + 'message': 'message' + } + + self._code = code + self._type = type + self._message = message + + @classmethod + def from_dict(cls, dikt) -> 'ApiResponse': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The ApiResponse of this ApiResponse. # noqa: E501 + :rtype: ApiResponse + """ + return util.deserialize_model(dikt, cls) + + @property + def code(self) -> int: + """Gets the code of this ApiResponse. + + + :return: The code of this ApiResponse. + :rtype: int + """ + return self._code + + @code.setter + def code(self, code: int): + """Sets the code of this ApiResponse. + + + :param code: The code of this ApiResponse. + :type code: int + """ + + self._code = code + + @property + def type(self) -> str: + """Gets the type of this ApiResponse. + + + :return: The type of this ApiResponse. + :rtype: str + """ + return self._type + + @type.setter + def type(self, type: str): + """Sets the type of this ApiResponse. + + + :param type: The type of this ApiResponse. + :type type: str + """ + + self._type = type + + @property + def message(self) -> str: + """Gets the message of this ApiResponse. + + + :return: The message of this ApiResponse. + :rtype: str + """ + return self._message + + @message.setter + def message(self, message: str): + """Sets the message of this ApiResponse. + + + :param message: The message of this ApiResponse. + :type message: str + """ + + self._message = message diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/models/base_model_.py b/samples/server/petstore/python-blueplanet/app/openapi_server/models/base_model_.py new file mode 100644 index 000000000000..b835b909b700 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/models/base_model_.py @@ -0,0 +1,69 @@ +import pprint + +import six +import typing + +from openapi_server import util + +T = typing.TypeVar('T') + + +class Model(object): + # swaggerTypes: The key is attribute name and the + # value is attribute type. + swagger_types = {} + + # attributeMap: The key is attribute name and the + # value is json key in definition. + attribute_map = {} + + @classmethod + def from_dict(cls: typing.Type[T], dikt) -> T: + """Returns the dict as a model""" + return util.deserialize_model(dikt, cls) + + def to_dict(self): + """Returns the model properties as a dict + + :rtype: dict + """ + result = {} + + for attr, _ in six.iteritems(self.swagger_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + + return result + + def to_str(self): + """Returns the string representation of the model + + :rtype: str + """ + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """Returns true if both objects are not equal""" + return not self == other diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/models/category.py b/samples/server/petstore/python-blueplanet/app/openapi_server/models/category.py new file mode 100644 index 000000000000..2b407d025090 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/models/category.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from app.openapi_server.models.base_model_ import Model +from openapi_server import util + + +class Category(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + def __init__(self, id: int=None, name: str=None): # noqa: E501 + """Category - a model defined in Swagger + + :param id: The id of this Category. # noqa: E501 + :type id: int + :param name: The name of this Category. # noqa: E501 + :type name: str + """ + self.swagger_types = { + 'id': int, + 'name': str + } + + self.attribute_map = { + 'id': 'id', + 'name': 'name' + } + + self._id = id + self._name = name + + @classmethod + def from_dict(cls, dikt) -> 'Category': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Category of this Category. # noqa: E501 + :rtype: Category + """ + return util.deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """Gets the id of this Category. + + + :return: The id of this Category. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """Sets the id of this Category. + + + :param id: The id of this Category. + :type id: int + """ + + self._id = id + + @property + def name(self) -> str: + """Gets the name of this Category. + + + :return: The name of this Category. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this Category. + + + :param name: The name of this Category. + :type name: str + """ + + self._name = name diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/models/order.py b/samples/server/petstore/python-blueplanet/app/openapi_server/models/order.py new file mode 100644 index 000000000000..e222f5ee0069 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/models/order.py @@ -0,0 +1,202 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from app.openapi_server.models.base_model_ import Model +from openapi_server import util + + +class Order(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + def __init__(self, id: int=None, pet_id: int=None, quantity: int=None, ship_date: datetime=None, status: str=None, complete: bool=False): # noqa: E501 + """Order - a model defined in Swagger + + :param id: The id of this Order. # noqa: E501 + :type id: int + :param pet_id: The pet_id of this Order. # noqa: E501 + :type pet_id: int + :param quantity: The quantity of this Order. # noqa: E501 + :type quantity: int + :param ship_date: The ship_date of this Order. # noqa: E501 + :type ship_date: datetime + :param status: The status of this Order. # noqa: E501 + :type status: str + :param complete: The complete of this Order. # noqa: E501 + :type complete: bool + """ + self.swagger_types = { + 'id': int, + 'pet_id': int, + 'quantity': int, + 'ship_date': datetime, + 'status': str, + 'complete': bool + } + + self.attribute_map = { + 'id': 'id', + 'pet_id': 'petId', + 'quantity': 'quantity', + 'ship_date': 'shipDate', + 'status': 'status', + 'complete': 'complete' + } + + self._id = id + self._pet_id = pet_id + self._quantity = quantity + self._ship_date = ship_date + self._status = status + self._complete = complete + + @classmethod + def from_dict(cls, dikt) -> 'Order': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Order of this Order. # noqa: E501 + :rtype: Order + """ + return util.deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """Gets the id of this Order. + + + :return: The id of this Order. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """Sets the id of this Order. + + + :param id: The id of this Order. + :type id: int + """ + + self._id = id + + @property + def pet_id(self) -> int: + """Gets the pet_id of this Order. + + + :return: The pet_id of this Order. + :rtype: int + """ + return self._pet_id + + @pet_id.setter + def pet_id(self, pet_id: int): + """Sets the pet_id of this Order. + + + :param pet_id: The pet_id of this Order. + :type pet_id: int + """ + + self._pet_id = pet_id + + @property + def quantity(self) -> int: + """Gets the quantity of this Order. + + + :return: The quantity of this Order. + :rtype: int + """ + return self._quantity + + @quantity.setter + def quantity(self, quantity: int): + """Sets the quantity of this Order. + + + :param quantity: The quantity of this Order. + :type quantity: int + """ + + self._quantity = quantity + + @property + def ship_date(self) -> datetime: + """Gets the ship_date of this Order. + + + :return: The ship_date of this Order. + :rtype: datetime + """ + return self._ship_date + + @ship_date.setter + def ship_date(self, ship_date: datetime): + """Sets the ship_date of this Order. + + + :param ship_date: The ship_date of this Order. + :type ship_date: datetime + """ + + self._ship_date = ship_date + + @property + def status(self) -> str: + """Gets the status of this Order. + + Order Status # noqa: E501 + + :return: The status of this Order. + :rtype: str + """ + return self._status + + @status.setter + def status(self, status: str): + """Sets the status of this Order. + + Order Status # noqa: E501 + + :param status: The status of this Order. + :type status: str + """ + allowed_values = ["placed", "approved", "delivered"] # noqa: E501 + if status not in allowed_values: + raise ValueError( + "Invalid value for `status` ({0}), must be one of {1}" + .format(status, allowed_values) + ) + + self._status = status + + @property + def complete(self) -> bool: + """Gets the complete of this Order. + + + :return: The complete of this Order. + :rtype: bool + """ + return self._complete + + @complete.setter + def complete(self, complete: bool): + """Sets the complete of this Order. + + + :param complete: The complete of this Order. + :type complete: bool + """ + + self._complete = complete diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/models/pet.py b/samples/server/petstore/python-blueplanet/app/openapi_server/models/pet.py new file mode 100644 index 000000000000..0a427ef53e19 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/models/pet.py @@ -0,0 +1,208 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from app.openapi_server.models.base_model_ import Model +from app.openapi_server.models.category import Category # noqa: F401,E501 +from app.openapi_server.models.tag import Tag # noqa: F401,E501 +from openapi_server import util + + +class Pet(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + def __init__(self, id: int=None, category: Category=None, name: str=None, photo_urls: List[str]=None, tags: List[Tag]=None, status: str=None): # noqa: E501 + """Pet - a model defined in Swagger + + :param id: The id of this Pet. # noqa: E501 + :type id: int + :param category: The category of this Pet. # noqa: E501 + :type category: Category + :param name: The name of this Pet. # noqa: E501 + :type name: str + :param photo_urls: The photo_urls of this Pet. # noqa: E501 + :type photo_urls: List[str] + :param tags: The tags of this Pet. # noqa: E501 + :type tags: List[Tag] + :param status: The status of this Pet. # noqa: E501 + :type status: str + """ + self.swagger_types = { + 'id': int, + 'category': Category, + 'name': str, + 'photo_urls': List[str], + 'tags': List[Tag], + 'status': str + } + + self.attribute_map = { + 'id': 'id', + 'category': 'category', + 'name': 'name', + 'photo_urls': 'photoUrls', + 'tags': 'tags', + 'status': 'status' + } + + self._id = id + self._category = category + self._name = name + self._photo_urls = photo_urls + self._tags = tags + self._status = status + + @classmethod + def from_dict(cls, dikt) -> 'Pet': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Pet of this Pet. # noqa: E501 + :rtype: Pet + """ + return util.deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """Gets the id of this Pet. + + + :return: The id of this Pet. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """Sets the id of this Pet. + + + :param id: The id of this Pet. + :type id: int + """ + + self._id = id + + @property + def category(self) -> Category: + """Gets the category of this Pet. + + + :return: The category of this Pet. + :rtype: Category + """ + return self._category + + @category.setter + def category(self, category: Category): + """Sets the category of this Pet. + + + :param category: The category of this Pet. + :type category: Category + """ + + self._category = category + + @property + def name(self) -> str: + """Gets the name of this Pet. + + + :return: The name of this Pet. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this Pet. + + + :param name: The name of this Pet. + :type name: str + """ + if name is None: + raise ValueError("Invalid value for `name`, must not be `None`") # noqa: E501 + + self._name = name + + @property + def photo_urls(self) -> List[str]: + """Gets the photo_urls of this Pet. + + + :return: The photo_urls of this Pet. + :rtype: List[str] + """ + return self._photo_urls + + @photo_urls.setter + def photo_urls(self, photo_urls: List[str]): + """Sets the photo_urls of this Pet. + + + :param photo_urls: The photo_urls of this Pet. + :type photo_urls: List[str] + """ + if photo_urls is None: + raise ValueError("Invalid value for `photo_urls`, must not be `None`") # noqa: E501 + + self._photo_urls = photo_urls + + @property + def tags(self) -> List[Tag]: + """Gets the tags of this Pet. + + + :return: The tags of this Pet. + :rtype: List[Tag] + """ + return self._tags + + @tags.setter + def tags(self, tags: List[Tag]): + """Sets the tags of this Pet. + + + :param tags: The tags of this Pet. + :type tags: List[Tag] + """ + + self._tags = tags + + @property + def status(self) -> str: + """Gets the status of this Pet. + + pet status in the store # noqa: E501 + + :return: The status of this Pet. + :rtype: str + """ + return self._status + + @status.setter + def status(self, status: str): + """Sets the status of this Pet. + + pet status in the store # noqa: E501 + + :param status: The status of this Pet. + :type status: str + """ + allowed_values = ["available", "pending", "sold"] # noqa: E501 + if status not in allowed_values: + raise ValueError( + "Invalid value for `status` ({0}), must be one of {1}" + .format(status, allowed_values) + ) + + self._status = status diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/models/tag.py b/samples/server/petstore/python-blueplanet/app/openapi_server/models/tag.py new file mode 100644 index 000000000000..19a8f833ac25 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/models/tag.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from app.openapi_server.models.base_model_ import Model +from openapi_server import util + + +class Tag(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + def __init__(self, id: int=None, name: str=None): # noqa: E501 + """Tag - a model defined in Swagger + + :param id: The id of this Tag. # noqa: E501 + :type id: int + :param name: The name of this Tag. # noqa: E501 + :type name: str + """ + self.swagger_types = { + 'id': int, + 'name': str + } + + self.attribute_map = { + 'id': 'id', + 'name': 'name' + } + + self._id = id + self._name = name + + @classmethod + def from_dict(cls, dikt) -> 'Tag': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Tag of this Tag. # noqa: E501 + :rtype: Tag + """ + return util.deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """Gets the id of this Tag. + + + :return: The id of this Tag. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """Sets the id of this Tag. + + + :param id: The id of this Tag. + :type id: int + """ + + self._id = id + + @property + def name(self) -> str: + """Gets the name of this Tag. + + + :return: The name of this Tag. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this Tag. + + + :param name: The name of this Tag. + :type name: str + """ + + self._name = name diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/models/user.py b/samples/server/petstore/python-blueplanet/app/openapi_server/models/user.py new file mode 100644 index 000000000000..e45a8a55a4d8 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/models/user.py @@ -0,0 +1,248 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from app.openapi_server.models.base_model_ import Model +from openapi_server import util + + +class User(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + def __init__(self, id: int=None, username: str=None, first_name: str=None, last_name: str=None, email: str=None, password: str=None, phone: str=None, user_status: int=None): # noqa: E501 + """User - a model defined in Swagger + + :param id: The id of this User. # noqa: E501 + :type id: int + :param username: The username of this User. # noqa: E501 + :type username: str + :param first_name: The first_name of this User. # noqa: E501 + :type first_name: str + :param last_name: The last_name of this User. # noqa: E501 + :type last_name: str + :param email: The email of this User. # noqa: E501 + :type email: str + :param password: The password of this User. # noqa: E501 + :type password: str + :param phone: The phone of this User. # noqa: E501 + :type phone: str + :param user_status: The user_status of this User. # noqa: E501 + :type user_status: int + """ + self.swagger_types = { + 'id': int, + 'username': str, + 'first_name': str, + 'last_name': str, + 'email': str, + 'password': str, + 'phone': str, + 'user_status': int + } + + self.attribute_map = { + 'id': 'id', + 'username': 'username', + 'first_name': 'firstName', + 'last_name': 'lastName', + 'email': 'email', + 'password': 'password', + 'phone': 'phone', + 'user_status': 'userStatus' + } + + self._id = id + self._username = username + self._first_name = first_name + self._last_name = last_name + self._email = email + self._password = password + self._phone = phone + self._user_status = user_status + + @classmethod + def from_dict(cls, dikt) -> 'User': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The User of this User. # noqa: E501 + :rtype: User + """ + return util.deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """Gets the id of this User. + + + :return: The id of this User. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """Sets the id of this User. + + + :param id: The id of this User. + :type id: int + """ + + self._id = id + + @property + def username(self) -> str: + """Gets the username of this User. + + + :return: The username of this User. + :rtype: str + """ + return self._username + + @username.setter + def username(self, username: str): + """Sets the username of this User. + + + :param username: The username of this User. + :type username: str + """ + + self._username = username + + @property + def first_name(self) -> str: + """Gets the first_name of this User. + + + :return: The first_name of this User. + :rtype: str + """ + return self._first_name + + @first_name.setter + def first_name(self, first_name: str): + """Sets the first_name of this User. + + + :param first_name: The first_name of this User. + :type first_name: str + """ + + self._first_name = first_name + + @property + def last_name(self) -> str: + """Gets the last_name of this User. + + + :return: The last_name of this User. + :rtype: str + """ + return self._last_name + + @last_name.setter + def last_name(self, last_name: str): + """Sets the last_name of this User. + + + :param last_name: The last_name of this User. + :type last_name: str + """ + + self._last_name = last_name + + @property + def email(self) -> str: + """Gets the email of this User. + + + :return: The email of this User. + :rtype: str + """ + return self._email + + @email.setter + def email(self, email: str): + """Sets the email of this User. + + + :param email: The email of this User. + :type email: str + """ + + self._email = email + + @property + def password(self) -> str: + """Gets the password of this User. + + + :return: The password of this User. + :rtype: str + """ + return self._password + + @password.setter + def password(self, password: str): + """Sets the password of this User. + + + :param password: The password of this User. + :type password: str + """ + + self._password = password + + @property + def phone(self) -> str: + """Gets the phone of this User. + + + :return: The phone of this User. + :rtype: str + """ + return self._phone + + @phone.setter + def phone(self, phone: str): + """Sets the phone of this User. + + + :param phone: The phone of this User. + :type phone: str + """ + + self._phone = phone + + @property + def user_status(self) -> int: + """Gets the user_status of this User. + + User Status # noqa: E501 + + :return: The user_status of this User. + :rtype: int + """ + return self._user_status + + @user_status.setter + def user_status(self, user_status: int): + """Sets the user_status of this User. + + User Status # noqa: E501 + + :param user_status: The user_status of this User. + :type user_status: int + """ + + self._user_status = user_status diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/swagger/swagger.yaml b/samples/server/petstore/python-blueplanet/app/openapi_server/swagger/swagger.yaml new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/test/__init__.py b/samples/server/petstore/python-blueplanet/app/openapi_server/test/__init__.py new file mode 100644 index 000000000000..6ce57864885a --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/test/__init__.py @@ -0,0 +1,16 @@ +import logging + +import connexion +from flask_testing import TestCase + +from openapi_server.encoder import JSONEncoder + + +class BaseTestCase(TestCase): + + def create_app(self): + logging.getLogger('connexion.operation').setLevel('ERROR') + app = connexion.App(__name__, specification_dir='../swagger/') + app.app.json_encoder = JSONEncoder + app.add_api('swagger.yaml') + return app.app diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/test/test_pet_controller.py b/samples/server/petstore/python-blueplanet/app/openapi_server/test/test_pet_controller.py new file mode 100644 index 000000000000..34b8e534e666 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/test/test_pet_controller.py @@ -0,0 +1,159 @@ +# coding: utf-8 + +from __future__ import absolute_import + +from flask import json +from six import BytesIO + +from app.openapi_server.models.api_response import ApiResponse # noqa: E501 +from app.openapi_server.models.pet import Pet # noqa: E501 +from openapi_server.test import BaseTestCase + + +class TestPetController(BaseTestCase): + """PetController integration test stubs""" + + def test_add_pet(self): + """Test case for add_pet + + Add a new pet to the store + """ + body = { + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" +} + response = self.client.open( + '/v2/pet', + method='POST', + data=json.dumps(body), + content_type='application/json') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_delete_pet(self): + """Test case for delete_pet + + Deletes a pet + """ + headers = [('api_key', 'api_key_example')] + response = self.client.open( + '/v2/pet/{pet_id}'.format(pet_id=56), + method='DELETE', + headers=headers) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_find_pets_by_status(self): + """Test case for find_pets_by_status + + Finds Pets by status + """ + query_string = [('status', 'available')] + response = self.client.open( + '/v2/pet/findByStatus', + method='GET', + query_string=query_string) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_find_pets_by_tags(self): + """Test case for find_pets_by_tags + + Finds Pets by tags + """ + query_string = [('tags', 'tags_example')] + response = self.client.open( + '/v2/pet/findByTags', + method='GET', + query_string=query_string) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_get_pet_by_id(self): + """Test case for get_pet_by_id + + Find pet by ID + """ + response = self.client.open( + '/v2/pet/{pet_id}'.format(pet_id=56), + method='GET') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_update_pet(self): + """Test case for update_pet + + Update an existing pet + """ + body = { + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" +} + response = self.client.open( + '/v2/pet', + method='PUT', + data=json.dumps(body), + content_type='application/json') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_update_pet_with_form(self): + """Test case for update_pet_with_form + + Updates a pet in the store with form data + """ + data = dict(name='name_example', + status='status_example') + response = self.client.open( + '/v2/pet/{pet_id}'.format(pet_id=56), + method='POST', + data=data, + content_type='application/x-www-form-urlencoded') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_upload_file(self): + """Test case for upload_file + + uploads an image + """ + data = dict(additional_metadata='additional_metadata_example', + file=(BytesIO(b'some file data'), 'file.txt')) + response = self.client.open( + '/v2/pet/{pet_id}/uploadImage'.format(pet_id=56), + method='POST', + data=data, + content_type='multipart/form-data') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + +if __name__ == '__main__': + import unittest + unittest.main() diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/test/test_store_controller.py b/samples/server/petstore/python-blueplanet/app/openapi_server/test/test_store_controller.py new file mode 100644 index 000000000000..3695ff4a3b3a --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/test/test_store_controller.py @@ -0,0 +1,65 @@ +# coding: utf-8 + +from __future__ import absolute_import + +from flask import json +from six import BytesIO + +from app.openapi_server.models.order import Order # noqa: E501 +from openapi_server.test import BaseTestCase + + +class TestStoreController(BaseTestCase): + """StoreController integration test stubs""" + + def test_delete_order(self): + """Test case for delete_order + + Delete purchase order by ID + """ + response = self.client.open( + '/v2/store/order/{order_id}'.format(order_id='order_id_example'), + method='DELETE') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_get_inventory(self): + """Test case for get_inventory + + Returns pet inventories by status + """ + response = self.client.open( + '/v2/store/inventory', + method='GET') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_get_order_by_id(self): + """Test case for get_order_by_id + + Find purchase order by ID + """ + response = self.client.open( + '/v2/store/order/{order_id}'.format(order_id=5), + method='GET') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_place_order(self): + """Test case for place_order + + Place an order for a pet + """ + body = {} + response = self.client.open( + '/v2/store/order', + method='POST', + data=json.dumps(body), + content_type='application/json') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + +if __name__ == '__main__': + import unittest + unittest.main() diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/test/test_user_controller.py b/samples/server/petstore/python-blueplanet/app/openapi_server/test/test_user_controller.py new file mode 100644 index 000000000000..1ef108621bdf --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/test/test_user_controller.py @@ -0,0 +1,121 @@ +# coding: utf-8 + +from __future__ import absolute_import + +from flask import json +from six import BytesIO + +from app.openapi_server.models.user import User # noqa: E501 +from openapi_server.test import BaseTestCase + + +class TestUserController(BaseTestCase): + """UserController integration test stubs""" + + def test_create_user(self): + """Test case for create_user + + Create user + """ + body = {} + response = self.client.open( + '/v2/user', + method='POST', + data=json.dumps(body), + content_type='application/json') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_create_users_with_array_input(self): + """Test case for create_users_with_array_input + + Creates list of users with given input array + """ + body = [] + response = self.client.open( + '/v2/user/createWithArray', + method='POST', + data=json.dumps(body), + content_type='application/json') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_create_users_with_list_input(self): + """Test case for create_users_with_list_input + + Creates list of users with given input array + """ + body = [] + response = self.client.open( + '/v2/user/createWithList', + method='POST', + data=json.dumps(body), + content_type='application/json') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_delete_user(self): + """Test case for delete_user + + Delete user + """ + response = self.client.open( + '/v2/user/{username}'.format(username='username_example'), + method='DELETE') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_get_user_by_name(self): + """Test case for get_user_by_name + + Get user by user name + """ + response = self.client.open( + '/v2/user/{username}'.format(username='username_example'), + method='GET') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_login_user(self): + """Test case for login_user + + Logs user into the system + """ + query_string = [('username', 'username_example'), + ('password', 'password_example')] + response = self.client.open( + '/v2/user/login', + method='GET', + query_string=query_string) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_logout_user(self): + """Test case for logout_user + + Logs out current logged in user session + """ + response = self.client.open( + '/v2/user/logout', + method='GET') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_update_user(self): + """Test case for update_user + + Updated user + """ + body = {} + response = self.client.open( + '/v2/user/{username}'.format(username='username_example'), + method='PUT', + data=json.dumps(body), + content_type='application/json') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + +if __name__ == '__main__': + import unittest + unittest.main() diff --git a/samples/server/petstore/python-blueplanet/app/openapi_server/util.py b/samples/server/petstore/python-blueplanet/app/openapi_server/util.py new file mode 100644 index 000000000000..527d1424c3d5 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/openapi_server/util.py @@ -0,0 +1,141 @@ +import datetime + +import six +import typing + + +def _deserialize(data, klass): + """Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if klass in six.integer_types or klass in (float, str, bool): + return _deserialize_primitive(data, klass) + elif klass == object: + return _deserialize_object(data) + elif klass == datetime.date: + return deserialize_date(data) + elif klass == datetime.datetime: + return deserialize_datetime(data) + elif type(klass) == typing.GenericMeta: + if klass.__extra__ == list: + return _deserialize_list(data, klass.__args__[0]) + if klass.__extra__ == dict: + return _deserialize_dict(data, klass.__args__[1]) + else: + return deserialize_model(data, klass) + + +def _deserialize_primitive(data, klass): + """Deserializes to primitive type. + + :param data: data to deserialize. + :param klass: class literal. + + :return: int, long, float, str, bool. + :rtype: int | long | float | str | bool + """ + try: + value = klass(data) + except UnicodeEncodeError: + value = six.u(data) + except TypeError: + value = data + return value + + +def _deserialize_object(value): + """Return a original value. + + :return: object. + """ + return value + + +def deserialize_date(string): + """Deserializes string to date. + + :param string: str. + :type string: str + :return: date. + :rtype: date + """ + try: + from dateutil.parser import parse + return parse(string).date() + except ImportError: + return string + + +def deserialize_datetime(string): + """Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :type string: str + :return: datetime. + :rtype: datetime + """ + try: + from dateutil.parser import parse + return parse(string) + except ImportError: + return string + + +def deserialize_model(data, klass): + """Deserializes list or dict to model. + + :param data: dict, list. + :type data: dict | list + :param klass: class literal. + :return: model object. + """ + instance = klass() + + if not instance.swagger_types: + return data + + for attr, attr_type in six.iteritems(instance.swagger_types): + if data is not None \ + and instance.attribute_map[attr] in data \ + and isinstance(data, (list, dict)): + value = data[instance.attribute_map[attr]] + setattr(instance, attr, _deserialize(value, attr_type)) + + return instance + + +def _deserialize_list(data, boxed_type): + """Deserializes a list and its elements. + + :param data: list to deserialize. + :type data: list + :param boxed_type: class literal. + + :return: deserialized list. + :rtype: list + """ + return [_deserialize(sub_data, boxed_type) + for sub_data in data] + + +def _deserialize_dict(data, boxed_type): + """Deserializes a dict and its elements. + + :param data: dict to deserialize. + :type data: dict + :param boxed_type: class literal. + + :return: deserialized dict. + :rtype: dict + """ + return {k: _deserialize(v, boxed_type) + for k, v in six.iteritems(data)} diff --git a/samples/server/petstore/python-blueplanet/app/requirements.txt b/samples/server/petstore/python-blueplanet/app/requirements.txt new file mode 100644 index 000000000000..770b2ca9726b --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/requirements.txt @@ -0,0 +1,6 @@ +connexion == 1.1.15 +python_dateutil == 2.6.0 +setuptools >= 21.0.0 +bp2hookutil==3.3.0 +plansdk +twigjack diff --git a/samples/server/petstore/python-blueplanet/app/setup.py b/samples/server/petstore/python-blueplanet/app/setup.py new file mode 100644 index 000000000000..d36a8f5415b1 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/setup.py @@ -0,0 +1,35 @@ +# coding: utf-8 + +import sys +from setuptools import setup, find_packages + +NAME = "openapi_server" +VERSION = "1.0.0" + +# To install the library, run the following +# +# python setup.py install +# +# prerequisite: setuptools +# http://pypi.python.org/pypi/setuptools + +REQUIRES = ["connexion"] + +setup( + name=NAME, + version=VERSION, + description="OpenAPI Petstore", + author_email="", + url="", + keywords=["Swagger", "OpenAPI Petstore"], + install_requires=REQUIRES, + packages=find_packages(), + package_data={'': ['swagger/swagger.yaml']}, + include_package_data=True, + entry_points={ + 'console_scripts': ['openapi_server=openapi_server.__main__:main']}, + long_description="""\ + This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + """ +) + diff --git a/samples/server/petstore/python-blueplanet/app/test-requirements.txt b/samples/server/petstore/python-blueplanet/app/test-requirements.txt new file mode 100644 index 000000000000..7f8d96e6b40e --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/test-requirements.txt @@ -0,0 +1,6 @@ +flask_testing==0.6.1 +coverage>=4.0.3 +nose>=1.3.7 +pluggy>=0.3.1 +py>=1.4.31 +randomize>=0.13 diff --git a/samples/server/petstore/python-blueplanet/app/tox.ini b/samples/server/petstore/python-blueplanet/app/tox.ini new file mode 100644 index 000000000000..3e0b644eec48 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/app/tox.ini @@ -0,0 +1,10 @@ +[tox] +envlist = py35 + +[testenv] +deps=-r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +commands= + nosetests \ + [] \ No newline at end of file diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.ApiResponse/create.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.ApiResponse/create.json new file mode 100644 index 000000000000..199641307511 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.ApiResponse/create.json @@ -0,0 +1,19 @@ +{ + "type": "form", + "version": "2.0", + "cells": [{ + "label": "General", + "children": [ + {"model": "label"}, + {"model": "description"} + ] + },{ + "label": "Details", + "model": "properties", + "children": [ + {"model": "code" }, + {"model": "type" }, + {"model": "message" }, + ] + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.ApiResponse/high.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.ApiResponse/high.json new file mode 100644 index 000000000000..5b261500f725 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.ApiResponse/high.json @@ -0,0 +1,76 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "children": [{ + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "domain-by-product-renderer" + }, + "model": "productId" + } + ] + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "State", + "model": "orchState" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.ApiResponse/low.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.ApiResponse/low.json new file mode 100644 index 000000000000..fcfefc103482 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.ApiResponse/low.json @@ -0,0 +1,53 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Category/create.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Category/create.json new file mode 100644 index 000000000000..12138c1358d5 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Category/create.json @@ -0,0 +1,18 @@ +{ + "type": "form", + "version": "2.0", + "cells": [{ + "label": "General", + "children": [ + {"model": "label"}, + {"model": "description"} + ] + },{ + "label": "Details", + "model": "properties", + "children": [ + {"model": "id" }, + {"model": "name" }, + ] + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Category/high.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Category/high.json new file mode 100644 index 000000000000..5b261500f725 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Category/high.json @@ -0,0 +1,76 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "children": [{ + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "domain-by-product-renderer" + }, + "model": "productId" + } + ] + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "State", + "model": "orchState" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Category/low.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Category/low.json new file mode 100644 index 000000000000..fcfefc103482 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Category/low.json @@ -0,0 +1,53 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Order/create.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Order/create.json new file mode 100644 index 000000000000..88eac1191f16 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Order/create.json @@ -0,0 +1,22 @@ +{ + "type": "form", + "version": "2.0", + "cells": [{ + "label": "General", + "children": [ + {"model": "label"}, + {"model": "description"} + ] + },{ + "label": "Details", + "model": "properties", + "children": [ + {"model": "id" }, + {"model": "pet_id" }, + {"model": "quantity" }, + {"model": "ship_date" }, + {"model": "status" }, + {"model": "complete" }, + ] + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Order/high.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Order/high.json new file mode 100644 index 000000000000..5b261500f725 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Order/high.json @@ -0,0 +1,76 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "children": [{ + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "domain-by-product-renderer" + }, + "model": "productId" + } + ] + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "State", + "model": "orchState" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Order/low.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Order/low.json new file mode 100644 index 000000000000..fcfefc103482 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Order/low.json @@ -0,0 +1,53 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Pet/create.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Pet/create.json new file mode 100644 index 000000000000..7520ba7856b3 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Pet/create.json @@ -0,0 +1,22 @@ +{ + "type": "form", + "version": "2.0", + "cells": [{ + "label": "General", + "children": [ + {"model": "label"}, + {"model": "description"} + ] + },{ + "label": "Details", + "model": "properties", + "children": [ + {"model": "id" }, + {"model": "category" }, + {"model": "name" }, + {"model": "photo_urls" }, + {"model": "tags" }, + {"model": "status" }, + ] + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Pet/high.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Pet/high.json new file mode 100644 index 000000000000..5b261500f725 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Pet/high.json @@ -0,0 +1,76 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "children": [{ + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "domain-by-product-renderer" + }, + "model": "productId" + } + ] + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "State", + "model": "orchState" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Pet/low.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Pet/low.json new file mode 100644 index 000000000000..fcfefc103482 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Pet/low.json @@ -0,0 +1,53 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Tag/create.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Tag/create.json new file mode 100644 index 000000000000..12138c1358d5 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Tag/create.json @@ -0,0 +1,18 @@ +{ + "type": "form", + "version": "2.0", + "cells": [{ + "label": "General", + "children": [ + {"model": "label"}, + {"model": "description"} + ] + },{ + "label": "Details", + "model": "properties", + "children": [ + {"model": "id" }, + {"model": "name" }, + ] + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Tag/high.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Tag/high.json new file mode 100644 index 000000000000..5b261500f725 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Tag/high.json @@ -0,0 +1,76 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "children": [{ + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "domain-by-product-renderer" + }, + "model": "productId" + } + ] + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "State", + "model": "orchState" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Tag/low.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Tag/low.json new file mode 100644 index 000000000000..fcfefc103482 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.Tag/low.json @@ -0,0 +1,53 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.User/create.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.User/create.json new file mode 100644 index 000000000000..2be780072af4 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.User/create.json @@ -0,0 +1,24 @@ +{ + "type": "form", + "version": "2.0", + "cells": [{ + "label": "General", + "children": [ + {"model": "label"}, + {"model": "description"} + ] + },{ + "label": "Details", + "model": "properties", + "children": [ + {"model": "id" }, + {"model": "username" }, + {"model": "first_name" }, + {"model": "last_name" }, + {"model": "email" }, + {"model": "password" }, + {"model": "phone" }, + {"model": "user_status" }, + ] + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.User/high.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.User/high.json new file mode 100644 index 000000000000..5b261500f725 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.User/high.json @@ -0,0 +1,76 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "children": [{ + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "domain-by-product-renderer" + }, + "model": "productId" + } + ] + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "State", + "model": "orchState" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.User/low.json b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.User/low.json new file mode 100644 index 000000000000..fcfefc103482 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/ddui-views/openapi_server.resourceTypes.User/low.json @@ -0,0 +1,53 @@ +{ + "version": "2.0", + "type": "form", + "cells": [{ + "children": [{ + "classNames": { + "cell": "large", + "value": "ob-input", + "label": "ob-label hide-label" + }, + "model": "id", + "renderer": { + "defaultLabel": "- View detail -", + "label": "${./label}", + "name": "link", + "url": "/orchestrate/#/details/resource/${./id}/details" + } + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "model": "createdAt" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "renderer": { + "name": "full-tenant-name-renderer" + }, + "label": "tenant", + "model": "tenantId" + }, + { + "classNames": { + "cell": "small", + "value": "ob-input", + "label": "ob-label" + }, + "label": "Resource Type", + "model": "resourceTypeId" + } + ], + "classNames": { + "cell": "flex-row small" + } + }] +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/ApiResponse_ResourceType.tosca b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/ApiResponse_ResourceType.tosca new file mode 100644 index 000000000000..ea06c9c3fc8b --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/ApiResponse_ResourceType.tosca @@ -0,0 +1,45 @@ +"$schema" = "http://cyaninc.com/json-schemas/tosca-lite-v1/definition-module#" +title = "openapi_server ApiResponse" +package = openapi_server +version = "1.0" +description = "Defines a ApiResponse" +authors = ["F. Bar (foo@bar.baz)"] + +imports { + Root = tosca.resourceTypes.Root +} +resourceTypes { + + ApiResponse { + title = ApiResponse + description = ApiResponse + derivedFrom = Root + properties { + code { + type = integer + description = "" + optional = false + } + type { + type = string + description = "" + optional = false + } + message { + type = string + description = "" + optional = false + } + } + } +} + +serviceTemplates { + + ApiResponse { + title = ApiResponse + description = ApiResponse + implements = openapi_server.resourceTypes.ApiResponse + + } +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Category_ResourceType.tosca b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Category_ResourceType.tosca new file mode 100644 index 000000000000..00e1dbd1e6b6 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Category_ResourceType.tosca @@ -0,0 +1,40 @@ +"$schema" = "http://cyaninc.com/json-schemas/tosca-lite-v1/definition-module#" +title = "openapi_server Category" +package = openapi_server +version = "1.0" +description = "Defines a Category" +authors = ["F. Bar (foo@bar.baz)"] + +imports { + Root = tosca.resourceTypes.Root +} +resourceTypes { + + Category { + title = Category + description = Category + derivedFrom = Root + properties { + id { + type = integer + description = "" + optional = false + } + name { + type = string + description = "" + optional = false + } + } + } +} + +serviceTemplates { + + Category { + title = Category + description = Category + implements = openapi_server.resourceTypes.Category + + } +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Order_ResourceType.tosca b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Order_ResourceType.tosca new file mode 100644 index 000000000000..cf6768d1dea1 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Order_ResourceType.tosca @@ -0,0 +1,61 @@ +"$schema" = "http://cyaninc.com/json-schemas/tosca-lite-v1/definition-module#" +title = "openapi_server Order" +package = openapi_server +version = "1.0" +description = "Defines a Order" +authors = ["F. Bar (foo@bar.baz)"] + +imports { + Root = tosca.resourceTypes.Root +} +resourceTypes { + + Order { + title = Order + description = Order + derivedFrom = Root + properties { + id { + type = integer + description = "" + optional = false + } + pet_id { + type = integer + description = "" + optional = false + } + quantity { + type = integer + description = "" + optional = false + } + ship_date { + type = string + description = "" + optional = false + } + status { + type = string + description = "Order Status" + enum = ["placed", "approved", "delivered"] + optional = false + } + complete { + type = boolean + description = "" + optional = false + } + } + } +} + +serviceTemplates { + + Order { + title = Order + description = Order + implements = openapi_server.resourceTypes.Order + + } +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Pet_ResourceType.tosca b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Pet_ResourceType.tosca new file mode 100644 index 000000000000..bba38ce60bd7 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Pet_ResourceType.tosca @@ -0,0 +1,65 @@ +"$schema" = "http://cyaninc.com/json-schemas/tosca-lite-v1/definition-module#" +title = "openapi_server Pet" +package = openapi_server +version = "1.0" +description = "Defines a Pet" +authors = ["F. Bar (foo@bar.baz)"] + +imports { + Root = tosca.resourceTypes.Root + Category = openapi_server.resourceTypes.Category + Tag = openapi_server.resourceTypes.Tag +} +resourceTypes { + + Pet { + title = Pet + description = Pet + derivedFrom = Root + properties { + id { + type = integer + description = "" + optional = false + } + category { + type = Category + description = "" + optional = false + } + name { + type = string + description = "" + optional = true + } + photo_urls { + type = array + items.type = string + description = "" + optional = true + } + tags { + type = array + items.type = Tag + description = "" + optional = false + } + status { + type = string + description = "pet status in the store" + enum = ["available", "pending", "sold"] + optional = false + } + } + } +} + +serviceTemplates { + + Pet { + title = Pet + description = Pet + implements = openapi_server.resourceTypes.Pet + + } +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Tag_ResourceType.tosca b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Tag_ResourceType.tosca new file mode 100644 index 000000000000..af080d370253 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/Tag_ResourceType.tosca @@ -0,0 +1,40 @@ +"$schema" = "http://cyaninc.com/json-schemas/tosca-lite-v1/definition-module#" +title = "openapi_server Tag" +package = openapi_server +version = "1.0" +description = "Defines a Tag" +authors = ["F. Bar (foo@bar.baz)"] + +imports { + Root = tosca.resourceTypes.Root +} +resourceTypes { + + Tag { + title = Tag + description = Tag + derivedFrom = Root + properties { + id { + type = integer + description = "" + optional = false + } + name { + type = string + description = "" + optional = false + } + } + } +} + +serviceTemplates { + + Tag { + title = Tag + description = Tag + implements = openapi_server.resourceTypes.Tag + + } +} diff --git a/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/User_ResourceType.tosca b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/User_ResourceType.tosca new file mode 100644 index 000000000000..0b5bee16d2b7 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/model-definitions/types/tosca/openapi_server/User_ResourceType.tosca @@ -0,0 +1,70 @@ +"$schema" = "http://cyaninc.com/json-schemas/tosca-lite-v1/definition-module#" +title = "openapi_server User" +package = openapi_server +version = "1.0" +description = "Defines a User" +authors = ["F. Bar (foo@bar.baz)"] + +imports { + Root = tosca.resourceTypes.Root +} +resourceTypes { + + User { + title = User + description = User + derivedFrom = Root + properties { + id { + type = integer + description = "" + optional = false + } + username { + type = string + description = "" + optional = false + } + first_name { + type = string + description = "" + optional = false + } + last_name { + type = string + description = "" + optional = false + } + email { + type = string + description = "" + optional = false + } + password { + type = string + description = "" + optional = false + } + phone { + type = string + description = "" + optional = false + } + user_status { + type = integer + description = "User Status" + optional = false + } + } + } +} + +serviceTemplates { + + User { + title = User + description = User + implements = openapi_server.resourceTypes.User + + } +} diff --git a/samples/server/petstore/python-blueplanet/requirements.txt b/samples/server/petstore/python-blueplanet/requirements.txt new file mode 100644 index 000000000000..08a16baf59c1 --- /dev/null +++ b/samples/server/petstore/python-blueplanet/requirements.txt @@ -0,0 +1,2 @@ +--extra-index-url https://pypi.blueplanet.com/simple/ +solution-maker==0.1.6 diff --git a/samples/server/petstore/python-blueplanet/solution/fig.yml b/samples/server/petstore/python-blueplanet/solution/fig.yml new file mode 100644 index 000000000000..13c69f8df6fb --- /dev/null +++ b/samples/server/petstore/python-blueplanet/solution/fig.yml @@ -0,0 +1,51 @@ + +# +# Ciena +# +# Copyright(c) 2016, Ciena, Inc. All rights reserved. +# + +# REFERENCES: +# =========================================================== +# +# "Fig file format for solutions": +# https://confluence.ciena.com/display/blueplanet/Fig+file+format+for+solutions +# + +__version__: 1 + +# Docker registry must be specified in this file. +# if only passed as the --registry argument to solmaker, +# solman will not find the images at deployment time. +# MAKE SURE it is aligned with the value in the Makefile +docker_registry: registry.blueplanet.com + +# this name is read by the Makefile and used to build various paths +solution_name: openapi_server + +# version is not read from this file, but coded in the Makefile +# the vendor and tag are provided by the Makefile as argumernts to solmaker +solution_version: 1.0.0 + +# ============ NOTE =============================================================================== +# The app image versions listed below are hard coded of course. +# Verify GIT commits against the respective image versions housed in bpdr.io ... to ensure +# you're getting what you want! bpdr.io repo for each app is listed. +# ================================================================================================= + +apps: + tapi-swagger: + # https://..../openapi_server + image: registry.blueplanet.com/blueplanet/openapi_server:1.0.0 + volumes: + - /dev/log:/dev/log + environment: + - NBI_openapi_server_type=http + - NBI_openapi_server_port=8080 +app_bar: + System: + Documentation: + 'openapi_server Swagger': + description: 'openapi_server Swagger UI' + icon: 'orchestrate' + url: '/openapi_server/ui/#'