Python SDK Reference

Package: mima-governance · Version: 0.3.x · Python: 3.9+

$pip install mima-governance # core
$pip install "mima-governance[otel]" # + OpenTelemetry guard
$pip install "mima-governance[all]" # + otel + langchain + llamaindex + autogen

Client setup

1from mima_governance import MimaGovernance, AuthorisedBy
2
3mima = MimaGovernance(
4 api_key="mima_ext_...", # required
5 system_name="my-ai-pipeline", # required — matches mima.attest() system_name
6 workspace_id=None, # resolved automatically from API key
7 base_url="https://api.mima.ai", # override for self-hosted deployments
8 agent_name=None, # defaults to system_name
9 signing_key=None, # 32-byte hex key for HMAC-SHA256 GRC signing
10 authorised_by=AuthorisedBy( # default principal for all attestations
11 identity="alice@example.com",
12 role="ml-engineer",
13 ),
14 on_error="warn", # "warn" | "raise" | "silent"
15 batch_flush_interval=30.0, # seconds
16 batch_max_size=100,
17)

Environment variables

VariablePurpose
MIMA_API_KEYAlternative to passing api_key=
MIMA_WORKSPACE_IDAlternative to passing workspace_id=
MIMA_BASE_URLAlternative to passing base_url=

Attestation

@mima.attest() — decorator

Wraps any function. Records input hash, output hash, and execution time.

1@mima.attest(tool_name="classify_document", model_id="claude-opus-4-6")
2def classify(document: str) -> str:
3 return llm.complete(document)

Parameters

ParameterTypeDefaultDescription
tool_namestrrequiredName of the tool / action
modestr"sync""sync" pushes immediately; "batch" buffers
model_idstrNoneLLM model identifier
authorised_byAuthorisedByclient defaultOverride for this call
approval_tokentokenNoneToken from require_approval()

Works with async functions:

1@mima.attest(tool_name="generate_summary")
2async def summarise(text: str) -> str:
3 return await async_llm.complete(text)

mima.push() — explicit attestation

Use when you already have input/output hashes (e.g. from a pipeline step).

1import hashlib
2
3input_hash = hashlib.sha256(json.dumps(payload).encode()).hexdigest()
4output_hash = hashlib.sha256(json.dumps(result).encode()).hexdigest()
5
6result = mima.push(
7 "generate_report",
8 input_hash,
9 output_hash,
10 model_id="claude-opus-4-6",
11)

mima.trace() — context manager

Capture hashes manually within the with block.

1with mima.trace("run_pipeline") as t:
2 t.set_input(input_docs)
3 output = pipeline.run(input_docs)
4 t.set_output(output)
5 t.set_model_id("gpt-4o")

mima.batch() — buffered bulk push

1with mima.batch() as b:
2 for item in work_queue:
3 result = process(item)
4 b.add("process_item", input=item, output=result)
5# Flushes on exit — single batch API call.

Pre-approval gates

Block an AI action until a GRC manager approves it in the dashboard.

1from mima_governance.approvals import ApprovalDenied, ApprovalTimeout
2
3try:
4 token = mima.require_approval(
5 action_type="high_risk_decision",
6 context={"affected_users": 1200, "policy": "credit_v3"},
7 timeout_seconds=300,
8 approver="bob@example.com",
9 on_timeout="raise",
10 )
11except ApprovalDenied:
12 return {"status": "rejected"}
13
14# Use the token to link attestation to the approval record.
15@mima.attest(tool_name="credit_decision", approval_token=token)
16def make_credit_decision(application):
17 return model.predict(application)

When token is an ApprovalToken, the decorator also pushes a human_oversight GRC record with oversight_status='approved', earning EUAIA_ART14.

Do not call require_approval() inside a web request handler — it holds the connection for up to timeout_seconds. Gate job submission instead.


GRC evidence methods

All 11 methods push to POST /api/workspaces/{ws}/governance/grc/evidence and return a GrcResult:

1@dataclass
2class GrcResult:
3 record_id: str # "" on failure
4 record_type: str
5 mapped_controls: list # e.g. ['EUAIA_ART9', 'ISO42001_6_1']
6 detail: str # "ok" on success, error message on failure

mima.ai_risk_assessment()

Records an AI system risk classification under EU AI Act Art. 9.

1mima.ai_risk_assessment(
2 system_name="loan-scorer",
3 risk_tier="high",
4 use_case="Automated credit scoring for consumer loans",
5 intended_purpose="Score loan applications and surface them for human review",
6 impact_domains=["credit", "consumer_finance"],
7 art5_self_assessment=True, # certifies no Art.5 prohibited practices
8 assessor="alice@example.com",
9 annex_iii_category="essential_services", # required for high-risk
10 environment="production",
11 system_version="v2.1.0",
12 technical_doc_url="https://docs.internal/loan-scorer/annex-iv",
13)

art5_self_assessment=True certifies the system does not engage in any Art. 5 prohibited practices. Never set without explicit human confirmation.

annex_iii_category must be one of: biometric_identification, critical_infrastructure, education_vocational, employment_management, essential_services, law_enforcement, migration_border, justice_democratic, not_annex_iii


mima.model_evaluation()

1mima.model_evaluation(
2 model_id="loan-scorer-v2.1",
3 dataset="holdout-q2-2026",
4 accuracy=0.94,
5 evaluated_by="alice@example.com",
6 evaluation_type="quarterly", # "initial" | "quarterly" | "triggered"
7 bias_metrics={"demographic_parity": 0.02, "equal_opportunity": 0.01},
8 robustness_score=0.91,
9 passed_threshold=True,
10)

