Skip to content

Commit 0b183f9

Browse files
committed
Merge branch 'feature/added_connexion' into develop
2 parents ec2e9e3 + c7d388d commit 0b183f9

File tree

10 files changed

+164
-200
lines changed

10 files changed

+164
-200
lines changed

docs/configuration.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Documentation
1717
The Microservice create a URL to inspect the Swagger documentation of the api in:
1818

1919
.. code-block:: bash
20-
localhost:5000/[APPLICATION_ROOT]/apidocs/
20+
localhost:5000/[APPLICATION_ROOT]/ui/
2121
22-
Our API Rest work with `Flasgger <https://github.com/rochacbruno/flasgger>`_. You can see Flasgger docs or the official
22+
Our API Rest work with `connexion <http://connexion.readthedocs.io>`_. You can see connexion docs or the official
2323
`Swagger documentation <https://swagger.io/specification/>`_ to add the syntax to your APIS and create your Swagger docs

docs/index.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ Python Microservices
77

88
Stack
99
-----
10+
* `connexion <http://connexion.readthedocs.io>`_
1011
* `Flask <https://github.com/pallets/flask>`_
1112
* `SQLAlchemy <https://www.sqlalchemy.org/>`_
1213
* `Flask-SQLAlchemy <http://flask-sqlalchemy.pocoo.org/2.3/>`_
13-
* `Flasgger <https://github.com/rochacbruno/flasgger>`_
14+
* `Flask-Injector <https://github.com/alecthomas/flask_injector>`_
1415
* `Flask-Script <https://flask-script.readthedocs.io/en/latest/>`_
16+
* `Opentracing <https://github.com/opentracing-contrib/python-flask>`_
1517

1618

1719
Content

docs/structure.rst

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,18 @@ You have a project with this structure:
2323
project
2424
├ __init__.py
2525
├ config.py
26-
├ views
27-
│ ├ __init__.py
28-
│ └ views.py
2926
├ models
3027
│ ├ __init__.py
3128
│ └ models.py
32-
└ tests
33-
└ test_views.py
29+
├ swagger
30+
│ └ swagger.yaml
31+
├ tests
32+
│ └ test_views.py
33+
└views
34+
├ __init__.py
35+
└ views.py
36+
37+
3438
3539
manager.py
3640
----------
@@ -80,6 +84,10 @@ See :doc:`configuration </configuration>` section
8084

8185
project/views
8286
~~~~~~~~~~~~~
83-
use views.py or create your file. You must add after register the view blueprint in `project/views/__init__.py`.
87+
use views.py or create your file.
88+
89+
swagger/swagger.yaml
90+
~~~~~~~~~~~~~
91+
Use to define your rest behaviour, endpoints and routes. See `connexion <http://connexion.readthedocs.io>`_ docs to how add new views
8492

8593

project/__init__.py

Lines changed: 19 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import logging
44
import os
55

6-
from flasgger import Swagger
7-
from flask import Flask
6+
import connexion
87
from flask_injector import FlaskInjector
98
from injector import Injector
109

@@ -23,109 +22,42 @@
2322

2423
ENVIRONMENT = os.environ.get("ENVIRONMENT", "default")
2524

