From 8dbc054cea5ffdaf8c46eb35ea762dae892c69dd Mon Sep 17 00:00:00 2001 From: Georgia Kokkinou Date: Tue, 2 Nov 2021 13:43:13 +0200 Subject: [PATCH 1/6] Return user ID upon user creation --- index.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.py b/index.py index 0b87b12..61feada 100644 --- a/index.py +++ b/index.py @@ -32,8 +32,7 @@ async def create_new_user(*, user: User): with Session(engine) as session: session.add(user) session.commit() - # TODO return the User ID - return {"message": "User created"} + return {"message": "User with ID {} created".format(user.id)} @app.get("/user/{id}") async def get_user(id: int): From 3ca8dd1e35efcdcdd345f4cd9c4e5ba99442ce64 Mon Sep 17 00:00:00 2001 From: Georgia Kokkinou Date: Tue, 2 Nov 2021 13:47:51 +0200 Subject: [PATCH 2/6] Use timestamp as default user ID --- index.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.py b/index.py index 61feada..857cdfd 100644 --- a/index.py +++ b/index.py @@ -10,7 +10,6 @@ from sqlmodel import Field, Session, SQLModel, create_engine, select class User(SQLModel, table=True): - # TODO change the default value to the timestamp that the user is created id: Optional[int] = Field(default=None, primary_key=True) name: str secret_name: str @@ -30,6 +29,8 @@ async def root(): @app.post("/user") async def create_new_user(*, user: User): with Session(engine) as session: + if user.id is None: + user.id = int(time.time()) session.add(user) session.commit() return {"message": "User with ID {} created".format(user.id)} From e0d6d1125de75364b791ea969133d0a291fa2c57 Mon Sep 17 00:00:00 2001 From: Georgia Kokkinou Date: Tue, 2 Nov 2021 13:53:18 +0200 Subject: [PATCH 3/6] Get user based on ID --- index.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/index.py b/index.py index 857cdfd..2a27bc4 100644 --- a/index.py +++ b/index.py @@ -3,7 +3,7 @@ import time from typing import Any, Dict, Optional -from fastapi import FastAPI +from fastapi import FastAPI, HTTPException from typing import Optional @@ -38,9 +38,10 @@ async def create_new_user(*, user: User): @app.get("/user/{id}") async def get_user(id: int): with Session(engine) as session: - # TODO return the user based on the ID (and an error if not) - statement = select(User).where(User.name == id) + statement = select(User).where(User.id == id) user = session.exec(statement).first() + if user is None: + raise HTTPException(status_code=404, detail="User not found") return {"user": user} @app.get("/api/webhooks") From 6c09a3f4e31cff6f9fa8de64c6980962e936f88e Mon Sep 17 00:00:00 2001 From: Georgia Kokkinou Date: Tue, 2 Nov 2021 14:12:56 +0200 Subject: [PATCH 4/6] Greet user by name if logged in --- index.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/index.py b/index.py index 2a27bc4..6b5bd80 100644 --- a/index.py +++ b/index.py @@ -3,7 +3,8 @@ import time from typing import Any, Dict, Optional -from fastapi import FastAPI, HTTPException +from fastapi import Depends, FastAPI, HTTPException +from fastapi.security import HTTPBasic, HTTPBasicCredentials from typing import Optional @@ -19,11 +20,14 @@ class User(SQLModel, table=True): SQLModel.metadata.create_all(engine) # Create an instance of the API class app = FastAPI() +security = HTTPBasic(auto_error=False) +# NOTE: This authentication implementation is not complete nor robust. It +# is only meant to be used as an example. @app.get("/") -async def root(): - # TODO include the user's name if they are logged in - return {"message": "Hello {}".format("World")} +async def root(credentials: HTTPBasicCredentials = Depends(security)): + username = credentials.username if credentials else "World" + return {"message": "Hello {}".format(username)} @app.post("/user") From 7d8bf5f0d8ec372bf9f43e5f5fcb90fb6bee8124 Mon Sep 17 00:00:00 2001 From: Georgia Kokkinou Date: Tue, 2 Nov 2021 14:23:33 +0200 Subject: [PATCH 5/6] Apply various minor improvements Remove some unused imports and some redundant blank lines. Also, change the type of the age attribute of the User class from str to int. Finally, use consistent indentation of four spaces throughout the code. --- index.py | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/index.py b/index.py index 6b5bd80..2a9ceb3 100644 --- a/index.py +++ b/index.py @@ -1,20 +1,17 @@ -from __future__ import print_function - import time -from typing import Any, Dict, Optional +from typing import Any, Optional from fastapi import Depends, FastAPI, HTTPException from fastapi.security import HTTPBasic, HTTPBasicCredentials - -from typing import Optional - from sqlmodel import Field, Session, SQLModel, create_engine, select + class User(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) name: str secret_name: str - age: Optional[str] = None + age: Optional[int] = None + engine = create_engine("sqlite:///database.db") SQLModel.metadata.create_all(engine) @@ -29,35 +26,25 @@ async def root(credentials: HTTPBasicCredentials = Depends(security)): username = credentials.username if credentials else "World" return {"message": "Hello {}".format(username)} - @app.post("/user") async def create_new_user(*, user: User): with Session(engine) as session: - if user.id is None: - user.id = int(time.time()) - session.add(user) - session.commit() - return {"message": "User with ID {} created".format(user.id)} + if user.id is None: + user.id = int(time.time()) + session.add(user) + session.commit() + return {"message": "User with ID {} created".format(user.id)} @app.get("/user/{id}") async def get_user(id: int): - with Session(engine) as session: - statement = select(User).where(User.id == id) - user = session.exec(statement).first() - if user is None: - raise HTTPException(status_code=404, detail="User not found") - return {"user": user} + with Session(engine) as session: + statement = select(User).where(User.id == id) + user = session.exec(statement).first() + if user is None: + raise HTTPException(status_code=404, detail="User not found") + return {"user": user} @app.get("/api/webhooks") async def handle_hook(*, event: Any): id = event.payload.conversation.id return {"message": "Hello World"} - - - - - - - - - From e73348a7c28cc1ea96d0f5dff0e771a1b3b58c28 Mon Sep 17 00:00:00 2001 From: Georgia Kokkinou Date: Tue, 2 Nov 2021 14:27:36 +0200 Subject: [PATCH 6/6] Add a couple of TODOs --- index.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/index.py b/index.py index 2a9ceb3..8a2d769 100644 --- a/index.py +++ b/index.py @@ -28,6 +28,7 @@ async def root(credentials: HTTPBasicCredentials = Depends(security)): @app.post("/user") async def create_new_user(*, user: User): +# TODO: Should handle the case where the user already exists with Session(engine) as session: if user.id is None: user.id = int(time.time()) @@ -44,6 +45,8 @@ async def get_user(id: int): raise HTTPException(status_code=404, detail="User not found") return {"user": user} +# TODO: The purpose of this webhook is unclear and its implementation is +# incomplete @app.get("/api/webhooks") async def handle_hook(*, event: Any): id = event.payload.conversation.id