Skip to content

Commit bcf386f

Browse files
authored
Create project from scaffold (#90)
* Added new command startproject * Updated docs * Update README.md
1 parent cc95e01 commit bcf386f

File tree

13 files changed

+206
-20
lines changed

13 files changed

+206
-20
lines changed

README.md

+52-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,20 @@
1010
[![Gitter](https://img.shields.io/gitter/room/DAVFoundation/DAV-Contributors.svg)](https://gitter.im/python-microservices/pyms)
1111

1212

13-
PyMS, Python MicroService, is a collections of libraries, best practices and recommended ways to build microservices with Python.
13+
PyMS, Python MicroService, is a [Microservice chassis pattern](https://microservices.io/patterns/microservice-chassis.html)
14+
like Spring Boot (Java) or Gizmo (Golang). PyMS is a collection of libraries, best practices and recommended ways to build
15+
microservices with Python which handles cross-cutting concerns:
16+
17+
- Externalized configuration
18+
- Logging
19+
- Health checks
20+
- Metrics
21+
- Distributed tracing
22+
23+
PyMS is powered by [Flask](https://flask.palletsprojects.com/en/1.1.x/), [Connexion](https://github.com/zalando/connexion)
24+
and [Opentracing](https://opentracing.io/).
25+
26+
Get started with [Installation](installation.md) and then get an overview with the [Quickstart](quickstart.md).
1427

1528
## Documentation
1629

@@ -26,15 +39,15 @@ nothing to create professional projects. Most articles say:
2639
- (Sometimes) "Create a swagger specs"
2740
- "TA-DA! you have a microservice"
2841

29-
But... what happens with our configuration out of code like Kubernetes configmap? what happens with transactionality?
42+
But... what happens with our configuration out of code like Kubernetes configmap? what happens with transactionality?
3043
If we have many microservices, what happens with traces?.
3144

3245
There are many problems around Python and microservices and we can`t find anyone to give a solution.
3346

34-
We start creating these projects to try to solve all the problems we have found in our professional lives about
47+
We start creating these projects to try to solve all the problems we have found in our professional lives about
3548
microservices architecture.
3649

37-
Nowadays, is not perfect and we have a looong roadmap, but we hope this library could help other felas and friends ;)
50+
Nowadays, is not perfect and we have a looong roadmap, but we hope this library could help other fellas and friends ;)
3851

3952
## Installation
4053

@@ -97,6 +110,41 @@ override it.
97110

98111
See [Documentation](https://py-ms.readthedocs.io/en/latest/) to learn more.
99112

113+
## Create a project from scaffold
114+
115+
PyMS has a command line option to create a project template like [Microservices Scaffold](https://github.com/python-microservices/microservices-scaffold).
116+
This command use [cookiecutter](https://github.com/cookiecutter/cookiecutter) to download and install this [template](https://github.com/python-microservices/microservices-template)
117+
118+
**[Warning]** You must run first `pip install cookiecutter==1.7.0`
119+
120+
```bash
121+
pyms startproject
122+
```
123+
124+
this output a lot of options step by step:
125+
126+
```bash
127+
project_repo_url [https://github.com/python-microservices/microservices-scaffold]:
128+
project_name [Python Microservices Boilerplate]: prueba descarga
129+
project_folder [prueba_descarga]:
130+
project_short_description [Python Boilerplate contains all the boilerplate you need to create a Python package.]:
131+
create_model_class [y]:
132+
microservice_with_swagger_and_connexion [y]:
133+
microservice_with_traces [y]:
134+
microservice_with_metrics [y]:
135+
application_root [/prueba_descarga]:
136+
Select open_source_license:
137+
1 - MIT license
138+
2 - BSD license
139+
3 - ISC license
140+
4 - Apache Software License 2.0
141+
5 - GNU General Public License v3
142+
6 - Not open source
143+
Choose from 1, 2, 3, 4, 5, 6 [1]:
144+
```
145+
146+
When you finish to introduce the options, a project will be created in `project_slug` folder
147+
100148
## How To Contrib
101149

102150
We appreciate opening issues and pull requests to make PyMS even more stable & useful! See [This doc](CONTRIBUTING.md)

docs/command_line.md

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Commnand line
2+
3+
PyMS has some command to make easy your developments:
4+
5+
```bash
6+
pyms -h
7+
```
8+
Show you a list of options and help instructions to use this command like:
9+
10+
```bash
11+
usage: main.py [-h] [-v VERBOSE] {encrypt,create-key,startproject} ...
12+
13+
Python Microservices
14+
15+
optional arguments:
16+
-h, --help show this help message and exit
17+
-v VERBOSE, --verbose VERBOSE
18+
Verbose
19+
20+
Commands:
21+
Available commands
22+
23+
{encrypt,create-key,startproject}
24+
encrypt Encrypt a string
25+
create-key Generate a Key to encrypt strings in config
26+
startproject Generate a project from https://github.com/python-
27+
microservices/microservices-template
28+
29+
```
30+
31+
## Start a project
32+
33+
Command:
34+
```bash
35+
pyms startproject
36+
```
37+
38+
This command create a project template like [Microservices Scaffold](https://github.com/python-microservices/microservices-scaffold).
39+
This command use [cookiecutter](https://github.com/cookiecutter/cookiecutter) to download and install this [template](https://github.com/python-microservices/microservices-template)
40+
41+
!!! warning
42+
You must run first `pip install cookiecutter==1.7.0`
43+
44+
## Create a key encrypt/decrypt file
45+
46+
Command:
47+
```bash
48+
pyms create-key
49+
```
50+
51+
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).
52+
You can run the next command in the terminal. See [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md)
53+
for more information
54+
55+
## Encrypt a string
56+
57+
Command:
58+
```bash
59+
pyms encrypt [string]
60+
```
61+
62+
Encrypt a string to use in your [configfile](configuration.md)
63+
64+
```bash
65+
pyms encrypt 'mysql+mysqlconnector://important_user:****@localhost/my_schema'
66+
>> Encrypted OK: b'gAAAAABeSwBJv43hnGAWZOY50QjBX6uGLxUb3Q6fcUhMxKspIVIco8qwwZvxRg930uRlsd47isroXzkdRRnb4-x2dsQMp0dln8Pm2ySHH7TryLbQYEFbSh8RQK7zor-hX6gB-JY3uQD3IMtiVKx9AF95D6U4ydT-OA=='
67+
```
68+
69+
See [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md) for more information

docs/index.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ Nowadays, is not perfect and we have a looong roadmap, but we hope this library
4040
* [Installation](installation.md)
4141
* [Quickstart](quickstart.md)
4242
* [Configuration](configuration.md)
43-
* [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md)
4443
* [Services](services.md)
45-
* [PyMS structure](structure.md)
4644
* [Microservice class](ms_class.md)
47-
* [Examples](examples.md)
4845
* [Routing](routing.md)
46+
* [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md)
47+
* [Command line](command_line.md)
48+
* [Examples](examples.md)
49+
* [PyMS structure](structure.md)
4950
* [Structure of a microservice project](structure_project.md)

docs/quickstart.md

+37
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,43 @@ if it was defined in the pyms configuration block, create a tracer, add health-c
4545
`ms` attribute and you can access to it with `current_app.ms`. This steps has their each functions and you can easy override it.
4646
3. `create_app` return the flask instance and you can interact with it as a typical flask app
4747

48+
# Create a project from scaffold
4849

50+
PyMS have a command line option to create a project template like [Microservices Scaffold](https://github.com/python-microservices/microservices-scaffold).
51+
This command use [cookiecutter](https://github.com/cookiecutter/cookiecutter) to download and install this [template](https://github.com/python-microservices/microservices-template)
52+
53+
!!! warning
54+
You must run first `pip install cookiecutter==1.7.0`
55+
56+
## Installation
57+
58+
```bash
59+
pyms startproject
60+
`
61+
``
62+
63+
this output a lot of options step by step
64+
65+
```bash
66+
project_repo_url [https://github.com/python-microservices/microservices-scaffold]:
67+
project_name [Python Microservices Boilerplate]: prueba descarga
68+
project_folder [prueba_descarga]:
69+
project_short_description [Python Boilerplate contains all the boilerplate you need to create a Python package.]:
70+
create_model_class [y]:
71+
microservice_with_swagger_and_connexion [y]:
72+
microservice_with_traces [y]:
73+
microservice_with_metrics [y]:
74+
application_root [/prueba_descarga]:
75+
Select open_source_license:
76+
1 - MIT license
77+
2 - BSD license
78+
3 - ISC license
79+
4 - Apache Software License 2.0
80+
5 - GNU General Public License v3
81+
6 - Not open source
82+
Choose from 1, 2, 3, 4, 5, 6 [1]:
83+
```
84+
85+
When you finish to introduce the options, a project will be created in `[project_slug]` folder
4986

5087
See [Configuration](configuration.md), [Routing](routing.md) and [Examples](examples.md) to continue with this tutorial

mkdocs.yml

+7-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ nav:
99
- Quickstart: quickstart.md
1010
- Configuration: configuration.md
1111
- Services: services.md
12-
- Structure: structure.md
1312
- Microservice class: ms_class.md
14-
- Examples: examples.md
1513
- Routing: routing.md
14+
- Encrypt/Decrypt Configuration: encrypt_decryt_configuration.md
15+
- Command line: command_line.md
16+
- Examples: examples.md
17+
- PyMS structure: structure.md
1618
- Structure of a microservice project: structure_project.md
19+
20+
markdown_extensions:
21+
- admonition
1722
theme:
1823
name: 'material'

pyms/cmd/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
from pyms.cmd.main import Command
1+
from .main import Command
22

33
__all__ = ['Command']

pyms/cmd/main.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import argparse
66
import sys
77

8+
from pyms.utils import check_package_exists, import_from
89
from pyms.utils.crypt import Crypt
910

1011

@@ -28,10 +29,18 @@ def __init__(self, *args, **kwargs):
2829
parser_encrypt = commands.add_parser('encrypt', help='Encrypt a string')
2930
parser_encrypt.add_argument("encrypt", default='', type=str, help='Encrypt a string')
3031

31-
parser_create_key = commands.add_parser('create-key', help='Encrypt a string')
32+
parser_create_key = commands.add_parser('create-key', help='Generate a Key to encrypt strings in config')
3233
parser_create_key.add_argument("create_key", action='store_true',
3334
help='Generate a Key to encrypt strings in config')
3435

36+
parser_startproject = commands.add_parser('startproject',
37+
help='Generate a project from https://github.com/python-microservices/microservices-template')
38+
parser_startproject.add_argument("startproject", action='store_true',
39+
help='Generate a project from https://github.com/python-microservices/microservices-template')
40+
41+
parser_startproject.add_argument("-b", "--branch",
42+
help='Select a branch from https://github.com/python-microservices/microservices-template')
43+
3544
parser.add_argument("-v", "--verbose", default="", type=str, help="Verbose ")
3645

3746
args = parser.parse_args(arguments)
@@ -43,6 +52,11 @@ def __init__(self, *args, **kwargs):
4352
self.encrypt = args.encrypt
4453
except AttributeError:
4554
self.encrypt = ""
55+
try:
56+
self.startproject = args.startproject
57+
self.branch = args.branch
58+
except AttributeError:
59+
self.startproject = False
4660
self.verbose = len(args.verbose)
4761
if autorun: # pragma: no cover
4862
result = self.run()
@@ -70,6 +84,11 @@ def run(self):
7084
if self.encrypt:
7185
encrypted = crypt.encrypt(self.encrypt)
7286
self.print_ok("Encrypted OK: {}".format(encrypted))
87+
if self.startproject:
88+
check_package_exists("cookiecutter")
89+
cookiecutter = import_from("cookiecutter.main", "cookiecutter")
90+
cookiecutter('gh:python-microservices/cookiecutter-pyms', checkout=self.branch)
91+
self.print_ok("Created project OK")
7392
return True
7493

7594
@staticmethod

pyms/config/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pyms.config.conf import get_conf
2-
from pyms.config.confile import ConfFile
1+
from .conf import get_conf
2+
from .confile import ConfFile
33

44
__all__ = ['get_conf', 'ConfFile']

pyms/flask/app/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from pyms.flask.app.create_app import Microservice
2-
from pyms.flask.app.create_config import config
1+
from .create_app import Microservice
2+
from .create_config import config
33

44

55
__all__ = ['Microservice', 'config']

pyms/flask/healthcheck/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pyms.flask.healthcheck.healthcheck import healthcheck_blueprint
1+
from .healthcheck import healthcheck_blueprint
22

33

44
__all__ = ['healthcheck_blueprint']

pyms/logger/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Init file
22
"""
3-
from pyms.logger.logger import CustomJsonFormatter
3+
from .logger import CustomJsonFormatter
44

55
__all__ = ['CustomJsonFormatter', ]

pyms/utils/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
from pyms.utils.utils import import_from, import_package, check_package_exists
1+
from .utils import import_from, import_package, check_package_exists
22

33
__all__ = ['import_from', 'import_package', 'check_package_exists']

tests/test_cmd.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import pytest
88

99
from pyms.cmd import Command
10-
from pyms.exceptions import FileDoesNotExistException
10+
from pyms.exceptions import FileDoesNotExistException, PackageNotExists
1111
from pyms.utils.crypt import Crypt
1212

1313

@@ -47,4 +47,11 @@ def test_output_key(self, input):
4747
cmd.run()
4848
with pytest.raises(FileNotFoundError) as excinfo:
4949
crypt.delete_key()
50-
assert ("[Errno 2] No such file or directory: 'key.key'") in str(excinfo.value)
50+
assert "[Errno 2] No such file or directory: 'key.key'" in str(excinfo.value)
51+
52+
def test_startproject_error(self):
53+
arguments = ["startproject"]
54+
cmd = Command(arguments=arguments, autorun=False)
55+
with pytest.raises(PackageNotExists) as excinfo:
56+
cmd.run()
57+
assert "cookiecutter is not installed. try with pip install -U cookiecutter" in str(excinfo.value)

0 commit comments

Comments
 (0)