Skip to content

Commit

Permalink
Acces to config out of Flask context (#55)
Browse files Browse the repository at this point in the history
* Create Microservice class with singleton to import config in any file

* Updated doc and examples

* Updated dependencies

* Updated tests dependencies

* increment version
  • Loading branch information
avara1986 authored Aug 30, 2019
1 parent 1d42abe commit 8d25eaa
Show file tree
Hide file tree
Showing 20 changed files with 488 additions and 333 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ pylintReport.txt

# Deploy
build/
dist/
dist/

# other
site/*
7 changes: 4 additions & 3 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ verify_ssl = true
name = "pypi"

[packages]
flask = "*"
flask = ">=1.1.1"
python-json-logger = ">=0.1.10"
pyyaml = ">=4.2b4"
pyyaml = ">=5.1.2"
anyconfig = ">=0.9.8"
swagger-ui-bundle = ">=0.0.2"
connexion = {extras = ["swagger-ui"],version = ">=2.2.0"}
lightstep = "*"
lightstep = "==4.1.0"
flask-opentracing = "*"
opentracing = ">=2.0.0"

[dev-packages]
requests-mock = "*"
Expand Down
235 changes: 120 additions & 115 deletions Pipfile.lock

Large diffs are not rendered by default.

54 changes: 53 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# Configuration

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

a simple configuration file could be a config.yaml:

Expand Down Expand Up @@ -91,3 +95,51 @@ ms1-api:
DEBUG: true
TESTING: false
```

## Import Configuration
With pyms, all configuration is stored as flask configuration and it can be acceded from:

```python
from flask import current_app;
def my_endpoint():
print(current_app.config["DEBUG"])
```

But, what happend if you need the configuration BEFORE Flask class is instanced? Imagine this case:

```python
from flask import Blueprint, current_app
from flask_restplus import Api
my_api_blueprint = Blueprint('api', __name__)
API = Api(
my_api_blueprint,
title='My Microservice',
version=current_app.config["APP_VERSION"],
description='Microservice to manage hierarchies',
add_specs=True,
)
```

This raise a `'working outside of application context` error. Who can solve this problem?

```python
from flask import Blueprint, current_app
from flask_restplus import Api
from pyms.flask.app import config
my_api_blueprint = Blueprint('api', __name__)
API = Api(
my_api_blueprint,
title='My Microservice',
version=config().APP_VERSION,
description='Microservice to manage hierarchies',
add_specs=True,
)
```

**IMPORTANT:** If you use this method to get configuration out of context, you must set the `CONFIGMAP_SERVICE` or set
the default key `ms` for your configuration block in your config.yml
Empty file added examples/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions examples/microservice_configuration/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from pyms.flask.app import Microservice

ms = Microservice(path=__file__)
15 changes: 15 additions & 0 deletions examples/microservice_configuration/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pyms:
requests:
data: ""
swagger:
path: ""
file: "swagger.yaml"
my-configure-microservice:
DEBUG: true
TESTING: false
APP_NAME: "Python Microservice"
APPLICATION_ROOT: ""
request_variable_test: "this is a test"
MyVar: "this is MyVar"
test1: "ttest1"
test2: "ttest2"
9 changes: 9 additions & 0 deletions examples/microservice_configuration/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from examples.microservice_configuration import ms
app = ms.create_app()

if __name__ == '__main__':
"""
run first:
export CONFIGMAP_SERVICE=my-configure-microservice
"""
app.run()
55 changes: 55 additions & 0 deletions examples/microservice_configuration/swagger.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
swagger: "2.0"
info:
description: "This is a sample server Test server"
version: "1.0.0"
title: "Swagger Test list"
termsOfService: "http://swagger.io/terms/"
contact:
email: "[email protected]"
license:
name: "Apache 2.0"
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
tags:
- name: "colors"
description: "Everything about your colors"
externalDocs:
description: "Find out more"
url: "http://swagger.io"
- name: "store"
description: "Example endpoint list of colors"
- name: "user"
description: "Operations about user"
externalDocs:
description: "Find out more about our store"
url: "http://swagger.io"
schemes:
- "http"
paths:
/:
get:
tags:
- "test"
summary: "Example endpoint"
description: ""
operationId: "examples.microservice_configuration.views.example"
consumes:
- "application/json"
produces:
- "application/json"
responses:
200:
description: "A list of colors (may be filtered by palette)"
schema:
$ref: '#/definitions/Example'
405:
description: "Invalid input"
definitions:
Example:
type: "object"
properties:
main:
type: "string"
externalDocs:
description: "Find out more about Swagger"
url: "http://swagger.io"
13 changes: 13 additions & 0 deletions examples/microservice_configuration/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from pyms.flask.app import config

GLOBAL_VARIABLE = config().request_variable_test
GLOBAL_VARIABLE2 = config().MyVar


def example():
return {
"GLOBAL_VARIABLE": GLOBAL_VARIABLE,
"GLOBAL_VARIABLE2": GLOBAL_VARIABLE2,
"test1": config().test1,
"test2": config().test2
}
4 changes: 3 additions & 1 deletion examples/microservice_requests/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from examples.microservice_requests import ms
from flask import current_app

from examples.microservice_requests import ms


def example():
current_app.logger.info("start request")
result = ms.requests.get_for_object("https://ghibliapi.herokuapp.com/films/2baf70d1-42bb-4437-b551-e5fed5a87abe")
Expand Down
74 changes: 1 addition & 73 deletions pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -54,79 +54,7 @@ confidence=
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=print-statement,
parameter-unpacking,
unpacking-in-except,
old-raise-syntax,
backtick,
long-suffix,
old-ne-operator,
old-octal-literal,
import-star-module-level,
non-ascii-bytes-literal,
raw-checker-failed,
bad-inline-option,
locally-disabled,
locally-enabled,
file-ignored,
suppressed-message,
useless-suppression,
deprecated-pragma,
apply-builtin,
basestring-builtin,
buffer-builtin,
cmp-builtin,
coerce-builtin,
execfile-builtin,
file-builtin,
long-builtin,
raw_input-builtin,
reduce-builtin,
standarderror-builtin,
unicode-builtin,
xrange-builtin,
coerce-method,
delslice-method,
getslice-method,
setslice-method,
no-absolute-import,
old-division,
dict-iter-method,
dict-view-method,
next-method-called,
metaclass-assignment,
indexing-exception,
raising-string,
reload-builtin,
oct-method,
hex-method,
nonzero-method,
cmp-method,
input-builtin,
round-builtin,
intern-builtin,
unichr-builtin,
map-builtin-not-iterating,
zip-builtin-not-iterating,
range-builtin-not-iterating,
filter-builtin-not-iterating,
using-cmp-argument,
eq-without-hash,
div-method,
idiv-method,
rdiv-method,
exception-message-attribute,
invalid-str-codec,
sys-max-int,
bad-python3-import,
deprecated-string-function,
deprecated-str-translate-call,
deprecated-itertools-function,
deprecated-types-field,
next-method-defined,
dict-items-not-iterating,
dict-keys-not-iterating,
dict-values-not-iterating
disable=C0301

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
Expand Down
2 changes: 1 addition & 1 deletion pyms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

__email__ = "[email protected]"

__version__ = "1.0.3"
__version__ = "1.1.0"
1 change: 1 addition & 0 deletions pyms/constants.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
CONFIGMAP_FILE_ENVIRONMENT = "CONFIGMAP_FILE"
SERVICE_ENVIRONMENT = "CONFIGMAP_SERVICE"

LOGGER_NAME = "pyms"

Expand Down
Loading

0 comments on commit 8d25eaa

Please sign in to comment.