add Blueplanet language (#2184)

Add python-blueplanet server generator
This commit is contained in:
Jeff Groom
2019-03-07 00:48:57 -07:00
committed by William Cheng
parent 6a9117edd1
commit 9236e50098
93 changed files with 5142 additions and 0 deletions

View File

@@ -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

View File

@@ -98,6 +98,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)

View File

@@ -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|

View File

@@ -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);
}
}

View File

@@ -76,6 +76,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

View File

@@ -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

View File

@@ -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/)

View File

@@ -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}}"]

View File

@@ -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}}
```

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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}}

View File

@@ -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

View File

@@ -0,0 +1,10 @@
[tox]
envlist = {{#supportPython2}}py27, {{/supportPython2}}py35
[testenv]
deps=-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands=
nosetests \
[]

View File

@@ -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()

View File

@@ -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}}

View File

@@ -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)

View File

@@ -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}}

View File

@@ -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

View File

@@ -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}}

View File

@@ -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

View File

@@ -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()

View File

@@ -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)}

View File

@@ -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}}
]
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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}}

View File

@@ -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}}

View File

@@ -0,0 +1,2 @@
--extra-index-url https://pypi.blueplanet.com/simple/
solution-maker==0.1.6

View File

@@ -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/#'

View File

@@ -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

View File

@@ -0,0 +1 @@
4.0.0-SNAPSHOT

View File

@@ -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

View File

@@ -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/)

View File

@@ -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

View File

@@ -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

View File

@@ -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"]

View File

@@ -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
```

View File

@@ -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()

View File

@@ -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!'

View File

@@ -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 &lt; 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 &lt;&#x3D; 5 or &gt; 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!'

View File

@@ -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!'

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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)}

View File

@@ -0,0 +1,6 @@
connexion == 1.1.15
python_dateutil == 2.6.0
setuptools >= 21.0.0
bp2hookutil==3.3.0
plansdk
twigjack

View File

@@ -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 &#x60;special-key&#x60; to test the authorization filters.
"""
)

View File

@@ -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

View File

@@ -0,0 +1,10 @@
[tox]
envlist = py35
[testenv]
deps=-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands=
nosetests \
[]

View File

@@ -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" },
]
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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" },
]
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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" },
]
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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" },
]
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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" },
]
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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" },
]
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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"
}
}]
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -0,0 +1,2 @@
--extra-index-url https://pypi.blueplanet.com/simple/
solution-maker==0.1.6

View File

@@ -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/#'