26-
SWAGGER_CONFIG = {
27-
"headers": [
28-
],
29-
"specs": [
30-
{
31-
"endpoint": 'apispec_1',
32-
"route": '{application_root}/apispec_1.json',
33-
"rule_filter": lambda rule: True, # all in
34-
"model_filter": lambda tag: True, # all in
35-
}
36-
],
37-
"info": {
38-
"title": "API ",
39-
"description": "API para...",
40-
"contact": {
41-
"responsibleOrganization": "ME",
42-
"responsibleDeveloper": "Me",
43-
"email": "[email protected]",
44-
},
45-
"version": "0.0.1"
46-
},
47-
"securityDefinitions": {
48-
"APIKeyHeader": {"type": "apiKey", "name": "Authorization", "in": "header"},
49-
},
50-
"static_url_path": "{application_root}/flasgger_static",
51-
"swagger_ui": True,
52-
"uiversion": 2,
53-
"specs_route": "/apidocs/",
54-
"basePath": "{application_root}"
55-
}
56-
57-
58-
class PrefixMiddleware(object):
59-
"""Set a prefix path to all routes. This action is needed if you have a stack of microservices and each of them
60-
exist in the same domain but different path. Por example:
61-
* mydomain.com/ms1/
62-
* mydomain.com/ms2/
63-
"""
64-
65-
def __init__(self, app, prefix=''):
66-
self.app = app
67-
self.prefix = prefix
68-
69-
def __call__(self, environ, start_response):
70-
if environ['PATH_INFO'].startswith(self.prefix):
71-
environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
72-
environ['SCRIPT_NAME'] = self.prefix
73-
return self.app(environ, start_response)
74-
elif environ['PATH_INFO'].startswith("/healthcheck"):
75-
return self.app(environ, start_response)
76-
else:
77-
start_response('404', [('Content-Type', 'text/plain')])
78-
return ["This url does not belong to the app.".encode()]
79-
8025

8126
def create_app():
8227
"""Initialize the Flask app, register blueprints and intialize all libraries like Swagger, database, the trace system...
8328
return the app and the database objects.
8429
:return:
8530
"""
86-
87-
from project.views import views_bp as views_blueprint
8831
environment = os.environ.get("ENVIRONMENT", "default")
8932

90-
app = Flask(__name__)
91-
app.config.from_object(CONFIG[environment])
92-
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix=app.config["APPLICATION_ROOT"])
33+
app = connexion.App(__name__, specification_dir='./swagger/')
34+
# app.app.json_encoder = encoder.JSONEncoder
9335

94-
db.init_app(app)
36+
app.add_api('swagger.yaml',
37+
arguments={'title': 'Swagger Example Project'},
38+
base_path=CONFIG[environment].APPLICATION_ROOT)
9539

96-
# Initialize Swagger
97-
SWAGGER_CONFIG["specs"][0]["route"] = SWAGGER_CONFIG["specs"][0]["route"].format(
98-
application_root=app.config["APPLICATION_ROOT"]
99-
)
100-
SWAGGER_CONFIG["static_url_path"] = SWAGGER_CONFIG["static_url_path"].format(
101-
application_root=app.config["APPLICATION_ROOT"]
102-
)
103-
SWAGGER_CONFIG["specs_route"] = SWAGGER_CONFIG["specs_route"].format(
104-
application_root=app.config["APPLICATION_ROOT"]
105-
)
106-
SWAGGER_CONFIG["basePath"] = SWAGGER_CONFIG["basePath"].format(
107-
application_root=app.config["APPLICATION_ROOT"]
108-
)
109-
Swagger(app, config=SWAGGER_CONFIG)
40+
application = app.app
41+
application.config.from_object(CONFIG[environment])
42+
db.init_app(application)
11043

11144
# Initialize Blueprints
112-
app.register_blueprint(views_blueprint)
113-
app.register_blueprint(healthcheck_blueprint)
45+
application.register_blueprint(healthcheck_blueprint)
11446

11547
# Inject Modules
116-
# Inject Modules
117-
if not app.config["TESTING"] and not app.config["DEBUG"]:
48+
if not application.config["TESTING"] and not application.config["DEBUG"]:
11849
log_handler = logging.StreamHandler()
11950
formatter = CustomJsonFormatter('(timestamp) (level) (name) (module) (funcName) (lineno) (message)')
120-
formatter.add_service_name(app.config["APP_NAME"])
121-
tracer = TracerModule(app)
51+
formatter.add_service_name(application.config["APP_NAME"])
52+
tracer = TracerModule(application)
12253
injector = Injector([tracer])
123-
FlaskInjector(app=app, injector=injector)
54+
FlaskInjector(app=application, injector=injector)
12455
formatter.add_trace_span(tracer.tracer)
12556
log_handler.setFormatter(formatter)
126-
app.logger.addHandler(log_handler)
127-
app.logger.setLevel(logging.INFO)
57+
application.logger.addHandler(log_handler)
58+
application.logger.setLevel(logging.INFO)
12859

