darkfrostx commited on
Commit
d8ef0e2
·
verified ·
1 Parent(s): 6a3f790

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -22
app.py CHANGED
@@ -2,18 +2,24 @@ from fastapi import FastAPI
2
  from pydantic import BaseModel, conlist, confloat
3
  from typing import Dict, Any, List, Literal
4
  from datetime import datetime
 
5
 
6
- # LangSmith (OTel) tracing via Traceloop SDK
7
- # Set these in the Space Settings Variables (key/value):
8
- # TRACELOOP_BASE_URL = https://api.smith.langchain.com/otel
9
- # TRACELOOP_HEADERS = x-api-key=<YOUR_LANGSMITH_API_KEY>
10
- from traceloop.sdk import Traceloop
11
- Traceloop.init(app_name="ssra-auditor") # traces show up under this name
12
- from traceloop.sdk.decorators import workflow
 
 
 
 
 
 
13
 
14
- # Guardrails AI: schema + semantic guardrails
15
  from guardrails import Guard
16
- from guardrails.validators import ValidLength # example semantic validator
17
 
18
  app = FastAPI()
19
 
@@ -39,24 +45,17 @@ AUDIT_SCHEMA = {
39
  },
40
  "required": ["decision","metrics","deltas"]
41
  }
42
-
43
- # Example: cap deltas to 10 items (semantic-ish)
44
- guard = Guard().configure(
45
- output_schema=AUDIT_SCHEMA,
46
- validators={ "deltas": [ValidLength(min=0, max=10)] }
47
- )
48
 
49
  @app.get("/health")
50
  def health():
51
- return {"ok": True, "service": "auditor", "ts": datetime.utcnow().isoformat()}
52
 
53
- @workflow(name="audit_workflow") # shows up as a workflow in traces
54
- @app.post("/audit", response_model=AuditResult)
55
- def audit(payload: Dict[str, Any]):
56
  bundle = payload.get("bundle", {}) or {}
57
  m_in = payload.get("metrics", {}) or {}
58
 
59
- # start from inbound metrics
60
  m = {
61
  "TCS": float(m_in.get("TCS", 0.0)),
62
  "HDI": float(m_in.get("HDI", 0.0)),
@@ -70,7 +69,6 @@ def audit(payload: Dict[str, Any]):
70
  regions = len((bundle.get("regions",{}).get("data") or {}).get("regions_ranked",[]) or [])
71
  lit_ok = bool(bundle.get("literature"))
72
 
73
- # recompute (simple heuristics)
74
  m["TCS"] = min(1.0, (1 if edges>0 else 0) + (1 if regions>0 else 0) + (1 if lit_ok else 0)) * 0.9
75
  m["HDI"] = 1.2 if regions>8 else (1.0 if regions>4 else 0.8)
76
  m["EVI"] = (1 if edges>0 else 0) + (1 if regions>0 else 0) + (1 if lit_ok else 0)
@@ -85,7 +83,18 @@ def audit(payload: Dict[str, Any]):
85
  if m["EVI"] < 3: deltas.append("Add one more evidence type (review/trials).")
86
  if m["CBS"] > 0.6: deltas.append("Surface/address contrary findings explicitly.")
87
 
88
- # Guardrails validate & auto-repair minor schema issues
89
  out_raw = {"metrics": m, "decision": decision, "deltas": deltas}
90
  _, validated, *_ = guard.parse(out_raw)
91
  return AuditResult(**validated)
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  from pydantic import BaseModel, conlist, confloat
3
  from typing import Dict, Any, List, Literal
4
  from datetime import datetime
5
+ import os
6
 
7
+ # --- Optional tracing (won't crash if key missing) ---
8
+ # If you want tracing, create a LangSmith or Traceloop account.
9
+ # For Traceloop: set TRACELOOP_API_KEY=<your_key> in Space → Settings → Variables.
10
+ try:
11
+ if os.getenv("TRACELOOP_API_KEY"):
12
+ from traceloop.sdk import Traceloop
13
+ from traceloop.sdk.decorators import workflow
14
+ Traceloop.init(app_name="ssra-auditor")
15
+ TRACING = True
16
+ else:
17
+ TRACING = False
18
+ except Exception:
19
+ TRACING = False
20
 
21
+ # --- Guardrails schema guard (semantic validators are optional) ---
22
  from guardrails import Guard
 
23
 
24
  app = FastAPI()
25
 
 
45
  },
46
  "required": ["decision","metrics","deltas"]
47
  }
48
+ guard = Guard().configure(output_schema=AUDIT_SCHEMA)
49
+ # Guardrails: schema + optional semantic validators; see docs & hub for options. :contentReference[oaicite:1]{index=1}
 
 
 
 
50
 
51
  @app.get("/health")
52
  def health():
53
+ return {"ok": True, "service": "auditor", "ts": datetime.utcnow().isoformat(), "tracing": TRACING}
54
 
55
+ def _audit_logic(payload: Dict[str, Any]) -> AuditResult:
 
 
56
  bundle = payload.get("bundle", {}) or {}
57
  m_in = payload.get("metrics", {}) or {}
58
 
 
59
  m = {
60
  "TCS": float(m_in.get("TCS", 0.0)),
61
  "HDI": float(m_in.get("HDI", 0.0)),
 
69
  regions = len((bundle.get("regions",{}).get("data") or {}).get("regions_ranked",[]) or [])
70
  lit_ok = bool(bundle.get("literature"))
71
 
 
72
  m["TCS"] = min(1.0, (1 if edges>0 else 0) + (1 if regions>0 else 0) + (1 if lit_ok else 0)) * 0.9
73
  m["HDI"] = 1.2 if regions>8 else (1.0 if regions>4 else 0.8)
74
  m["EVI"] = (1 if edges>0 else 0) + (1 if regions>0 else 0) + (1 if lit_ok else 0)
 
83
  if m["EVI"] < 3: deltas.append("Add one more evidence type (review/trials).")
84
  if m["CBS"] > 0.6: deltas.append("Surface/address contrary findings explicitly.")
85
 
 
86
  out_raw = {"metrics": m, "decision": decision, "deltas": deltas}
87
  _, validated, *_ = guard.parse(out_raw)
88
  return AuditResult(**validated)
89
+
90
+ # Route with or without Traceloop @workflow
91
+ if TRACING:
92
+ from traceloop.sdk.decorators import workflow
93
+ @workflow(name="audit_workflow")
94
+ @app.post("/audit", response_model=AuditResult)
95
+ def audit(payload: Dict[str, Any]):
96
+ return _audit_logic(payload)
97
+ else:
98
+ @app.post("/audit", response_model=AuditResult)
99
+ def audit(payload: Dict[str, Any]):
100
+ return _audit_logic(payload)