├── .gitignore ├── README.md ├── functions ├── hello │ ├── lib │ │ └── function.py │ ├── requirements.txt │ ├── setup.py │ └── tests │ │ ├── __init__.py │ │ └── function.py └── joke │ ├── lib │ └── function.py │ ├── requirements.txt │ ├── setup.py │ └── tests │ ├── __init__.py │ └── function.py ├── package.json └── serverless.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .serverless/ 3 | venv/ 4 | *.egg-info/ 5 | __pycache__/ 6 | node_modules/ 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | This is a pretty basic template that I use when working with 4 | [Serverless](https://serverless.com) and Python. 5 | 6 | For a more in-depth explanation, please see: 7 | 8 | https://dev.to/egrajeda/my-python-serverless-setup-ca1 -------------------------------------------------------------------------------- /functions/hello/lib/function.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def main(event, context): 5 | return { 6 | "statusCode": 200, 7 | "body": "Hello! My name is {}.".format(os.environ['NAME']) 8 | } 9 | -------------------------------------------------------------------------------- /functions/hello/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/egrajeda/serverless-python-template/7870633b585da596e346c5a0e5364d501ff985cc/functions/hello/requirements.txt -------------------------------------------------------------------------------- /functions/hello/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup(name='hello', 4 | packages=find_packages(), 5 | test_suite='tests') 6 | -------------------------------------------------------------------------------- /functions/hello/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/egrajeda/serverless-python-template/7870633b585da596e346c5a0e5364d501ff985cc/functions/hello/tests/__init__.py -------------------------------------------------------------------------------- /functions/hello/tests/function.py: -------------------------------------------------------------------------------- 1 | import os 2 | import unittest 3 | 4 | from lib.function import main 5 | 6 | 7 | class TestSuite(unittest.TestCase): 8 | def test_main(self): 9 | os.environ["NAME"] = "Jane Doe" 10 | self.assertEqual(main({}, {}), { 11 | "statusCode": 200, 12 | "body": "Hello! My name is Jane Doe." 13 | }) 14 | -------------------------------------------------------------------------------- /functions/joke/lib/function.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../venv/lib/python3.6/site-packages")) 4 | 5 | import requests 6 | 7 | 8 | def main(event, context): 9 | response = requests.get("https://api.icndb.com/jokes/random").json() 10 | return { 11 | "statusCode": 200, 12 | "body": response["value"]["joke"] 13 | } 14 | -------------------------------------------------------------------------------- /functions/joke/requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.19.1 2 | -------------------------------------------------------------------------------- /functions/joke/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup(name='joke', 4 | packages=find_packages(), 5 | test_suite='tests') 6 | -------------------------------------------------------------------------------- /functions/joke/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/egrajeda/serverless-python-template/7870633b585da596e346c5a0e5364d501ff985cc/functions/joke/tests/__init__.py -------------------------------------------------------------------------------- /functions/joke/tests/function.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from lib.function import main 4 | 5 | 6 | class TestSuite(unittest.TestCase): 7 | def test_main(self): 8 | self.assertTrue(main({}, {})) 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "serverless-plugin-aws-alerts": "^1.2.4" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /serverless.yml: -------------------------------------------------------------------------------- 1 | service: chatty 2 | 3 | provider: 4 | name: aws 5 | runtime: python3.6 6 | stage: dev 7 | 8 | package: 9 | individually: true 10 | 11 | functions: 12 | hello: 13 | handler: functions/hello/lib/function.main 14 | environment: 15 | NAME: ${opt:name, "John Doe"} 16 | events: 17 | - http: GET hello 18 | package: 19 | exclude: 20 | - ./** 21 | include: 22 | - functions/hello/lib/function.py 23 | - functions/hello/venv/lib/python3.6/site-packages/** 24 | 25 | joke: 26 | handler: functions/joke/lib/function.main 27 | events: 28 | - http: GET joke 29 | package: 30 | exclude: 31 | - ./** 32 | include: 33 | - functions/joke/lib/function.py 34 | - functions/joke/venv/lib/python3.6/site-packages/** 35 | 36 | plugins: 37 | - serverless-plugin-aws-alerts 38 | 39 | custom: 40 | alerts: 41 | stages: 42 | - production 43 | topics: 44 | alarm: 45 | topic: ${self:service}-${self:custom.config.stage}-alerts 46 | notifications: 47 | - protocol: email 48 | endpoint: me@egrajeda.com 49 | alarms: 50 | - functionErrors 51 | - functionThrottles 52 | config: 53 | region: ${opt:region, self:provider.region} 54 | stage: ${opt:stage, self:provider.stage} --------------------------------------------------------------------------------