Spaces:
Sleeping
Sleeping
File size: 11,352 Bytes
69601d4 d7fd1be 69601d4 1b179fe 69601d4 1b179fe 69601d4 1b179fe 69601d4 1b179fe 69601d4 |
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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
from ..models.requestModels import UpdateProjectState, CreateProject, EditMetadata
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from fastapi.exceptions import HTTPException
from fastapi.responses import JSONResponse
from ..utils.functions import verifyToken
from fastapi import APIRouter, Depends
from supabase import create_client
from urllib.request import urlopen
from typing import Annotated
from . import pipeline
from jose import jwt
import pandas as pd
import uuid
import json
import time
import os
import io
router = APIRouter()
security = HTTPBearer()
client = create_client(
supabase_url = os.environ["SUPABASE_URL"],
supabase_key = os.environ["SUPABASE_KEY"]
)
@router.post("/createProject")
async def createProject(projectDetails: CreateProject, credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]):
try:
if verifyToken(token = credentials.credentials):
projectId = str(uuid.uuid4())
decodedToken = jwt.decode(
credentials.credentials,
os.environ["SECRET_KEY"],
algorithms = ["HS256"]
)
_ = client.table("Projects").insert({
"projectId": projectId,
"projectName": projectDetails.projectName,
"projectDescription": projectDetails.projectDescription,
"ownerUserId": decodedToken["userId"],
"ownerUserMail": decodedToken["email"]
}).execute()
return JSONResponse(status_code = 200, content = {"status": "SUCCESS", "projectId": projectId, "message": "Project created successfully"})
else:
return JSONResponse(status_code = 498, content = {"status": "ERROR", "errorDetail": "Invalid Token"})
except Exception as e:
raise HTTPException(status_code = 500, detail = f"Endpoint says: {e}")
@router.get("/listProjects")
async def listProjects(credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]):
try:
if verifyToken(token = credentials.credentials):
decodedToken = jwt.decode(
credentials.credentials,
os.environ["SECRET_KEY"],
algorithms = ["HS256"]
)
data = pd.DataFrame(client.table("Projects").select("*").execute().data)
data = data[data["ownerUserId"] == decodedToken["userId"]]
return JSONResponse(status_code = 200, content = {"projects": data.to_dict(orient = "records")})
else:
return JSONResponse(status_code = 498, content = {"status": "ERROR", "errorDetail": "Invalid Token"})
except Exception as e:
raise HTTPException(status_code = 500, detail = f"Endpoint says: {e}")
@router.patch("/updateBookmark")
async def updateBookmark(updateBookmarkDetails: UpdateProjectState, credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]):
try:
if verifyToken(token = credentials.credentials):
if updateBookmarkDetails.action == "add":
_ = client.table("Projects").update({"isBookmarked": 1}).eq("projectId", updateBookmarkDetails.projectId).execute()
else:
_ = client.table("Projects").update({"isBookmarked": 0}).eq("projectId", updateBookmarkDetails.projectId).execute()
return JSONResponse(status_code = 200, content = {"status": "SUCCESS", "message": "Project bookmark status updated successfully"})
else:
return JSONResponse(status_code = 498, content = {"status": "ERROR", "errorDetail": "Invalid Token"})
except Exception as e:
raise HTTPException(status_code = 500, detail = f"Endpoint says: {e}")
@router.patch("/updateArchive")
async def updateArchive(updateArchiveDetails: UpdateProjectState, credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]):
try:
if verifyToken(token = credentials.credentials):
if updateArchiveDetails.action == "add":
_ = client.table("Projects").update({"isArchived": 1}).eq("projectId", updateArchiveDetails.projectId).execute()
else:
_ = client.table("Projects").update({"isArchived": 0}).eq("projectId", updateArchiveDetails.projectId).execute()
return JSONResponse(status_code = 200, content = {"status": "SUCCESS", "message": "Project archive status updated successfully"})
else:
return JSONResponse(status_code = 498, content = {"status": "ERROR", "errorDetail": "Invalid Token"})
except Exception as e:
raise HTTPException(status_code = 500, detail = f"Endpoint says: {e}")
@router.patch("/updateTrash")
async def updateTrash(updateTrashDetails: UpdateProjectState, credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]):
try:
if verifyToken(token = credentials.credentials):
if updateTrashDetails.action == "add":
_ = client.table("Projects").update({"isTrash": 1}).eq("projectId", updateTrashDetails.projectId).execute()
else:
_ = client.table("Projects").update({"isTrash": 0}).eq("projectId", updateTrashDetails.projectId).execute()
return JSONResponse(status_code = 200, content = {"status": "SUCCESS", "message": "Project trash status updated successfully"})
else:
return JSONResponse(status_code = 498, content = {"status": "ERROR", "errorDetail": "Invalid Token"})
except Exception as e:
raise HTTPException(status_code = 500, detail = f"Endpoint says: {e}")
@router.post("/generateMetadata/{projectId}")
async def generateMetadata(projectId: str, credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]):
try:
if verifyToken(token = credentials.credentials):
filenames = [x.get("name") for x in client.storage.from_("AnalyticsHub").list(projectId)]
if "metadata.json" in filenames:
fileUrl = os.environ["FILE_URL"].format(projectId = projectId, fileName = "metadata.json").replace(".parquet", "") + f"?cb={int(time.time())}"
jsonData = json.loads(urlopen(fileUrl).read())
jsonDataTables = set(jsonData.keys())
newMetadata = pipeline.generateMetadata(projectId = projectId)
newMetadataTables = set(newMetadata.keys())
newKeys = newMetadataTables.difference(jsonDataTables)
for key in newKeys: jsonData[key] = newMetadata[key]
else:
jsonData = pipeline.generateMetadata(projectId = projectId)
with io.BytesIO() as buffer:
buffer.write(json.dumps(jsonData, indent=4).encode("utf-8"))
buffer.seek(0)
client.storage.from_("AnalyticsHub").upload(path = f"{projectId}/metadata.json", file = buffer.getvalue(), file_options = {"upsert": "true"})
return JSONResponse(status_code = 200, content = {"status": "SUCCESS", "metadata": jsonData})
else:
return JSONResponse(status_code = 498, content = {"status": "ERROR", "errorDetail": "Invalid Token"})
except Exception as e:
raise HTTPException(status_code = 500, detail = f"Endpoint says: {e}")
@router.get("/getMetadata/{projectId}")
async def getMetadata(projectId: str, credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]):
try:
if verifyToken(token = credentials.credentials):
fileUrl = os.environ["FILE_URL"].format(projectId = projectId, fileName = "metadata.json").replace(".parquet", "") + f"?cb={int(time.time())}"
jsonData = json.loads(urlopen(fileUrl).read())
newJson = {"tables": []}
for key in jsonData:
tableJson = {
"tableName": key,
"tableDesc": jsonData.get(key).get("description"),
"shape": jsonData.get(key).get("shape"),
"columns": jsonData.get(key).get("columns")
}
newJson.get("tables").append(tableJson)
return JSONResponse(status_code = 200, content = newJson)
else:
return JSONResponse(status_code = 498, content = {"status": "ERROR", "errorDetail": "Invalid Token"})
except Exception as e:
raise HTTPException(status_code = 500, detail = f"Endpoint says: {e}")
@router.put("/editMetadata")
async def editMetadata(modifiedMetadata: EditMetadata, credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]):
try:
if verifyToken(token = credentials.credentials):
fileUrl = os.environ["FILE_URL"].format(projectId = modifiedMetadata.projectId, fileName = "metadata.json").replace(".parquet", "") + f"?cb={int(time.time())}"
jsonData = json.loads(urlopen(fileUrl).read())
if modifiedMetadata.tableDescription and not (modifiedMetadata.columnName or modifiedMetadata.columnDescription):
jsonData[modifiedMetadata.tableName]["description"] = modifiedMetadata.tableDescription
elif (modifiedMetadata.columnName and modifiedMetadata.columnDescription) and not modifiedMetadata.tableDescription:
columns = jsonData[modifiedMetadata.tableName]["columns"]
for column in columns:
if column["name"] == modifiedMetadata.columnName:
idx = columns.index(column)
columns[idx]["description"] = modifiedMetadata.columnDescription
jsonData[modifiedMetadata.tableName]["columns"] = columns
else:
raise AttributeError("Invalid combination of parameters provided")
with io.BytesIO() as buffer:
buffer.write(json.dumps(jsonData, indent=4).encode("utf-8"))
buffer.seek(0)
client.storage.from_("AnalyticsHub").upload(path = f"{modifiedMetadata.projectId}/metadata.json", file = buffer.getvalue(), file_options = {"upsert": "true"})
return JSONResponse(status_code = 200, content = {"status": "SUCCESS", "metadata": jsonData})
else:
return JSONResponse(status_code = 498, content = {"status": "ERROR", "errorDetail": "Invalid Token"})
except Exception as e:
raise HTTPException(status_code = 500, detail = f"Endpoint says: {e}")
@router.delete("/deleteProject")
async def deleteProject(projectId: str, credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]):
try:
if verifyToken(token = credentials.credentials):
_ = client.table("Projects").delete().eq("projectId", projectId).execute()
allFiles = client.storage.from_("AnalyticsHub").list(projectId)
fileNames = [os.path.join(projectId, x.get("name")) for x in allFiles]
_ = client.storage.from_("AnalyticsHub").remove(fileNames)
return JSONResponse(status_code = 200, content = {"status": "SUCCESS", "message": "Project deleted successfully"})
else:
return JSONResponse(status_code = 498, content = {"status": "ERROR", "errorDetail": "Invalid Token"})
except Exception as e:
raise HTTPException(status_code = 500, detail = f"Endpoint says: {e}") |