luisoala commited on
Commit
299be58
Β·
1 Parent(s): e7bc9a5
Files changed (2) hide show
  1. app.py +76 -16
  2. validation.py +14 -22
app.py CHANGED
@@ -82,7 +82,7 @@ def create_ui():
82
  validation_progress = gr.HTML(visible=False)
83
 
84
  # Collapsible report section
85
- with gr.Accordion("Download full validation repoort", visible=False) as report_group:
86
  with gr.Column():
87
  report_md = gr.File(
88
  label="Download Report",
@@ -220,6 +220,25 @@ def create_ui():
220
  background-color: var(--background-fill-secondary);
221
  border-radius: 8px;
222
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  </style>
224
  """)
225
 
@@ -274,7 +293,13 @@ def create_ui():
274
 
275
  def fetch_from_url(url):
276
  if not url:
277
- return """<div class="progress-status">Please enter a URL</div>""", gr.update(visible=False)
 
 
 
 
 
 
278
 
279
  try:
280
  # Fetch JSON from URL
@@ -282,33 +307,68 @@ def create_ui():
282
  response.raise_for_status()
283
  json_data = response.json()
284
 
285
- # Show success message
286
- progress_html = """<div class="progress-status">βœ… JSON fetched successfully from URL</div>"""
287
-
288
- # Validate the fetched JSON
289
  results = []
290
- results.append(("JSON Format Validation", True, "βœ… The URL returned valid JSON."))
291
 
292
  croissant_valid, croissant_message = validate_croissant(json_data)
293
  results.append(("Croissant Schema Validation", croissant_valid, croissant_message))
294
 
295
  if not croissant_valid:
296
- return progress_html, build_results_html(results)
 
 
 
 
 
 
297
 
298
  records_valid, records_message = validate_records(json_data)
299
  results.append(("Records Generation Test", records_valid, records_message))
300
 
301
- return progress_html, build_results_html(results)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
  except requests.exceptions.RequestException as e:
304
- error_message = f"❌ Error fetching URL: {str(e)}"
305
- return f"""<div class="progress-status">{error_message}</div>""", gr.update(visible=False)
 
 
 
 
 
 
306
  except json.JSONDecodeError as e:
307
- error_message = f"❌ URL did not return valid JSON: {str(e)}"
308
- return f"""<div class="progress-status">{error_message}</div>""", gr.update(visible=False)
 
 
 
 
 
 
309
  except Exception as e:
310
- error_message = f"❌ Unexpected error: {str(e)}"
311
- return f"""<div class="progress-status">{error_message}</div>""", gr.update(visible=False)
 
 
 
 
 
 
312
 
313
  def build_results_html(results):
314
  # Build validation results HTML
@@ -423,7 +483,7 @@ def create_ui():
423
  fetch_btn.click(
424
  fetch_from_url,
425
  inputs=url_input,
426
- outputs=[upload_progress, validation_results]
427
  )
428
 
429
  # Footer
 
82
  validation_progress = gr.HTML(visible=False)
83
 
84
  # Collapsible report section
85
+ with gr.Accordion("Download full validation report β–Ά", visible=False, open=False) as report_group:
86
  with gr.Column():
87
  report_md = gr.File(
88
  label="Download Report",
 
220
  background-color: var(--background-fill-secondary);
221
  border-radius: 8px;
222
  }
223
+
224
+ /* Override Gradio's default accordion arrow */
225
+ .gr-accordion {
226
+ position: relative;
227
+ }
228
+ .gr-accordion > .label-wrap {
229
+ display: flex;
230
+ align-items: center;
231
+ gap: 8px;
232
+ }
233
+ .gr-accordion > .label-wrap::after {
234
+ content: "β–Ά";
235
+ position: absolute;
236
+ right: 16px;
237
+ transition: transform 0.3s ease;
238
+ }
239
+ .gr-accordion[data-open=true] > .label-wrap::after {
240
+ transform: rotate(90deg);
241
+ }
242
  </style>
243
  """)
244
 
 
293
 
294
  def fetch_from_url(url):
295
  if not url:
296
+ return [
297
+ """<div class="progress-status">Please enter a URL</div>""",
298
+ gr.update(visible=False),
299
+ gr.update(visible=False),
300
+ None,
301
+ None
302
+ ]
303
 
304
  try:
305
  # Fetch JSON from URL
 
307
  response.raise_for_status()
308
  json_data = response.json()
309
 
310
+ # Process validation
 
 
 
311
  results = []
