Skip to content

Commit b055f31

Browse files
Lucas BeloLucas Belo
Lucas Belo
authored and
Lucas Belo
committed
New task operations
1 parent b546d95 commit b055f31

File tree

9 files changed

+298
-7
lines changed

9 files changed

+298
-7
lines changed

services/tasks_api/config.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from typing import Optional
2+
3+
from pydantic_settings import BaseSettings
4+
5+
6+
class Config(BaseSettings):
7+
TABLE_NAME: str = ""
8+
DYNAMODB_URL: Optional[str] = None

services/tasks_api/main.py

+68-1
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,87 @@
1-
from fastapi import FastAPI
1+
import uuid
2+
from typing import Union
3+
4+
import jwt
5+
from fastapi import Depends, FastAPI, Header
26
from fastapi.middleware.cors import CORSMiddleware
37
from mangum import Mangum
8+
from starlette import status
9+
10+
from config import Config
11+
from models import Task
12+
from schemas import APITask, APITaskList, CreateTask, CloseTask
13+
from store import TaskStore
414

515
app = FastAPI()
16+
617
app.add_middleware(
718
CORSMiddleware,
819
allow_origins="*",
920
allow_credentials=True,
1021
allow_methods=["*"],
1122
allow_headers=["*"],
1223
)
24+
config = Config()
25+
26+
27+
def get_task_store() -> TaskStore:
28+
return TaskStore(config.TABLE_NAME, dynamodb_url=config.DYNAMODB_URL)
29+
30+
31+
def get_user_email(authorization: Union[str, None] = Header(default=None)) -> str:
32+
return jwt.decode(authorization, options={"verify_signature": False})[
33+
"cognito:username"
34+
]
1335

1436

1537
@app.get("/api/health-check/")
1638
def health_check():
1739
return {"message": "OK"}
1840

1941

42+
@app.post(
43+
"/api/create-task", response_model=APITask, status_code=status.HTTP_201_CREATED
44+
)
45+
def create_task(
46+
parameters: CreateTask,
47+
user_email: str = Depends(get_user_email),
48+
task_store: TaskStore = Depends(get_task_store),
49+
):
50+
task = Task.create(id_=uuid.uuid4(), title=parameters.title, owner=user_email)
51+
task_store.add(task)
52+
53+
return task
54+
55+
56+
@app.get("/api/open-tasks", response_model=APITaskList)
57+
def open_tasks(
58+
user_email: str = Depends(get_user_email),
59+
task_store: TaskStore = Depends(get_task_store),
60+
):
61+
results=task_store.list_open(owner=user_email)
62+
print("Results: ", results)
63+
return APITaskList(results=results)
64+
65+
2066
handle = Mangum(app)
67+
68+
69+
@app.post("/api/close-task", response_model=APITask)
70+
def close_task(
71+
parameters: CloseTask,
72+
user_email: str = Depends(get_user_email),
73+
task_store: TaskStore = Depends(get_task_store),
74+
):
75+
task = task_store.get_by_id(task_id=parameters.id, owner=user_email)
76+
task.close()
77+
task_store.add(task)
78+
79+
return task
80+
81+
82+
@app.get("/api/closed-tasks", response_model=APITaskList)
83+
def closed_tasks(
84+
user_email: str = Depends(get_user_email),
85+
task_store: TaskStore = Depends(get_task_store),
86+
):
87+
return APITaskList(results=task_store.list_closed(owner=user_email))

services/tasks_api/models.py

+4
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ class Task:
1818
@classmethod
1919
def create(cls, id_, title, owner):
2020
return cls(id_, title, TaskStatus.OPEN, owner)
21+
22+
23+
def close(self):
24+
self.status = TaskStatus.CLOSED

services/tasks_api/poetry.lock

+90-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

services/tasks_api/pyproject.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ authors = ["Lucas"]
66
readme = "README.md"
77

88
[tool.poetry.dependencies]
9-
python = "^3.11"
9+
python = "^3.9"
1010
fastapi = "^0.115.0"
1111
uvicorn = "^0.31.0"
1212
httpx = "^0.27.2"
1313
mangum = "^0.19.0"
1414
boto3 = "1.21.45"
15+
pyjwt = "^2.9.0"
16+
pydantic = "^2.9.2"
17+
pydantic-settings = "^2.5.2"
1518

1619

1720
[tool.poetry.group.dev.dependencies]

services/tasks_api/schemas.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from uuid import UUID
2+
3+
from pydantic import BaseModel, ConfigDict
4+
5+
from models import TaskStatus
6+
7+
8+
class CreateTask(BaseModel):
9+
title: str
10+
11+
12+
class APITask(BaseModel):
13+
id: UUID
14+
title: str
15+
status: TaskStatus
16+
owner: str
17+
18+
model_config = ConfigDict(from_attributes=True)
19+
20+
21+
class APITaskList(BaseModel):
22+
results: list[APITask]
23+
24+
model_config = ConfigDict(from_attributes=True)
25+
26+
27+
class CloseTask(BaseModel):
28+
id: UUID

services/tasks_api/serverless.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ useDotenv: true
66

77
provider:
88
name: aws
9-
runtime: python3.11
9+
runtime: python3.9
1010
region: ${opt:region, 'eu-west-1'}
1111
stage: ${opt:stage, 'development'}
1212
logRetentionInDays: 30
1313
environment:
1414
APP_ENVIRONMENT: ${self:provider.stage}
15+
TABLE_NAME: ${self:custom.tableName}
1516
iam:
1617
role:
1718
statements:

services/tasks_api/store.py

+1
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,5 @@ def _list_by_status(self, owner, status):
7777
last_key = response.get("LastEvaluatedKey")
7878
if last_key is None:
7979
break
80+
8081
return tasks

0 commit comments

Comments
 (0)