Skip to content

Commit

Permalink
refractored code
Browse files Browse the repository at this point in the history
- added more test cases
- enhanced documentation
- enhanced setup file
- updated CHANGELOG
- updated terraform code
  • Loading branch information
satyamsoni-gsa committed Jun 14, 2022
1 parent 9ab75c7 commit d19016f
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 8 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

### [0.1.4] - 2022-06-14

### Changed

- Added support for concurrency
- Added test cases for testing code
- Enhanced documentation

### [0.1.3] - 2022-05-19

### Changed
Expand Down
54 changes: 50 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This is a utility project designed to cater neccessities for warming up `Lambda`
- [Installing Warmer](#installing-warmer)
- [Using Warmer](#using-warmer)
- [Setting up Event Bridge Notifications](#setting-up-event-bridge-notifications)
- [Working on enhancements](#working-on-enhancements)

#

Expand Down Expand Up @@ -33,29 +34,37 @@ This is very easy to incorporate in your existing Python Lambda Handlers. Follow

```python
from warmer import warmer
@warmer(flag="custom_event_key")
@warmer(flag="custom_event_key", _concurrency=1)
def handler(event, context):
pass
```

If you handler is a Flask/FastApi application, you may follow below steps:
> Parameters:
> *flag* (type: str)- name of the event flag to look for
> *_concurrency* (type: int)- (optional) Number of concurrent handlers to warm up, default: 1

If your handler is a Flask/FastApi application, you may follow below steps:

```python
from warmer import warmer
from flask import Flask
app = Flask()
@warmer(flag="custom_event_key")
@warmer(flag="custom_event_key",_concurrency=1)
def application(event, context):
return app(event, context)

# or

application = warmer(flag="custom_event_key")(app)
application = warmer(flag="custom_event_key",_concurrency=1)(app)

# you may now use application as your handler
```

> `warmer` will help you cater the custom events that are coming for warming _Lambda_ function.
> Though `_concurrency` is optional and by default it only warms up current execution. In case you want to warm up multiple instances of lambda handler, you may need to adjust `_concurrency` to *number of handlers running*.
> `Warmer` uses threading mechnism to ensure that the warming calls are actually happening concurrently and not serially.
<a name="setting-up-event-bridge-notifications"></a>

Expand Down Expand Up @@ -102,4 +111,41 @@ TransactionCompsAPI:
Input: '{"warmer": true}' # this refers to the warmer flag
```
In case you want to include concurrent executions, you may add below to include concurrent invocations.
```yaml
TransactionCompsAPI:
Type: "AWS::Serverless::Function"
Properties:
FunctionName: fake-function
Events:
WarmerSchedule: # add this event to the same template
Type: Schedule
Properties:
Schedule: cron(*/5 * ? * 2-6 *)
Name: fake-function-warmer-event
Description: Warmer Event for Lambda Function
Enabled: true
Input: '{"warmer": true, "concurrency": 5}' # this refers to the warmer flag and concurrency
```
<a name="working-on-enhancements"></a>
## Working on enhancements
If you want to work on enhancements or development, you may clone the project and run the below commands to setup environment:
```bash
python -m pip install pipenv
pipenv shell

# or

python -m pip install virtualenv
virtualenv venv
source venv/bin/activate
python -m pip install -r dev_requirements.txt
```

You may also raise a `PR` to get merged into existing project.

Happy Warming.
3 changes: 3 additions & 0 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-r requirements.txt
pytest
tox
2 changes: 1 addition & 1 deletion release
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.3
0.1.4
13 changes: 11 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
long_description = fr.read()
setup(
name="py_lambda_warmer",
version="0.1.3",
version="0.1.4",
description="Warmer Utility for Lambda Function",
long_description=long_description,
long_description_content_type='text/markdown',
Expand All @@ -20,5 +20,14 @@
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9"
]
],
install_requires=[
'boto3',
],
extras_require={
"dev": [
"pytest",
"tox"
]
}
)
3 changes: 2 additions & 1 deletion terraform_resources/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ resource "aws_cloudwatch_event_target" "lambda_warmer_target" {
rule = aws_cloudwatch_event_rule.trigger_lambda.name
input = <<-INPUT
{
"warmer": true
"warmer": true,
"concurrency": 1
}
INPUT
}
Expand Down
21 changes: 21 additions & 0 deletions tests/test_warmer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ def fake_wsgi(*args, **kwargs):
return "_response"


@warmer()
def fake_wsgi_with_concurrency_event(*args, **kwargs):
return "_response"


class TestWarmerFunction(TestCase):
@patch("botocore.client.BaseClient._make_api_call")
def test_warmer_concurrency(self, mock: Mock):
Expand Down Expand Up @@ -39,3 +44,19 @@ def test_concurrency_function_args(self, mock: Mock):
fake_wsgi({"warmer": True}, {})
mock.assert_called()
mock.assert_called_with(5, "warmer")

@patch("botocore.client.BaseClient._make_api_call")
def test_for_concurrency_using_event(self, mock: Mock):
# function to check for concurrent calls when passed via event
fake_wsgi_with_concurrency_event(
{"warmer": True, "concurrency": 5}, {})
self.assertEqual(mock.call_count, 4)

@patch("botocore.client.BaseClient._make_api_call")
def test_for_concurrency_using_default_event(self, mock: Mock):
# No concurrent calls should be made in case
# of concurrency = 1
fake_wsgi_with_concurrency_event(
{"warmer": True}, {})
self.assertEqual(mock.call_count, 0)
mock.assert_not_called()

0 comments on commit d19016f

Please sign in to comment.