<p align="center">
  <a  href="https://github.com/NoeCruzMW/zpy-flask-msc-docs"><img width="150" src="https://lh3.googleusercontent.com/a-/AOh14GjLO5qYYR5nQl5hgavUKz4Dv3LVzWDvGtV4xNam=s600-k-no-rp-mo" alt="Zurck'z"></a>
</p>
<p align="center">
    <em>ZPy Flask Core, Layer for build microservices</em>
</p>
<p align="center"></p>

---

# ZPy Flask Core

> Zurck'z Py Flask Micro Services Core

This package contains some helpers features for build python microservices using Flask framework

ZPy use the following packages:

- Flask
- marshmallow
- marshmallow_objects
- requests
- aws-lambda-wsgi

## Requirements

- Python 3.6+

## Installation

Use the package manager [pip](https://pip.pypa.io/en/stable/) to install py flask micro service core .

```bash
pip install zpy-api-core
```

## Features

Contains some helper features.

- Api
    - Api Builder
    - Response Builder
    - Models
    - Hooks
    - Middlewares
    - Exceptions
- Cloud Implementations
    - Aws Handler decorators
    - [See: AWS Package](https://pypi.org/project/zpy-cloud-utils)
- CLI
    - DDD Project structure generator
    - Bounded Context Generator
    - UseCases generator
- Database
    - [See: SQL Oracle & MySQL](https://pypi.org/project/zpy-db-core)
- Logger
    - Stream
- Utils
    - Collections
    - Ciphers
        - [See: Crypto Wrappers](https://pypi.org/project/zpy-ciphers-utils)
    - Functions
    - Objects
    - gzip

## Basic Usage

Generate project using _zpy CLI_

```shell
# Generate project with basic information. for more type: zpy --help
zpy make -p awesome-api -d "My awsome users api" -c Users -uc UserSearcher -op
...

cd awesome-api

```

zpy will generate the project with the following structure

```
awesome-api
│   .env
│   .gitignore
│   CHANGELOG.md
│   CHANGELOG.md
│   README.md
│   requirements.txt    
│
└───src
│   │   di.py
│   │   handler.py
│   │   local_deploy.py
│   │
│   └───┬api
│       │   routes.py
│       │   ...
│       └contexts
│       │   ...
│       └───users
│         │   ...
│         └───┬application
│         │   │ ...
│         └───┬domain
│         │   │ ...
│         └───┬infraestructure
│             │ ...
└───tests
    │   user_searcher_test.py    
```

Dependencies file

```python
# 🛸 Generated by zPy
from zpy.utils import get_env_or_throw as var
from zpy.app.usecase import UseCase
from typing import Any

# * Setup Dependencies 📃
from contexts.users.domain.repositories import UserRepository
from contexts.users.infraestructure.payment_repository import AwesomeUserRepository
from contexts.users.application.user_searcher import UserSearcher

repository: UserRepository = AwesomeUserRepository()

# Setup UseCases

user_searcher_uc: UseCase[Any, None] = UserSearcher(repository)
print("🚀 Dependencies loaded successfully...")
```

routes.py

```python
# 🛸 Generated by zPy
from di import user_searcher_uc
from flask import Flask
from zpy.api.http.response import response_builder
from zpy.api.flask import create_app

app: Flask = create_app()


@app.route("/api/users", methods=["GET"])
@response_builder
def users():
    return user_searcher_uc.execute(None)
```

Use Case

```python
# 🛸 Generated by zPy
from typing import Any

from zpy.app.usecase import UseCase

from ..domain.repositories import UserRepository


class UserSearcher(UseCase[Any, Any]):
    """
        Use Case description.
    """

    def __init__(self, repository: PaymentRepository) -> None:
        self.repository = repository

    def execute(self, data: Any, *args, **kwargs) -> None:
        # TODO Do magic with business rules 😁
        return self.repository.user_searcher(data)
```

Local Dev Deploy

```python
# 🛸 Generated by zPy
from dotenv import load_dotenv

load_dotenv(
    dotenv_path="|3:\\projects\\demos\\awesome-api\\.env"
)

from api.routes import app

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5050, debug=True)
```

handler.py configure for aws lambda and api gateway

```python
# 🛸 Generated by zPy
from zpy.api.flask.cloud_handlers import aws_lambda

from api.routes import app
import aws_lambda_wsgi as awsgi


@aws_lambda()
def handle(event: dict, context: dict) -> any:
    return awsgi.response(app, event, context)
```

## Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

## License

[MIT](https://choosealicense.com/licenses/mit/)

## Authors

[Noé Cruz](https://www.linkedin.com/in/zurckz/)
