Skip to content

Commit

Permalink
Create project from scaffold (#90)
Browse files Browse the repository at this point in the history
* Added new command startproject

* Updated docs

* Update README.md
  • Loading branch information
avara1986 committed Feb 25, 2020
1 parent cc95e01 commit bcf386f
Show file tree
Hide file tree
Showing 13 changed files with 206 additions and 20 deletions.
56 changes: 52 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,20 @@
[![Gitter](https://img.shields.io/gitter/room/DAVFoundation/DAV-Contributors.svg)](https://gitter.im/python-microservices/pyms)


PyMS, Python MicroService, is a collections of libraries, best practices and recommended ways to build microservices with Python.
PyMS, Python MicroService, is a [Microservice chassis pattern](https://microservices.io/patterns/microservice-chassis.html)
like Spring Boot (Java) or Gizmo (Golang). PyMS is a collection of libraries, best practices and recommended ways to build
microservices with Python which handles cross-cutting concerns:

- Externalized configuration
- Logging
- Health checks
- Metrics
- Distributed tracing

PyMS is powered by [Flask](https://flask.palletsprojects.com/en/1.1.x/), [Connexion](https://github.com/zalando/connexion)
and [Opentracing](https://opentracing.io/).

Get started with [Installation](installation.md) and then get an overview with the [Quickstart](quickstart.md).

## Documentation

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

But... what happens with our configuration out of code like Kubernetes configmap? what happens with transactionality?
But... what happens with our configuration out of code like Kubernetes configmap? what happens with transactionality?
If we have many microservices, what happens with traces?.

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

We start creating these projects to try to solve all the problems we have found in our professional lives about
We start creating these projects to try to solve all the problems we have found in our professional lives about
microservices architecture.

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

## Installation

Expand Down Expand Up @@ -97,6 +110,41 @@ override it.

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

## Create a project from scaffold

PyMS has a command line option to create a project template like [Microservices Scaffold](https://github.com/python-microservices/microservices-scaffold).
This command use [cookiecutter](https://github.com/cookiecutter/cookiecutter) to download and install this [template](https://github.com/python-microservices/microservices-template)

**[Warning]** You must run first `pip install cookiecutter==1.7.0`

```bash
pyms startproject
```

this output a lot of options step by step:

```bash
project_repo_url [https://github.com/python-microservices/microservices-scaffold]:
project_name [Python Microservices Boilerplate]: prueba descarga
project_folder [prueba_descarga]:
project_short_description [Python Boilerplate contains all the boilerplate you need to create a Python package.]:
create_model_class [y]:
microservice_with_swagger_and_connexion [y]:
microservice_with_traces [y]:
microservice_with_metrics [y]:
application_root [/prueba_descarga]:
Select open_source_license:
1 - MIT license
2 - BSD license
3 - ISC license
4 - Apache Software License 2.0
5 - GNU General Public License v3
6 - Not open source
Choose from 1, 2, 3, 4, 5, 6 [1]:
```

When you finish to introduce the options, a project will be created in `project_slug` folder

## How To Contrib

We appreciate opening issues and pull requests to make PyMS even more stable & useful! See [This doc](CONTRIBUTING.md)
Expand Down
69 changes: 69 additions & 0 deletions docs/command_line.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Commnand line

PyMS has some command to make easy your developments:

```bash
pyms -h
```
Show you a list of options and help instructions to use this command like:

```bash
usage: main.py [-h] [-v VERBOSE] {encrypt,create-key,startproject} ...

Python Microservices

optional arguments:
-h, --help show this help message and exit
-v VERBOSE, --verbose VERBOSE
Verbose

Commands:
Available commands

{encrypt,create-key,startproject}
encrypt Encrypt a string
create-key Generate a Key to encrypt strings in config
startproject Generate a project from https://github.com/python-
microservices/microservices-template

```

## Start a project

Command:
```bash
pyms startproject
```

This command create a project template like [Microservices Scaffold](https://github.com/python-microservices/microservices-scaffold).
This command use [cookiecutter](https://github.com/cookiecutter/cookiecutter) to download and install this [template](https://github.com/python-microservices/microservices-template)

!!! warning
You must run first `pip install cookiecutter==1.7.0`

## Create a key encrypt/decrypt file

Command:
```bash
pyms create-key
```

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).
You can run the next command in the terminal. See [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md)
for more information

## Encrypt a string

Command:
```bash
pyms encrypt [string]
```

Encrypt a string to use in your [configfile](configuration.md)

```bash
pyms encrypt 'mysql+mysqlconnector://important_user:****@localhost/my_schema'
>> Encrypted OK: b'gAAAAABeSwBJv43hnGAWZOY50QjBX6uGLxUb3Q6fcUhMxKspIVIco8qwwZvxRg930uRlsd47isroXzkdRRnb4-x2dsQMp0dln8Pm2ySHH7TryLbQYEFbSh8RQK7zor-hX6gB-JY3uQD3IMtiVKx9AF95D6U4ydT-OA=='
```

See [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md) for more information
7 changes: 4 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ Nowadays, is not perfect and we have a looong roadmap, but we hope this library
* [Installation](installation.md)
* [Quickstart](quickstart.md)
* [Configuration](configuration.md)
* [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md)
* [Services](services.md)
* [PyMS structure](structure.md)
* [Microservice class](ms_class.md)
* [Examples](examples.md)
* [Routing](routing.md)
* [Encrypt/Decrypt Configuration](encrypt_decryt_configuration.md)
* [Command line](command_line.md)
* [Examples](examples.md)
* [PyMS structure](structure.md)
* [Structure of a microservice project](structure_project.md)
37 changes: 37 additions & 0 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,43 @@ if it was defined in the pyms configuration block, create a tracer, add health-c
`ms` attribute and you can access to it with `current_app.ms`. This steps has their each functions and you can easy override it.
3. `create_app` return the flask instance and you can interact with it as a typical flask app

# Create a project from scaffold

PyMS have a command line option to create a project template like [Microservices Scaffold](https://github.com/python-microservices/microservices-scaffold).
This command use [cookiecutter](https://github.com/cookiecutter/cookiecutter) to download and install this [template](https://github.com/python-microservices/microservices-template)

!!! warning
You must run first `pip install cookiecutter==1.7.0`

## Installation

```bash
pyms startproject
`
``
this output a lot of options step by step
```bash
project_repo_url [https://github.com/python-microservices/microservices-scaffold]:
project_name [Python Microservices Boilerplate]: prueba descarga
project_folder [prueba_descarga]:
project_short_description [Python Boilerplate contains all the boilerplate you need to create a Python package.]:
create_model_class [y]:
microservice_with_swagger_and_connexion [y]:
microservice_with_traces [y]:
microservice_with_metrics [y]:
application_root [/prueba_descarga]:
Select open_source_license:
1 - MIT license
2 - BSD license
3 - ISC license
4 - Apache Software License 2.0
5 - GNU General Public License v3
6 - Not open source
Choose from 1, 2, 3, 4, 5, 6 [1]:
```

When you finish to introduce the options, a project will be created in `[project_slug]` folder

See [Configuration](configuration.md), [Routing](routing.md) and [Examples](examples.md) to continue with this tutorial
9 changes: 7 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ nav:
- Quickstart: quickstart.md
- Configuration: configuration.md
- Services: services.md
- Structure: structure.md
- Microservice class: ms_class.md
- Examples: examples.md
- Routing: routing.md
- Encrypt/Decrypt Configuration: encrypt_decryt_configuration.md
- Command line: command_line.md
- Examples: examples.md
- PyMS structure: structure.md
- Structure of a microservice project: structure_project.md

markdown_extensions:
- admonition
theme:
name: 'material'
2 changes: 1 addition & 1 deletion pyms/cmd/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from pyms.cmd.main import Command
from .main import Command

__all__ = ['Command']
21 changes: 20 additions & 1 deletion pyms/cmd/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import argparse
import sys

from pyms.utils import check_package_exists, import_from
from pyms.utils.crypt import Crypt


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

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

parser_startproject = commands.add_parser('startproject',
help='Generate a project from https://github.com/python-microservices/microservices-template')
parser_startproject.add_argument("startproject", action='store_true',
help='Generate a project from https://github.com/python-microservices/microservices-template')

parser_startproject.add_argument("-b", "--branch",
help='Select a branch from https://github.com/python-microservices/microservices-template')

parser.add_argument("-v", "--verbose", default="", type=str, help="Verbose ")

args = parser.parse_args(arguments)
Expand All @@ -43,6 +52,11 @@ def __init__(self, *args, **kwargs):
self.encrypt = args.encrypt
except AttributeError:
self.encrypt = ""
try:
self.startproject = args.startproject
self.branch = args.branch
except AttributeError:
self.startproject = False
self.verbose = len(args.verbose)
if autorun: # pragma: no cover
result = self.run()
Expand Down Expand Up @@ -70,6 +84,11 @@ def run(self):
if self.encrypt:
encrypted = crypt.encrypt(self.encrypt)
self.print_ok("Encrypted OK: {}".format(encrypted))
if self.startproject:
check_package_exists("cookiecutter")
cookiecutter = import_from("cookiecutter.main", "cookiecutter")
cookiecutter('gh:python-microservices/cookiecutter-pyms', checkout=self.branch)
self.print_ok("Created project OK")
return True

@staticmethod
Expand Down
4 changes: 2 additions & 2 deletions pyms/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyms.config.conf import get_conf
from pyms.config.confile import ConfFile
from .conf import get_conf
from .confile import ConfFile

__all__ = ['get_conf', 'ConfFile']
4 changes: 2 additions & 2 deletions pyms/flask/app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pyms.flask.app.create_app import Microservice
from pyms.flask.app.create_config import config
from .create_app import Microservice
from .create_config import config


__all__ = ['Microservice', 'config']
2 changes: 1 addition & 1 deletion pyms/flask/healthcheck/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyms.flask.healthcheck.healthcheck import healthcheck_blueprint
from .healthcheck import healthcheck_blueprint


__all__ = ['healthcheck_blueprint']
2 changes: 1 addition & 1 deletion pyms/logger/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Init file
"""
from pyms.logger.logger import CustomJsonFormatter
from .logger import CustomJsonFormatter

__all__ = ['CustomJsonFormatter', ]
2 changes: 1 addition & 1 deletion pyms/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from pyms.utils.utils import import_from, import_package, check_package_exists
from .utils import import_from, import_package, check_package_exists

__all__ = ['import_from', 'import_package', 'check_package_exists']
11 changes: 9 additions & 2 deletions tests/test_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pytest

from pyms.cmd import Command
from pyms.exceptions import FileDoesNotExistException
from pyms.exceptions import FileDoesNotExistException, PackageNotExists
from pyms.utils.crypt import Crypt


Expand Down Expand Up @@ -47,4 +47,11 @@ def test_output_key(self, input):
cmd.run()
with pytest.raises(FileNotFoundError) as excinfo:
crypt.delete_key()
assert ("[Errno 2] No such file or directory: 'key.key'") in str(excinfo.value)
assert "[Errno 2] No such file or directory: 'key.key'" in str(excinfo.value)

def test_startproject_error(self):
arguments = ["startproject"]
cmd = Command(arguments=arguments, autorun=False)
with pytest.raises(PackageNotExists) as excinfo:
cmd.run()
assert "cookiecutter is not installed. try with pip install -U cookiecutter" in str(excinfo.value)

0 comments on commit bcf386f

Please sign in to comment.