forked from microsoft/python-sample-vscode-fastapi-tutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
126 lines (100 loc) · 5.03 KB
/
main.py
File metadata and controls
126 lines (100 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import os
import redis
from fastapi import FastAPI, HTTPException, Request
from models import DocumentPayload
app = FastAPI()
redis_client = redis.StrictRedis(host="0.0.0.0", port=6379, db=0, decode_responses=True)
@app.get("/")
def home(request: Request) -> dict[str, str]:
url: str = (
f"https://{os.getenv('CODESPACE_NAME')}-8000.{os.getenv('GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN')}/"
if os.getenv("CODESPACE_NAME")
else str(request.base_url)
)
return {
"message": f"Navigate to the following URL to access the Swagger UI: {url}docs"
}
# Route to add a document
@app.post("/documents/{document_id}/{quantity}")
def add_document(document_name: str, quantity: int) -> dict[str, DocumentPayload]:
if quantity <= 0:
raise HTTPException(status_code=400, detail="Quantity must be greater than 0.")
# Check if document already exists
document_id_str: str | None = redis_client.hget("document_name_to_id", document_name)
if document_id_str is not None:
document_id = int(document_id_str)
quantity = redis_client.hincrby(f"document_id:{document_id}", "quantity", quantity)
else:
# Generate an id for the document
document_id: int = redis_client.incr("document_ids")
redis_client.hset(
f"document_id:{document_id}",
mapping={
"document_id": document_id,
"document_name": document_name,
"quantity": quantity,
},
)
# Create a set so we can search by name too
redis_client.hset("document_name_to_id", document_name, document_id)
return {
"document": DocumentPayload(document_id=document_id, document_name=document_name, quantity=quantity)
}
# Route to list a specific document by id but using Redis
@app.get("/documents/{document_id}")
def list_document(document_id: int) -> dict[str, dict[str, str]]:
if not redis_client.hexists(f"document_id:{document_id}", "document_id"):
raise HTTPException(status_code=404, detail="Document not found.")
else:
return {"document": redis_client.hgetall(f"document_id:{document_id}")}
@app.get("/documents")
def list_documents() -> dict[str, list[DocumentPayload]]:
documents: list[DocumentPayload] = []
stored_documents: dict[str, str] = redis_client.hgetall("document_name_to_id")
for name, id_str in stored_documents.items():
document_id: int = int(id_str)
document_name_str: str | None = redis_client.hget(f"document_id:{document_id}", "document_name")
if document_name_str is not None:
document_name: str = document_name_str
else:
continue # skip this item if it has no name
document_quantity_str: str | None = redis_client.hget(
f"document_id:{document_id}", "quantity"
)
if document_quantity_str is not None:
document_quantity: int = int(document_quantity_str)
else:
document_quantity = 0
documents.append(
DocumentPayload(document_id=document_id, document_name=document_name, quantity=document_quantity)
)
return {"documents": documents}
# Route to delete a specific document by id but using Redis
@app.delete("/documents/{document_id}")
def delete_document(document_id: int) -> dict[str, str]:
if not redis_client.hexists(f"document_id:{document_id}", "document_id"):
raise HTTPException(status_code=404, detail="Document not found.")
else:
document_name: str | None = redis_client.hget(f"document_id:{document_id}", "document_name")
redis_client.hdel("document_name_to_id", f"{document_name}")
redis_client.delete(f"document_id:{document_id}")
return {"result": "document deleted."}
# Route to remove some quantity of a specific document by id but using Redis
@app.delete("/documents/{document_id}/{quantity}")
def remove_quantity(document_id: int, quantity: int) -> dict[str, str]:
if not redis_client.hexists(f"document_id:{document_id}", "document_id"):
raise HTTPException(status_code=404, detail="Document not found.")
document_quantity: str | None = redis_client.hget(f"document_id:{document_id}", "quantity")
# if quantity to be removed is higher or equal to document's quantity, delete the document
if document_quantity is None:
existing_quantity: int = 0
else:
existing_quantity: int = int(document_quantity)
if existing_quantity <= quantity:
document_name: str | None = redis_client.hget(f"document_id:{document_id}", "document_name")
redis_client.hdel("document_name_to_id", f"{document_name}")
redis_client.delete(f"document_id:{document_id}")
return {"result": "document deleted because quantity >0."}
else:
redis_client.hincrby(f"document_id:{document_id}", "quantity", -quantity)
return {"result": f"{quantity} removed from quantity of document id:"+str(document_id)}