312
+ results.append(("JSON Format Validation", True, "The URL returned valid JSON."))
313
 
314
  croissant_valid, croissant_message = validate_croissant(json_data)
315
  results.append(("Croissant Schema Validation", croissant_valid, croissant_message))
316
 
317
  if not croissant_valid:
318
+ return [
319
+ """<div class="progress-status">βœ… JSON fetched successfully from URL</div>""",
320
+ build_results_html(results),
321
+ gr.update(visible=False),
322
+ None,
323
+ None
324
+ ]
325
 
326
  records_valid, records_message = validate_records(json_data)
327
  results.append(("Records Generation Test", records_valid, records_message))
328
 
329
+ # Generate report
330
+ report = generate_validation_report(url.split("/")[-1], json_data, results)
331
+ report_filename = f"report_croissant-validation_{json_data.get('name', 'unnamed')}.md"
332
+
333
+ if report:
334
+ with open(report_filename, "w") as f:
335
+ f.write(report)
336
+
337
+ return [
338
+ """<div class="progress-status">βœ… JSON fetched successfully from URL</div>""",
339
+ build_results_html(results),
340
+ gr.update(visible=True),
341
+ report,
342
+ report_filename
343
+ ]
344
 
345
  except requests.exceptions.RequestException as e:
346
+ error_message = f"Error fetching URL: {str(e)}"
347
+ return [
348
+ f"""<div class="progress-status">{error_message}</div>""",
349
+ gr.update(visible=False),
350
+ gr.update(visible=False),
351
+ None,
352
+ None
353
+ ]
354
  except json.JSONDecodeError as e:
355
+ error_message = f"URL did not return valid JSON: {str(e)}"
356
+ return [
357
+ f"""<div class="progress-status">{error_message}</div>""",
358
+ gr.update(visible=False),
359
+ gr.update(visible=False),
360
+ None,
361
+ None
362
+ ]
363
  except Exception as e:
364
+ error_message = f"Unexpected error: {str(e)}"
365
+ return [
366
+ f"""<div class="progress-status">{error_message}</div>""",
367
+ gr.update(visible=False),
368
+ gr.update(visible=False),
369
+ None,
370
+ None
371
+ ]
372
 
373
  def build_results_html(results):
374
  # Build validation results HTML
 
483
  fetch_btn.click(
484
  fetch_from_url,
485
  inputs=url_input,
486
+ outputs=[upload_progress, validation_results, report_group, report_text, report_md]
487
  )
488
 
489
  # Footer
validation.py CHANGED
@@ -10,26 +10,26 @@ def validate_json(file_path):
10
  try:
11
  with open(file_path, 'r') as f:
12
  json_data = json.load(f)
13
- return True, "βœ… The file is valid JSON.", json_data
14
  except json.JSONDecodeError as e:
15
- error_message = f"❌ Invalid JSON format: {str(e)}"
16
  return False, error_message, None
17
  except Exception as e:
18
- error_message = f"❌ Error reading file: {str(e)}"
19
  return False, error_message, None
20
 
21
  def validate_croissant(json_data):
22
  """Validate that the JSON follows Croissant schema."""
23
  try:
24
  dataset = mlc.Dataset(jsonld=json_data)
25
- return True, "βœ… The dataset passes Croissant validation."
26
  except mlc.ValidationError as e:
27
  error_details = traceback.format_exc()
28
- error_message = f"❌ Validation failed: {str(e)}\n\n{error_details}"
29
  return False, error_message
30
  except Exception as e:
31
  error_details = traceback.format_exc()
32
- error_message = f"❌ Unexpected error during validation: {str(e)}\n\n{error_details}"
33
  return False, error_message
34
 
35
  def validate_records(json_data):
@@ -39,7 +39,7 @@ def validate_records(json_data):
39
  record_sets = dataset.metadata.record_sets
40
 
41
  if not record_sets:
42
- return True, "βœ… No record sets found to validate."
43
 
44
  results = []
45
 
@@ -48,19 +48,19 @@ def validate_records(json_data):
48
  records = dataset.records(record_set=record_set.uuid)
49
  print(records)
50
  _ = func_timeout.func_timeout(WAIT_TIME, lambda: next(iter(records)))
51
- results.append(f"βœ… Record set '{record_set.uuid}' passed validation.")
52
  except func_timeout.exceptions.FunctionTimedOut:
53
- error_message = f"❌ Record set '{record_set.uuid}' generation took too long (>300s)"
54
  return False, error_message
55
  except Exception as e:
56
  error_details = traceback.format_exc()
