Skip to content

New example: PyMongo #448

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ serverless install -u https://github.com/serverless/examples/tree/master/folder-
| [Aws Python Pynamodb S3 Sigurl](https://github.com/serverless/examples/tree/master/aws-python-pynamodb-s3-sigurl) <br/> Serverless signed uploader REST API using pynamodb, s3 generated events, custom log format, and DRY serverless.yml with custom section | python |
| [Aws Rest With Dynamodb](https://github.com/serverless/examples/tree/master/aws-python-rest-api-with-dynamodb) <br/> Serverless CRUD service exposing a REST HTTP interface | python |
| [Aws Rest With Faunadb](https://github.com/serverless/examples/tree/master/aws-python-rest-api-with-faunadb) <br/> Serverless CRUD service exposing a REST HTTP interface | python |
| [Aws Python Rest Api With Pymongo](https://github.com/serverless/examples/tree/master/aws-python-rest-api-with-pymongo) <br/> Serverless pymongo example | python |
| [Aws Rest With Pynamodb](https://github.com/serverless/examples/tree/master/aws-python-rest-api-with-pynamodb) <br/> Serverless CRUD service exposing a REST HTTP interface | python |
| [Aws Scheduled Cron](https://github.com/serverless/examples/tree/master/aws-python-scheduled-cron) <br/> Example of creating a function that runs as a cron job using the serverless `schedule` event | python |
| [Aws Simple Http Endpoint](https://github.com/serverless/examples/tree/master/aws-python-simple-http-endpoint) <br/> Example demonstrates how to setup a simple HTTP GET endpoint with python | python |
Expand Down
174 changes: 174 additions & 0 deletions aws-python-rest-api-with-pymongo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<!--
title: 'AWS Python Rest API with Pymongo'
description: 'AWS Python Rest API with Pymongo Example'
layout: Doc
framework: v1
platform: AWS
language: python
authorLink: 'https://github.com/gsweene2'
authorName: 'Garrett Sweeney'
authorAvatar: ''
-->
# aws-python-rest-api-with-dynamodb

## Create the Mongo Atlas backend

1. Follow `Part 1: Cluster Creation` of [this artice](https://medium.com/swlh/creating-a-mongodb-cluster-and-inserting-a-document-with-python-ac90cc9d979c) to create a cluster on Mongo Atlas' Free Tier.

## Deploy the Serverless API to AWS

1. Install Serverless

```
npm install -g serverless
```

2. Install `serverless-python-requirements`

```
npm i --save serverless-python-requirements
```

3. Define necessary environment variables

Append this to your ~/.bash_profile

```
export MONGO_DB_USER=
export MONGO_DB_PASS=
export MONGO_DB_NAME=SampleDatabase
export MONGO_COLLECTION_NAME=SampleCollection
export MONGO_DB_URL=
```

4. Deploy the API

```
sls deploy
```

Your results should look something like this:
```
Serverless: Stack update finished...
Service Information
service: serverless-pymongo-item-api
stage: dev
region: us-east-1
stack: serverless-pymongo-item-api-dev
resources: 28
api keys:
None
endpoints:
POST - https://0xfyi15qci.execute-api.us-east-1.amazonaws.com/dev/item
GET - https://0xfyi15qci.execute-api.us-east-1.amazonaws.com/dev/item
GET - https://0xfyi15qci.execute-api.us-east-1.amazonaws.com/dev/item/{id}
DELETE - https://0xfyi15qci.execute-api.us-east-1.amazonaws.com/dev/item/{id}
functions:
create: serverless-pymongo-item-api-dev-create
list: serverless-pymongo-item-api-dev-list
get: serverless-pymongo-item-api-dev-get
delete: serverless-pymongo-item-api-dev-delete
layers:
None
Serverless: Removing old service artifacts from S3...
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.
```

## Test the API by Creating and Querying items

Substitute your endpoints into these curl commands to test the Create, Read, and Delete operations

### CREATE

```
curl --request POST \
--url https://0xfyi15qci.execute-api.us-east-1.amazonaws.com/dev/item \
--header 'content-type: application/json' \
--data '{
"attribute_1": "Pet",
"attribute_2": "Rock"
}'
```

#### Expected Response

204 status

```
{
"_id": "c6f03ca0-f792-11e9-9534-260a4b91bfe9",
"data": {
"attribute_1": "Pet",
"attribute_2": "Rock"
}
}
```

### GET

```
curl --request GET \
--url https://0xfyi15qci.execute-api.us-east-1.amazonaws.com/dev/item/c6f03ca0-f792-11e9-9534-260a4b91bfe9 \
--header 'content-type: application/json'
```

#### Expected Response

200 status

```
{
"_id": "c6f03ca0-f792-11e9-9534-260a4b91bfe9",
"data": {
"attribute_1": "Pet",
"attribute_2": "Rock"
}
}
```

### LIST

```
curl --request GET \
--url https://0xfyi15qci.execute-api.us-east-1.amazonaws.com/dev/item \
--header 'content-type: application/json'
```

### Expected Response

200 status

```
{
"response_items": [
{
"_id": "c6f03ca0-f792-11e9-9534-260a4b91bfe9",
"data": {
"attribute_1": "Pet",
"attribute_2": "Rock"
}
},
{
"_id": "717c5f36-f799-11e9-a921-1e0e685be73c",
"data": {
"attribute_1": "Pete",
"attribute_2": "Rock"
}
}
],
"filter": null
}
```

## Delete

```
curl --request DELETE \
--url https://0xfyi15qci.execute-api.us-east-1.amazonaws.com/dev/item/c6f03ca0-f792-11e9-9534-260a4b91bfe9 \
--header 'content-type: application/json'
```

### Expected Response

204 status

Empty file.
39 changes: 39 additions & 0 deletions aws-python-rest-api-with-pymongo/item/create.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import json
import os
import uuid
import pymongo

# Fetch mongo env vars
usr = os.environ['MONGO_DB_USER']
pwd = os.environ['MONGO_DB_PASS']
mongo_db_name = os.environ['MONGO_DB_NAME']
mongo_collection_name = os.environ['MONGO_COLLECTION_NAME']
url = os.environ['MONGO_DB_URL']

# Connection String
client = pymongo.MongoClient("mongodb+srv://" + usr + ":" + pwd + "@" + url + "/test?retryWrites=true&w=majority")
db = client[mongo_db_name]
collection = db[mongo_collection_name]


def create(event, context):
# get request body
data = json.loads(event['body'])

# create item to insert
item = {
'_id': str(uuid.uuid1()),
'data': data,
}

# write item to database
collection.insert_one(item)

# create response
response = {
"statusCode": 200,
"body": json.dumps(item)
}

# return response
return response
38 changes: 38 additions & 0 deletions aws-python-rest-api-with-pymongo/item/delete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import os
import pymongo

# Fetch mongo env vars
usr = os.environ['MONGO_DB_USER']
pwd = os.environ['MONGO_DB_PASS']
mongo_db_name = os.environ['MONGO_DB_NAME']
mongo_collection_name = os.environ['MONGO_COLLECTION_NAME']
url = os.environ['MONGO_DB_URL']

# Connection String
client = pymongo.MongoClient("mongodb+srv://" + usr + ":" + pwd + "@" + url + "/test?retryWrites=true&w=majority")
db = client[mongo_db_name]
collection = db[mongo_collection_name]


def delete(event, context):
# get item_id to delete from path parameter
item_id = event['pathParameters']['id']

# delete item from the database
del_resp = collection.delete_one({"_id": item_id})

# if no item return 404
if del_resp.deleted_count == 0:

response = {
"statusCode": 404,
}

return response

# create a response
response = {
"statusCode": 204,
}

return response
32 changes: 32 additions & 0 deletions aws-python-rest-api-with-pymongo/item/get.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import json
import os
import pymongo

# Fetch mongo env vars
usr = os.environ['MONGO_DB_USER']
pwd = os.environ['MONGO_DB_PASS']
mongo_db_name = os.environ['MONGO_DB_NAME']
mongo_collection_name = os.environ['MONGO_COLLECTION_NAME']
url = os.environ['MONGO_DB_URL']

# Connection String
client = pymongo.MongoClient("mongodb+srv://" + usr + ":" + pwd + "@" + url + "/test?retryWrites=true&w=majority")
db = client[mongo_db_name]
collection = db[mongo_collection_name]


def get(event, context):
# get item_id to delete from path parameter
item_id = event['pathParameters']['id']

# delete item from the database
item = collection.find_one({"_id": item_id})

# create a response
response = {
"statusCode": 200,
"body": json.dumps(item)
}

# return response
return response
46 changes: 46 additions & 0 deletions aws-python-rest-api-with-pymongo/item/list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import json
import os
import pymongo

# Fetch mongo env vars
usr = os.environ['MONGO_DB_USER']
pwd = os.environ['MONGO_DB_PASS']
mongo_db_name = os.environ['MONGO_DB_NAME']
mongo_collection_name = os.environ['MONGO_COLLECTION_NAME']
url = os.environ['MONGO_DB_URL']

# Connection String
client = pymongo.MongoClient("mongodb+srv://" + usr + ":" + pwd + "@" + url + "/test?retryWrites=true&w=majority")
db = client[mongo_db_name]
collection = db[mongo_collection_name]


def list(event, context):
# create response body object
response_body = {}

# create array for reponse items
response_body['response_items'] = []

# return path parameters with filter key
response_body['filter'] = event['multiValueQueryStringParameters']

# build query with any path parameters
query = {}
if event['multiValueQueryStringParameters'] is not None:
for parameter in event['multiValueQueryStringParameters']:
query[parameter] = event['multiValueQueryStringParameters'][parameter][0]

# create list of items
cursor = collection.find(query)
for document in cursor:
response_body['response_items'].append(document)

# create response
response = {
"statusCode": 200,
"body": json.dumps(response_body)
}

# return response
return response
10 changes: 10 additions & 0 deletions aws-python-rest-api-with-pymongo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "aws-python-rest-api-with-pymongo",
"version": "1.0.0",
"description": "Serverless pymongo example",
"author": "",
"license": "MIT",
"dependencies": {
"serverless-python-requirements": "^5.0.0"
}
}
2 changes: 2 additions & 0 deletions aws-python-rest-api-with-pymongo/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pymongo
dnspython
Loading