Merge pull request #4249 from cbornet/flask_package

[Flask] Add packaging support
This commit is contained in:
wing328 2016-11-24 19:43:34 +08:00 committed by GitHub
commit a7ecaa27df
76 changed files with 788 additions and 222 deletions

View File

@ -29,9 +29,9 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf
public static final String DEFAULT_CONTROLLER = "defaultController";
public static final String SUPPORT_PYTHON2= "supportPython2";
protected String apiVersion = "1.0.0";
protected int serverPort = 8080;
protected String projectName = "swagger-server";
protected String packageName;
protected String packageVersion;
protected String controllerPackage;
protected String defaultController;
@ -91,7 +91,6 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files
*/
additionalProperties.put("apiVersion", apiVersion);
additionalProperties.put("serverPort", serverPort);
/*
@ -99,28 +98,19 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf
* 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
*/
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py"));
supportingFiles.add(new SupportingFile("tox.mustache", "", "tox.ini"));
supportingFiles.add(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt"));
supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
supportingFiles.add(new SupportingFile("swagger.mustache",
"swagger",
"swagger.yaml")
);
supportingFiles.add(new SupportingFile("app.mustache",
"",
"app.py")
);
supportingFiles.add(new SupportingFile("util.mustache",
"",
"util.py")
);
supportingFiles.add(new SupportingFile("README.mustache",
"",
"README.md")
);
supportingFiles.add(new SupportingFile("__init__controller.mustache",
"",
"__init__.py")
);
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "python package name (convention: snake_case).")
.defaultValue("swagger_server"));
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION, "python package version.")
.defaultValue("1.0.0"));
cliOptions.add(new CliOption(CONTROLLER_PACKAGE, "controller package").
defaultValue("controllers"));
cliOptions.add(new CliOption(DEFAULT_CONTROLLER, "default controller").
@ -134,48 +124,47 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf
super.processOpts();
//apiTemplateFiles.clear();
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
} else {
setPackageName("swagger_server");
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 {
} else {
this.controllerPackage = "controllers";
additionalProperties.put(CONTROLLER_PACKAGE, this.controllerPackage);
}
if (additionalProperties.containsKey(DEFAULT_CONTROLLER)) {
this.defaultController = additionalProperties.get(DEFAULT_CONTROLLER).toString();
}
else {
} 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");
}
supportingFiles.add(new SupportingFile("__init__.mustache", packageName, "__init__.py"));
supportingFiles.add(new SupportingFile("__main__.mustache", packageName, "__main__.py"));
supportingFiles.add(new SupportingFile("encoder.mustache", packageName, "encoder.py"));
supportingFiles.add(new SupportingFile("util.mustache", packageName, "util.py"));
supportingFiles.add(new SupportingFile("__init__.mustache", packageName + File.separatorChar + controllerPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__model.mustache", packageName + File.separatorChar + modelPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("base_model_.mustache", packageName + File.separatorChar + modelPackage, "base_model_.py"));
supportingFiles.add(new SupportingFile("__init__test.mustache", packageName + File.separatorChar + testPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("swagger.mustache", packageName + File.separatorChar + "swagger", "swagger.yaml"));
if(!new java.io.File(controllerPackage + File.separator + defaultController + ".py").exists()) {
supportingFiles.add(new SupportingFile("__init__controller.mustache",
controllerPackage,
"__init__.py")
);
}
supportingFiles.add(new SupportingFile("__init__model.mustache",
modelPackage,
"__init__.py")
);
supportingFiles.add(new SupportingFile("base_model_.mustache",
modelPackage,
"base_model_.py")
);
supportingFiles.add(new SupportingFile("__init__test.mustache",
testPackage,
"__init__.py")
);
modelPackage = packageName + "." + modelPackage;
controllerPackage = packageName + "." + controllerPackage;
testPackage = packageName + "." + testPackage;
}
private static String dropDots(String str) {
@ -628,6 +617,14 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf
p.example = example;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
@Override
public String escapeQuotationMark(String input) {

View File

@ -7,16 +7,16 @@ 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.
To run the server, please execute the following:
To run the server, please execute the following from the root directory:
```
{{#supportPython2}}
sudo pip install -U connexion flask_testing typing # install Connexion from PyPI
python app.py
pip install -r requirements.txt
python -m {{packageName}}
{{/supportPython2}}
{{^supportPython2}}
sudo pip3 install -U connexion flask_testing # install Connexion from PyPI
python3 app.py
pip3 install -r requirements.txt
python3 -m {{packageName}}
{{/supportPython2}}
```
@ -32,3 +32,8 @@ Your Swagger definition lives here:
http://localhost:{{serverPort}}{{contextPath}}/swagger.json
```
To launch the integration tests, use tox:
```
sudo pip install tox
tox
```

View File

@ -1,5 +1,5 @@
from flask_testing import TestCase
from app import JSONEncoder
from ..encoder import JSONEncoder
import connexion
import logging

View File

@ -0,0 +1,16 @@
{{#supportPython2}}
#!/usr/bin/env python
{{/supportPython2}}
{{^supportPython2}}
#!/usr/bin/env python3
{{/supportPython2}}
import connexion
from .encoder import JSONEncoder
if __name__ == '__main__':
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = JSONEncoder
app.add_api('swagger.yaml', arguments={'title': '{{appDescription}}'})
app.run(port={{serverPort}})

View File

@ -3,7 +3,7 @@ from pprint import pformat
from typing import TypeVar, Type
{{/supportPython2}}
from six import iteritems
from util import deserialize_model
from ..util import deserialize_model
{{^supportPython2}}
T = TypeVar('T')

View File

@ -4,7 +4,7 @@ import connexion
from datetime import date, datetime
from typing import List, Dict
from six import iteritems
from util import deserialize_date, deserialize_datetime
from ..util import deserialize_date, deserialize_datetime
{{#operations}}
{{#operation}}

View File

@ -1,11 +1,3 @@
{{#supportPython2}}
#!/usr/bin/env python
{{/supportPython2}}
{{^supportPython2}}
#!/usr/bin/env python3
{{/supportPython2}}
import connexion
from connexion.decorators import produces
from six import iteritems
from {{modelPackage}}.base_model_ import Model
@ -24,11 +16,4 @@ class JSONEncoder(produces.JSONEncoder):
attr = o.attribute_map[attr]
dikt[attr] = value
return dikt
return produces.JSONEncoder.default(self, o)
if __name__ == '__main__':
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = JSONEncoder
app.add_api('swagger.yaml', arguments={'title': '{{appDescription}}'})
app.run(port={{serverPort}})
return produces.JSONEncoder.default(self, o)

View File

@ -0,0 +1,52 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update"
git_user_id=$1
git_repo_id=$2
release_note=$3
if [ "$git_user_id" = "" ]; then
git_user_id="{{{gitUserId}}}"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="{{{gitRepoId}}}"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="{{{releaseNote}}}"
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
fi
# Initialize the local directory as a Git repository
git init
# Adds the files in the local repository and stages them for commit.
git add .
# Commits the tracked changes and prepares them to be pushed to a remote repository.
git commit -m "$release_note"
# Sets the new remote
git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
fi
fi
git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

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

@ -6,7 +6,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
{{#models}}

View File

@ -0,0 +1,6 @@
connexion == 1.0.129
python_dateutil == 2.6.0
{{#supportPython2}}
typing == 3.5.2.2
{{/supportPython2}}
setuptools >= 21.0.0

View File

@ -0,0 +1,33 @@
# 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,
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,16 @@
# ref: https://docs.travis-ci.com/user/languages/python
language: python
python:
{{#supportPython2}}
- "2.7"
{{/supportPython2}}
- "3.2"
- "3.3"
- "3.4"
- "3.5"
#- "3.5-dev" # 3.5 development branch
#- "nightly" # points to the latest development branch e.g. 3.6-dev
# command to install dependencies
install: "pip install -r requirements.txt"
# command to run tests
script: nosetests

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,14 @@
# ref: https://docs.travis-ci.com/user/languages/python
language: python
python:
- "2.7"
- "3.2"
- "3.3"
- "3.4"
- "3.5"
#- "3.5-dev" # 3.5 development branch
#- "nightly" # points to the latest development branch e.g. 3.6-dev
# command to install dependencies
install: "pip install -r requirements.txt"
# command to run tests
script: nosetests

View File

@ -7,11 +7,11 @@ 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.
To run the server, please execute the following:
To run the server, please execute the following from the root directory:
```
sudo pip install -U connexion flask_testing typing # install Connexion from PyPI
python app.py
pip install -r requirements.txt
python -m swagger_server
```
and open your browser to here:
@ -26,3 +26,8 @@ Your Swagger definition lives here:
http://localhost:8080/v2/swagger.json
```
To launch the integration tests, use tox:
```
sudo pip install tox
tox
```

View File

@ -1,29 +0,0 @@
#!/usr/bin/env python
import connexion
from connexion.decorators import produces
from six import iteritems
from models.base_model_ import Model
class JSONEncoder(produces.JSONEncoder):
include_nulls = False
def default(self, o):
if isinstance(o, Model):
dikt = {}
for attr, _ in 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 produces.JSONEncoder.default(self, o)
if __name__ == '__main__':
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = JSONEncoder
app.add_api('swagger.yaml', arguments={'title': 'This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.'})
app.run(port=8080)

View File

@ -0,0 +1,52 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update"
git_user_id=$1
git_repo_id=$2
release_note=$3
if [ "$git_user_id" = "" ]; then
git_user_id="GIT_USER_ID"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="GIT_REPO_ID"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="Minor update"
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
fi
# Initialize the local directory as a Git repository
git init
# Adds the files in the local repository and stages them for commit.
git add .
# Commits the tracked changes and prepares them to be pushed to a remote repository.
git commit -m "$release_note"
# Sets the new remote
git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
fi
fi
git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

View File

@ -0,0 +1,4 @@
connexion == 1.0.129
python_dateutil == 2.6.0
typing == 3.5.2.2
setuptools >= 21.0.0

View File

@ -0,0 +1,33 @@
# coding: utf-8
import sys
from setuptools import setup, find_packages
NAME = "swagger_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="Swagger Petstore",
author_email="apiteam@swagger.io",
url="",
keywords=["Swagger", "Swagger Petstore"],
install_requires=REQUIRES,
packages=find_packages(),
package_data={'': ['swagger/swagger.yaml']},
include_package_data=True,
long_description="""\
This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
"""
)

View File

@ -0,0 +1,11 @@
#!/usr/bin/env python
import connexion
from .encoder import JSONEncoder
if __name__ == '__main__':
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = JSONEncoder
app.add_api('swagger.yaml', arguments={'title': 'This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.'})
app.run(port=8080)

View File

@ -1,10 +1,10 @@
import connexion
from models.api_response import ApiResponse
from models.pet import Pet
from swagger_server.models.api_response import ApiResponse
from swagger_server.models.pet import Pet
from datetime import date, datetime
from typing import List, Dict
from six import iteritems
from util import deserialize_date, deserialize_datetime
from ..util import deserialize_date, deserialize_datetime
def add_pet(body):

View File

@ -1,9 +1,9 @@
import connexion
from models.order import Order
from swagger_server.models.order import Order
from datetime import date, datetime
from typing import List, Dict
from six import iteritems
from util import deserialize_date, deserialize_datetime
from ..util import deserialize_date, deserialize_datetime
def delete_order(orderId):

View File

@ -1,9 +1,9 @@
import connexion
from models.user import User
from swagger_server.models.user import User
from datetime import date, datetime
from typing import List, Dict
from six import iteritems
from util import deserialize_date, deserialize_datetime
from ..util import deserialize_date, deserialize_datetime
def create_user(body):

View File

@ -0,0 +1,19 @@
from connexion.decorators import produces
from six import iteritems
from swagger_server.models.base_model_ import Model
class JSONEncoder(produces.JSONEncoder):
include_nulls = False
def default(self, o):
if isinstance(o, Model):
dikt = {}
for attr, _ in 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 produces.JSONEncoder.default(self, o)

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class ApiResponse(Model):

View File

@ -1,6 +1,6 @@
from pprint import pformat
from six import iteritems
from util import deserialize_model
from ..util import deserialize_model
class Model(object):

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class Category(Model):

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class Order(Model):

View File

@ -1,12 +1,12 @@
# coding: utf-8
from __future__ import absolute_import
from models.category import Category
from models.tag import Tag
from swagger_server.models.category import Category
from swagger_server.models.tag import Tag
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class Pet(Model):

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class Tag(Model):

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class User(Model):

View File

@ -58,7 +58,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
put:
tags:
- "pet"
@ -89,7 +89,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/pet/findByStatus:
get:
tags:
@ -127,7 +127,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/pet/findByTags:
get:
tags:
@ -161,7 +161,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/pet/{petId}:
get:
tags:
@ -190,7 +190,7 @@ paths:
description: "Pet not found"
security:
- api_key: []
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
post:
tags:
- "pet"
@ -226,7 +226,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
delete:
tags:
- "pet"
@ -254,7 +254,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/pet/{petId}/uploadImage:
post:
tags:
@ -292,7 +292,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/store/inventory:
get:
tags:
@ -313,7 +313,7 @@ paths:
format: "int32"
security:
- api_key: []
x-swagger-router-controller: "controllers.store_controller"
x-swagger-router-controller: "swagger_server.controllers.store_controller"
/store/order:
post:
tags:
@ -338,7 +338,7 @@ paths:
$ref: "#/definitions/Order"
400:
description: "Invalid Order"
x-swagger-router-controller: "controllers.store_controller"
x-swagger-router-controller: "swagger_server.controllers.store_controller"
/store/order/{orderId}:
get:
tags:
@ -368,7 +368,7 @@ paths:
description: "Invalid ID supplied"
404:
description: "Order not found"
x-swagger-router-controller: "controllers.store_controller"
x-swagger-router-controller: "swagger_server.controllers.store_controller"
delete:
tags:
- "store"
@ -391,7 +391,7 @@ paths:
description: "Invalid ID supplied"
404:
description: "Order not found"
x-swagger-router-controller: "controllers.store_controller"
x-swagger-router-controller: "swagger_server.controllers.store_controller"
/user:
post:
tags:
@ -412,7 +412,7 @@ paths:
responses:
default:
description: "successful operation"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/createWithArray:
post:
tags:
@ -435,7 +435,7 @@ paths:
responses:
default:
description: "successful operation"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/createWithList:
post:
tags:
@ -458,7 +458,7 @@ paths:
responses:
default:
description: "successful operation"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/login:
get:
tags:
@ -496,7 +496,7 @@ paths:
description: "date in UTC when toekn expires"
400:
description: "Invalid username/password supplied"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/logout:
get:
tags:
@ -511,7 +511,7 @@ paths:
responses:
default:
description: "successful operation"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/{username}:
get:
tags:
@ -537,7 +537,7 @@ paths:
description: "Invalid username supplied"
404:
description: "User not found"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
put:
tags:
- "user"
@ -564,7 +564,7 @@ paths:
description: "Invalid user supplied"
404:
description: "User not found"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
delete:
tags:
- "user"
@ -585,7 +585,7 @@ paths:
description: "Invalid username supplied"
404:
description: "User not found"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
securityDefinitions:
petstore_auth:
type: "oauth2"

View File

@ -1,5 +1,5 @@
from flask_testing import TestCase
from app import JSONEncoder
from ..encoder import JSONEncoder
import connexion
import logging

View File

@ -2,8 +2,8 @@
from __future__ import absolute_import
from models.api_response import ApiResponse
from models.pet import Pet
from swagger_server.models.api_response import ApiResponse
from swagger_server.models.pet import Pet
from . import BaseTestCase
from six import BytesIO
from flask import json

View File

@ -2,7 +2,7 @@
from __future__ import absolute_import
from models.order import Order
from swagger_server.models.order import Order
from . import BaseTestCase
from six import BytesIO
from flask import json

View File

@ -2,7 +2,7 @@
from __future__ import absolute_import
from models.user import User
from swagger_server.models.user import User
from . import BaseTestCase
from six import BytesIO
from flask import json

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 = py27, py35
[testenv]
deps=-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands=
nosetests \
[]

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,13 @@
# ref: https://docs.travis-ci.com/user/languages/python
language: python
python:
- "3.2"
- "3.3"
- "3.4"
- "3.5"
#- "3.5-dev" # 3.5 development branch
#- "nightly" # points to the latest development branch e.g. 3.6-dev
# command to install dependencies
install: "pip install -r requirements.txt"
# command to run tests
script: nosetests

View File

@ -7,11 +7,11 @@ 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.
To run the server, please execute the following:
To run the server, please execute the following from the root directory:
```
sudo pip3 install -U connexion flask_testing # install Connexion from PyPI
python3 app.py
pip3 install -r requirements.txt
python3 -m swagger_server
```
and open your browser to here:
@ -26,3 +26,8 @@ Your Swagger definition lives here:
http://localhost:8080/v2/swagger.json
```
To launch the integration tests, use tox:
```
sudo pip install tox
tox
```

View File

@ -1,29 +0,0 @@
#!/usr/bin/env python3
import connexion
from connexion.decorators import produces
from six import iteritems
from models.base_model_ import Model
class JSONEncoder(produces.JSONEncoder):
include_nulls = False
def default(self, o):
if isinstance(o, Model):
dikt = {}
for attr, _ in 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 produces.JSONEncoder.default(self, o)
if __name__ == '__main__':
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = JSONEncoder
app.add_api('swagger.yaml', arguments={'title': 'This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.'})
app.run(port=8080)

View File

@ -0,0 +1,52 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update"
git_user_id=$1
git_repo_id=$2
release_note=$3
if [ "$git_user_id" = "" ]; then
git_user_id="GIT_USER_ID"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="GIT_REPO_ID"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="Minor update"
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
fi
# Initialize the local directory as a Git repository
git init
# Adds the files in the local repository and stages them for commit.
git add .
# Commits the tracked changes and prepares them to be pushed to a remote repository.
git commit -m "$release_note"
# Sets the new remote
git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
fi
fi
git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

View File

@ -0,0 +1,3 @@
connexion == 1.0.129
python_dateutil == 2.6.0
setuptools >= 21.0.0

View File

@ -0,0 +1,33 @@
# coding: utf-8
import sys
from setuptools import setup, find_packages
NAME = "swagger_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="Swagger Petstore",
author_email="apiteam@swagger.io",
url="",
keywords=["Swagger", "Swagger Petstore"],
install_requires=REQUIRES,
packages=find_packages(),
package_data={'': ['swagger/swagger.yaml']},
include_package_data=True,
long_description="""\
This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
"""
)

View File

@ -0,0 +1,11 @@
#!/usr/bin/env python3
import connexion
from .encoder import JSONEncoder
if __name__ == '__main__':
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = JSONEncoder
app.add_api('swagger.yaml', arguments={'title': 'This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.'})
app.run(port=8080)

View File

@ -1,10 +1,10 @@
import connexion
from models.api_response import ApiResponse
from models.pet import Pet
from swagger_server.models.api_response import ApiResponse
from swagger_server.models.pet import Pet
from datetime import date, datetime
from typing import List, Dict
from six import iteritems
from util import deserialize_date, deserialize_datetime
from ..util import deserialize_date, deserialize_datetime
def add_pet(body):

View File

@ -1,9 +1,9 @@
import connexion
from models.order import Order
from swagger_server.models.order import Order
from datetime import date, datetime
from typing import List, Dict
from six import iteritems
from util import deserialize_date, deserialize_datetime
from ..util import deserialize_date, deserialize_datetime
def delete_order(orderId):

View File

@ -1,9 +1,9 @@
import connexion
from models.user import User
from swagger_server.models.user import User
from datetime import date, datetime
from typing import List, Dict
from six import iteritems
from util import deserialize_date, deserialize_datetime
from ..util import deserialize_date, deserialize_datetime
def create_user(body):

View File

@ -0,0 +1,19 @@
from connexion.decorators import produces
from six import iteritems
from swagger_server.models.base_model_ import Model
class JSONEncoder(produces.JSONEncoder):
include_nulls = False
def default(self, o):
if isinstance(o, Model):
dikt = {}
for attr, _ in 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 produces.JSONEncoder.default(self, o)

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class ApiResponse(Model):

View File

@ -1,7 +1,7 @@
from pprint import pformat
from typing import TypeVar, Type
from six import iteritems
from util import deserialize_model
from ..util import deserialize_model
T = TypeVar('T')

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class Category(Model):

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class Order(Model):

View File

@ -1,12 +1,12 @@
# coding: utf-8
from __future__ import absolute_import
from models.category import Category
from models.tag import Tag
from swagger_server.models.category import Category
from swagger_server.models.tag import Tag
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class Pet(Model):

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class Tag(Model):

View File

@ -4,7 +4,7 @@ from __future__ import absolute_import
from .base_model_ import Model
from datetime import date, datetime
from typing import List, Dict
from util import deserialize_model
from ..util import deserialize_model
class User(Model):

View File

@ -58,7 +58,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
put:
tags:
- "pet"
@ -89,7 +89,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/pet/findByStatus:
get:
tags:
@ -127,7 +127,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/pet/findByTags:
get:
tags:
@ -161,7 +161,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/pet/{petId}:
get:
tags:
@ -190,7 +190,7 @@ paths:
description: "Pet not found"
security:
- api_key: []
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
post:
tags:
- "pet"
@ -226,7 +226,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
delete:
tags:
- "pet"
@ -254,7 +254,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/pet/{petId}/uploadImage:
post:
tags:
@ -292,7 +292,7 @@ paths:
- petstore_auth:
- "write:pets"
- "read:pets"
x-swagger-router-controller: "controllers.pet_controller"
x-swagger-router-controller: "swagger_server.controllers.pet_controller"
/store/inventory:
get:
tags:
@ -313,7 +313,7 @@ paths:
format: "int32"
security:
- api_key: []
x-swagger-router-controller: "controllers.store_controller"
x-swagger-router-controller: "swagger_server.controllers.store_controller"
/store/order:
post:
tags:
@ -338,7 +338,7 @@ paths:
$ref: "#/definitions/Order"
400:
description: "Invalid Order"
x-swagger-router-controller: "controllers.store_controller"
x-swagger-router-controller: "swagger_server.controllers.store_controller"
/store/order/{orderId}:
get:
tags:
@ -368,7 +368,7 @@ paths:
description: "Invalid ID supplied"
404:
description: "Order not found"
x-swagger-router-controller: "controllers.store_controller"
x-swagger-router-controller: "swagger_server.controllers.store_controller"
delete:
tags:
- "store"
@ -391,7 +391,7 @@ paths:
description: "Invalid ID supplied"
404:
description: "Order not found"
x-swagger-router-controller: "controllers.store_controller"
x-swagger-router-controller: "swagger_server.controllers.store_controller"
/user:
post:
tags:
@ -412,7 +412,7 @@ paths:
responses:
default:
description: "successful operation"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/createWithArray:
post:
tags:
@ -435,7 +435,7 @@ paths:
responses:
default:
description: "successful operation"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/createWithList:
post:
tags:
@ -458,7 +458,7 @@ paths:
responses:
default:
description: "successful operation"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/login:
get:
tags:
@ -496,7 +496,7 @@ paths:
description: "date in UTC when toekn expires"
400:
description: "Invalid username/password supplied"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/logout:
get:
tags:
@ -511,7 +511,7 @@ paths:
responses:
default:
description: "successful operation"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
/user/{username}:
get:
tags:
@ -537,7 +537,7 @@ paths:
description: "Invalid username supplied"
404:
description: "User not found"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
put:
tags:
- "user"
@ -564,7 +564,7 @@ paths:
description: "Invalid user supplied"
404:
description: "User not found"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
delete:
tags:
- "user"
@ -585,7 +585,7 @@ paths:
description: "Invalid username supplied"
404:
description: "User not found"
x-swagger-router-controller: "controllers.user_controller"
x-swagger-router-controller: "swagger_server.controllers.user_controller"
securityDefinitions:
petstore_auth:
type: "oauth2"

View File

@ -1,5 +1,5 @@
from flask_testing import TestCase
from app import JSONEncoder
from ..encoder import JSONEncoder
import connexion
import logging

View File

@ -2,8 +2,8 @@
from __future__ import absolute_import
from models.api_response import ApiResponse
from models.pet import Pet
from swagger_server.models.api_response import ApiResponse
from swagger_server.models.pet import Pet
from . import BaseTestCase
from six import BytesIO
from flask import json

View File

@ -2,7 +2,7 @@
from __future__ import absolute_import
from models.order import Order
from swagger_server.models.order import Order
from . import BaseTestCase
from six import BytesIO
from flask import json

View File

@ -2,7 +2,7 @@
from __future__ import absolute_import
from models.user import User
from swagger_server.models.user import User
from . import BaseTestCase
from six import BytesIO
from flask import json

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 \
[]