57
- error_message = f"❌ Record set '{record_set.uuid}' failed: {str(e)}\n\n{error_details}"
58
  return False, error_message
59
 
60
  return True, "\n".join(results)
61
  except Exception as e:
62
  error_details = traceback.format_exc()
63
- error_message = f"❌ Unexpected error during records validation: {str(e)}\n\n{error_details}"
64
  return False, error_message
65
 
66
  def generate_validation_report(filename, json_data, results):
@@ -68,27 +68,19 @@ def generate_validation_report(filename, json_data, results):
68
  report = []
69
  report.append("# CROISSANT VALIDATION REPORT")
70
  report.append("=" * 80)
71
- report.append("\n## VALIDATION RESULTS")
72
  report.append("-" * 80)
73
-
74
  report.append(f"Starting validation for file: {filename}")
75
- report.append("")
76
 
77
  # Add validation results
78
  for test_name, passed, message in results:
79
  report.append(f"### {test_name}")
80
- if passed:
81
- report.append("βœ“")
82
- report.append(message.strip()) # Remove any trailing newlines
83
- else:
84
- report.append("❌")
85
- report.append(message.strip()) # Remove any trailing newlines
86
- report.append("") # Add spacing between sections
87
 
88
  # Add JSON-LD reference
89
  report.append("## JSON-LD REFERENCE")
90
  report.append("=" * 80)
91
- report.append("")
92
  report.append("```json")
93
  report.append(json.dumps(json_data, indent=2))
94
  report.append("```")
 
10
  try:
11
  with open(file_path, 'r') as f:
12
  json_data = json.load(f)
13
+ return True, "The file is valid JSON.", json_data
14
  except json.JSONDecodeError as e:
15
+ error_message = f"Invalid JSON format: {str(e)}"
16
  return False, error_message, None
17
  except Exception as e:
18
+ error_message = f"Error reading file: {str(e)}"
19
  return False, error_message, None
20
 
21
  def validate_croissant(json_data):
22
  """Validate that the JSON follows Croissant schema."""
23
  try:
24
  dataset = mlc.Dataset(jsonld=json_data)
25
+ return True, "The dataset passes Croissant validation."
26
  except mlc.ValidationError as e:
27
  error_details = traceback.format_exc()
28
+ error_message = f"Validation failed: {str(e)}\n\n{error_details}"
29
  return False, error_message
30
  except Exception as e:
31
  error_details = traceback.format_exc()
32
+ error_message = f"Unexpected error during validation: {str(e)}\n\n{error_details}"
33
  return False, error_message
34
 
35
  def validate_records(json_data):
 
39
  record_sets = dataset.metadata.record_sets
40
 
41
  if not record_sets:
42
+ return True, "No record sets found to validate."
43
 
44
  results = []
45
 
 
48
  records = dataset.records(record_set=record_set.uuid)
49
  print(records)
50
  _ = func_timeout.func_timeout(WAIT_TIME, lambda: next(iter(records)))
51
+ results.append(f"Record set '{record_set.uuid}' passed validation.")
52
  except func_timeout.exceptions.FunctionTimedOut:
53
+ error_message = f"Record set '{record_set.uuid}' generation took too long (>300s)"
54
  return False, error_message
55
  except Exception as e:
56
  error_details = traceback.format_exc()
57
+ error_message = f"Record set '{record_set.uuid}' failed: {str(e)}\n\n{error_details}"
58
  return False, error_message
59
 
60
  return True, "\n".join(results)
61
  except Exception as e:
62
  error_details = traceback.format_exc()
63
+ error_message = f"Unexpected error during records validation: {str(e)}\n\n{error_details}"
64
  return False, error_message
65
 
66
  def generate_validation_report(filename, json_data, results):
 
68
  report = []
69
  report.append("# CROISSANT VALIDATION REPORT")
70
  report.append("=" * 80)
71
+ report.append("## VALIDATION RESULTS")
72
  report.append("-" * 80)
 
73
  report.append(f"Starting validation for file: {filename}")
 
74
 
75
  # Add validation results
76
  for test_name, passed, message in results:
77
  report.append(f"### {test_name}")
78
+ report.append("βœ“" if passed else "βœ—")
79
+ report.append(message.strip()) # Remove any trailing newlines
 
 
 
 
 
80
 
81
  # Add JSON-LD reference
82
  report.append("## JSON-LD REFERENCE")
83
  report.append("=" * 80)
 
84
  report.append("```json")
85
  report.append(json.dumps(json_data, indent=2))
86
  report.append("```")