Upload evaluation results
Deliver the original native report and retry saved uploads without rerunning your model.
Create a reporter using a writable local directory and a write key. Use a test write key for evaluation development.
import Foundation
import LedgeKit
import LedgeKitTesting
func uploadReport(fileURL: URL, directory: URL, writeKey: String) async throws {
let reporter = LedgeEvaluationReporter(directory: directory, credentials: .apiKey(writeKey))
let report = try LedgeEvaluationFile(data: Data(contentsOf: fileURL))
try await reporter.submit(report)
}Use the original JSON file exported by Apple Evaluations. LedgeEvaluationFile
validates its native identity, timestamps, row count, encoding, and 4 MiB size
limit. It retains the input bytes rather than re-encoding metrics or samples.
What submit means
submit(_:) saves the report under Pending before delivery. It returns after a
matching server receipt is accepted and the file is moved to Uploaded. On
failure it throws and retains the pending file.
Authentication and validation errors fail immediately. Temporary network/server errors allow up to three total attempts with short delays. Redirects are rejected. Reusing a pending result ID with different file bytes is a local conflict.
Retry saved reports
for delivery in try await reporter.retryPending() {
if let error = delivery.error {
print("Could not upload \(delivery.file.lastPathComponent): \(error)")
}
}retryPending() reads saved reports. Each returned Delivery includes the file
and an optional error string; inspect every result. Failure to read the pending
directory can throw from the method itself.
Retrying the same ID and exact file is idempotent. Retrying delivery does not execute the evaluator or call the model.
Optional execution metadata
LedgeProducer.capture(serviceName:).evaluationInfo can supply environment
metadata when your test creates the evaluation. For dataset evaluations, also
include dataset.evaluationInfo() before running. The uploader does not create
execution metadata after the fact.