Skip to content

Commit

Permalink
docs: add complete docs (#15)
Browse files Browse the repository at this point in the history

---------

Co-authored-by: Ran Isenberg <[email protected]>
  • Loading branch information
ran-isenberg and Ran Isenberg authored Jul 15, 2023
1 parent 3be8f5b commit f770d8f
Show file tree
Hide file tree
Showing 16 changed files with 233 additions and 154 deletions.
1 change: 0 additions & 1 deletion .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ jobs:
pip install --upgrade pip pre-commit poetry
make deps
pip install -r lib_requirements.txt
curl -sSL https://install.python-poetry.org | python3 -
- name: Build package
run: poetry build
- name: Publish package
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ Contributions via pull requests are much appreciated. Before sending us a pull r

1. You are working against the latest source on the **main** branch.
2. You check existing open, and recently merged pull requests to make sure someone else hasn't addressed the problem already.
3. You open an [issue](https://github.com/ran-isenberg/aws-lambda-env-vars-parser/issues) before you begin any implementation. We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.
3. You open an [issue](https://github.com/ran-isenberg/aws-lambda-env-modeler/issues) before you begin any implementation. We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

### Dev setup

[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/from-referrer/)

Firstly, [fork the repository](https://github.com/ran-isenberg/aws-lambda-env-vars-parser/fork).
Firstly, [fork the repository](https://github.com/ran-isenberg/aws-lambda-env-modeler/fork).


use `make dev` within your local virtual environment.
For more information on getting started check out the [official documentation](https://ran-isenberg.github.io/aws-lambda-env-vars-parser/getting_started/)
For more information on getting started check out the [official documentation](https://ran-isenberg.github.io/aws-lambda-env-modeler/getting_started/)

To send us a pull request, please follow these steps:

Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dev:

lint:
@echo "Running flake8"
flake8 aws_lambda_env_vars_parser/* tests/* docs/examples/* --exclude patterns='build,cdk.json,cdk.context.json,.yaml'
flake8 aws_lambda_env_modeler/* tests/* docs/snippets/* --exclude patterns='build,cdk.json,cdk.context.json,.yaml'
@echo "Running mypy"
make mypy-lint

Expand All @@ -27,13 +27,13 @@ pre-commit:
pre-commit run -a --show-diff-on-failure

mypy-lint:
mypy --pretty aws_lambda_env_vars_parser docs/examples tests
mypy --pretty aws_lambda_env_modeler docs/snippets tests

deps:
poetry export --with=dev --without-hashes --format=requirements.txt > lib_requirements.txt

unit:
pytest tests/unit --cov-config=.coveragerc --cov=aws_lambda_env_vars_parser --cov-report xml
pytest tests/unit --cov-config=.coveragerc --cov=aws_lambda_env_modeler --cov-report xml


pr: deps yapf sort pre-commit complex lint lint-docs unit
Expand All @@ -42,7 +42,7 @@ yapf:
yapf -i -vv --style=./.style --exclude=.venv --exclude=.build --exclude=cdk.out --exclude=.git -r .

pipeline-tests:
pytest tests/unit --cov-config=.coveragerc --cov=aws_lambda_env_vars_parser --cov-report xml
pytest tests/unit --cov-config=.coveragerc --cov=aws_lambda_env_modeler --cov-report xml


docs:
Expand Down
90 changes: 74 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,102 @@

# AWS Lambda Handler Environment Variables (Python)
# AWS Lambda Handler Environment Variables Modeler (Python)

[![license](https://img.shields.io/github/license/ran-isenberg/aws-lambda-env-vars-parser)](https://github.com/ran-isenberg/aws-lambda-env-vars-parser/blob/master/LICENSE)
[![license](https://img.shields.io/github/license/ran-isenberg/aws-lambda-env-modeler)](https://github.com/ran-isenberg/aws-lambda-env-modeler/blob/master/LICENSE)
![PythonSupport](https://img.shields.io/static/v1?label=python&message=3.8.1&color=blue?style=flat-square&logo=python)
![PythonSupport](https://img.shields.io/static/v1?label=python&message=3.9&color=blue?style=flat-square&logo=python)
![PythonSupport](https://img.shields.io/static/v1?label=python&message=3.10&color=blue?style=flat-square&logo=python)
[![codecov](https://codecov.io/gh/ran-isenberg/aws-lambda-env-vars-parser/branch/main/graph/badge.svg?token=P2K7K4KICF)](https://codecov.io/gh/ran-isenberg/aws-lambda-env-vars-parser)
![version](https://img.shields.io/github/v/release/ran-isenberg/aws-lambda-env-vars-parser)
![github-star-badge](https://img.shields.io/github/stars/ran-isenberg/aws-lambda-env-vars-parser.svg?style=social)
![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/ran-isenberg/aws-lambda-env-vars-parser/badge)
![issues](https://img.shields.io/github/issues/ran-isenberg/aws-lambda-env-vars-parser)
[![codecov](https://codecov.io/gh/ran-isenberg/aws-lambda-env-modeler/branch/main/graph/badge.svg?token=P2K7K4KICF)](https://codecov.io/gh/ran-isenberg/aws-lambda-env-modeler)
![version](https://img.shields.io/github/v/release/ran-isenberg/aws-lambda-env-modeler)
![github-star-badge](https://img.shields.io/github/stars/ran-isenberg/aws-lambda-env-modeler.svg?style=social)
![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/ran-isenberg/aws-lambda-env-modeler/badge)
![issues](https://img.shields.io/github/issues/ran-isenberg/aws-lambda-env-modeler)

![alt text](https://github.com/ran-isenberg/aws-lambda-env-vars-parser/blob/main/docs/media/banner.png?raw=true)
![alt text](https://github.com/ran-isenberg/aws-lambda-env-modeler/blob/main/docs/media/banner.png?raw=true)

This project provides a
AWS-Lambda-Env-Modeler is a Python library designed to simplify the process of managing and validating environment variables in your AWS Lambda functions.

**[📜Documentation](https://ran-isenberg.github.io/aws-lambda-env-vars-parser/)** | **[Blogs website](https://www.ranthebuilder.cloud)**
It leverages the power of [Pydantic](https://pydantic-docs.helpmanual.io/) models to define the expected structure and types of the environment variables.

This library is especially handy for serverless applications where managing configuration via environment variables is a common practice.

**[📜Documentation](https://ran-isenberg.github.io/aws-lambda-env-modeler/)** | **[Blogs website](https://www.ranthebuilder.cloud)**
> **Contact details | [email protected]**

## **The Problem**

Environment variables are often viewed as an essential utility. They serve as static AWS Lambda function configuration.

Their values are set during the Lambda deployment, and the only way to change them is to redeploy the Lambda function with updated values.

However, many engineers use them unsafely despite being such an integral and fundamental part of any AWS Lambda function deployment.

This usage may cause nasty bugs or even crashes in production.

## **The Solution**

This library allows you to correctly parse, validate, and use your environment variables in your Python AWS Lambda code.

Read more about it [here](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-environment-variables)

### **Features**

- Validates the environment variables against a Pydantic model: define both semantic and syntactic validation.
- Serializes the string environment variables into complex classes and types.
- Provides means to access the environment variables safely with a global getter function in every part of the function.
- Provides a decorator to initialize the environment variables before executing a function.
- Caches the parsed model for performance improvement for multiple 'get' calls.

- [Environment Variables](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-environment-variables)

## Installation

You can install it using pip:

```bash
pip install aws-lambda-env-modeler
```

## Getting started
Head over to the complete project documentation pages at GitHub pages at [https://ran-isenberg.github.io/aws-lambda-env-vars-parser](https://ran-isenberg.github.io/aws-lambda-env-vars-parser/)
Head over to the complete project documentation pages at GitHub pages at [https://ran-isenberg.github.io/aws-lambda-env-modeler](https://ran-isenberg.github.io/aws-lambda-env-modeler/)


## Usage
First, define a Pydantic model for your environment variables:

```python
from pydantic import BaseModel

class MyEnvVariables(BaseModel):
DB_HOST: str
DB_PORT: int
DB_USER: str
DB_PASS: str
```

You must first use the `@init_environment_variables` decorator to automatically validate and initialize the environment variables before executing a function:

```python
from aws_lambda_env_modeler import init_environment_variables

@init_environment_variables(MyEnvVariables)
def my_handler_entry_function(event, context):
# At this point, environment variables are already validated and initialized
pass
```

Then, you can fetch and validate the environment variables with your model:

```python
from aws_lambda_env_modeler import get_environment_variables

env_vars = get_environment_variables(MyEnvVariables)
print(env_vars.DB_HOST)
```

## Code Contributions
Code contributions are welcomed. Read this [guide.](https://github.com/ran-isenberg/aws-lambda-env-vars-parser/blob/main/CONTRIBUTING.md)
Code contributions are welcomed. Read this [guide.](https://github.com/ran-isenberg/aws-lambda-env-modeler/blob/main/CONTRIBUTING.md)

## Code of Conduct
Read our code of conduct [here.](https://github.com/ran-isenberg/aws-lambda-env-vars-parser/blob/main/CODE_OF_CONDUCT.md)
Read our code of conduct [here.](https://github.com/ran-isenberg/aws-lambda-env-modeler/blob/main/CODE_OF_CONDUCT.md)

## Connect
* Email: [[email protected]](mailto:[email protected])
Expand All @@ -48,4 +106,4 @@ Read our code of conduct [here.](https://github.com/ran-isenberg/aws-lambda-env-


## License
This library is licensed under the MIT License. See the [LICENSE](https://github.com/ran-isenberg/aws-lambda-env-vars-parser/blob/main/LICENSE) file.
This library is licensed under the MIT License. See the [LICENSE](https://github.com/ran-isenberg/aws-lambda-env-modeler/blob/main/LICENSE) file.
13 changes: 13 additions & 0 deletions aws_lambda_env_modeler/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Advanced event_parser utility
"""
from pydantic import BaseModel

from .modeler import get_environment_variables, init_environment_variables
from .types import Model

__all__ = [
'Model',
'BaseModel',
'init_environment_variables',
'get_environment_variables',
]
65 changes: 65 additions & 0 deletions aws_lambda_env_modeler/modeler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import os
from functools import lru_cache, wraps
from typing import Any, Callable, Dict, Type

from aws_lambda_env_modeler.types import Model


def get_environment_variables(model: Type[Model]) -> Model:
"""
This function receives a model of type Model, uses it to validate the environment variables, and returns the
validated model.
Args:
model (Type[Model]): A Pydantic model that defines the structure and types of the expected environment variables.
Returns:
Model: An instance of the provided model filled with the values of the validated environment variables.
"""
return __parse_model(model)


def init_environment_variables(model: Type[Model]):
"""
A decorator function for AWS Lambda handler functions that initializes environment variables based on the given Pydantic model before executing
the decorated function. The decorator validates the environment variables according to the model structure before
running the handler.
Args:
model (Type[Model]): A Pydantic model that defines the structure and types of the expected environment variables.
Returns:
Callable: A decorated function that first initializes the environment variables and then runs the function.
"""

def decorator(lambda_handler_function: Callable):

@wraps(lambda_handler_function)
def wrapper(event: Dict[str, Any], context):
__parse_model(model)
return lambda_handler_function(event, context)

return wrapper

return decorator


@lru_cache
def __parse_model(model: Type[Model]) -> Model:
"""
A helper function to validate and parse environment variables based on a given Pydantic model. This function is
also cached to improve performance in successive calls.
Args:
model (Type[Model]): A Pydantic model that defines the structure and types of the expected environment variables.
Returns:
Model: An instance of the provided model filled with the values of the validated environment variables.
Raises:
ValueError: If the environment variables do not match the structure of the model or cannot be validated.
"""
try:
return model.model_validate(os.environ)
except Exception as exc:
raise ValueError(f'failed to load environment variables, exception={str(exc)}') from exc
7 changes: 7 additions & 0 deletions aws_lambda_env_modeler/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from typing import TypeVar

from pydantic import BaseModel

Model = TypeVar('Model', bound=BaseModel)

__all__ = ['Model']
Empty file.
46 changes: 0 additions & 46 deletions aws_lambda_env_vars_parser/parser.py

This file was deleted.

Empty file.
68 changes: 0 additions & 68 deletions docs/getting_started.md

This file was deleted.

Loading

0 comments on commit f770d8f

Please sign in to comment.