from typing import List, Optional from pydantic import BaseModel, Field from config import CONFIG import requests class RetinaResult(BaseModel): hash: Optional[str] binary: Optional[str] quality_too_low: Optional[bool] = Field(alias="qualityTooLow") class RetinaClient: def __init__(self) -> None: self._retina_host = CONFIG.retina_host def get_image_hash(self, did: str, cid: str): resp = requests.post( f"{self._retina_host}/api/hash", json={ "did": did, "cid": cid, }, ) resp.raise_for_status() return RetinaResult.model_validate_json(resp.text) RETINA_CLIENT = RetinaClient() def hex_to_binary(hex: str): return bytes.fromhex(hex) def binary_to_float_vector(bin: bytes): vector_data: List[float] = [] for byte in bin: for j in range(8): if (byte >> (7 - j)) & 1 == 1: vector_data.append(1.0) else: vector_data.append(0.0) return vector_data