mirror of
https://github.com/LukeHagar/pypistats.dev.git
synced 2025-12-06 12:47:48 +00:00
Upgrade OpenAPI version to 3.1.0 and expand API documentation with additional query parameters and response formats. Remove deprecated cache, cron, and data processing endpoints for cleaner codebase.
This commit is contained in:
39
openapi.yaml
39
openapi.yaml
@@ -1,4 +1,4 @@
|
|||||||
openapi: 3.0.3
|
openapi: 3.1.0
|
||||||
info:
|
info:
|
||||||
title: PyPI Stats API
|
title: PyPI Stats API
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
@@ -237,7 +237,7 @@ paths:
|
|||||||
- in: path
|
- in: path
|
||||||
name: type
|
name: type
|
||||||
required: true
|
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
|
- in: query
|
||||||
name: chart
|
name: chart
|
||||||
schema: { type: string, enum: [line, bar] }
|
schema: { type: string, enum: [line, bar] }
|
||||||
@@ -254,17 +254,50 @@ paths:
|
|||||||
name: os
|
name: os
|
||||||
schema: { type: string, enum: [Windows, Linux, Darwin, other] }
|
schema: { type: string, enum: [Windows, Linux, Darwin, other] }
|
||||||
description: Only for type=system
|
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:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: PNG image
|
description: PNG image by default, or JSON when format=json
|
||||||
content:
|
content:
|
||||||
image/png:
|
image/png:
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: binary
|
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 }
|
'400': { description: Bad request }
|
||||||
'404': { description: Package not found }
|
'404': { description: Package not found }
|
||||||
|
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes: {}
|
securitySchemes: {}
|
||||||
|
|
||||||
|
|||||||
88
src/routes/api/admin/cache/+server.ts
vendored
88
src/routes/api/admin/cache/+server.ts
vendored
@@ -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 });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -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.' });
|
|
||||||
};
|
|
||||||
@@ -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 });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user