├── firstlamdba
├── .gitignore
├── .idea
│ ├── .gitignore
│ ├── firstlamdba.iml
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ └── modules.xml
├── README.md
├── __init__.py
├── events
│ └── event.json
├── hello_world
│ ├── __init__.py
│ ├── app.py
│ ├── datatypes.py
│ └── requirements.txt
├── outputfile.txt
├── samconfig.toml
├── template.yaml
└── tests
│ ├── __init__.py
│ ├── integration
│ ├── __init__.py
│ └── test_api_gateway.py
│ ├── requirements.txt
│ └── unit
│ ├── __init__.py
│ └── test_handler.py
├── orders-api
├── .gitignore
├── .idea
│ ├── .gitignore
│ ├── inspectionProfiles
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── orders-api.iml
├── README.md
├── __init__.py
├── events
│ └── event.json
├── orders_api
│ ├── __init__.py
│ ├── app.py
│ ├── create.py
│ ├── read.py
│ └── requirements.txt
├── samconfig.toml
├── template.yaml
└── tests
│ ├── __init__.py
│ ├── integration
│ ├── __init__.py
│ └── test_api_gateway.py
│ ├── requirements.txt
│ └── unit
│ ├── __init__.py
│ └── test_handler.py
└── patientcheckout
├── .DS_Store
├── .idea
├── .gitignore
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── patientcheckout.iml
├── README.md
├── __init__.py
├── events
└── event.json
├── patientData.json
├── patient_checkout
├── __init__.py
├── app.py
├── billmanagement.py
├── claimmanagement.py
├── errorhandler.py
├── patientcheckout.py
└── requirements.txt
├── samconfig.toml
├── template.yaml
└── tests
├── __init__.py
├── integration
├── __init__.py
└── test_api_gateway.py
├── requirements.txt
└── unit
├── __init__.py
└── test_handler.py
/firstlamdba/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode
3 |
4 | ### Linux ###
5 | *~
6 |
7 | # temporary files which can be created if a process still has a handle open of a deleted file
8 | .fuse_hidden*
9 |
10 | # KDE directory preferences
11 | .directory
12 |
13 | # Linux trash folder which might appear on any partition or disk
14 | .Trash-*
15 |
16 | # .nfs files are created when an open file is removed but is still being accessed
17 | .nfs*
18 |
19 | ### OSX ###
20 | *.DS_Store
21 | .AppleDouble
22 | .LSOverride
23 |
24 | # Icon must end with two \r
25 | Icon
26 |
27 | # Thumbnails
28 | ._*
29 |
30 | # Files that might appear in the root of a volume
31 | .DocumentRevisions-V100
32 | .fseventsd
33 | .Spotlight-V100
34 | .TemporaryItems
35 | .Trashes
36 | .VolumeIcon.icns
37 | .com.apple.timemachine.donotpresent
38 |
39 | # Directories potentially created on remote AFP share
40 | .AppleDB
41 | .AppleDesktop
42 | Network Trash Folder
43 | Temporary Items
44 | .apdisk
45 |
46 | ### PyCharm ###
47 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
48 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
49 |
50 | # User-specific stuff:
51 | .idea/**/workspace.xml
52 | .idea/**/tasks.xml
53 | .idea/dictionaries
54 |
55 | # Sensitive or high-churn files:
56 | .idea/**/dataSources/
57 | .idea/**/dataSources.ids
58 | .idea/**/dataSources.xml
59 | .idea/**/dataSources.local.xml
60 | .idea/**/sqlDataSources.xml
61 | .idea/**/dynamic.xml
62 | .idea/**/uiDesigner.xml
63 |
64 | # Gradle:
65 | .idea/**/gradle.xml
66 | .idea/**/libraries
67 |
68 | # CMake
69 | cmake-build-debug/
70 |
71 | # Mongo Explorer plugin:
72 | .idea/**/mongoSettings.xml
73 |
74 | ## File-based project format:
75 | *.iws
76 |
77 | ## Plugin-specific files:
78 |
79 | # IntelliJ
80 | /out/
81 |
82 | # mpeltonen/sbt-idea plugin
83 | .idea_modules/
84 |
85 | # JIRA plugin
86 | atlassian-ide-plugin.xml
87 |
88 | # Cursive Clojure plugin
89 | .idea/replstate.xml
90 |
91 | # Ruby plugin and RubyMine
92 | /.rakeTasks
93 |
94 | # Crashlytics plugin (for Android Studio and IntelliJ)
95 | com_crashlytics_export_strings.xml
96 | crashlytics.properties
97 | crashlytics-build.properties
98 | fabric.properties
99 |
100 | ### PyCharm Patch ###
101 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
102 |
103 | # *.iml
104 | # modules.xml
105 | # .idea/misc.xml
106 | # *.ipr
107 |
108 | # Sonarlint plugin
109 | .idea/sonarlint
110 |
111 | ### Python ###
112 | # Byte-compiled / optimized / DLL files
113 | __pycache__/
114 | *.py[cod]
115 | *$py.class
116 |
117 | # C extensions
118 | *.so
119 |
120 | # Distribution / packaging
121 | .Python
122 | build/
123 | develop-eggs/
124 | dist/
125 | downloads/
126 | eggs/
127 | .eggs/
128 | lib/
129 | lib64/
130 | parts/
131 | sdist/
132 | var/
133 | wheels/
134 | *.egg-info/
135 | .installed.cfg
136 | *.egg
137 |
138 | # PyInstaller
139 | # Usually these files are written by a python script from a template
140 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
141 | *.manifest
142 | *.spec
143 |
144 | # Installer logs
145 | pip-log.txt
146 | pip-delete-this-directory.txt
147 |
148 | # Unit test / coverage reports
149 | htmlcov/
150 | .tox/
151 | .coverage
152 | .coverage.*
153 | .cache
154 | .pytest_cache/
155 | nosetests.xml
156 | coverage.xml
157 | *.cover
158 | .hypothesis/
159 |
160 | # Translations
161 | *.mo
162 | *.pot
163 |
164 | # Flask stuff:
165 | instance/
166 | .webassets-cache
167 |
168 | # Scrapy stuff:
169 | .scrapy
170 |
171 | # Sphinx documentation
172 | docs/_build/
173 |
174 | # PyBuilder
175 | target/
176 |
177 | # Jupyter Notebook
178 | .ipynb_checkpoints
179 |
180 | # pyenv
181 | .python-version
182 |
183 | # celery beat schedule file
184 | celerybeat-schedule.*
185 |
186 | # SageMath parsed files
187 | *.sage.py
188 |
189 | # Environments
190 | .env
191 | .venv
192 | env/
193 | venv/
194 | ENV/
195 | env.bak/
196 | venv.bak/
197 |
198 | # Spyder project settings
199 | .spyderproject
200 | .spyproject
201 |
202 | # Rope project settings
203 | .ropeproject
204 |
205 | # mkdocs documentation
206 | /site
207 |
208 | # mypy
209 | .mypy_cache/
210 |
211 | ### VisualStudioCode ###
212 | .vscode/*
213 | !.vscode/settings.json
214 | !.vscode/tasks.json
215 | !.vscode/launch.json
216 | !.vscode/extensions.json
217 | .history
218 |
219 | ### Windows ###
220 | # Windows thumbnail cache files
221 | Thumbs.db
222 | ehthumbs.db
223 | ehthumbs_vista.db
224 |
225 | # Folder config file
226 | Desktop.ini
227 |
228 | # Recycle Bin used on file shares
229 | $RECYCLE.BIN/
230 |
231 | # Windows Installer files
232 | *.cab
233 | *.msi
234 | *.msm
235 | *.msp
236 |
237 | # Windows shortcuts
238 | *.lnk
239 |
240 | # Build folder
241 |
242 | */build/*
243 |
244 | # End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode
--------------------------------------------------------------------------------
/firstlamdba/.idea/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/firstlamdba/.idea/.gitignore
--------------------------------------------------------------------------------
/firstlamdba/.idea/firstlamdba.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/firstlamdba/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/firstlamdba/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/firstlamdba/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/firstlamdba/README.md:
--------------------------------------------------------------------------------
1 | # firstlamdba
2 |
3 | This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders.
4 |
5 | - hello_world - Code for the application's Lambda function.
6 | - events - Invocation events that you can use to invoke the function.
7 | - tests - Unit tests for the application code.
8 | - template.yaml - A template that defines the application's AWS resources.
9 |
10 | The application uses several AWS resources, including Lambda functions and an API Gateway API. These resources are defined in the `template.yaml` file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code.
11 |
12 | If you prefer to use an integrated development environment (IDE) to build and test your application, you can use the AWS Toolkit.
13 | The AWS Toolkit is an open source plug-in for popular IDEs that uses the SAM CLI to build and deploy serverless applications on AWS. The AWS Toolkit also adds a simplified step-through debugging experience for Lambda function code. See the following links to get started.
14 |
15 | * [PyCharm](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html)
16 | * [IntelliJ](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html)
17 | * [VS Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html)
18 | * [Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html)
19 |
20 | ## Deploy the sample application
21 |
22 | The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API.
23 |
24 | To use the SAM CLI, you need the following tools.
25 |
26 | * SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
27 | * [Python 3 installed](https://www.python.org/downloads/)
28 | * Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community)
29 |
30 | To build and deploy your application for the first time, run the following in your shell:
31 |
32 | ```bash
33 | sam build --use-container
34 | sam deploy --guided
35 | ```
36 |
37 | The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts:
38 |
39 | * **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name.
40 | * **AWS Region**: The AWS region you want to deploy your app to.
41 | * **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes.
42 | * **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modified IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command.
43 | * **Save arguments to samconfig.toml**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application.
44 |
45 | You can find your API Gateway Endpoint URL in the output values displayed after deployment.
46 |
47 | ## Use the SAM CLI to build and test locally
48 |
49 | Build your application with the `sam build --use-container` command.
50 |
51 | ```bash
52 | firstlamdba$ sam build --use-container
53 | ```
54 |
55 | The SAM CLI installs dependencies defined in `hello_world/requirements.txt`, creates a deployment package, and saves it in the `.aws-sam/build` folder.
56 |
57 | Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project.
58 |
59 | Run functions locally and invoke them with the `sam local invoke` command.
60 |
61 | ```bash
62 | firstlamdba$ sam local invoke HelloWorldFunction --event events/event.json
63 | ```
64 |
65 | The SAM CLI can also emulate your application's API. Use the `sam local start-api` to run the API locally on port 3000.
66 |
67 | ```bash
68 | firstlamdba$ sam local start-api
69 | firstlamdba$ curl http://localhost:3000/
70 | ```
71 |
72 | The SAM CLI reads the application template to determine the API's routes and the functions that they invoke. The `Events` property on each function's definition includes the route and method for each path.
73 |
74 | ```yaml
75 | Events:
76 | HelloWorld:
77 | Type: Api
78 | Properties:
79 | Path: /hello
80 | Method: get
81 | ```
82 |
83 | ## Add a resource to your application
84 | The application template uses AWS Serverless Application Model (AWS SAM) to define application resources. AWS SAM is an extension of AWS CloudFormation with a simpler syntax for configuring common serverless application resources such as functions, triggers, and APIs. For resources not included in [the SAM specification](https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md), you can use standard [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) resource types.
85 |
86 | ## Fetch, tail, and filter Lambda function logs
87 |
88 | To simplify troubleshooting, SAM CLI has a command called `sam logs`. `sam logs` lets you fetch logs generated by your deployed Lambda function from the command line. In addition to printing the logs on the terminal, this command has several nifty features to help you quickly find the bug.
89 |
90 | `NOTE`: This command works for all AWS Lambda functions; not just the ones you deploy using SAM.
91 |
92 | ```bash
93 | firstlamdba$ sam logs -n HelloWorldFunction --stack-name firstlamdba --tail
94 | ```
95 |
96 | You can find more information and examples about filtering Lambda function logs in the [SAM CLI Documentation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html).
97 |
98 | ## Tests
99 |
100 | Tests are defined in the `tests` folder in this project. Use PIP to install the test dependencies and run tests.
101 |
102 | ```bash
103 | firstlamdba$ pip install -r tests/requirements.txt --user
104 | # unit test
105 | firstlamdba$ python -m pytest tests/unit -v
106 | # integration test, requiring deploying the stack first.
107 | # Create the env variable AWS_SAM_STACK_NAME with the name of the stack we are testing
108 | firstlamdba$ AWS_SAM_STACK_NAME= python -m pytest tests/integration -v
109 | ```
110 |
111 | ## Cleanup
112 |
113 | To delete the sample application that you created, use the AWS CLI. Assuming you used your project name for the stack name, you can run the following:
114 |
115 | ```bash
116 | aws cloudformation delete-stack --stack-name firstlambda
117 | ```
118 |
119 | ## Resources
120 |
121 | See the [AWS SAM developer guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) for an introduction to SAM specification, the SAM CLI, and serverless application concepts.
122 |
123 | Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: [AWS Serverless Application Repository main page](https://aws.amazon.com/serverless/serverlessrepo/)
124 |
--------------------------------------------------------------------------------
/firstlamdba/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/firstlamdba/__init__.py
--------------------------------------------------------------------------------
/firstlamdba/events/event.json:
--------------------------------------------------------------------------------
1 | {"john": [100,80,90], "bob": 90, "bharath": 100}
--------------------------------------------------------------------------------
/firstlamdba/hello_world/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/firstlamdba/hello_world/__init__.py
--------------------------------------------------------------------------------
/firstlamdba/hello_world/app.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 |
4 | def first_lambda(event, context):
5 | return "Hello "+event
6 |
--------------------------------------------------------------------------------
/firstlamdba/hello_world/datatypes.py:
--------------------------------------------------------------------------------
1 | import time
2 | import os
3 | import random
4 |
5 |
6 | global_random_val = random.random()
7 |
8 |
9 | def cold_start_basics(event, context):
10 | local_random_val = random.random()
11 | print(local_random_val)
12 | print(global_random_val)
13 |
14 |
15 | def simple_types(event, context):
16 | print(event)
17 | return event
18 |
19 |
20 | def list_types(event, context):
21 | print(event)
22 | student_scores = {"john": 100, "bob": 90, "bharath": 100}
23 | scores = []
24 | for name in event:
25 | scores.append(student_scores[name])
26 | return scores
27 |
28 |
29 | def dict_types(event, context):
30 | john_scores = event["john"]
31 | for score in john_scores:
32 | print(score)
33 | return event
34 |
35 |
36 | def lambda_handler(event, context):
37 | print("Lambda function ARN:", context.invoked_function_arn)
38 | print("CloudWatch log stream name:", context.log_stream_name)
39 | print("CloudWatch log group name:", context.log_group_name)
40 | print("Lambda Request ID:", context.aws_request_id)
41 | print("Lambda function memory limits in MB:", context.memory_limit_in_mb)
42 | # We have added a 1 second delay so you can see the time remaining in get_remaining_time_in_millis.
43 | time.sleep(4)
44 | print("Lambda time remaining in MS:", context.get_remaining_time_in_millis())
45 | print(os.getenv('restapiurl'))
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/firstlamdba/hello_world/requirements.txt:
--------------------------------------------------------------------------------
1 | requests
--------------------------------------------------------------------------------
/firstlamdba/outputfile.txt:
--------------------------------------------------------------------------------
1 | {"statusCode":200,"body":"\"Lamdas are super easy and cool\""}
--------------------------------------------------------------------------------
/firstlamdba/samconfig.toml:
--------------------------------------------------------------------------------
1 | version = 0.1
2 | [default]
3 | [default.deploy]
4 | [default.deploy.parameters]
5 | stack_name = "firstlambda"
6 | s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1skp8gr29jnoj"
7 | s3_prefix = "firstlambda"
8 | region = "us-east-1"
9 | capabilities = "CAPABILITY_IAM"
10 |
--------------------------------------------------------------------------------
/firstlamdba/template.yaml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: '2010-09-09'
2 | Transform: AWS::Serverless-2016-10-31
3 | Description: >
4 | firstlamdba
5 |
6 | Sample SAM Template for firstlamdba
7 |
8 | Resources:
9 | HelloWorldFunction:
10 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
11 | Properties:
12 | CodeUri: hello_world/
13 | Handler: datatypes.cold_start_basics
14 | Runtime: python3.8
15 | Timeout: 7
16 | Environment:
17 | Variables:
18 | restapiurl: http://dummyurl
19 | dbname: mydb
--------------------------------------------------------------------------------
/firstlamdba/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/firstlamdba/tests/__init__.py
--------------------------------------------------------------------------------
/firstlamdba/tests/integration/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/firstlamdba/tests/integration/__init__.py
--------------------------------------------------------------------------------
/firstlamdba/tests/integration/test_api_gateway.py:
--------------------------------------------------------------------------------
1 | import os
2 | from unittest import TestCase
3 |
4 | import boto3
5 | import requests
6 |
7 | """
8 | Make sure env variable AWS_SAM_STACK_NAME exists with the name of the stack we are going to test.
9 | """
10 |
11 |
12 | class TestApiGateway(TestCase):
13 | api_endpoint: str
14 |
15 | @classmethod
16 | def get_stack_name(cls) -> str:
17 | stack_name = os.environ.get("AWS_SAM_STACK_NAME")
18 | if not stack_name:
19 | raise Exception(
20 | "Cannot find env var AWS_SAM_STACK_NAME. \n"
21 | "Please setup this environment variable with the stack name where we are running integration tests."
22 | )
23 |
24 | return stack_name
25 |
26 | def setUp(self) -> None:
27 | """
28 | Based on the provided env variable AWS_SAM_STACK_NAME,
29 | here we use cloudformation API to find out what the HelloWorldApi URL is
30 | """
31 | stack_name = TestApiGateway.get_stack_name()
32 |
33 | client = boto3.client("cloudformation")
34 |
35 | try:
36 | response = client.describe_stacks(StackName=stack_name)
37 | except Exception as e:
38 | raise Exception(
39 | f"Cannot find stack {stack_name}. \n" f'Please make sure stack with the name "{stack_name}" exists.'
40 | ) from e
41 |
42 | stacks = response["Stacks"]
43 |
44 | stack_outputs = stacks[0]["Outputs"]
45 | api_outputs = [output for output in stack_outputs if output["OutputKey"] == "HelloWorldApi"]
46 | self.assertTrue(api_outputs, f"Cannot find output HelloWorldApi in stack {stack_name}")
47 |
48 | self.api_endpoint = api_outputs[0]["OutputValue"]
49 |
50 | def test_api_gateway(self):
51 | """
52 | Call the API Gateway endpoint and check the response
53 | """
54 | response = requests.get(self.api_endpoint)
55 | self.assertDictEqual(response.json(), {"message": "hello world"})
56 |
--------------------------------------------------------------------------------
/firstlamdba/tests/requirements.txt:
--------------------------------------------------------------------------------
1 | pytest
2 | pytest-mock
3 | boto3
--------------------------------------------------------------------------------
/firstlamdba/tests/unit/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/firstlamdba/tests/unit/__init__.py
--------------------------------------------------------------------------------
/firstlamdba/tests/unit/test_handler.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | import pytest
4 |
5 | from hello_world import app
6 |
7 |
8 | @pytest.fixture()
9 | def apigw_event():
10 | """ Generates API GW Event"""
11 |
12 | return {
13 | "body": '{ "test": "body"}',
14 | "resource": "/{proxy+}",
15 | "requestContext": {
16 | "resourceId": "123456",
17 | "apiId": "1234567890",
18 | "resourcePath": "/{proxy+}",
19 | "httpMethod": "POST",
20 | "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
21 | "accountId": "123456789012",
22 | "identity": {
23 | "apiKey": "",
24 | "userArn": "",
25 | "cognitoAuthenticationType": "",
26 | "caller": "",
27 | "userAgent": "Custom User Agent String",
28 | "user": "",
29 | "cognitoIdentityPoolId": "",
30 | "cognitoIdentityId": "",
31 | "cognitoAuthenticationProvider": "",
32 | "sourceIp": "127.0.0.1",
33 | "accountId": "",
34 | },
35 | "stage": "prod",
36 | },
37 | "queryStringParameters": {"foo": "bar"},
38 | "headers": {
39 | "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
40 | "Accept-Language": "en-US,en;q=0.8",
41 | "CloudFront-Is-Desktop-Viewer": "true",
42 | "CloudFront-Is-SmartTV-Viewer": "false",
43 | "CloudFront-Is-Mobile-Viewer": "false",
44 | "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
45 | "CloudFront-Viewer-Country": "US",
46 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
47 | "Upgrade-Insecure-Requests": "1",
48 | "X-Forwarded-Port": "443",
49 | "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
50 | "X-Forwarded-Proto": "https",
51 | "X-Amz-Cf-Id": "aaaaaaaaaae3VYQb9jd-nvCd-de396Uhbp027Y2JvkCPNLmGJHqlaA==",
52 | "CloudFront-Is-Tablet-Viewer": "false",
53 | "Cache-Control": "max-age=0",
54 | "User-Agent": "Custom User Agent String",
55 | "CloudFront-Forwarded-Proto": "https",
56 | "Accept-Encoding": "gzip, deflate, sdch",
57 | },
58 | "pathParameters": {"proxy": "/examplepath"},
59 | "httpMethod": "POST",
60 | "stageVariables": {"baz": "qux"},
61 | "path": "/examplepath",
62 | }
63 |
64 |
65 | def test_lambda_handler(apigw_event, mocker):
66 |
67 | ret = app.lambda_handler(apigw_event, "")
68 | data = json.loads(ret["body"])
69 |
70 | assert ret["statusCode"] == 200
71 | assert "message" in ret["body"]
72 | assert data["message"] == "hello world"
73 | # assert "location" in data.dict_keys()
74 |
--------------------------------------------------------------------------------
/orders-api/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode
3 |
4 | ### Linux ###
5 | *~
6 |
7 | # temporary files which can be created if a process still has a handle open of a deleted file
8 | .fuse_hidden*
9 |
10 | # KDE directory preferences
11 | .directory
12 |
13 | # Linux trash folder which might appear on any partition or disk
14 | .Trash-*
15 |
16 | # .nfs files are created when an open file is removed but is still being accessed
17 | .nfs*
18 |
19 | ### OSX ###
20 | *.DS_Store
21 | .AppleDouble
22 | .LSOverride
23 |
24 | # Icon must end with two \r
25 | Icon
26 |
27 | # Thumbnails
28 | ._*
29 |
30 | # Files that might appear in the root of a volume
31 | .DocumentRevisions-V100
32 | .fseventsd
33 | .Spotlight-V100
34 | .TemporaryItems
35 | .Trashes
36 | .VolumeIcon.icns
37 | .com.apple.timemachine.donotpresent
38 |
39 | # Directories potentially created on remote AFP share
40 | .AppleDB
41 | .AppleDesktop
42 | Network Trash Folder
43 | Temporary Items
44 | .apdisk
45 |
46 | ### PyCharm ###
47 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
48 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
49 |
50 | # User-specific stuff:
51 | .idea/**/workspace.xml
52 | .idea/**/tasks.xml
53 | .idea/dictionaries
54 |
55 | # Sensitive or high-churn files:
56 | .idea/**/dataSources/
57 | .idea/**/dataSources.ids
58 | .idea/**/dataSources.xml
59 | .idea/**/dataSources.local.xml
60 | .idea/**/sqlDataSources.xml
61 | .idea/**/dynamic.xml
62 | .idea/**/uiDesigner.xml
63 |
64 | # Gradle:
65 | .idea/**/gradle.xml
66 | .idea/**/libraries
67 |
68 | # CMake
69 | cmake-build-debug/
70 |
71 | # Mongo Explorer plugin:
72 | .idea/**/mongoSettings.xml
73 |
74 | ## File-based project format:
75 | *.iws
76 |
77 | ## Plugin-specific files:
78 |
79 | # IntelliJ
80 | /out/
81 |
82 | # mpeltonen/sbt-idea plugin
83 | .idea_modules/
84 |
85 | # JIRA plugin
86 | atlassian-ide-plugin.xml
87 |
88 | # Cursive Clojure plugin
89 | .idea/replstate.xml
90 |
91 | # Ruby plugin and RubyMine
92 | /.rakeTasks
93 |
94 | # Crashlytics plugin (for Android Studio and IntelliJ)
95 | com_crashlytics_export_strings.xml
96 | crashlytics.properties
97 | crashlytics-build.properties
98 | fabric.properties
99 |
100 | ### PyCharm Patch ###
101 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
102 |
103 | # *.iml
104 | # modules.xml
105 | # .idea/misc.xml
106 | # *.ipr
107 |
108 | # Sonarlint plugin
109 | .idea/sonarlint
110 |
111 | ### Python ###
112 | # Byte-compiled / optimized / DLL files
113 | __pycache__/
114 | *.py[cod]
115 | *$py.class
116 |
117 | # C extensions
118 | *.so
119 |
120 | # Distribution / packaging
121 | .Python
122 | build/
123 | develop-eggs/
124 | dist/
125 | downloads/
126 | eggs/
127 | .eggs/
128 | lib/
129 | lib64/
130 | parts/
131 | sdist/
132 | var/
133 | wheels/
134 | *.egg-info/
135 | .installed.cfg
136 | *.egg
137 |
138 | # PyInstaller
139 | # Usually these files are written by a python script from a template
140 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
141 | *.manifest
142 | *.spec
143 |
144 | # Installer logs
145 | pip-log.txt
146 | pip-delete-this-directory.txt
147 |
148 | # Unit test / coverage reports
149 | htmlcov/
150 | .tox/
151 | .coverage
152 | .coverage.*
153 | .cache
154 | .pytest_cache/
155 | nosetests.xml
156 | coverage.xml
157 | *.cover
158 | .hypothesis/
159 |
160 | # Translations
161 | *.mo
162 | *.pot
163 |
164 | # Flask stuff:
165 | instance/
166 | .webassets-cache
167 |
168 | # Scrapy stuff:
169 | .scrapy
170 |
171 | # Sphinx documentation
172 | docs/_build/
173 |
174 | # PyBuilder
175 | target/
176 |
177 | # Jupyter Notebook
178 | .ipynb_checkpoints
179 |
180 | # pyenv
181 | .python-version
182 |
183 | # celery beat schedule file
184 | celerybeat-schedule.*
185 |
186 | # SageMath parsed files
187 | *.sage.py
188 |
189 | # Environments
190 | .env
191 | .venv
192 | env/
193 | venv/
194 | ENV/
195 | env.bak/
196 | venv.bak/
197 |
198 | # Spyder project settings
199 | .spyderproject
200 | .spyproject
201 |
202 | # Rope project settings
203 | .ropeproject
204 |
205 | # mkdocs documentation
206 | /site
207 |
208 | # mypy
209 | .mypy_cache/
210 |
211 | ### VisualStudioCode ###
212 | .vscode/*
213 | !.vscode/settings.json
214 | !.vscode/tasks.json
215 | !.vscode/launch.json
216 | !.vscode/extensions.json
217 | .history
218 |
219 | ### Windows ###
220 | # Windows thumbnail cache files
221 | Thumbs.db
222 | ehthumbs.db
223 | ehthumbs_vista.db
224 |
225 | # Folder config file
226 | Desktop.ini
227 |
228 | # Recycle Bin used on file shares
229 | $RECYCLE.BIN/
230 |
231 | # Windows Installer files
232 | *.cab
233 | *.msi
234 | *.msm
235 | *.msp
236 |
237 | # Windows shortcuts
238 | *.lnk
239 |
240 | # Build folder
241 |
242 | */build/*
243 |
244 | # End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode
--------------------------------------------------------------------------------
/orders-api/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/orders-api/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/orders-api/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/orders-api/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/orders-api/.idea/orders-api.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/orders-api/README.md:
--------------------------------------------------------------------------------
1 | # orders-api
2 |
3 | This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders.
4 |
5 | - hello_world - Code for the application's Lambda function.
6 | - events - Invocation events that you can use to invoke the function.
7 | - tests - Unit tests for the application code.
8 | - template.yaml - A template that defines the application's AWS resources.
9 |
10 | The application uses several AWS resources, including Lambda functions and an API Gateway API. These resources are defined in the `template.yaml` file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code.
11 |
12 | If you prefer to use an integrated development environment (IDE) to build and test your application, you can use the AWS Toolkit.
13 | The AWS Toolkit is an open source plug-in for popular IDEs that uses the SAM CLI to build and deploy serverless applications on AWS. The AWS Toolkit also adds a simplified step-through debugging experience for Lambda function code. See the following links to get started.
14 |
15 | * [PyCharm](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html)
16 | * [IntelliJ](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html)
17 | * [VS Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html)
18 | * [Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html)
19 |
20 | ## Deploy the sample application
21 |
22 | The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API.
23 |
24 | To use the SAM CLI, you need the following tools.
25 |
26 | * SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
27 | * [Python 3 installed](https://www.python.org/downloads/)
28 | * Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community)
29 |
30 | To build and deploy your application for the first time, run the following in your shell:
31 |
32 | ```bash
33 | sam build --use-container
34 | sam deploy --guided
35 | ```
36 |
37 | The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts:
38 |
39 | * **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name.
40 | * **AWS Region**: The AWS region you want to deploy your app to.
41 | * **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes.
42 | * **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modified IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command.
43 | * **Save arguments to samconfig.toml**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application.
44 |
45 | You can find your API Gateway Endpoint URL in the output values displayed after deployment.
46 |
47 | ## Use the SAM CLI to build and test locally
48 |
49 | Build your application with the `sam build --use-container` command.
50 |
51 | ```bash
52 | orders-api$ sam build --use-container
53 | ```
54 |
55 | The SAM CLI installs dependencies defined in `hello_world/requirements.txt`, creates a deployment package, and saves it in the `.aws-sam/build` folder.
56 |
57 | Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project.
58 |
59 | Run functions locally and invoke them with the `sam local invoke` command.
60 |
61 | ```bash
62 | orders-api$ sam local invoke HelloWorldFunction --event events/event.json
63 | ```
64 |
65 | The SAM CLI can also emulate your application's API. Use the `sam local start-api` to run the API locally on port 3000.
66 |
67 | ```bash
68 | orders-api$ sam local start-api
69 | orders-api$ curl http://localhost:3000/
70 | ```
71 |
72 | The SAM CLI reads the application template to determine the API's routes and the functions that they invoke. The `Events` property on each function's definition includes the route and method for each path.
73 |
74 | ```yaml
75 | Events:
76 | HelloWorld:
77 | Type: Api
78 | Properties:
79 | Path: /hello
80 | Method: get
81 | ```
82 |
83 | ## Add a resource to your application
84 | The application template uses AWS Serverless Application Model (AWS SAM) to define application resources. AWS SAM is an extension of AWS CloudFormation with a simpler syntax for configuring common serverless application resources such as functions, triggers, and APIs. For resources not included in [the SAM specification](https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md), you can use standard [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) resource types.
85 |
86 | ## Fetch, tail, and filter Lambda function logs
87 |
88 | To simplify troubleshooting, SAM CLI has a command called `sam logs`. `sam logs` lets you fetch logs generated by your deployed Lambda function from the command line. In addition to printing the logs on the terminal, this command has several nifty features to help you quickly find the bug.
89 |
90 | `NOTE`: This command works for all AWS Lambda functions; not just the ones you deploy using SAM.
91 |
92 | ```bash
93 | orders-api$ sam logs -n HelloWorldFunction --stack-name orders-api --tail
94 | ```
95 |
96 | You can find more information and examples about filtering Lambda function logs in the [SAM CLI Documentation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html).
97 |
98 | ## Tests
99 |
100 | Tests are defined in the `tests` folder in this project. Use PIP to install the test dependencies and run tests.
101 |
102 | ```bash
103 | orders-api$ pip install -r tests/requirements.txt --user
104 | # unit test
105 | orders-api$ python -m pytest tests/unit -v
106 | # integration test, requiring deploying the stack first.
107 | # Create the env variable AWS_SAM_STACK_NAME with the name of the stack we are testing
108 | orders-api$ AWS_SAM_STACK_NAME= python -m pytest tests/integration -v
109 | ```
110 |
111 | ## Cleanup
112 |
113 | To delete the sample application that you created, use the AWS CLI. Assuming you used your project name for the stack name, you can run the following:
114 |
115 | ```bash
116 | aws cloudformation delete-stack --stack-name orders-api
117 | ```
118 |
119 | ## Resources
120 |
121 | See the [AWS SAM developer guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) for an introduction to SAM specification, the SAM CLI, and serverless application concepts.
122 |
123 | Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: [AWS Serverless Application Repository main page](https://aws.amazon.com/serverless/serverlessrepo/)
124 |
--------------------------------------------------------------------------------
/orders-api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/orders-api/__init__.py
--------------------------------------------------------------------------------
/orders-api/events/event.json:
--------------------------------------------------------------------------------
1 | {
2 | "body": "{\"message\": \"hello world\"}",
3 | "resource": "/{proxy+}",
4 | "path": "/path/to/resource",
5 | "httpMethod": "POST",
6 | "isBase64Encoded": false,
7 | "queryStringParameters": {
8 | "foo": "bar"
9 | },
10 | "pathParameters": {
11 | "proxy": "/path/to/resource"
12 | },
13 | "stageVariables": {
14 | "baz": "qux"
15 | },
16 | "headers": {
17 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
18 | "Accept-Encoding": "gzip, deflate, sdch",
19 | "Accept-Language": "en-US,en;q=0.8",
20 | "Cache-Control": "max-age=0",
21 | "CloudFront-Forwarded-Proto": "https",
22 | "CloudFront-Is-Desktop-Viewer": "true",
23 | "CloudFront-Is-Mobile-Viewer": "false",
24 | "CloudFront-Is-SmartTV-Viewer": "false",
25 | "CloudFront-Is-Tablet-Viewer": "false",
26 | "CloudFront-Viewer-Country": "US",
27 | "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
28 | "Upgrade-Insecure-Requests": "1",
29 | "User-Agent": "Custom User Agent String",
30 | "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
31 | "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
32 | "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
33 | "X-Forwarded-Port": "443",
34 | "X-Forwarded-Proto": "https"
35 | },
36 | "requestContext": {
37 | "accountId": "123456789012",
38 | "resourceId": "123456",
39 | "stage": "prod",
40 | "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
41 | "requestTime": "09/Apr/2015:12:34:56 +0000",
42 | "requestTimeEpoch": 1428582896000,
43 | "identity": {
44 | "cognitoIdentityPoolId": null,
45 | "accountId": null,
46 | "cognitoIdentityId": null,
47 | "caller": null,
48 | "accessKey": null,
49 | "sourceIp": "127.0.0.1",
50 | "cognitoAuthenticationType": null,
51 | "cognitoAuthenticationProvider": null,
52 | "userArn": null,
53 | "userAgent": "Custom User Agent String",
54 | "user": null
55 | },
56 | "path": "/prod/path/to/resource",
57 | "resourcePath": "/{proxy+}",
58 | "httpMethod": "POST",
59 | "apiId": "1234567890",
60 | "protocol": "HTTP/1.1"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/orders-api/orders_api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/orders-api/orders_api/__init__.py
--------------------------------------------------------------------------------
/orders-api/orders_api/app.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | # import requests
4 |
5 |
6 | def lambda_handler(event, context):
7 | """Sample pure Lambda function
8 |
9 | Parameters
10 | ----------
11 | event: dict, required
12 | API Gateway Lambda Proxy Input Format
13 |
14 | Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
15 |
16 | context: object, required
17 | Lambda Context runtime methods and attributes
18 |
19 | Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html
20 |
21 | Returns
22 | ------
23 | API Gateway Lambda Proxy Output Format: dict
24 |
25 | Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
26 | """
27 |
28 | # try:
29 | # ip = requests.get("http://checkip.amazonaws.com/")
30 | # except requests.RequestException as e:
31 | # # Send some context about this error to Lambda Logs
32 | # print(e)
33 |
34 | # raise e
35 |
36 | return {
37 | "statusCode": 200,
38 | "body": json.dumps({
39 | "message": "hello world",
40 | # "location": ip.text.replace("\n", "")
41 | }),
42 | }
43 |
--------------------------------------------------------------------------------
/orders-api/orders_api/create.py:
--------------------------------------------------------------------------------
1 | import json
2 | import boto3
3 | import os
4 |
5 | dynamodb = boto3.resource('dynamodb')
6 | table_name = os.environ.get('ORDERS_TABLE')
7 |
8 |
9 | def lambda_handler(event, context):
10 | order = json.loads(event['body'])
11 | table = dynamodb.Table(table_name)
12 | response = table.put_item(TableName=table_name, Item=order)
13 | print(response)
14 | return{
15 | 'statusCode': 201,
16 | 'headers': {},
17 | 'body': json.dumps({'message': 'Order Created'})
18 | }
19 |
--------------------------------------------------------------------------------
/orders-api/orders_api/read.py:
--------------------------------------------------------------------------------
1 | import simplejson as json
2 | import boto3
3 | import os
4 | from boto3.dynamodb.conditions import Key
5 |
6 | dynamodb = boto3.resource('dynamodb')
7 | table_name = os.environ.get('ORDERS_TABLE')
8 |
9 |
10 | def lambda_handler(event, context):
11 | table = dynamodb.Table(table_name)
12 | order_id = int(event['pathParameters']['id'])
13 | response = table.query(KeyConditionExpression=Key('id').eq(order_id))
14 |
15 | return{
16 | 'statusCode': 200,
17 | 'headers': {},
18 | 'body': json.dumps(response['Items'])
19 | }
20 |
--------------------------------------------------------------------------------
/orders-api/orders_api/requirements.txt:
--------------------------------------------------------------------------------
1 | requests
2 | boto3
3 | simplejson
--------------------------------------------------------------------------------
/orders-api/samconfig.toml:
--------------------------------------------------------------------------------
1 | version = 0.1
2 | [default]
3 | [default.deploy]
4 | [default.deploy.parameters]
5 | stack_name = "ordersapi"
6 | s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1skp8gr29jnoj"
7 | s3_prefix = "ordersapi"
8 | region = "us-east-1"
9 | capabilities = "CAPABILITY_IAM"
10 |
--------------------------------------------------------------------------------
/orders-api/template.yaml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: '2010-09-09'
2 | Transform: AWS::Serverless-2016-10-31
3 | Description: >
4 | orders-api
5 |
6 | Globals:
7 | Function:
8 | Runtime: python3.8
9 | Timeout: 30
10 | Environment:
11 | Variables:
12 | ORDERS_TABLE: !Ref OrdersTable
13 |
14 | Resources:
15 | OrdersTable:
16 | Type: AWS::Serverless::SimpleTable
17 | Properties:
18 | PrimaryKey:
19 | Name: id
20 | Type: Number
21 | CreateOrderFunction:
22 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
23 | Properties:
24 | CodeUri: orders_api/
25 | Handler: create.lambda_handler
26 | Events:
27 | CreateOrders:
28 | Type: Api
29 | Properties:
30 | Path: /orders
31 | Method: POST
32 | Policies:
33 | - DynamoDBCrudPolicy:
34 | TableName: !Ref OrdersTable
35 | ReadOrderFunction:
36 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
37 | Properties:
38 | CodeUri: orders_api/
39 | Handler: read.lambda_handler
40 | Events:
41 | ReadOrders:
42 | Type: Api
43 | Properties:
44 | Path: /orders/{id}
45 | Method: GET
46 | Policies:
47 | - DynamoDBReadPolicy:
48 | TableName: !Ref OrdersTable
49 | Outputs:
50 | CreateOrdersAPI:
51 | Description: "API Gateway endpoint url for creating orders"
52 | Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/orders"
53 | CreateOrderFunction:
54 | Description: "Create Order function ARN"
55 | Value: !GetAtt CreateOrderFunction.Arn
56 | CreateOrderFunctionIamRole:
57 | Description: "Create Order function IAM Role ARN"
58 | Value: !GetAtt CreateOrderFunctionRole.Arn
--------------------------------------------------------------------------------
/orders-api/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/orders-api/tests/__init__.py
--------------------------------------------------------------------------------
/orders-api/tests/integration/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/orders-api/tests/integration/__init__.py
--------------------------------------------------------------------------------
/orders-api/tests/integration/test_api_gateway.py:
--------------------------------------------------------------------------------
1 | import os
2 | from unittest import TestCase
3 |
4 | import boto3
5 | import requests
6 |
7 | """
8 | Make sure env variable AWS_SAM_STACK_NAME exists with the name of the stack we are going to test.
9 | """
10 |
11 |
12 | class TestApiGateway(TestCase):
13 | api_endpoint: str
14 |
15 | @classmethod
16 | def get_stack_name(cls) -> str:
17 | stack_name = os.environ.get("AWS_SAM_STACK_NAME")
18 | if not stack_name:
19 | raise Exception(
20 | "Cannot find env var AWS_SAM_STACK_NAME. \n"
21 | "Please setup this environment variable with the stack name where we are running integration tests."
22 | )
23 |
24 | return stack_name
25 |
26 | def setUp(self) -> None:
27 | """
28 | Based on the provided env variable AWS_SAM_STACK_NAME,
29 | here we use cloudformation API to find out what the HelloWorldApi URL is
30 | """
31 | stack_name = TestApiGateway.get_stack_name()
32 |
33 | client = boto3.client("cloudformation")
34 |
35 | try:
36 | response = client.describe_stacks(StackName=stack_name)
37 | except Exception as e:
38 | raise Exception(
39 | f"Cannot find stack {stack_name}. \n" f'Please make sure stack with the name "{stack_name}" exists.'
40 | ) from e
41 |
42 | stacks = response["Stacks"]
43 |
44 | stack_outputs = stacks[0]["Outputs"]
45 | api_outputs = [output for output in stack_outputs if output["OutputKey"] == "HelloWorldApi"]
46 | self.assertTrue(api_outputs, f"Cannot find output HelloWorldApi in stack {stack_name}")
47 |
48 | self.api_endpoint = api_outputs[0]["OutputValue"]
49 |
50 | def test_api_gateway(self):
51 | """
52 | Call the API Gateway endpoint and check the response
53 | """
54 | response = requests.get(self.api_endpoint)
55 | self.assertDictEqual(response.json(), {"message": "hello world"})
56 |
--------------------------------------------------------------------------------
/orders-api/tests/requirements.txt:
--------------------------------------------------------------------------------
1 | pytest
2 | pytest-mock
3 | boto3
--------------------------------------------------------------------------------
/orders-api/tests/unit/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/orders-api/tests/unit/__init__.py
--------------------------------------------------------------------------------
/orders-api/tests/unit/test_handler.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | import pytest
4 |
5 | from hello_world import app
6 |
7 |
8 | @pytest.fixture()
9 | def apigw_event():
10 | """ Generates API GW Event"""
11 |
12 | return {
13 | "body": '{ "test": "body"}',
14 | "resource": "/{proxy+}",
15 | "requestContext": {
16 | "resourceId": "123456",
17 | "apiId": "1234567890",
18 | "resourcePath": "/{proxy+}",
19 | "httpMethod": "POST",
20 | "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
21 | "accountId": "123456789012",
22 | "identity": {
23 | "apiKey": "",
24 | "userArn": "",
25 | "cognitoAuthenticationType": "",
26 | "caller": "",
27 | "userAgent": "Custom User Agent String",
28 | "user": "",
29 | "cognitoIdentityPoolId": "",
30 | "cognitoIdentityId": "",
31 | "cognitoAuthenticationProvider": "",
32 | "sourceIp": "127.0.0.1",
33 | "accountId": "",
34 | },
35 | "stage": "prod",
36 | },
37 | "queryStringParameters": {"foo": "bar"},
38 | "headers": {
39 | "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
40 | "Accept-Language": "en-US,en;q=0.8",
41 | "CloudFront-Is-Desktop-Viewer": "true",
42 | "CloudFront-Is-SmartTV-Viewer": "false",
43 | "CloudFront-Is-Mobile-Viewer": "false",
44 | "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
45 | "CloudFront-Viewer-Country": "US",
46 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
47 | "Upgrade-Insecure-Requests": "1",
48 | "X-Forwarded-Port": "443",
49 | "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
50 | "X-Forwarded-Proto": "https",
51 | "X-Amz-Cf-Id": "aaaaaaaaaae3VYQb9jd-nvCd-de396Uhbp027Y2JvkCPNLmGJHqlaA==",
52 | "CloudFront-Is-Tablet-Viewer": "false",
53 | "Cache-Control": "max-age=0",
54 | "User-Agent": "Custom User Agent String",
55 | "CloudFront-Forwarded-Proto": "https",
56 | "Accept-Encoding": "gzip, deflate, sdch",
57 | },
58 | "pathParameters": {"proxy": "/examplepath"},
59 | "httpMethod": "POST",
60 | "stageVariables": {"baz": "qux"},
61 | "path": "/examplepath",
62 | }
63 |
64 |
65 | def test_lambda_handler(apigw_event, mocker):
66 |
67 | ret = app.lambda_handler(apigw_event, "")
68 | data = json.loads(ret["body"])
69 |
70 | assert ret["statusCode"] == 200
71 | assert "message" in ret["body"]
72 | assert data["message"] == "hello world"
73 | # assert "location" in data.dict_keys()
74 |
--------------------------------------------------------------------------------
/patientcheckout/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/patientcheckout/.DS_Store
--------------------------------------------------------------------------------
/patientcheckout/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/patientcheckout/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/patientcheckout/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/patientcheckout/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/patientcheckout/.idea/patientcheckout.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/patientcheckout/README.md:
--------------------------------------------------------------------------------
1 | # patientcheckout
2 |
3 | This project contains source code and supporting files for a serverless application that you can deploy with the SAM CLI. It includes the following files and folders.
4 |
5 | - hello_world - Code for the application's Lambda function.
6 | - events - Invocation events that you can use to invoke the function.
7 | - tests - Unit tests for the application code.
8 | - template.yaml - A template that defines the application's AWS resources.
9 |
10 | The application uses several AWS resources, including Lambda functions and an API Gateway API. These resources are defined in the `template.yaml` file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code.
11 |
12 | If you prefer to use an integrated development environment (IDE) to build and test your application, you can use the AWS Toolkit.
13 | The AWS Toolkit is an open source plug-in for popular IDEs that uses the SAM CLI to build and deploy serverless applications on AWS. The AWS Toolkit also adds a simplified step-through debugging experience for Lambda function code. See the following links to get started.
14 |
15 | * [PyCharm](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html)
16 | * [IntelliJ](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html)
17 | * [VS Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html)
18 | * [Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html)
19 |
20 | ## Deploy the sample application
21 |
22 | The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. It uses Docker to run your functions in an Amazon Linux environment that matches Lambda. It can also emulate your application's build environment and API.
23 |
24 | To use the SAM CLI, you need the following tools.
25 |
26 | * SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
27 | * [Python 3 installed](https://www.python.org/downloads/)
28 | * Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community)
29 |
30 | To build and deploy your application for the first time, run the following in your shell:
31 |
32 | ```bash
33 | sam build --use-container
34 | sam deploy --guided
35 | ```
36 |
37 | The first command will build the source of your application. The second command will package and deploy your application to AWS, with a series of prompts:
38 |
39 | * **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name.
40 | * **AWS Region**: The AWS region you want to deploy your app to.
41 | * **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes.
42 | * **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modified IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command.
43 | * **Save arguments to samconfig.toml**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application.
44 |
45 | You can find your API Gateway Endpoint URL in the output values displayed after deployment.
46 |
47 | ## Use the SAM CLI to build and test locally
48 |
49 | Build your application with the `sam build --use-container` command.
50 |
51 | ```bash
52 | patientcheckout$ sam build --use-container
53 | ```
54 |
55 | The SAM CLI installs dependencies defined in `hello_world/requirements.txt`, creates a deployment package, and saves it in the `.aws-sam/build` folder.
56 |
57 | Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project.
58 |
59 | Run functions locally and invoke them with the `sam local invoke` command.
60 |
61 | ```bash
62 | patientcheckout$ sam local invoke HelloWorldFunction --event events/event.json
63 | ```
64 |
65 | The SAM CLI can also emulate your application's API. Use the `sam local start-api` to run the API locally on port 3000.
66 |
67 | ```bash
68 | patientcheckout$ sam local start-api
69 | patientcheckout$ curl http://localhost:3000/
70 | ```
71 |
72 | The SAM CLI reads the application template to determine the API's routes and the functions that they invoke. The `Events` property on each function's definition includes the route and method for each path.
73 |
74 | ```yaml
75 | Events:
76 | HelloWorld:
77 | Type: Api
78 | Properties:
79 | Path: /hello
80 | Method: get
81 | ```
82 |
83 | ## Add a resource to your application
84 | The application template uses AWS Serverless Application Model (AWS SAM) to define application resources. AWS SAM is an extension of AWS CloudFormation with a simpler syntax for configuring common serverless application resources such as functions, triggers, and APIs. For resources not included in [the SAM specification](https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md), you can use standard [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) resource types.
85 |
86 | ## Fetch, tail, and filter Lambda function logs
87 |
88 | To simplify troubleshooting, SAM CLI has a command called `sam logs`. `sam logs` lets you fetch logs generated by your deployed Lambda function from the command line. In addition to printing the logs on the terminal, this command has several nifty features to help you quickly find the bug.
89 |
90 | `NOTE`: This command works for all AWS Lambda functions; not just the ones you deploy using SAM.
91 |
92 | ```bash
93 | patientcheckout$ sam logs -n HelloWorldFunction --stack-name patientcheckout --tail
94 | ```
95 |
96 | You can find more information and examples about filtering Lambda function logs in the [SAM CLI Documentation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html).
97 |
98 | ## Tests
99 |
100 | Tests are defined in the `tests` folder in this project. Use PIP to install the test dependencies and run tests.
101 |
102 | ```bash
103 | patientcheckout$ pip install -r tests/requirements.txt --user
104 | # unit test
105 | patientcheckout$ python -m pytest tests/unit -v
106 | # integration test, requiring deploying the stack first.
107 | # Create the env variable AWS_SAM_STACK_NAME with the name of the stack we are testing
108 | patientcheckout$ AWS_SAM_STACK_NAME= python -m pytest tests/integration -v
109 | ```
110 |
111 | ## Cleanup
112 |
113 | To delete the sample application that you created, use the AWS CLI. Assuming you used your project name for the stack name, you can run the following:
114 |
115 | ```bash
116 | aws cloudformation delete-stack --stack-name patientcheckout
117 | ```
118 |
119 | ## Resources
120 |
121 | See the [AWS SAM developer guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) for an introduction to SAM specification, the SAM CLI, and serverless application concepts.
122 |
123 | Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: [AWS Serverless Application Repository main page](https://aws.amazon.com/serverless/serverlessrepo/)
124 |
--------------------------------------------------------------------------------
/patientcheckout/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/patientcheckout/__init__.py
--------------------------------------------------------------------------------
/patientcheckout/events/event.json:
--------------------------------------------------------------------------------
1 | {
2 | "body": "{\"message\": \"hello world\"}",
3 | "resource": "/{proxy+}",
4 | "path": "/path/to/resource",
5 | "httpMethod": "POST",
6 | "isBase64Encoded": false,
7 | "queryStringParameters": {
8 | "foo": "bar"
9 | },
10 | "pathParameters": {
11 | "proxy": "/path/to/resource"
12 | },
13 | "stageVariables": {
14 | "baz": "qux"
15 | },
16 | "headers": {
17 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
18 | "Accept-Encoding": "gzip, deflate, sdch",
19 | "Accept-Language": "en-US,en;q=0.8",
20 | "Cache-Control": "max-age=0",
21 | "CloudFront-Forwarded-Proto": "https",
22 | "CloudFront-Is-Desktop-Viewer": "true",
23 | "CloudFront-Is-Mobile-Viewer": "false",
24 | "CloudFront-Is-SmartTV-Viewer": "false",
25 | "CloudFront-Is-Tablet-Viewer": "false",
26 | "CloudFront-Viewer-Country": "US",
27 | "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
28 | "Upgrade-Insecure-Requests": "1",
29 | "User-Agent": "Custom User Agent String",
30 | "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
31 | "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
32 | "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
33 | "X-Forwarded-Port": "443",
34 | "X-Forwarded-Proto": "https"
35 | },
36 | "requestContext": {
37 | "accountId": "123456789012",
38 | "resourceId": "123456",
39 | "stage": "prod",
40 | "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
41 | "requestTime": "09/Apr/2015:12:34:56 +0000",
42 | "requestTimeEpoch": 1428582896000,
43 | "identity": {
44 | "cognitoIdentityPoolId": null,
45 | "accountId": null,
46 | "cognitoIdentityId": null,
47 | "caller": null,
48 | "accessKey": null,
49 | "sourceIp": "127.0.0.1",
50 | "cognitoAuthenticationType": null,
51 | "cognitoAuthenticationProvider": null,
52 | "userArn": null,
53 | "userAgent": "Custom User Agent String",
54 | "user": null
55 | },
56 | "path": "/prod/path/to/resource",
57 | "resourcePath": "/{proxy+}",
58 | "httpMethod": "POST",
59 | "apiId": "1234567890",
60 | "protocol": "HTTP/1.1"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/patientcheckout/patientData.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "firstName":"Bharath",
4 | "middleName":"Reddy",
5 | "lastName":"Thippireddy",
6 | "ssn": "123456789"
7 | },
8 | {
9 | "firstName":"Sarath",
10 | "middleName":"Reddy",
11 | "lastName":"Thippireddy",
12 | "ssn": "123456781"
13 | }
14 |
--------------------------------------------------------------------------------
/patientcheckout/patient_checkout/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/patientcheckout/patient_checkout/__init__.py
--------------------------------------------------------------------------------
/patientcheckout/patient_checkout/app.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | # import requests
4 |
5 |
6 | def lambda_handler(event, context):
7 | """Sample pure Lambda function
8 |
9 | Parameters
10 | ----------
11 | event: dict, required
12 | API Gateway Lambda Proxy Input Format
13 |
14 | Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
15 |
16 | context: object, required
17 | Lambda Context runtime methods and attributes
18 |
19 | Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html
20 |
21 | Returns
22 | ------
23 | API Gateway Lambda Proxy Output Format: dict
24 |
25 | Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
26 | """
27 |
28 | # try:
29 | # ip = requests.get("http://checkip.amazonaws.com/")
30 | # except requests.RequestException as e:
31 | # # Send some context about this error to Lambda Logs
32 | # print(e)
33 |
34 | # raise e
35 |
36 | return {
37 | "statusCode": 200,
38 | "body": json.dumps({
39 | "message": "hello world",
40 | # "location": ip.text.replace("\n", "")
41 | }),
42 | }
43 |
--------------------------------------------------------------------------------
/patientcheckout/patient_checkout/billmanagement.py:
--------------------------------------------------------------------------------
1 | def lambda_handler(event, context):
2 | message = event['Records'][0]['Sns']['Message']
3 | print(message)
4 |
--------------------------------------------------------------------------------
/patientcheckout/patient_checkout/claimmanagement.py:
--------------------------------------------------------------------------------
1 | def lambda_handler(event, context):
2 | for each_record in event['Records']:
3 | print(each_record['body'])
4 |
--------------------------------------------------------------------------------
/patientcheckout/patient_checkout/errorhandler.py:
--------------------------------------------------------------------------------
1 | def lambda_handler(event, context):
2 | message = event['Records'][0]['Sns']['Message']
3 | print(message)
4 |
--------------------------------------------------------------------------------
/patientcheckout/patient_checkout/patientcheckout.py:
--------------------------------------------------------------------------------
1 | import boto3
2 | import json
3 | import os
4 | import logging
5 |
6 |
7 | s3 = boto3.client('s3')
8 | sns_client = boto3.client('sns')
9 | logger = logging.getLogger('patientcheckout')
10 | logger.setLevel(logging.INFO)
11 |
12 |
13 | def lambda_handler(event, context):
14 | topic = os.environ.get('PATIENT_CHECKOUT_TOPIC')
15 | bucket_name = event['Records'][0]['s3']['bucket']['name']
16 | file_key = event['Records'][0]['s3']['object']['key']
17 | logger.info('Reading {} from {}'.format(file_key, bucket_name))
18 | obj = s3.get_object(Bucket=bucket_name, Key=file_key)
19 | file_content = obj['Body'].read().decode('utf-8')
20 | checkout_events = json.loads(file_content)
21 | for each_event in checkout_events:
22 | logger.info('Messaging being published')
23 | logger.info(each_event)
24 | sns_client.publish(
25 | TopicArn=topic,
26 | Message=json.dumps({'default': json.dumps(each_event)}),
27 | MessageStructure='json'
28 | )
29 |
--------------------------------------------------------------------------------
/patientcheckout/patient_checkout/requirements.txt:
--------------------------------------------------------------------------------
1 | requests
2 | boto3
--------------------------------------------------------------------------------
/patientcheckout/samconfig.toml:
--------------------------------------------------------------------------------
1 | version = 0.1
2 | [default]
3 | [default.deploy]
4 | [default.deploy.parameters]
5 | stack_name = "patientcheckout"
6 | s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1skp8gr29jnoj"
7 | s3_prefix = "patientcheckout"
8 | region = "us-east-1"
9 | capabilities = "CAPABILITY_IAM"
10 |
--------------------------------------------------------------------------------
/patientcheckout/template.yaml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: '2010-09-09'
2 | Transform: AWS::Serverless-2016-10-31
3 | Description: >
4 | patientcheckout
5 |
6 | Globals:
7 | Function:
8 | Timeout: 20
9 |
10 | Resources:
11 | PatientCheckoutDLQ:
12 | Type: AWS::SNS::Topic
13 | PatientCheckoutTopic:
14 | Type: AWS::SNS::Topic
15 | PatientCheckoutBucket:
16 | Type: AWS::S3::Bucket
17 | Properties:
18 | BucketName: !Sub ${AWS::StackName}-${AWS::AccountId}-${AWS::Region}
19 | PatientCheckoutFunction:
20 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
21 | Properties:
22 | CodeUri: patient_checkout/
23 | Handler: patientcheckout.lambda_handler
24 | Runtime: python3.8
25 | DeadLetterQueue:
26 | Type: SNS
27 | TargetArn: !Ref PatientCheckoutDLQ
28 | Policies:
29 | - S3ReadPolicy:
30 | BucketName: !Sub ${AWS::StackName}-${AWS::AccountId}-${AWS::Region}
31 | - SNSPublishMessagePolicy:
32 | TopicName: !GetAtt PatientCheckoutTopic.TopicName
33 | Environment:
34 | Variables:
35 | PATIENT_CHECKOUT_TOPIC: !Ref PatientCheckoutTopic
36 | Events:
37 | S3Event:
38 | Type: S3
39 | Properties:
40 | Bucket: !Ref PatientCheckoutBucket
41 | Events: s3:ObjectCreated:*
42 | BillManagementFunction:
43 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
44 | Properties:
45 | CodeUri: patient_checkout/
46 | Handler: billmanagement.lambda_handler
47 | Runtime: python3.8
48 | Events:
49 | SNSEvent:
50 | Type: SNS
51 | Properties:
52 | Topic: !Ref PatientCheckoutTopic
53 | ErrorHandlerFunction:
54 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
55 | Properties:
56 | CodeUri: patient_checkout/
57 | Handler: errorhandler.lambda_handler
58 | Runtime: python3.8
59 | Events:
60 | SNSEvent:
61 | Type: SNS
62 | Properties:
63 | Topic: !Ref PatientCheckoutDLQ
--------------------------------------------------------------------------------
/patientcheckout/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/patientcheckout/tests/__init__.py
--------------------------------------------------------------------------------
/patientcheckout/tests/integration/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/patientcheckout/tests/integration/__init__.py
--------------------------------------------------------------------------------
/patientcheckout/tests/integration/test_api_gateway.py:
--------------------------------------------------------------------------------
1 | import os
2 | from unittest import TestCase
3 |
4 | import boto3
5 | import requests
6 |
7 | """
8 | Make sure env variable AWS_SAM_STACK_NAME exists with the name of the stack we are going to test.
9 | """
10 |
11 |
12 | class TestApiGateway(TestCase):
13 | api_endpoint: str
14 |
15 | @classmethod
16 | def get_stack_name(cls) -> str:
17 | stack_name = os.environ.get("AWS_SAM_STACK_NAME")
18 | if not stack_name:
19 | raise Exception(
20 | "Cannot find env var AWS_SAM_STACK_NAME. \n"
21 | "Please setup this environment variable with the stack name where we are running integration tests."
22 | )
23 |
24 | return stack_name
25 |
26 | def setUp(self) -> None:
27 | """
28 | Based on the provided env variable AWS_SAM_STACK_NAME,
29 | here we use cloudformation API to find out what the HelloWorldApi URL is
30 | """
31 | stack_name = TestApiGateway.get_stack_name()
32 |
33 | client = boto3.client("cloudformation")
34 |
35 | try:
36 | response = client.describe_stacks(StackName=stack_name)
37 | except Exception as e:
38 | raise Exception(
39 | f"Cannot find stack {stack_name}. \n" f'Please make sure stack with the name "{stack_name}" exists.'
40 | ) from e
41 |
42 | stacks = response["Stacks"]
43 |
44 | stack_outputs = stacks[0]["Outputs"]
45 | api_outputs = [output for output in stack_outputs if output["OutputKey"] == "HelloWorldApi"]
46 | self.assertTrue(api_outputs, f"Cannot find output HelloWorldApi in stack {stack_name}")
47 |
48 | self.api_endpoint = api_outputs[0]["OutputValue"]
49 |
50 | def test_api_gateway(self):
51 | """
52 | Call the API Gateway endpoint and check the response
53 | """
54 | response = requests.get(self.api_endpoint)
55 | self.assertDictEqual(response.json(), {"message": "hello world"})
56 |
--------------------------------------------------------------------------------
/patientcheckout/tests/requirements.txt:
--------------------------------------------------------------------------------
1 | pytest
2 | pytest-mock
3 | boto3
--------------------------------------------------------------------------------
/patientcheckout/tests/unit/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharaththippireddy/serverlessusingawslambdaforpythondevelopers/86ee7b6683d8d362cce54a07bc60df789e718c10/patientcheckout/tests/unit/__init__.py
--------------------------------------------------------------------------------
/patientcheckout/tests/unit/test_handler.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | import pytest
4 |
5 | from hello_world import app
6 |
7 |
8 | @pytest.fixture()
9 | def apigw_event():
10 | """ Generates API GW Event"""
11 |
12 | return {
13 | "body": '{ "test": "body"}',
14 | "resource": "/{proxy+}",
15 | "requestContext": {
16 | "resourceId": "123456",
17 | "apiId": "1234567890",
18 | "resourcePath": "/{proxy+}",
19 | "httpMethod": "POST",
20 | "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
21 | "accountId": "123456789012",
22 | "identity": {
23 | "apiKey": "",
24 | "userArn": "",
25 | "cognitoAuthenticationType": "",
26 | "caller": "",
27 | "userAgent": "Custom User Agent String",
28 | "user": "",
29 | "cognitoIdentityPoolId": "",
30 | "cognitoIdentityId": "",
31 | "cognitoAuthenticationProvider": "",
32 | "sourceIp": "127.0.0.1",
33 | "accountId": "",
34 | },
35 | "stage": "prod",
36 | },
37 | "queryStringParameters": {"foo": "bar"},
38 | "headers": {
39 | "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
40 | "Accept-Language": "en-US,en;q=0.8",
41 | "CloudFront-Is-Desktop-Viewer": "true",
42 | "CloudFront-Is-SmartTV-Viewer": "false",
43 | "CloudFront-Is-Mobile-Viewer": "false",
44 | "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
45 | "CloudFront-Viewer-Country": "US",
46 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
47 | "Upgrade-Insecure-Requests": "1",
48 | "X-Forwarded-Port": "443",
49 | "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
50 | "X-Forwarded-Proto": "https",
51 | "X-Amz-Cf-Id": "aaaaaaaaaae3VYQb9jd-nvCd-de396Uhbp027Y2JvkCPNLmGJHqlaA==",
52 | "CloudFront-Is-Tablet-Viewer": "false",
53 | "Cache-Control": "max-age=0",
54 | "User-Agent": "Custom User Agent String",
55 | "CloudFront-Forwarded-Proto": "https",
56 | "Accept-Encoding": "gzip, deflate, sdch",
57 | },
58 | "pathParameters": {"proxy": "/examplepath"},
59 | "httpMethod": "POST",
60 | "stageVariables": {"baz": "qux"},
61 | "path": "/examplepath",
62 | }
63 |
64 |
65 | def test_lambda_handler(apigw_event, mocker):
66 |
67 | ret = app.lambda_handler(apigw_event, "")
68 | data = json.loads(ret["body"])
69 |
70 | assert ret["statusCode"] == 200
71 | assert "message" in ret["body"]
72 | assert data["message"] == "hello world"
73 | # assert "location" in data.dict_keys()
74 |
--------------------------------------------------------------------------------