Skip to content

Commit 8621065

Browse files
committed
Create JSON Schema report
1 parent 3085ac9 commit 8621065

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

infer_json_schema.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import json
2+
import requests
3+
from datetime import datetime
4+
5+
def load_json_remote(url):
6+
"""Load JSON data from a remote URL."""
7+
response = requests.get(url)
8+
response.raise_for_status()
9+
return response.json()
10+
11+
def infer_schema(data, level=0):
12+
"""
13+
Recursively infer schema of a JSON object.
14+
Returns a nested dict describing keys and their types.
15+
"""
16+
if isinstance(data, dict):
17+
schema = {}
18+
for key, value in data.items():
19+
schema[key] = infer_schema(value, level + 1)
20+
return schema
21+
elif isinstance(data, list):
22+
if len(data) == 0:
23+
return ["empty_list"]
24+
# Infer schema from first element
25+
element_schema = infer_schema(data[0], level + 1)
26+
return [element_schema]
27+
else:
28+
return type(data).__name__
29+
30+
def format_schema(schema, indent=0):
31+
"""Convert schema dictionary to formatted Markdown text."""
32+
lines = []
33+
prefix = " " * indent
34+
if isinstance(schema, dict):
35+
for key, value in schema.items():
36+
if isinstance(value, (dict, list)):
37+
lines.append(f"{prefix}- **{key}**:")
38+
lines.extend(format_schema(value, indent + 1))
39+
else:
40+
lines.append(f"{prefix}- **{key}**: `{value}`")
41+
elif isinstance(schema, list):
42+
if len(schema) == 1:
43+
lines.append(f"{prefix}- List of:")
44+
lines.extend(format_schema(schema[0], indent + 1))
45+
else:
46+
lines.append(f"{prefix}- Mixed list elements: {schema}")
47+
else:
48+
lines.append(f"{prefix}- `{schema}`")
49+
return lines
50+
51+
def write_markdown(schema, output_file):
52+
"""Write inferred schema to a Markdown file."""
53+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
54+
with open(output_file, "w", encoding="utf-8") as f:
55+
f.write(f"# JSON Schema Report\n")
56+
f.write(f"**Generated on:** {timestamp}\n\n")
57+
f.write("## Inferred Schema\n\n")
58+
for line in format_schema(schema):
59+
f.write(line + "\n")
60+
print(f"✅ Schema written to {output_file}")
61+
62+
def main():
63+
url = "https://raw.githubusercontent.com/SingularityNET-Archive/SingularityNET-Archive/refs/heads/main/Data/Snet-Ambassador-Program/Meeting-Summaries/2025/meeting-summaries-array.json"
64+
output_file = "json_schema_report.md"
65+
66+
print("📡 Fetching JSON from remote source...")
67+
data = load_json_remote(url)
68+
print(f"✅ Downloaded {len(data)} top-level records.")
69+
70+
# If the file is a list, infer schema of the first element
71+
if isinstance(data, list) and len(data) > 0:
72+
schema = [infer_schema(data[0])]
73+
else:
74+
schema = infer_schema(data)
75+
76+
print("🔍 Inferring JSON schema...")
77+
for line in format_schema(schema):
78+
print(line)
79+
80+
write_markdown(schema, output_file)
81+
82+
if __name__ == "__main__":
83+
main()

json_schema_report.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# JSON Schema Report
2+
**Generated on:** 2025-10-13 12:56:57
3+
4+
## Inferred Schema
5+
6+
- List of:
7+
- **workgroup**: `str`
8+
- **workgroup_id**: `str`
9+
- **meetingInfo**:
10+
- **typeOfMeeting**: `str`
11+
- **date**: `str`
12+
- **host**: `str`
13+
- **documenter**: `str`
14+
- **peoplePresent**: `str`
15+
- **purpose**: `str`
16+
- **meetingVideoLink**: `str`
17+
- **workingDocs**:
18+
- List of:
19+
- **title**: `str`
20+
- **link**: `str`
21+
- **timestampedVideo**:
22+
- **agendaItems**:
23+
- List of:
24+
- **status**: `str`
25+
- **actionItems**:
26+
- List of:
27+
- **text**: `str`
28+
- **assignee**: `str`
29+
- **dueDate**: `str`
30+
- **status**: `str`
31+
- **decisionItems**:
32+
- List of:
33+
- **decision**: `str`
34+
- **effect**: `str`
35+
- **tags**:
36+
- **topicsCovered**: `str`
37+
- **emotions**: `str`
38+
- **type**: `str`
39+
- **noSummaryGiven**: `bool`
40+
- **canceledSummary**: `bool`

0 commit comments

Comments
 (0)