dalim-fusion-es-api/parse_api.py
DJP 584b7df68b feat: Dalim DAM web application — full build
Complete client-facing DAM interface for Dalim ES FUSiON GraphQL API:

- Asset browsing, search with faceted filtering, project/folder navigation
- Send To distribution to 17 MMS platforms (PIM, Social, Google, In-Store, Print)
- 10 workflow templates, approval queue, process monitor with progress bars
- Collections with thumbnail mosaics, dashboard with KPI cards and activity feed
- Docker Compose (app + PostgreSQL), mock mode, error boundaries
- Two-tier API reference docs (466 operations indexed, 29 detailed)
- MediaMarkt branding: Noto Sans Display, #DF0000 red, dark sidebar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 22:12:18 -04:00

135 lines
5.6 KiB
Python

#!/usr/bin/env python3
"""Parse FUSION_API_index.html using regex to extract all GraphQL operations."""
import re
import json
def strip_html(text):
"""Remove HTML tags and clean whitespace."""
text = re.sub(r'<[^>]+>', '', text)
text = re.sub(r'\s+', ' ', text).strip()
return text
def extract_code_text(html):
"""Extract text content from code blocks, stripping span tags."""
return strip_html(html)
def main():
print("Reading HTML file...")
with open('/Users/daveporter/Desktop/CODING-2024/DALIM-API/FUSION_API_index.html', 'r', encoding='utf-8') as f:
html = f.read()
print(f"HTML size: {len(html):,} bytes")
# Extract all operation sections
# Each section starts with <section id="query-xxx" or id="mutation-xxx"
section_pattern = r'<section\s+id="(query|mutation|subscription)-([^"]+)"[^>]*class="operation[^"]*"[^>]*>(.*?)</section>'
sections = re.findall(section_pattern, html, re.DOTALL)
print(f"Found {len(sections)} operation sections")
operations = []
for op_type, op_name, content in sections:
op = {
'name': op_name,
'type': op_type,
'description': '',
'response_type': '',
'arguments': [],
'example_query': '',
'example_variables': '',
'example_response': ''
}
# Description
desc_match = re.search(r'class="operation-description[^"]*"[^>]*>.*?<p>(.*?)</p>', content, re.DOTALL)
if desc_match:
op['description'] = strip_html(desc_match.group(1))
# Response type
resp_match = re.search(r'class="operation-response[^"]*"[^>]*>.*?Returns\s+(.*?)</p>', content, re.DOTALL)
if resp_match:
op['response_type'] = strip_html(resp_match.group(1))
# Arguments from table
args_section = re.search(r'class="operation-arguments[^"]*"[^>]*>(.*?)</div>', content, re.DOTALL)
if args_section:
rows = re.findall(r'<tr>\s*<td>(.*?)</td>\s*<td>(.*?)</td>\s*</tr>', args_section.group(1), re.DOTALL)
for name_cell, desc_cell in rows:
arg_name = ''
arg_type = ''
name_match = re.search(r'class="property-name"[^>]*>(.*?)</span>', name_cell, re.DOTALL)
if name_match:
arg_name = strip_html(name_match.group(1))
type_match = re.search(r'class="property-type"[^>]*>(.*?)</span>', name_cell, re.DOTALL)
if type_match:
arg_type = strip_html(type_match.group(1))
required = 'required' in name_cell.lower() or '!' in arg_type
desc = strip_html(desc_cell)
if arg_name:
op['arguments'].append({
'name': arg_name,
'type': arg_type,
'description': desc,
'required': required
})
# Example query
query_example = re.search(r'class="[^"]*operation-query-example[^"]*"[^>]*>.*?<pre><code[^>]*>(.*?)</code></pre>', content, re.DOTALL)
if query_example:
op['example_query'] = strip_html(query_example.group(1))
# Example variables
vars_example = re.search(r'class="[^"]*operation-variables-example[^"]*"[^>]*>.*?<pre><code[^>]*>(.*?)</code></pre>', content, re.DOTALL)
if vars_example:
op['example_variables'] = strip_html(vars_example.group(1))
# Example response
resp_example = re.search(r'class="[^"]*operation-response-example[^"]*"[^>]*>.*?<pre><code[^>]*>(.*?)</code></pre>', content, re.DOTALL)
if resp_example:
op['example_response'] = strip_html(resp_example.group(1))
operations.append(op)
# Count stats
queries = [op for op in operations if op['type'] == 'query']
mutations = [op for op in operations if op['type'] == 'mutation']
subscriptions = [op for op in operations if op['type'] == 'subscription']
print(f"\nResults:")
print(f" Queries: {len(queries)}")
print(f" Mutations: {len(mutations)}")
print(f" Subscriptions: {len(subscriptions)}")
with_desc = sum(1 for op in operations if op['description'])
with_args = sum(1 for op in operations if op['arguments'])
with_resp = sum(1 for op in operations if op['response_type'])
with_example = sum(1 for op in operations if op['example_query'])
print(f" With description: {with_desc}/{len(operations)}")
print(f" With arguments: {with_args}/{len(operations)}")
print(f" With response type: {with_resp}/{len(operations)}")
print(f" With example query: {with_example}/{len(operations)}")
# Save
with open('/Users/daveporter/Desktop/CODING-2024/DALIM-API/docs/api_parsed.json', 'w') as f:
json.dump({'operations': operations}, f, indent=2)
print("\nSaved to docs/api_parsed.json")
# Print a few samples
for name in ['activities', 'createProject', 'createUser', 'search', 'assets']:
matches = [op for op in operations if op['name'] == name]
if matches:
op = matches[0]
print(f"\n--- {op['type']} {op['name']} ---")
print(f" Desc: {op['description'][:100]}")
print(f" Response: {op['response_type']}")
print(f" Args ({len(op['arguments'])}):")
for a in op['arguments'][:3]:
print(f" {a['name']}: {a['type']} {'(required)' if a['required'] else ''} - {a['description'][:60]}")
if len(op['arguments']) > 3:
print(f" ... and {len(op['arguments'])-3} more")
if __name__ == '__main__':
main()