submission api client
This commit is contained in:
@@ -5,10 +5,23 @@ import type {
|
|||||||
QuestionDetail,
|
QuestionDetail,
|
||||||
QuestionListResponse,
|
QuestionListResponse,
|
||||||
Stats,
|
Stats,
|
||||||
|
SubmissionRequest,
|
||||||
|
SubmissionResponse,
|
||||||
} from "@/types";
|
} from "@/types";
|
||||||
|
|
||||||
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
|
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
|
||||||
|
|
||||||
|
export class ApiError extends Error {
|
||||||
|
constructor(
|
||||||
|
public status: number,
|
||||||
|
public statusText: string,
|
||||||
|
public detail?: string
|
||||||
|
) {
|
||||||
|
super(detail || `API error: ${status} ${statusText}`);
|
||||||
|
this.name = "ApiError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchApi<T>(
|
async function fetchApi<T>(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
options?: RequestInit
|
options?: RequestInit
|
||||||
@@ -23,7 +36,14 @@ async function fetchApi<T>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`API error: ${response.status} ${response.statusText}`);
|
let detail: string | undefined;
|
||||||
|
try {
|
||||||
|
const errorBody = await response.json();
|
||||||
|
detail = errorBody.detail;
|
||||||
|
} catch {
|
||||||
|
// Ignore JSON parse errors
|
||||||
|
}
|
||||||
|
throw new ApiError(response.status, response.statusText, detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.json();
|
return response.json();
|
||||||
@@ -77,3 +97,13 @@ export async function getPattern(slug: string): Promise<Pattern> {
|
|||||||
export async function getStats(): Promise<Stats> {
|
export async function getStats(): Promise<Stats> {
|
||||||
return fetchApi<Stats>("/api/stats");
|
return fetchApi<Stats>("/api/stats");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function submitSolution(
|
||||||
|
slug: string,
|
||||||
|
submission: SubmissionRequest
|
||||||
|
): Promise<SubmissionResponse> {
|
||||||
|
return fetchApi<SubmissionResponse>(`/api/questions/${slug}/submit`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(submission),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -61,6 +61,17 @@ export interface Solution {
|
|||||||
explanation: string | null;
|
explanation: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface VisibleTestCase {
|
||||||
|
id: number;
|
||||||
|
input: Record<string, unknown>;
|
||||||
|
expected: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HiddenTestInput {
|
||||||
|
id: number;
|
||||||
|
input: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface QuestionDetail extends QuestionListItem {
|
export interface QuestionDetail extends QuestionListItem {
|
||||||
description: string;
|
description: string;
|
||||||
constraints: string | null;
|
constraints: string | null;
|
||||||
@@ -69,6 +80,9 @@ export interface QuestionDetail extends QuestionListItem {
|
|||||||
output: string;
|
output: string;
|
||||||
explanation?: string;
|
explanation?: string;
|
||||||
}> | null;
|
}> | null;
|
||||||
|
function_signature: string | null;
|
||||||
|
visible_test_cases: VisibleTestCase[] | null;
|
||||||
|
hidden_test_inputs: HiddenTestInput[] | null;
|
||||||
explanation: Explanation | null;
|
explanation: Explanation | null;
|
||||||
solutions: Solution[];
|
solutions: Solution[];
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
@@ -114,3 +128,30 @@ export interface Stats {
|
|||||||
by_category: CategoryCount[];
|
by_category: CategoryCount[];
|
||||||
by_pattern: PatternCount[];
|
by_pattern: PatternCount[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HiddenTestOutput {
|
||||||
|
test_id: number;
|
||||||
|
output: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SubmissionRequest {
|
||||||
|
code: string;
|
||||||
|
hidden_outputs: HiddenTestOutput[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TestResult {
|
||||||
|
test_id: number;
|
||||||
|
passed: boolean;
|
||||||
|
input?: Record<string, unknown>;
|
||||||
|
expected?: unknown;
|
||||||
|
actual: unknown;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SubmissionResponse {
|
||||||
|
passed: boolean;
|
||||||
|
visible_results: TestResult[];
|
||||||
|
hidden_results: TestResult[];
|
||||||
|
total_passed: number;
|
||||||
|
total_tests: number;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user