Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 153 #387

Merged
merged 12 commits into from
May 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ io.swagger.codegen.v3.generators.kotlin.KotlinClientCodegen
io.swagger.codegen.v3.generators.kotlin.KotlinServerCodegen
io.swagger.codegen.v3.generators.php.PhpClientCodegen
io.swagger.codegen.v3.generators.python.PythonClientCodegen
io.swagger.codegen.v3.generators.python.PythonFlaskConnexionCodegen
io.swagger.codegen.v3.generators.scala.ScalaClientCodegen
io.swagger.codegen.v3.generators.scala.AkkaHttpServerCodegen
io.swagger.codegen.v3.generators.swift.Swift3Codegen
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{{#supportPython2}}
FROM python:2-alpine
{{/supportPython2}}
{{^supportPython2}}
FROM python:3-alpine
{{/supportPython2}}

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY requirements.txt /usr/src/app/

{{#supportPython2}}
RUN pip install --no-cache-dir -r requirements.txt
{{/supportPython2}}
{{^supportPython2}}
RUN pip3 install --no-cache-dir -r requirements.txt
{{/supportPython2}}

COPY . /usr/src/app

EXPOSE {{serverPort}}

{{#supportPython2}}
ENTRYPOINT ["python"]
{{/supportPython2}}
{{^supportPython2}}
ENTRYPOINT ["python3"]
{{/supportPython2}}

CMD ["-m", "{{packageName}}"]
60 changes: 60 additions & 0 deletions src/main/resources/handlebars/pythonFlaskConnexion/README.mustache
Original file line number Diff line number Diff line change
@@ -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}}
```
Empty file.
Original file line number Diff line number Diff line change
@@ -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}}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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}}'}, pythonic_params=True)
app.run(port={{serverPort}})


if __name__ == '__main__':
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import List
"""
controller generated to handled auth operation described at:
https://connexion.readthedocs.io/en/latest/security.html
"""
{{#authMethods}}
{{#isApiKey}}
def check_{{name}}(api_key, required_scopes):
return {'test_key': 'test_value'}

{{/isApiKey}}
{{#isBasic}}
def check_{{name}}(username, password, required_scopes):
return {'test_key': 'test_value'}

{{/isBasic}}
{{#isBearer}}
def check_{{name}}(token):
return {'test_key': 'test_value'}

{{/isBearer}}
{{#isOAuth}}
def check_{{name}}(token):
return {'scopes': ['read:pets', 'write:pets'], 'uid': 'test_value'}

def validate_scope_{{name}}(required_scopes, token_scopes):
return set(required_scopes).issubset(set(token_scopes))

{{/isOAuth}}
{{/authMethods}}

Original file line number Diff line number Diff line change
@@ -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
112 changes: 112 additions & 0 deletions src/main/resources/handlebars/pythonFlaskConnexion/controller.mustache
Original file line number Diff line number Diff line change
@@ -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}}: {{>param_type}}
{{/isPrimitiveType}}
{{#isUuid}}
:type {{paramName}}: {{>param_type}}
{{/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[{{>param_type}}]
{{/isPrimitiveType}}
{{^isPrimitiveType}}
:type {{paramName}}: list | bytes
{{/isPrimitiveType}}
{{/items}}
{{/isListContainer}}
{{#isMapContainer}}
{{#items}}
{{#isPrimitiveType}}
:type {{paramName}}: Dict[str, {{>param_type}}]
{{/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}}
Loading