Spaces:
Sleeping
Sleeping
| """ | |
| Generator utilities for creating JSON and Markdown outputs | |
| """ | |
| import json | |
| from datetime import datetime | |
| def generate_json_output(metadata, top_level, processes, generator_version): | |
| """ | |
| Generate JSON output for the model card | |
| Args: | |
| metadata: Dictionary of metadata fields | |
| top_level: Dictionary of top-level elements (Figure 6) | |
| processes: Dictionary of data & process elements (Figure 7) | |
| generator_version: Version of the generator | |
| Returns: | |
| String containing JSON data ready for file download | |
| """ | |
| output = { | |
| "df_model_card_metadata": metadata, | |
| "df_mc_0_top_level": { | |
| k: v for k, v in top_level.items() | |
| if v.get("applicable") and v.get("description") | |
| }, | |
| "df_mc_1_data_processes": { | |
| k: v for k, v in processes.items() | |
| if v.get("applicable") and v.get("description") | |
| }, | |
| "generated_at": datetime.utcnow().isoformat() + "Z", | |
| "generator_version": generator_version, | |
| "schema_version": "1.0" | |
| } | |
| return json.dumps(output, indent=2) | |
| def generate_markdown_output(metadata, top_level, processes, generator_version): | |
| """ | |
| Generate Markdown README output for the model card | |
| Args: | |
| metadata: Dictionary of metadata fields | |
| top_level: Dictionary of top-level elements (Figure 6) | |
| processes: Dictionary of data & process elements (Figure 7) | |
| generator_version: Version of the generator | |
| Returns: | |
| String containing Markdown content ready for file download | |
| """ | |
| md = [] | |
| # Header | |
| md.append("# Digital Forensics Model Card\n") | |
| md.append(f"**Generated:** {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC\n") | |
| md.append("---\n") | |
| # Metadata Section | |
| md.append("## Metadata\n") | |
| md.append(f"- **Identifier (MMCID):** {metadata.get('mmcid', 'Not specified')}") | |
| md.append(f"- **Version (MCV):** {metadata.get('version', 'N/A')}") | |
| md.append(f"- **Owner:** {metadata.get('owner', 'Not specified')}") | |
| md.append(f"- **Usage Context:** {metadata.get('use_context', 'Not specified')}") | |
| md.append(f"- **Layer/Stage (Ln):** {metadata.get('layer_n', 'N/A')}\n") | |
| # Case Statement | |
| if metadata.get('case_statement'): | |
| md.append("### Case Statement") | |
| md.append(f"{metadata['case_statement']}\n") | |
| # Hypothesis | |
| if metadata.get('hypothesis'): | |
| md.append("### Hypothesis") | |
| md.append(f"{metadata['hypothesis']}\n") | |
| # Classification | |
| if metadata.get('classification'): | |
| md.append("### Classification") | |
| for item in metadata['classification']: | |
| md.append(f"- {item}") | |
| md.append("") | |
| # Reasoning Type | |
| if metadata.get('reasoning_type'): | |
| md.append("### Type of Reasoning") | |
| for item in metadata['reasoning_type']: | |
| md.append(f"- {item}") | |
| md.append("") | |
| # Bias | |
| if metadata.get('bias'): | |
| md.append("### Identified Bias") | |
| for item in metadata['bias']: | |
| md.append(f"- {item}") | |
| md.append("") | |
| if metadata.get('cause_of_bias'): | |
| md.append("**Cause(s) of Bias:**") | |
| for item in metadata['cause_of_bias']: | |
| md.append(f"- {item}") | |
| md.append("") | |
| # Error | |
| if metadata.get('error'): | |
| md.append("### Error") | |
| md.append(f"{metadata['error']}\n") | |
| if metadata.get('cause_of_error'): | |
| md.append("**Cause(s) of Error:**") | |
| for item in metadata['cause_of_error']: | |
| md.append(f"- {item}") | |
| md.append("") | |
| md.append("---\n") | |
| # Top Level Elements (Figure 6) | |
| md.append("## Top Level Elements (DF MC 0)\n") | |
| md.append("*Based on Figure 6 - Top Level Elements*\n") | |
| applicable_top_level = { | |
| k: v for k, v in top_level.items() | |
| if v.get("applicable") and v.get("description") | |
| } | |
| if applicable_top_level: | |
| for key, value in applicable_top_level.items(): | |
| title = key.replace("_", " ").title() | |
| md.append(f"### {title}") | |
| md.append(f"{value['description']}\n") | |
| else: | |
| md.append("*No top-level elements specified.*\n") | |
| md.append("---\n") | |
| # Data & Processes (Figure 7) | |
| md.append("## Data Types and Analytical Processes (DF MC 1)\n") | |
| md.append("*Based on Figure 7 - DF Data types and analytical processes (Hargreaves et al., 2024)*\n") | |
| applicable_processes = { | |
| k: v for k, v in processes.items() | |
| if v.get("applicable") and v.get("description") | |
| } | |
| if applicable_processes: | |
| for key, value in applicable_processes.items(): | |
| title = key.replace("_", " ").title() | |
| md.append(f"### {title}") | |
| md.append(f"{value['description']}\n") | |
| else: | |
| md.append("*No data processes specified.*\n") | |
| md.append("---\n") | |
| # References | |
| md.append("## References\n") | |
| md.append("This model card is based on the following works:\n") | |
| md.append("1. **Di Maio, P.** (2024). Towards Open Standards for Systemic Complexity in Digital Forensics. https://papers.cool/arxiv/2512.12970") | |
| md.append("2. **Hargreaves, C., Nelson, A., & Casey, E.** (2024). An abstract model for digital forensic analysis tools—A foundation for systematic error mitigation analysis. *Forensic Science International: Digital Investigation*, 48.\n") | |
| # Footer | |
| md.append("---\n") | |
| md.append(f"*Generated by [Digital Forensics Model Card Generator](https://huggingface.co/spaces/forensic-model-card-generator) v{generator_version}*") | |
| return "\n".join(md) |