Skip to content

Commit 21aabb1

Browse files
committed
enhancements
1 parent e7d4266 commit 21aabb1

File tree

33 files changed

+418
-66
lines changed

33 files changed

+418
-66
lines changed

FastAPIAWSLAMBDA/README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
## Serverless FastAPI with AWS Lambda
2+
3+
Mangum allows us to wrap the API with a handler that we will package and deploy as a Lambda function in AWS.
4+
Then using AWS API Gateway we will route all incoming requests to invoke the lambda and handle the routing internally within our application.
5+
6+
### Install Mangum
7+
8+
```shell
9+
pip install mangum
10+
```
11+
12+
### Setup AWS Resources
13+
This tutorial should fall under the AWS free-tier to create, however continued usage of these resources will have associated costs.
14+
15+
### Create S3 Bucket
16+
* Navigate to S3 in the AWS console and click Create Bucket.
17+
* Give it a name and click Create. In this example we're going to call it serverless-fastapi-lambda-dev
18+
19+
### Upload Zip File
20+
Before we can create the lambda we need to package up our existing FastApi app so it's ready for AWS Lambda.
21+
22+
The lambda won't be running in the virtual environment and will only be running one command (which we will determine when we create it) which will be **main.handler** So we need to install all the dependencies within the zip file since it won't be running pip install like we did locally.
23+
24+
### Package Lambda
25+
Inside your terminal from the root directory of your project, CD into the Python Site Packages folder.
26+
27+
```shell
28+
cd env/lib/python3.7/site-packages
29+
```
30+
31+
Then zip up the contents into the root of the project.
32+
33+
```shell
34+
cd env/lib/python3.7/site-packages
35+
```
36+
37+
```shell
38+
zip -r9 path/to/root/of/project/function.zip
39+
```
40+
41+
CD back into the root of the project.
42+
43+
```shell
44+
cd path/to/root/of/project
45+
```
46+
47+
Next we need to add the contents of the app folder so let's add that into the zip file.
48+
49+
```shell
50+
zip -g ./function.zip -r app
51+
```
52+
53+
### Upload Zip File to S3
54+
* Go inside the S3 bucket you just created and click Upload.
55+
* Add your zip file through the interface that pops up and and click Upload.
56+
57+
### Final Steps
58+
* Create AWS Lambda
59+
* Update Handler
60+
* Test FastAPI Lambda
61+
* Create API Gateway
62+
* Create Resource
63+
* Deploy Lambda Proxy API
64+
65+
### Summary
66+
That's it! We Created a FastAPI application and converted it to an AWS Lambda. Then we setup API Gateway to route all requests to our Lambda proxy.
67+
68+
#### References
69+
- Simple Serverless FastAPI with AWS Lambda - [https://www.deadbear.io/simple-serverless-fastapi-with-aws-lambda/]

FastAPIAWSLAMBDA/main.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from fastapi import FastAPI
2+
from mangum import Mangum
3+
4+
app = FastAPI()
5+
6+
7+
@app.get("/")
8+
async def root():
9+
return {"message": "Hello World!"}
10+
11+
12+
handler = Mangum(app)

FastAPIMongoEngine/.dockerignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.egg-info
2+
Dockerfile
3+
*.Dockerfile

FastAPIMongoEngine/.env

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
PROJECT_NAME=FastAPI-MongoEngine
2+
PROJECT_DESCRIPTION=A Simple Application to demonstrate MongoEngine with FastAPI
3+
API_VERSION=1.0.0
4+
API_VERSION_PATH=/api/v1
5+
ACCESS_TOKEN_EXPIRE_MINUTES=1440
6+
SERVER_NAME=FastAPI-MongoEngine
7+
PORT=8088
8+
DATABASE=mongodb
9+
MONGODB_HOST=mongodb_instance
10+
MONGODB_PORT=27017
11+
MONGO_ROOT_USER=root
12+
MONGO_ROOT_PASSWORD=mongo$321
13+
MONGOEXPRESS_LOGIN=admin
14+
MONGOEXPRESS_PASSWORD=admin$321
15+
MONGODB_DB_NAME=test_db
16+
AUTH_MONGODB_DB_NAME=admin

FastAPIMongoEngine/app/conf/conf.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
},
2222
"DATABASE_CONF": {
2323
"DATABASE": "mongodb",
24-
"MONGODB_HOST": "localhost",
24+
"MONGODB_HOST": "mongodb_instance",
2525
"MONGODB_PORT": "27017",
26-
"MONGODB_USER": "",
27-
"MONGODB_PASSWORD": "",
28-
"MONGODB_DB_NAME": "testdb"
26+
"MONGODB_USER": "root",
27+
"MONGODB_PASSWORD": "mongo$321",
28+
"MONGODB_DB_NAME": "testdb",
29+
"AUTH_MONGODB_DB_NAME": "admin"
2930
}
3031
}

