Skip to content

Commit 8d25eaa

Browse files
authored
Acces to config out of Flask context (#55)
* Create Microservice class with singleton to import config in any file * Updated doc and examples * Updated dependencies * Updated tests dependencies * increment version
1 parent 1d42abe commit 8d25eaa

File tree

20 files changed

+488
-333
lines changed

20 files changed

+488
-333
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ pylintReport.txt
2222

2323
# Deploy
2424
build/
25-
dist/
25+
dist/
26+
27+
# other
28+
site/*

Pipfile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ verify_ssl = true
44
name = "pypi"
55

66
[packages]
7-
flask = "*"
7+
flask = ">=1.1.1"
88
python-json-logger = ">=0.1.10"
9-
pyyaml = ">=4.2b4"
9+
pyyaml = ">=5.1.2"
1010
anyconfig = ">=0.9.8"
1111
swagger-ui-bundle = ">=0.0.2"
1212
connexion = {extras = ["swagger-ui"],version = ">=2.2.0"}
13-
lightstep = "*"
13+
lightstep = "==4.1.0"
1414
flask-opentracing = "*"
15+
opentracing = ">=2.0.0"
1516

1617
[dev-packages]
1718
requests-mock = "*"

Pipfile.lock

Lines changed: 120 additions & 115 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/configuration.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
# Configuration
22

3+
## Create configuration
34
Each microservice needs a config file in yaml or json format to work with it. This configuration contains
4-
the Flask settings of your project and the [Services](services.md).
5+
the Flask settings of your project and the [Services](services.md). With this way to create configuration files, we
6+
solve two problems of the [12 Factor apps](https://12factor.net/):
7+
- Store config out of the code
8+
- Dev/prod parity: the configuration could be injected and not depends of our code, for example, Kubernetes config maps
59

610
a simple configuration file could be a config.yaml:
711

@@ -91,3 +95,51 @@ ms1-api:
9195
DEBUG: true
9296
TESTING: false
9397
```
98+
99+
## Import Configuration
100+
With pyms, all configuration is stored as flask configuration and it can be acceded from:
101+
102+
```python
103+
from flask import current_app;
104+
105+
def my_endpoint():
106+
print(current_app.config["DEBUG"])
107+
```
108+
109+
But, what happend if you need the configuration BEFORE Flask class is instanced? Imagine this case:
110+
111+
```python
112+
from flask import Blueprint, current_app
113+
from flask_restplus import Api
114+
115+
my_api_blueprint = Blueprint('api', __name__)
116+
117+
API = Api(
118+
my_api_blueprint,
119+
title='My Microservice',
120+
version=current_app.config["APP_VERSION"],
121+
description='Microservice to manage hierarchies',
122+
add_specs=True,
123+
)
124+
```
125+
126+
This raise a `'working outside of application context` error. Who can solve this problem?
127+
128+
```python
129+
from flask import Blueprint, current_app
130+
from flask_restplus import Api
131+
from pyms.flask.app import config
132+
133+
my_api_blueprint = Blueprint('api', __name__)
134+
135+
API = Api(
136+
my_api_blueprint,
137+
title='My Microservice',
138+
version=config().APP_VERSION,
139+
description='Microservice to manage hierarchies',
140+
add_specs=True,
141+
)
142+
```
143+
144+
**IMPORTANT:** If you use this method to get configuration out of context, you must set the `CONFIGMAP_SERVICE` or set
145+
the default key `ms` for your configuration block in your config.yml

examples/__init__.py

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from pyms.flask.app import Microservice
2+
3+
ms = Microservice(path=__file__)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
pyms:
2+
requests:
3+
data: ""
4+
swagger:
5+
path: ""
6+
file: "swagger.yaml"
7+
my-configure-microservice:
8+
DEBUG: true
9+
TESTING: false
10+
APP_NAME: "Python Microservice"
11+
APPLICATION_ROOT: ""
12+
request_variable_test: "this is a test"
13+
MyVar: "this is MyVar"
14+
test1: "ttest1"
15+
test2: "ttest2"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from examples.microservice_configuration import ms
2+
app = ms.create_app()
3+
4+
if __name__ == '__main__':
5+
"""
6+
run first:
7+
export CONFIGMAP_SERVICE=my-configure-microservice
8+
"""
9+
app.run()
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
swagger: "2.0"
3+
info:
4+
description: "This is a sample server Test server"
5+
version: "1.0.0"
6+
title: "Swagger Test list"
7+
termsOfService: "http://swagger.io/terms/"
8+
contact:
9+
email: "apiteam@swagger.io"
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+
get:
31+
tags:
32+
- "test"
33+
summary: "Example endpoint"
34+
description: ""
35+
operationId: "examples.microservice_configuration.views.example"
36+
consumes:
37+
- "application/json"
38+
produces:
39+
- "application/json"
40+
responses:
41+
200:
42+
description: "A list of colors (may be filtered by palette)"
43+
schema:
44+
$ref: '#/definitions/Example'
45+
405:
46+
description: "Invalid input"
47+
definitions:
48+
Example:
49+
type: "object"
50+
properties:
51+
main:
52+
type: "string"
53+
externalDocs:
54+
description: "Find out more about Swagger"
55+
url: "http://swagger.io"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from pyms.flask.app import config
2+
3+
GLOBAL_VARIABLE = config().request_variable_test
4+
GLOBAL_VARIABLE2 = config().MyVar
5+
6+
7+
def example():
8+
return {
9+
"GLOBAL_VARIABLE": GLOBAL_VARIABLE,
10+
"GLOBAL_VARIABLE2": GLOBAL_VARIABLE2,
11+
"test1": config().test1,
12+
"test2": config().test2
13+
}

0 commit comments

Comments
 (0)