diff --git a/openapi.yaml b/openapi.yaml index b7b3768..9f3d5f3 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1,4 +1,4 @@ -openapi: 3.0.3 +openapi: 3.1.0 info: title: PyPI Stats API version: 1.0.0 @@ -237,7 +237,7 @@ paths: - in: path name: type required: true - schema: { type: string, enum: [overall, python_major, python_minor, system] } + schema: { type: string, enum: [overall, python_major, python_minor, system, installer, version] } - in: query name: chart schema: { type: string, enum: [line, bar] } @@ -254,17 +254,50 @@ paths: name: os schema: { type: string, enum: [Windows, Linux, Darwin, other] } description: Only for type=system + - in: query + name: format + schema: { type: string, enum: [json, data] } + description: Return JSON payload for interactive charts instead of a PNG image + - in: query + name: nocache + schema: { type: string } + description: Set to '1' to bypass server-side chart cache + - in: query + name: cache + schema: { type: string } + description: Set to 'false' to bypass server-side chart cache responses: '200': - description: PNG image + description: PNG image by default, or JSON when format=json content: image/png: schema: type: string format: binary + application/json: + schema: + type: object + properties: + package: { type: string } + type: { type: string } + chartType: { type: string, enum: [line, bar] } + title: { type: string } + labels: + type: array + items: { type: string } + datasets: + type: array + items: + type: object + properties: + label: { type: string } + data: + type: array + items: { type: number } '400': { description: Bad request } '404': { description: Package not found } + components: securitySchemes: {} diff --git a/src/routes/api/admin/cache/+server.ts b/src/routes/api/admin/cache/+server.ts deleted file mode 100644 index a08264d..0000000 --- a/src/routes/api/admin/cache/+server.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { json } from '@sveltejs/kit'; -import type { RequestHandler } from './$types'; -import { CacheManager } from '$lib/redis.js'; -import { clearAllCache, invalidatePackageCache, invalidateSearchCache } from '$lib/api.js'; - -const cache = new CacheManager(); - -export const GET: RequestHandler = async () => { - try { - // Get cache statistics - const stats = { - message: 'Cache management endpoint', - operations: ['GET', 'POST', 'DELETE'], - endpoints: { - 'GET /api/admin/cache': 'Get cache information', - 'POST /api/admin/cache/clear': 'Clear all cache', - 'POST /api/admin/cache/invalidate-package': 'Invalidate package cache', - 'POST /api/admin/cache/invalidate-search': 'Invalidate search cache' - } - }; - - return json(stats); - } catch (error) { - return json({ error: 'Failed to get cache information' }, { status: 500 }); - } -}; - -export const POST: RequestHandler = async ({ request }) => { - try { - const body = await request.json(); - const { action, packageName } = body; - - switch (action) { - case 'clear': - await clearAllCache(); - return json({ - success: true, - message: 'All cache cleared successfully' - }); - - case 'invalidate-package': - if (!packageName) { - return json({ - error: 'Package name is required' - }, { status: 400 }); - } - await invalidatePackageCache(packageName); - return json({ - success: true, - message: `Cache invalidated for package: ${packageName}` - }); - - case 'invalidate-search': - await invalidateSearchCache(); - return json({ - success: true, - message: 'Search cache invalidated successfully' - }); - - default: - return json({ - error: 'Invalid action. Use: clear, invalidate-package, or invalidate-search' - }, { status: 400 }); - } - } catch (error) { - console.error('Cache management error:', error); - return json({ - error: 'Cache management failed', - message: error instanceof Error ? error.message : 'Unknown error' - }, { status: 500 }); - } -}; - -export const DELETE: RequestHandler = async () => { - try { - await clearAllCache(); - return json({ - success: true, - message: 'All cache cleared successfully' - }); - } catch (error) { - console.error('Cache clear error:', error); - return json({ - error: 'Failed to clear cache', - message: error instanceof Error ? error.message : 'Unknown error' - }, { status: 500 }); - } -}; \ No newline at end of file diff --git a/src/routes/api/admin/cron/+server.ts b/src/routes/api/admin/cron/+server.ts deleted file mode 100644 index de33b6d..0000000 --- a/src/routes/api/admin/cron/+server.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { json } from '@sveltejs/kit'; -import type { RequestHandler } from './$types'; - -// Cron removed; keep endpoint for compatibility -export const GET: RequestHandler = async () => { - return json({ success: true, message: 'Cron removed; on-demand ingestion active.' }); -}; - -export const POST: RequestHandler = async () => { - return json({ success: true, message: 'Cron removed; on-demand ingestion active.' }); -}; \ No newline at end of file diff --git a/src/routes/api/admin/process-data/+server.ts b/src/routes/api/admin/process-data/+server.ts deleted file mode 100644 index 2e71f7d..0000000 --- a/src/routes/api/admin/process-data/+server.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { json } from '@sveltejs/kit'; -import type { RequestHandler } from './$types'; -import { DataProcessor } from '$lib/data-processor.js'; - -export const POST: RequestHandler = async ({ request }) => { - try { - const body = await request.json(); - const { date, purge = true } = body; - - console.log('Starting data processing via API...'); - - const processor = new DataProcessor(); - const results = await processor.etl(date, purge); - - return json({ - success: true, - message: 'Data processing completed successfully', - results - }); - } catch (error) { - console.error('Data processing failed:', error); - return json({ - success: false, - message: 'Data processing failed', - error: error instanceof Error ? error.message : 'Unknown error' - }, { status: 500 }); - } -}; \ No newline at end of file