Skip to content

Commit 0172e0b

Browse files
committed
Added docs
1 parent ef03c6b commit 0172e0b

File tree

106 files changed

+30240
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+30240
-0
lines changed

.gitignore

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
venv
2+
.python-version
3+
.idea
4+
*__pycache__*
5+
*.pyc
6+
tmp
7+
*.sqlite3
8+
9+
# Test&converage
10+
htmlcov/
11+
coverage.xml
12+
nosetests.xml
13+
.coverage
14+
.tox
15+
py_ms.egg-info/*
16+
.eggs/*
17+
pylintReport.txt
18+
.scannerwork/
19+
.mypy_cache
20+
21+
# Deploy
22+
build/
23+
dist/

.readthedocs.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# .readthedocs.yml
2+
# Read the Docs configuration file
3+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4+
5+
# Required
6+
version: 2
7+
8+
# Build documentation in the docs/ directory with Sphinx
9+
#sphinx:
10+
# configuration: docs/conf.py
11+
12+
# Build documentation with MkDocs
13+
mkdocs:
14+
configuration: mkdocs.yml
15+
16+
# Optionally build your docs in additional formats such as PDF and ePub
17+
formats: all
18+
19+
# Optionally set the version of Python and requirements required to build your docs
20+
python:
21+
version: 3.7
22+
install:
23+
- requirements: docs/requirements.txt

Pipfile

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[[source]]
2+
name = "pypi"
3+
url = "https://pypi.org/simple"
4+
verify_ssl = true
5+
6+
[dev-packages]
7+
8+
[packages]
9+
mkdocs = ">=1.1.2"
10+
mkdocs-material = ">=6.0.0"

Pipfile.lock

+286
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/command_line.md

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Commnand line
2+
3+
PyMS comes with some commands to make your developments easier:
4+
5+
```bash
6+
pyms -h
7+
```
8+
Lists the options and help instructions to use this command:
9+
10+
```bash
11+
usage: main.py [-h] [-v VERBOSE]
12+
{encrypt,create-key,startproject,merge-swagger} ...
13+
14+
Python Microservices
15+
16+
optional arguments:
17+
-h, --help show this help message and exit
18+
-v VERBOSE, --verbose VERBOSE
19+
Verbose
20+
21+
Commands:
22+
Available commands
23+
24+
{encrypt,create-key,startproject,merge-swagger}
25+
encrypt Encrypt a string
26+
create-key Generate a Key to encrypt strings in config
27+
startproject Generate a project from https://github.com/python-
28+
microservices/microservices-template
29+
merge-swagger Merge swagger into a single file
30+
31+
```
32+
33+
## Start a project
34+
35+
Command:
36+
```bash
37+
pyms startproject
38+
```
39+
40+
This command creates a project template like the one defined in [Microservices Scaffold](https://github.com/python-microservices/microservices-scaffold).
41+
This command uses [cookiecutter](https://github.com/cookiecutter/cookiecutter) to download and install this [template](https://github.com/python-microservices/microservices-template)
42+
43+
!!! warning
44+
First, you must run `pip install cookiecutter==1.7.0`
45+
46+
## Create a key encrypt/decrypt file
47+
48+
Command:
49+
```bash
50+
pyms create-key
51+
```
52+
53+
Create a key file to encrypt strings in your configuration file. This key is created with [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard).
54+
You can run the next command in the terminal. See [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md)
55+
for more information
56+
57+
## Encrypt a string
58+
59+
Command:
60+
```bash
61+
pyms encrypt [string]
62+
```
63+
64+
Encrypt a string to use in your [configfile](configuration.md)
65+
66+
```bash
67+
pyms encrypt 'mysql+mysqlconnector://important_user:****@localhost/my_schema'
68+
>> Encrypted OK: b'gAAAAABeSwBJv43hnGAWZOY50QjBX6uGLxUb3Q6fcUhMxKspIVIco8qwwZvxRg930uRlsd47isroXzkdRRnb4-x2dsQMp0dln8Pm2ySHH7TryLbQYEFbSh8RQK7zor-hX6gB-JY3uQD3IMtiVKx9AF95D6U4ydT-OA=='
69+
```
70+
71+
See [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md) for more information
72+
73+
## Merge swagger into a single file
74+
75+
Command:
76+
77+
```bash
78+
pyms merge-swagger [-h] [-f FILE]
79+
```
80+
81+
```bash
82+
optional arguments:
83+
-h, --help show this help message and exit
84+
-f FILE, --file FILE Swagger file path
85+
```
86+
87+
This command uses [prance](https://github.com/jfinkhaeuser/prance) to validate the API specification and generate a single YAML file. It has an optional argument to indicate the main file path of the API specification.
88+
89+
```bash
90+
pyms merge-swagger --file 'app/swagger/swagger.yaml'
91+
>> Swagger file generated [swagger-complete.yaml]
92+
>> OK
93+
```

docs/configuration.md

+195
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Configuration
2+
3+
## Environments variables of PyMS:
4+
5+
**PYMS_CONFIGMAP_FILE**: The path to the configuration file. By default, PyMS searches for the configuration file in your
6+
current folder with the name "config.yml"
7+
**PYMS_KEY_FILE**: The path to the key file to decrypt your configuration. By default, PyMS searches for the configuration file in your
8+
current folder with the name "key.key"
9+
10+
## Create configuration
11+
Each microservice needs a config file in yaml or json format for it to work with. This configuration contains
12+
the Flask settings of your project and the [Services](services.md). With this way of creating configuration files, we
13+
solve two problems of the [12 Factor apps](https://12factor.net/):
14+
15+
- Store config out of the code
16+
- Dev/prod parity: the configuration could be injected and doesn't depend on our code, for example, Kubernetes configmaps
17+
18+
A simple configuration file could be a config.yaml:
19+
20+
```yaml
21+
pyms:
22+
services:
23+
requests: true
24+
swagger:
25+
path: ""
26+
file: "swagger.yaml"
27+
config:
28+
debug: true
29+
testing: false
30+
app_name: "Python Microservice"
31+
APPLICATION_ROOT: ""
32+
```
33+
34+
or in a config.json:
35+
36+
```json
37+
{
38+
"pyms": {
39+
"services":{
40+
"requests": true,
41+
"swagger": {
42+
"path": "",
43+
"file": "swagger.yaml"
44+
}
45+
},
46+
"config": {
47+
"DEBUG": true,
48+
"TESTING": true,
49+
"APP_NAME": "Python Microservice",
50+
"APPLICATION_ROOT": "/",
51+
"test_var": "general",
52+
"subservice1": {
53+
"test": "input"
54+
},
55+
"subservice2": {
56+
"test": "output"
57+
}
58+
}
59+
}
60+
}
61+
```
62+
63+
This file can contain the following keywords:
64+
65+
## pyms - services block
66+
67+
```pyms```: all subsets inside this keyword are the settings of this library. Each keyword will be a service of our
68+
[Microservice class](ms_class.md). For example, if we declare our microservice class as:
69+
70+
```python
71+
from pyms.flask.app import Microservice
72+
ms = Microservice(path=__file__)
73+
```
74+
and have a `config.yaml` file such as:
75+
76+
```yaml
77+
pyms:
78+
services:
79+
requests: true
80+
```
81+
82+
our `ms` object will have an attribute `requests` that is a instance of our service [requests](services.md).
83+
84+
## pyms - config block
85+
This section contains all keywords used for general [Flask Configuration Handling](http://flask.pocoo.org/docs/1.0/config/), along
86+
with our constants for the different enviroments (local configuration, staging configuration...). Keep in mind that
87+
a Flask app configuration needs the keywords to be declared as uppercase. If you defined a variable like `app_name`,
88+
you will be able to retrieve it with `current_app.config["APP_NAME"]`
89+
90+
91+
## Import Configuration
92+
With pyms, all configuration is stored as flask configuration and it can be acceded from:
93+
94+
```python
95+
from flask import current_app;
96+
97+
def my_endpoint():
98+
print(current_app.config["DEBUG"])
99+
```
100+
101+
But, what happens if you need to access the configuration BEFORE Flask class is instanced? Imagine this case:
102+
103+
```python
104+
from flask import Blueprint, current_app
105+
from flask_restplus import Api
106+
107+
my_api_blueprint = Blueprint('api', __name__)
108+
109+
API = Api(
110+
my_api_blueprint,
111+
title='My Microservice',
112+
version=current_app.config["APP_VERSION"],
113+
description='Microservice to manage hierarchies',
114+
add_specs=True,
115+
)
116+
```
117+
118+
This raises a `'working outside of application context` error. Who can solve this problem?
119+
120+
```python
121+
from flask import Blueprint, current_app
122+
from flask_restplus import Api
123+
from pyms.flask.app import config
124+
125+
my_api_blueprint = Blueprint('api', __name__)
126+
127+
API = Api(
128+
my_api_blueprint,
129+
title='My Microservice',
130+
version=config().APP_VERSION,
131+
description='Microservice to manage hierarchies',
132+
add_specs=True,
133+
)
134+
```
135+
136+
137+
## Looking for Configuration file with Kubernetes Configmaps
138+
By default, the Microservice class searches for a config.yml in the same path. You can set a different route or set a json file.
139+
To change this path, you must define an environment variable called `PYMS_CONFIGMAP_FILE`.
140+
141+
This way of looking for the configuration is useful when you work with Docker and Kubernetes. For example, you could integrate
142+
a configmap of Kubernetes, with this microservice and a deployment with:
143+
144+
```yaml
145+
apiVersion: extensions/v1beta1
146+
kind: Deployment
147+
metadata:
148+
name: my-microservice
149+
spec:
150+
replicas: 1
151+
template:
152+
spec:
153+
containers:
154+
- name: my-microservice
155+
image: ...
156+
env:
157+
- name: PYMS_CONFIGMAP_FILE
158+
value: "/usr/share/microservice/config.yaml"
159+
160+
volumeMounts:
161+
- mountPath: /usr/share/microservice
162+
name: ms-config-volume
163+
volumes:
164+
- name: ms-config-volume
165+
configMap:
166+
name: my-microservice-configmap
167+
```
168+
169+
See [Routing](routing.md) and [Examples](examples.md) to continue with this tutorial
170+
171+
## Reload configuration without stopping your services
172+
173+
In a production environment you may need to change the microservice's configuration without restarting it.
174+
175+
PyMS has a feature to reload the configuration:
176+
177+
```
178+
curl -X POST http://localhost:5000/reload-config
179+
```
180+
181+
This endpoint calls the method `Microservice.reload_conf()`, which restarts the services,
182+
the encryption configuration and initializes `create_app`.
183+
184+
```python
185+
def reload_conf(self):
186+
self.delete_services()
187+
self.config.reload()
188+
self.services = []
189+
self.init_services()
190+
self.crypt.config.reload()
191+
self.create_app()
192+
```
193+
194+
This means that your libraries will be restarted, which is why it's important to initialize your BD,
195+
your configuration inside `init_libs` method. See more info [how to use Microservice class in this link](ms_class.md)

0 commit comments

Comments
 (0)