diff --git a/server.py b/server.py index 9a661a9..9469a28 100644 --- a/server.py +++ b/server.py @@ -8,6 +8,7 @@ from fastapi import ( UploadFile, File, + Form, FastAPI, Depends, HTTPException, @@ -32,6 +33,7 @@ import botocore from msal import ConfidentialClientApplication import httpx +import couchdb load_dotenv(".env") @@ -84,6 +86,9 @@ config=botocore.client.Config(signature_version="s3"), ) +couch = couchdb.Server('http://'+COUCHDB_USER+':'+COUCHDB_PASSWORD+'@'+COUCHDB_URL+'/') +#db_access = couch['access'] +db_canvas = couch['canvas'] def mint_noid(noid_type): url = f"{NOID_SERVER}/mint/1/{noid_type}" @@ -99,20 +104,38 @@ def convert_image(source_file, output_path): output = Image.open(output_path) return {"width": output.width, "height": output.height, "size": output.size} +def save_canvas(noid, encoded_noid, width, height, size, md5): + #canvas = db_canvas.get(canvas['id']) + db_canvas.save({ + "_id": noid, + "master": { + "width": width, + "extension": "jpg", + "md5": md5, + "size": size, + "height": height, + "mime": "image/jpeg" + }, + "source": { + "from": "IIIF", + "url": image_api_url+'/iiif/2/'+encoded_noid+'/info.json' + } + }) def save_image_to_swift(local_filename, swift_filename, container): - try: - with open(local_filename, "rb") as local_file: - file_content = local_file.read() - file_md5_hash = hashlib.md5(file_content).hexdigest() - conn.put_object(container, swift_filename, contents=file_content) - except: - return None - try: - conn.get_container(container, prefix=swift_filename) - return file_md5_hash - except: - return None + #try: + with open(local_filename, "rb") as local_file: + file_content = local_file.read() + file_md5_hash = hashlib.md5(file_content).hexdigest() + res = conn.put_object(container, swift_filename, contents=file_content) + print("res",file_md5_hash, res) + #except: + # return None + #try: + print(local_filename, swift_filename, container) + return file_md5_hash + #except: + # return None def get_file_from_swift(swift_filename, container): @@ -138,7 +161,6 @@ def get_file_from_swift(swift_filename, container): async def get_logged_user(cookie: str = Security(APIKeyCookie(name="token"))) -> OpenID: """Get user's JWT stored in cookie 'token', parse it and return the user's OpenID.""" try: - print("cookie", cookie) claims = jwt.decode(cookie, key=AAD_CLIENT_SECRET, algorithms=["HS256"]) return OpenID(**claims["pld"]) except Exception as error: @@ -150,14 +172,13 @@ async def get_logged_user(cookie: str = Security(APIKeyCookie(name="token"))) -> def verify_token(req: Request): try: token = req.headers["Authorization"] - print("token", token) # Here your code for verifying the token or whatever you use valid = jwt.decode( token.replace("Bearer ", ""), key=AAD_CLIENT_SECRET, algorithms=["HS256"] ) print("res", valid) if not valid: - raise HTTPException(status_code=401, detail="Unauthorized") + return False return True except Exception as error: print("An error occurred:", error) @@ -243,6 +264,16 @@ async def pdf(prefix, noid): else: raise HTTPException(status_code=500, detail=str(e)) +@app.get("/bearer-protected") +async def protected_endpoint(authorized: bool = Depends(verify_token)): + message = { + "message": f"You are not authorized!", + } + if authorized: + message = { + "message": f"You are authorized!", + } + return message @app.post("/savemanifest") async def create_files(file: UploadFile, authorized: bool = Depends(verify_token)): @@ -272,31 +303,34 @@ async def create_files(file: UploadFile, authorized: bool = Depends(verify_token } -@app.post("/uploadfiles") +@app.post("/uploadfiles/{prefix}/{noid}") async def create_files( + prefix, + noid, files: Annotated[List[bytes], File()], - manifest_noid, authorized: bool = Depends(verify_token), ): if not authorized: return { "message" : "You are not authorized to make this request." } + manifest_noid = f'{prefix}/{noid}' + print(manifest_noid) canvases = [] # if form ! have manifest noid min noid else use noid... - if not manifest_noid: - manifest_noid = mint_noid("manifest") + if 'new/new' == manifest_noid: + manifest_noid = mint_noid("manifest") #TODO-Replace with Mary code for file in files: # request_object_content = await file.read() source_file = io.BytesIO(file) - canvas_noid = mint_noid("canvas") + canvas_noid = mint_noid("canvas") #TODO-Replace with Mary code encoded_canvas_noid = canvas_noid.replace("/", "%2F") swift_filename = f"{canvas_noid}.jpg" # will handle more than 1 file local_filename = f"{encoded_canvas_noid}.jpg" convert_info = convert_image(source_file, local_filename) swift_md5 = save_image_to_swift(local_filename, swift_filename, "access-files") if swift_md5: - # save_canvas(canvas_noid, encoded_canvas_noid, convert_info['width'], convert_info['height'], convert_info['size'], swift_md5) + save_canvas(canvas_noid, encoded_canvas_noid, convert_info['width'], convert_info['height'], convert_info['size'], swift_md5) canvases.append( { "id": f"{presentation_api_url}/canvas/{canvas_noid}", @@ -409,16 +443,6 @@ async def create_files( """ ''' Authorized Examples -@app.get("/bearer-protected") -async def protected_endpoint(authorized: bool = Depends(verify_token)): - message = { - "message": f"You are not authroized!", - } - if authorized: - message = { - "message": f"You are authroized!", - } - return message @app.get("/protected") async def protected_endpoint(user: OpenID = Depends(get_logged_user)): @@ -448,14 +472,10 @@ async def protected_endpoint(user: OpenID = Depends(get_logged_user)): https://intility.github.io/fastapi-azure-auth/usage-and-faq/calling_your_apis_from_python Attach MARC as SeeAlso to manifest: // https://crkn-blacklight-beta.azurewebsites.net/catalog//librarian_view Attach OCR PDF SeeAlso to manifest - -- call this route from the front end app -- OCR PDF changes: - Change call for updating canvas in couch - file is replace with same name so we don't need to worry about updating IIIF) +- call this route from the front end app -- Hammer changes: - Use Mary API for Canvas and Manifest level data +- Create script for upserting data into couch for legacy access - Update this site on Azure (python now - will need to make a new app: crkn-access-api)