mima.human_oversight()

1mima.human_oversight(
2 decision_id="loan-app-48291",
3 ai_recommendation="approve",
4 human_decision="reject",
5 reviewer="bob@example.com",
6 rationale="Application flagged for fraud indicators not in model training data",
7 model_id="loan-scorer-v2.1",
8)
9# override=True is inferred automatically (ai_recommendation != human_decision)

mima.training_data_governance()

1mima.training_data_governance(
2 model_id="loan-scorer-v2.1",
3 dataset_id="training-set-2026-q1",
4 record_count=2_400_000,
5 bias_checks_performed=True,
6 approved_by="data-governance@example.com",
7 data_sources=["internal_originations", "credit_bureau_x"],
8 data_categories=["financial_history", "demographics"],
9 known_limitations="Underrepresented: self-employed applicants pre-2020",
10)

mima.incident_report()

1mima.incident_report(
2 title="Model output hallucination on edge case inputs",
3 severity="high", # "critical" | "high" | "medium" | "low"
4 description="Model returned invalid IBAN numbers for 3 users on 2026-06-01",
5 affected_systems=["payment-processor-ai"],
6 detected_at="2026-06-01T14:22:00Z",
7 authority_notified_at="2026-06-01T18:00:00Z",
8)

mima.access_review()

1mima.access_review(
2 user="contractor@external.com",
3 resource="model-training-pipeline",
4 granted=False,
5 reviewed_by="alice@example.com",
6 review_type="periodic",
7 reason="Contractor engagement ended 2026-05-31",
8)

mima.change_event()

1mima.change_event(
2 type="prompt_update",
3 by="alice@example.com",
4 description="Updated system prompt to add output format constraints",
5 environment="production",
6 system="customer-support-ai",
7 change_id="CHG-4821",
8)

mima.vendor_risk()

1mima.vendor_risk(
2 vendor="OpenAI",
3 tier="high", # "critical" | "high" | "medium" | "low"
4 last_reviewed="2026-06-01",
5 findings=2,
6 contacts=["security@openai.com"],
7)

mima.policy_acknowledged()

1mima.policy_acknowledged(
2 policy="AI Use Policy",
3 user="alice@example.com",
4 version="v3.1.0",
5 acknowledgment_type="initial", # "initial" | "renewal" | "update"
6 policy_url="https://internal.example.com/policies/ai-use/v3.1.0",
7 channel="in-app",
8)

mima.model_drift_event()

1mima.model_drift_event(
2 model_id="loan-scorer-v2.1",
3 metric="f1_score",
4 baseline=0.94,
5 current=0.88,
6 threshold=0.90,
7 drift_type="performance", # "performance" | "data" | "concept"
8 detected_by="monitoring-agent",
9 action_taken="Model retraining scheduled for 2026-07-01",
10)

mima.governance_review()

1mima.governance_review(
2 reviewed_by="ciso@example.com",
3 report_type="quarterly",
4 frameworks_reviewed=["EU_AI_ACT", "ISO_42001", "SOC2"],
5 overall_readiness=78,
6 action_items=4,
7 notes="Three open gaps in Art.9 documentation. Drift monitoring not yet wired.",
8)

Async client

1from mima_governance.async_client import AsyncMimaGovernance
2
3mima = AsyncMimaGovernance(
4 api_key="mima_ext_...",
5 system_name="async-pipeline",
6)
7
8@mima.attest(tool_name="generate")
9async def generate(prompt: str) -> str:
10 return await llm.complete(prompt)
11
12# GRC methods are also async:
13await mima.ai_risk_assessment(
14 system_name="async-pipeline",
15 risk_tier="limited",
16 ...
17)

Signing GRC records

Pass a 32-byte hex key to enable HMAC-SHA256 record signing:

1import secrets
2# Generate once and store in secrets manager:
3signing_key = secrets.token_hex(32)
4
5mima = MimaGovernance(
6 api_key="mima_ext_...",
7 system_name="my-system",
8 signing_key=signing_key,
9)

Every GRC push includes client_sig and client_sig_algo: "hmac-sha256". Auditors can verify signatures using the canonical message format (see api-reference.md).


Framework integrations

LangChain

1from mima_governance.integrations.langchain_callback import MimaLangChainCallback
2
3handler = MimaLangChainCallback(mima)
4chain.invoke({"question": "..."}, config={"callbacks": [handler]})

LlamaIndex

1from mima_governance.integrations.llamaindex_handler import MimaLlamaIndexHandler
2
3Settings.callback_manager.add_handler(MimaLlamaIndexHandler(mima))

AutoGen

1from mima_governance.integrations.autogen_middleware import MimaAutoGenMiddleware
2
3middleware = MimaAutoGenMiddleware(mima, agent_name="assistant")
4# Pass as a message hook when building your ConversableAgent reply chain.

Error handling

on_errorBehaviour
"warn" (default)Logs to stderr with warnings.warn, returns empty result
"raise"Raises MimaAttestationError
"silent"Swallows errors, returns empty result
1from mima_governance import MimaGovernance, MimaAttestationError
2
3mima = MimaGovernance(api_key="...", system_name="...", on_error="raise")
4
5try:
6 mima.push("tool", input_hash, output_hash)
7except MimaAttestationError as e:
8 logger.error("Governance record failed: %s", e)

Check for a failed push without raising:

1result = mima.push("tool", input_hash, output_hash)
2if not result.attestation_id:
3 logger.warning("Push failed: %s", result.detail)