from typing import List from fastapi import FastAPI, HTTPException from fastapi.responses import JSONResponse from models import RequestModel import os import json import cv2 import numpy as np import httpx BASE_DIR = "saved_data" app = FastAPI() def orb_sim(img1, img2): # ORB orb = cv2.ORB_create() kp_a, desc_a = orb.detectAndCompute(img1, None) kp_b, desc_b = orb.detectAndCompute(img2, None) # Brute-force matcher bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(desc_a, desc_b) similar_regions = [i for i in matches if i.distance < 20] if len(matches) == 0: return 0 return len(similar_regions) / len(matches) def load_image(source): Image.MAX_IMAGE_PIXELS = None if source.startswith('http'): response = requests.get(source) img = np.asarray(bytearray(response.content), dtype=np.uint8) img = cv2.imdecode(img, cv2.IMREAD_GRAYSCALE) else: img = base64.b64decode(source) img = Image.open(BytesIO(img)) img = np.array(img) img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) return img app = FastAPI() BASE_DIR = "/tmp/data" @app.post("/save") async def save(image_data: RequestModel): os.makedirs(BASE_DIR, exist_ok=True) filename = os.path.join(BASE_DIR, f"{image_data.originId}_{image_data.assetCode}.json") img1 = load_image(image_data.originSource) img2 = load_image(image_data.source) similarity_orb = None if img1 is not None and img2 is not None: similarity_orb = orb_sim(img1, img2) print(f"Similaridade ORB entre {image_data.originSource} e {image_data.source}: {similarity_orb}") data_to_save = image_data.dict() if similarity_orb is not None: data_to_save["similarityOrb"] = similarity_orb with open(filename, "w") as f: json.dump(data_to_save, f, indent=4) return True @app.get("/files") async def list_files(): try: files_data = [] for filename in os.listdir(BASE_DIR): filepath = os.path.join(BASE_DIR, filename) if os.path.isfile(filepath): try: with open(filepath, "r") as f: file_content = f.read() # Lê o conteúdo do ficheiro # Tenta decodificar o conteúdo como JSON, se possível try: file_content_json = json.loads(file_content) files_data.append({"filename": filename, "content": file_content_json}) except json.JSONDecodeError: files_data.append({"filename": filename, "content": file_content}) # Se não for JSON, retorna o texto except (IOError, OSError) as e: raise HTTPException(status_code=500, detail=f"Erro ao ler o ficheiro {filename}: {e}") return JSONResponse({"files_data": files_data}) except FileNotFoundError: raise HTTPException(status_code=404, detail="Diretório de dados não encontrado") @app.get("/files/similar") async def list_similar_files(): try: files_data = [] for filename in os.listdir(BASE_DIR): filepath = os.path.join(BASE_DIR, filename) if os.path.isfile(filepath): try: with open(filepath, "r") as f: file_content = f.read() try: file_content_json = json.loads(file_content) # Check for similarityOrb and filter if "similarityOrb" in file_content_json and file_content_json["similarityOrb"] > 0: files_data.append({"filename": filename, "content": file_content_json}) except json.JSONDecodeError: pass # Skip files that are not valid JSON except (IOError, OSError) as e: raise HTTPException(status_code=500, detail=f"Erro ao ler o ficheiro {filename}: {e}") return JSONResponse({"files_data": files_data}) except FileNotFoundError: raise HTTPException(status_code=404, detail="Diretório de dados não encontrado") @app.get("/files/find/{origin_id}") async def get_file_by_origin_id(origin_id: int): try: for filename in os.listdir(BASE_DIR): if filename.startswith(f"{origin_id}_") and filename.endswith(".json"): filepath = os.path.join(BASE_DIR, filename) if os.path.isfile(filepath): try: with open(filepath, "r") as f: file_content = f.read() try: file_content_json = json.loads(file_content) return JSONResponse({"filename": filename, "content": file_content_json}) except json.JSONDecodeError: return JSONResponse({"filename": filename, "content": file_content}) except (IOError, OSError) as e: raise HTTPException(status_code=500, detail=f"Erro ao ler o ficheiro {filename}: {e}") raise HTTPException(status_code=404, detail=f"Ficheiro com originId '{origin_id}' não encontrado") except FileNotFoundError: raise HTTPException(status_code=404, detail="Diretório de dados não encontrado")