""" tracer.py — Logging de traces para o badge "Sharing is Caring" do hackathon. Salva cada interação (analyze + confirm) em data/traces.jsonl. Quando quiser publicar no HF Hub, chame push_to_hub(). Variáveis de ambiente: HF_TOKEN — token HuggingFace (necessário só para push) HF_DATASET_ID — ex: "build-small-hackathon/animal-visto-traces" TRACE_ENABLED — "0" para desabilitar completamente (default: habilitado) """ import json import logging import os import threading from datetime import datetime, timezone from pathlib import Path from core.database import DATA_DIR log = logging.getLogger(__name__) TRACES_PATH = DATA_DIR / "traces.jsonl" ENABLED = os.environ.get("TRACE_ENABLED", "1") != "0" HF_DATASET = os.environ.get("HF_DATASET_ID", "") _lock = threading.Lock() def log_trace(record: dict) -> None: """Appenda um trace em data/traces.jsonl (thread-safe).""" if not ENABLED: return record = { "timestamp": datetime.now(timezone.utc).isoformat(), **record, } # Remove campos sensíveis record.pop("photo_path", None) record.pop("temp_path", None) coords = record.get("gps", {}) if coords: # Arredonda para 2 casas (~1km de precisão) para preservar privacidade record["gps"] = { "lat": round(coords["lat"], 2) if coords.get("lat") else None, "lng": round(coords["lng"], 2) if coords.get("lng") else None, } try: DATA_DIR.mkdir(parents=True, exist_ok=True) with _lock: with open(TRACES_PATH, "a", encoding="utf-8") as f: f.write(json.dumps(record, ensure_ascii=False) + "\n") except Exception as e: log.warning("Trace não salvo: %s", e) def push_to_hub() -> None: """ Publica traces.jsonl como dataset no HF Hub. Só chamar quando estiver pronto para publicar. Requer: HF_TOKEN e HF_DATASET_ID definidos. """ if not HF_DATASET: log.error("HF_DATASET_ID não definido — abortando push.") return if not TRACES_PATH.exists(): log.warning("Nenhum trace para publicar.") return try: from huggingface_hub import HfApi api = HfApi(token=os.environ.get("HF_TOKEN", "")) api.create_repo(repo_id=HF_DATASET, repo_type="dataset", exist_ok=True) api.upload_file( path_or_fileobj=str(TRACES_PATH), path_in_repo="traces.jsonl", repo_id=HF_DATASET, repo_type="dataset", commit_message="chore: update traces", ) log.info("Traces publicados em %s", HF_DATASET) except Exception as e: log.error("Erro ao publicar traces: %s", e)