-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
111 lines (97 loc) · 4.29 KB
/
app.py
File metadata and controls
111 lines (97 loc) · 4.29 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
from fastapi import FastAPI, File, UploadFile, HTTPException, Depends
from fastapi.responses import JSONResponse
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
import boto3
from botocore.exceptions import NoCredentialsError
from dotenv import load_dotenv
import os
import uvicorn
# Load environment variables from .env file
load_dotenv()
# Get AWS credentials and configuration from environment variables
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
AWS_REGION = os.getenv("AWS_REGION")
S3_BUCKET_NAME = os.getenv("S3_BUCKET_NAME")
SECRET_KEY = os.getenv("SECRET_KEY")
ALGORITHM = "HS256"
# Initialize the S3 client with the credentials
s3 = boto3.client(
's3',
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name=AWS_REGION
)
# OAuth2 scheme for token handling
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# FastAPI app initialization
app = FastAPI()
# Function to decode the JWT token
async def authenticate_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise HTTPException(status_code=401, detail="Invalid authentication credentials")
return username
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
# Upload file to S3 bucket with SSE-S3 encryption and authentication
@app.post("/upload/")
async def upload_file(file: UploadFile = File(...), token: str = Depends(authenticate_user)):
try:
# Check if the file already exists in S3
existing_files = s3.list_objects_v2(Bucket=S3_BUCKET_NAME, Prefix=file.filename)
if existing_files.get('KeyCount', 0) > 0:
raise HTTPException(status_code=400, detail=f"File '{file.filename}' already exists.")
# Upload the file to S3 with Server-Side Encryption (SSE-S3)
s3.upload_fileobj(
file.file,
S3_BUCKET_NAME,
file.filename,
ExtraArgs={'ServerSideEncryption': 'AES256'} # SSE-S3 encryption
)
return {"message": f"File '{file.filename}' uploaded successfully"}
except NoCredentialsError:
raise HTTPException(status_code=403, detail="AWS Credentials not found")
except Exception as e:
raise HTTPException(status_code=500, detail=f"File upload failed: {str(e)}")
# Download file from S3 bucket (generates a presigned URL with authentication)
@app.get("/download/{filename}")
async def download_file(filename: str, token: str = Depends(authenticate_user)):
try:
# Generate a presigned URL for the file download
file_url = s3.generate_presigned_url(
'get_object',
Params={'Bucket': S3_BUCKET_NAME, 'Key': filename},
ExpiresIn=3600 # URL expiration time in seconds
)
return JSONResponse(content={"url": file_url})
except Exception as e:
raise HTTPException(status_code=404, detail=f"File '{filename}' not found or download failed: {str(e)}")
# Share file (generates a presigned URL for sharing with authentication)
@app.post("/share/{filename}")
async def share_file(filename: str, token: str = Depends(authenticate_user)):
try:
# Generate a presigned URL for sharing
share_url = s3.generate_presigned_url(
'get_object',
Params={'Bucket': S3_BUCKET_NAME, 'Key': filename},
ExpiresIn=3600 # Link expires in 1 hour
)
return {"shareable_url": share_url}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Could not generate shareable URL: {str(e)}")
# Delete file from S3 with authentication
@app.delete("/delete/{filename}")
async def delete_file(filename: str, token: str = Depends(authenticate_user)):
try:
# Delete the file from S3
s3.delete_object(Bucket=S3_BUCKET_NAME, Key=filename)
return {"message": f"File '{filename}' deleted successfully"}
except Exception as e:
raise HTTPException(status_code=404, detail=f"File '{filename}' not found or could not be deleted: {str(e)}")
# Start the FastAPI app with Uvicorn
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)