1
- import logging ,os ,uuid
1
+ import logging
2
+ import os
3
+ import uuid
4
+ from datetime import datetime
5
+ from typing import List , Dict , Optional
2
6
3
7
import boto3
4
8
from fastapi import FastAPI , HTTPException
5
9
from fastapi .middleware .cors import CORSMiddleware
6
10
from mangum import Mangum
7
11
from pydantic import BaseModel
8
- from typing import List , Dict , Optional
9
-
10
- from datetime import datetime
12
+ from botocore .exceptions import ClientError
11
13
12
14
# Configure logging
13
15
logging .basicConfig (level = logging .DEBUG )
18
20
# Configure CORS middleware
19
21
app .add_middleware (
20
22
CORSMiddleware ,
21
- allow_origins = ["*" ], # Adjust the allowed origins for your use case
23
+ allow_origins = ["*" ],
22
24
allow_credentials = True ,
23
25
allow_methods = ["*" ],
24
26
allow_headers = ["*" ],
@@ -37,30 +39,30 @@ class TodoItem(BaseModel):
37
39
@app .get ("/todos" , response_model = List [TodoItem ])
38
40
async def get_todos ():
39
41
try :
40
- # Perform a scan operation on the DynamoDB table
41
42
response = table .scan ()
42
- # Return the 'Items' from the scan result
43
43
items = response .get ("Items" , [])
44
44
logging .debug (f"Fetched { len (items )} items from DynamoDB" )
45
45
return items
46
+ except ClientError as e :
47
+ logging .error (f"DynamoDB ClientError: { e } " )
48
+ raise HTTPException (status_code = 500 , detail = "Error fetching todos" )
46
49
except Exception as e :
47
50
logging .error (f"Error getting todos: { e } " )
48
51
raise HTTPException (status_code = 500 , detail = "Error fetching todos" )
49
52
50
53
@app .post ("/todos" , status_code = 201 , response_model = TodoItem )
51
54
async def create_todo (todo : TodoItem ):
52
55
try :
53
- # Add the current timestamp to the todo item
54
56
todo_dict = todo .dict ()
55
- todo_dict ["timestamp" ] = int (datetime .utcnow ().timestamp ()) # Unix timestamp in seconds
57
+ todo_dict ["id" ] = todo_dict .get ("id" ) or str (uuid .uuid4 ())
58
+ todo_dict ["timestamp" ] = int (datetime .utcnow ().timestamp ())
56
59
57
- # Add the todo item to DynamoDB
58
60
response = table .put_item (Item = todo_dict )
59
61
logging .debug (f"DynamoDB put_item response: { response } " )
60
- return todo_dict # Return the updated item with the timestamp
61
- except boto3 . exceptions . Boto3Error as boto_error :
62
- logging .error (f"Boto3Error : { boto_error } " )
63
- raise HTTPException (status_code = 500 , detail = f "DynamoDB Error: { str ( boto_error ) } " )
62
+ return todo_dict
63
+ except ClientError as boto_error :
64
+ logging .error (f"ClientError : { boto_error } " )
65
+ raise HTTPException (status_code = 500 , detail = "DynamoDB Error" )
64
66
except Exception as e :
65
67
logging .error (f"Unexpected error creating todo: { e } " )
66
68
raise HTTPException (status_code = 500 , detail = "Error creating todo" )
@@ -70,9 +72,8 @@ async def update_todo(id: str, todo: Dict[str, str]):
70
72
if "text" not in todo :
71
73
raise HTTPException (status_code = 400 , detail = "Missing 'text' in request body" )
72
74
try :
73
- # Update the todo item in DynamoDB
74
75
response = table .update_item (
75
- Key = {"id" : id }, # Ensure id is passed as a string
76
+ Key = {"id" : id },
76
77
UpdateExpression = "SET #t = :t" ,
77
78
ExpressionAttributeNames = {"#t" : "text" },
78
79
ExpressionAttributeValues = {":t" : todo ["text" ]},
@@ -83,20 +84,25 @@ async def update_todo(id: str, todo: Dict[str, str]):
83
84
raise HTTPException (status_code = 404 , detail = "Todo not found" )
84
85
logging .debug (f"Updated item: { updated_todo } " )
85
86
return updated_todo
87
+ except ClientError as e :
88
+ logging .error (f"ClientError updating todo: { e } " )
89
+ raise HTTPException (status_code = 500 , detail = "Error updating todo" )
86
90
except Exception as e :
87
91
logging .error (f"Error updating todo: { e } " )
88
92
raise HTTPException (status_code = 500 , detail = "Error updating todo" )
89
93
90
94
@app .delete ("/todos/{id}" , status_code = 204 )
91
95
async def delete_todo (id : str ):
92
96
try :
93
- # Delete the todo item from DynamoDB
94
- response = table .delete_item (Key = {"id" : id }) # Ensure id is passed as a string
97
+ response = table .delete_item (Key = {"id" : id })
95
98
status_code = response .get ("ResponseMetadata" , {}).get ("HTTPStatusCode" )
96
99
if status_code != 200 :
97
100
raise HTTPException (status_code = 404 , detail = "Todo not found" )
98
101
logging .debug (f"Deleted item with id: { id } " )
99
- return {"detail" : "Todo deleted successfully" }
102
+ return
103
+ except ClientError as e :
104
+ logging .error (f"ClientError deleting todo: { e } " )
105
+ raise HTTPException (status_code = 500 , detail = "Error deleting todo" )
100
106
except Exception as e :
101
107
logging .error (f"Error deleting todo: { e } " )
102
108
raise HTTPException (status_code = 500 , detail = "Error deleting todo" )
@@ -105,7 +111,6 @@ async def delete_todo(id: str):
105
111
async def health ():
106
112
try :
107
113
logging .debug ("Health check initiated" )
108
- # Simple check to see if everything is working
109
114
return {"message" : "Everything looks good!" }
110
115
except Exception as e :
111
116
logging .error (f"Health check error: { e } " )
@@ -115,4 +120,4 @@ async def health():
115
120
def handler (event , context ):
116
121
logging .info (f"Received event: { event } " )
117
122
mangum_handler = Mangum (app )
118
- return mangum_handler (event , context )
123
+ return mangum_handler (event , context )
0 commit comments