FastAPIMongoEngine/app/conf/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class DBSettings:
2929
MONGO_DATABASE_URL = f"{__DATA['DATABASE']}://{__DATA['MONGODB_USER']}" \
3030
f":{__DATA['MONGODB_PASSWORD']}@" \
3131
f"{__DATA['MONGODB_HOST']}:{__DATA['MONGODB_PORT']}/" \
32-
f"{__DATA['MONGODB_DB_NAME']}?authSource={__DATA['MONGODB_DB_NAME']}"
32+
f"{__DATA['MONGODB_DB_NAME']}?authSource={__DATA['AUTH_MONGODB_DB_NAME']}"
3333

3434

3535
class ProjectSettings:

FastAPIMongoEngine/app/crud/crud_articles.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,26 @@ def get_article(self, article_id: str):
5858
fastapi_logger.exception("get_article")
5959
return None
6060

61-
def get_all_articles(self, tag: str, page_num: int) -> Any:
61+
def get_all_articles(self, tag: str = None,
62+
article_title: str = None,
63+
page_num: int = 1, page_size=30) -> Any:
6264
""" Get All Articles """
6365
try:
64-
query = Article.objects.order_by('-modified_timestamp')
66+
query = Article.objects
6567

6668
if tag:
67-
query = Article.objects(tags=tag).order_by(
68-
'-modified_timestamp')
69+
query = query.filter(tags=tag)
6970

70-
data = pagination.paginate(query=query, page=page_num,
71-
page_size=30)
71+
if article_title:
72+
query = query.filter(article_title=article_title)
73+
74+
data = pagination.paginate(query=query.order_by(
75+
'modified_timestamp'), page=page_num,
76+
page_size=page_size)
7277
return data
7378
except Exception as e:
7479
fastapi_logger.exception("get_all_articles")
7580
return None
7681

7782

78-
crud_articles = CRUDArticles()
83+
crud_articles = CRUDArticles()

FastAPIMongoEngine/app/crud/crud_login.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from sqlalchemy.orm import Session
2-
from sqlalchemy.exc import SQLAlchemyError
31
from typing import Any
42

53
import sys
@@ -26,7 +24,7 @@ def check_active_session(self, session_id: str):
2624
db_session = UsersLoginAttempt.objects(
2725
session_id=session_id).first()
2826
return db_session
29-
except SQLAlchemyError as e:
27+
except Exception as e:
3028
fastapi_logger.exception("logoff_user")
3129
return None
3230

@@ -41,7 +39,7 @@ def login_user(self, user: schemas.UserLogIn, session_id: str) -> Any:
4139
status="logged_in")
4240
db_session.save()
4341
return db_session
44-
except SQLAlchemyError as e:
42+
except Exception as e:
4543
fastapi_logger.exception("login_user")
4644
return None
4745

@@ -53,7 +51,7 @@ def active_user(self, session_id: str) -> Any:
5351
db_session.status = "active"
5452
db_session.save()
5553
return db_session
56-
except SQLAlchemyError as e:
54+
except Exception as e:
5755
fastapi_logger.exception("active_user")
5856
return None
5957

@@ -66,7 +64,7 @@ def logoff_user(self, session_id: str) -> Any:
6664
db_session.status = "logged_off"
6765
db_session.save()
6866
return db_session
69-
except SQLAlchemyError as e:
67+
except Exception as e:
7068
fastapi_logger.exception("logoff_user")
7169
return None
7270

FastAPIMongoEngine/app/db/dbconf_models.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,22 @@
77
sys.path.append("..")
88
from conf import DBSettings
99

10+
clientOptions = {
11+
# This is the maximum time between when we fetch data from a cursor.
12+
# If it times out, the cursor is lost and we can't reconnect. If it
13+
# isn't set, we have issues with replica sets when the primary goes
14+
# down. This value can be overridden in the mongodb uri connection
15+
# string with the socketTimeoutMS.
16+
'socketTimeoutMS': 60000,
17+
'connectTimeoutMS': 20000,
18+
'serverSelectionTimeoutMS': 20000,
19+
'readPreference': 'secondaryPreferred',
20+
'replicaSet': None,
21+
'w': 'majority'
22+
}
23+
print(DBSettings.MONGO_DATABASE_URL)
1024
session = connect(
11-
host=DBSettings.MONGO_DATABASE_URL)
25+
host=DBSettings.MONGO_DATABASE_URL, **clientOptions)
1226

1327

1428
class User(gj.Document):
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
mongoengine
21
pandas==1.0.3
32
numpy==1.18.2
4-
psycopg2==2.8.5
3+
mongoengine==0.20.0
4+
mongoengine_goodjson
55
jwt==1.0.0
66
bcrypt==3.1.7
77
passlib==1.7.2
@@ -11,4 +11,6 @@ async-exit-stack
1111
async-generator
1212
async-exit-stack
1313
async-generator
14-
uuid==1.30
14+
uuid==1.30
15+
python-dotenv
16+
python-dateutil

0 commit comments

Comments
 (0)