-
Notifications
You must be signed in to change notification settings - Fork 134
/
Copy pathapp.py
105 lines (88 loc) · 3.76 KB
/
app.py
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
import os
from datetime import datetime
from typing import List
from urllib.parse import quote
import uvicorn
from azure.core.exceptions import ResourceNotFoundError
from azure.storage.blob import BlobServiceClient
from fastapi import Depends, FastAPI, File, HTTPException, Request, UploadFile
from fastapi.responses import RedirectResponse, StreamingResponse, JSONResponse
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
cache_header = {"Cache-Control": "max-age=31556952"}
shared_container_client = None
async def get_container_client():
global shared_container_client
if not shared_container_client:
connection_string = os.environ['CUSTOMCONNSTR_STORAGE']
service = BlobServiceClient.from_connection_string(conn_str=connection_string)
# Get a client to interact with a specific container - though it may not yet exist
shared_container_client = service.get_container_client("images")
return shared_container_client
@app.exception_handler(KeyError)
async def unicorn_exception_handler(request: Request, exc: KeyError):
if exc.args[0] == 'CUSTOMCONNSTR_STORAGE':
return JSONResponse(
status_code=500,
content={"message": f"Oops! You forgot to set the STORAGE connection string for your Azure Storage Account. You can test locally by setting CUSTOMCONNSTR_STORAGE. 🤓"},
)
raise exc
@app.exception_handler(ValueError)
async def unicorn_exception_handler(request: Request, exc: KeyError):
if exc.args[0] == 'Connection string is either blank or malformed.':
return JSONResponse(
status_code=500,
content={"message": f"Oops! Your connection string is either blank or malformed. 🤓"},
)
raise exc
class Image(BaseModel):
created_at: datetime = None
image_url: str
@app.get("/")
async def redirect_to_docs():
return RedirectResponse("/docs")
@app.get("/images", response_model=List[Image])
async def list_images(container_client = Depends(get_container_client)):
try:
blobs = [Image(created_at=b.last_modified,
image_url=f"/images/{quote(b.name)}") for b in container_client.list_blobs()]
blobs.sort(key=lambda a: a.created_at, reverse=True)
except ResourceNotFoundError:
return JSONResponse(
status_code=500,
content={"message": f"Oops! You forgot to create a blob storage container named 'images'. 🤓"},
)
return blobs
@app.get("/images/{image_name}")
async def images(image_name, container_client = Depends(get_container_client)):
try:
blob_container_client = container_client.get_blob_client(image_name)
blob = blob_container_client.download_blob()
except ResourceNotFoundError:
raise HTTPException(
status_code=404, detail="Your picture was not found, just try to upload again. 🤓")
return StreamingResponse(blob.chunks(), headers=cache_header)
@app.delete("/images/{image_name}")
async def delete(image_name, container_client = Depends(get_container_client)):
try:
blob_container_client = container_client.get_blob_client(image_name)
blob_container_client.delete_blob()
except ResourceNotFoundError:
raise HTTPException(
status_code=404, detail="Your picture was not found. 🤓")
return {}
@app.post("/upload/")
async def upload(file: UploadFile = File(...), container_client = Depends(get_container_client)):
container_client.upload_blob(
file.filename, file.file, blob_type="BlockBlob", overwrite=True)
return {"filename": file.filename}
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
if __name__ == "__main__":
uvicorn.run(app, port=8000)