Skip to content

Commit c487176

Browse files
authored
Merge pull request #21 from python-microservices/feature/add-app-more-reusable
Add app more reusable
2 parents f0038e0 + 74afab3 commit c487176

File tree

4 files changed

+69
-24
lines changed

4 files changed

+69
-24
lines changed

pyms/config/conf.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,21 @@ class Config:
99
def __init__(self):
1010
pass
1111

12-
@property
13-
def config(self):
12+
def config(self, *args, **kwargs):
1413
"""Set the configuration, if our yaml file is like:
1514
myservice:
1615
myservice1:
1716
myvar1
1817
and we want to get the configuration of service1, our self.service will be "myservice.myservice1"
1918
"""
2019
if not self._config:
21-
self._config = ConfFile()
20+
self._config = ConfFile(*args, **kwargs)
2221
if not self.service:
2322
raise ServiceDoesNotExistException("Service not defined")
2423
return getattr(self._config, self.service)
2524

2625

27-
def get_conf(service=None):
26+
def get_conf(service=None, *args, **kwargs):
2827
config = Config()
2928
config.service = service
30-
return config.config
29+
return config.config(*args, **kwargs)

pyms/config/confile.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""Module to read yaml or json conf"""
22
import logging
33
import os
4-
54
from typing import Text
65

76
import anyconfig
@@ -13,16 +12,23 @@
1312

1413

1514
class ConfFile(dict):
15+
empty_init = False
16+
1617
def __init__(self, *args, **kwargs):
1718
"""
1819
Get configuration from a dictionary(variable `config`), from path (variable `path`) or from
1920
environment with the constant `CONFIGMAP_FILE_ENVIRONMENT`
2021
"""
21-
22-
config = kwargs.get("config") or self._get_conf_from_file(kwargs.get("path")) or self._get_conf_from_env()
22+
self.empty_init = kwargs.get("empty_init", False)
23+
config = kwargs.get("config")
24+
if config is None:
25+
config = self._get_conf_from_file(kwargs.get("path")) or self._get_conf_from_env()
2326

2427
if not config:
25-
raise ConfigDoesNotFoundException("Configuration file not found")
28+
if self.empty_init:
29+
config = {}
30+
else:
31+
raise ConfigDoesNotFoundException("Configuration file not found")
2632

2733
logger.debug("[CONF] INIT: Settings {kwargs}".format(
2834
kwargs=kwargs,
@@ -35,7 +41,7 @@ def __init__(self, *args, **kwargs):
3541
def normalize_config(self, config):
3642
for key, item in config.items():
3743
if isinstance(item, dict):
38-
item = ConfFile(config=item)
44+
item = ConfFile(config=item, empty_init=self.empty_init)
3945
yield self.normalize_keys(key), item
4046

4147
def normalize_keys(self, key):
@@ -51,7 +57,10 @@ def __getattr__(self, name, *args, **kwargs):
5157
aux_dict = aux_dict[k]
5258
return aux_dict
5359
except KeyError:
54-
raise AttrDoesNotExistException("Variable {} not exist in the config file".format(name))
60+
if self.empty_init:
61+
return ConfFile(config={}, empty_init=self.empty_init)
62+
else:
63+
raise AttrDoesNotExistException("Variable {} not exist in the config file".format(name))
5564

5665
def _get_conf_from_env(self):
5766
file = os.environ.get(CONFIGMAP_FILE_ENVIRONMENT)

pyms/flask/app/__init__.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@ def __init__(self, service: Text, path=__file__):
2222
def init_libs(self):
2323
return self.application
2424

25+
def init_tracer(self):
26+
self.application.tracer = FlaskTracer(init_jaeger_tracer(), True, self.application)
27+
28+
def init_logger(self):
29+
formatter = CustomJsonFormatter('(timestamp) (level) (name) (module) (funcName) (lineno) (message)')
30+
formatter.add_service_name(self.application.config["APP_NAME"])
31+
if getattr(self.application, "tracer", False):
32+
formatter.add_trace_span(self.application.tracer)
33+
log_handler = logging.StreamHandler()
34+
log_handler.setFormatter(formatter)
35+
self.application.logger.addHandler(log_handler)
36+
self.application.logger.propagate = False
37+
self.application.logger.setLevel(logging.INFO)
38+
2539
def create_app(self):
2640
"""Initialize the Flask app, register blueprints and initialize
2741
all libraries like Swagger, database,
@@ -47,18 +61,10 @@ def create_app(self):
4761
self.init_libs()
4862
self.add_error_handlers()
4963

50-
# Inject Modules
51-
formatter = CustomJsonFormatter('(timestamp) (level) (name) (module) (funcName) (lineno) (message)')
5264
if not self.application.config["TESTING"]:
53-
log_handler = logging.StreamHandler()
65+
self.init_tracer()
5466

55-
self.application.tracer = FlaskTracer(init_jaeger_tracer(), True, self.application)
56-
formatter.add_service_name(self.application.config["APP_NAME"])
57-
formatter.add_trace_span(self.application.tracer)
58-
log_handler.setFormatter(formatter)
59-
self.application.logger.addHandler(log_handler)
60-
self.application.logger.propagate = False
61-
self.application.logger.setLevel(logging.INFO)
67+
self.init_logger()
6268

6369
return self.application
6470

@@ -74,5 +80,4 @@ def add_error_handler(self, code_or_exception, handler):
7480
:param code_or_exception: HTTP error code or exception
7581
:param handler: callback for error handler
7682
"""
77-
7883
self.application._connexion_app.add_error_handler(code_or_exception, handler)

tests/tests_config.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import logging
2+
import os
23
import unittest
34

4-
import os
5+
from pyms.config.conf import Config
6+
57
from pyms.config.confile import ConfFile
6-
from pyms.exceptions import AttrDoesNotExistException, ConfigDoesNotFoundException
78
from pyms.constants import CONFIGMAP_FILE_ENVIRONMENT, LOGGER_NAME
9+
from pyms.exceptions import AttrDoesNotExistException, ConfigDoesNotFoundException, ServiceDoesNotExistException
810

911
logger = logging.getLogger(LOGGER_NAME)
1012

@@ -66,3 +68,33 @@ def test_example_test_yaml_file(self):
6668
def test_example_test_json_file(self):
6769
config = ConfFile(path=os.path.join(self.BASE_DIR, "config-tests.json"))
6870
self.assertEqual(config.my_ms.test_var, "general")
71+
72+
73+
class ConfServiceTests(unittest.TestCase):
74+
75+
def test_config_with_service(self):
76+
class MyService(Config):
77+
service = "service"
78+
79+
config = MyService()
80+
configuration = config.config(config={"service": {"service1": "a", "service2": "b"}})
81+
self.assertEqual(configuration.service1, "a")
82+
83+
def test_config_with_service_not_exist(self):
84+
config = Config()
85+
with self.assertRaises(ServiceDoesNotExistException):
86+
configuration = config.config(config={"service": {"service1": "a", "service2": "b"}})
87+
88+
89+
class ConfNotExistTests(unittest.TestCase):
90+
def test_empty_conf(self):
91+
config = ConfFile(empty_init=True)
92+
self.assertEqual(config.my_ms, {})
93+
94+
def test_empty_conf_two_levels(self):
95+
config = ConfFile(empty_init=True)
96+
self.assertEqual(config.my_ms.level_two, {})
97+
98+
def test_empty_conf_three_levels(self):
99+
config = ConfFile(empty_init=True)
100+
self.assertEqual(config.my_ms.level_two.level_three, {})

0 commit comments

Comments
 (0)