129-
with app.test_request_context():
60+
with application.test_request_context():
13061
db.create_all()
131-
return app, db
62+
63+
return application, db

project/swagger/swagger.yaml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
swagger: "2.0"
3+
info:
4+
description: "This is a sample server Color 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."
5+
version: "1.0.0"
6+
title: "Swagger Color list"
7+
termsOfService: "http://swagger.io/terms/"
8+
contact:
9+
10+
license:
11+
name: "Apache 2.0"
12+
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
13+
tags:
14+
- name: "colors"
15+
description: "Everything about your colors"
16+
externalDocs:
17+
description: "Find out more"
18+
url: "http://swagger.io"
19+
- name: "store"
20+
description: "Example endpoint list of colors"
21+
- name: "user"
22+
description: "Operations about user"
23+
externalDocs:
24+
description: "Find out more about our store"
25+
url: "http://swagger.io"
26+
schemes:
27+
- "http"
28+
paths:
29+
/:
30+
post:
31+
tags:
32+
- "colors"
33+
summary: "Example endpoint return create a color"
34+
description: ""
35+
operationId: "create_view"
36+
consumes:
37+
- "application/json"
38+
produces:
39+
- "application/json"
40+
parameters:
41+
- in: "body"
42+
name: "name"
43+
description: "Pet object that needs to be added to the store"
44+
required: true
45+
schema:
46+
$ref: "#/definitions/Color"
47+
responses:
48+
200:
49+
description: "The color created"
50+
schema:
51+
$ref: '#/definitions/Color'
52+
405:
53+
description: "Invalid input"
54+
x-swagger-router-controller: "project.views.views"
55+
get:
56+
tags:
57+
- "colors"
58+
summary: "Example endpoint return a list of colors by palette"
59+
description: ""
60+
operationId: "list_view"
61+
consumes:
62+
- "application/json"
63+
produces:
64+
- "application/json"
65+
responses:
66+
200:
67+
description: "A list of colors (may be filtered by palette)"
68+
schema:
69+
$ref: '#/definitions/Color'
70+
400:
71+
description: "Invalid ID supplied"
72+
404:
73+
description: "Pet not found"
74+
405:
75+
description: "Validation exception"
76+
x-swagger-router-controller: "project.views.views"
77+
definitions:
78+
Color:
79+
type: "object"
80+
properties:
81+
id:
82+
type: "string"
83+
timestamp:
84+
type: "string"
85+
name:
86+
type: "string"
87+
externalDocs:
88+
description: "Find out more about Swagger"
89+
url: "http://swagger.io"

project/tests/test_views.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ def test_list_view(self):
3636

3737
def test_create_view(self):
3838
name = "blue"
39-
response = self.client.post('{base_url}/'.format(base_url=self.base_url), data={"name": name})
39+
response = self.client.post('{base_url}/'.format(
40+
base_url=self.base_url),
41+
data=json.dumps(dict(name=name)),
42+
content_type='application/json'
43+
)
4044
self.assertEqual(response.status_code, 200)
4145
self.assertEqual(_format_response(response.data)["name"], name)

project/views/__init__.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,2 @@
11
# coding=utf-8
2-
from __future__ import unicode_literals, print_function, absolute_import, division
3-
4-
from flask import Blueprint
5-
6-
views_bp = Blueprint('views', __name__, static_url_path='/static')
7-
8-
from project.views import views
2+
from __future__ import unicode_literals, print_function, absolute_import, division

0 commit comments

Comments
 (0)