243 lines
8.6 KiB
Python
243 lines
8.6 KiB
Python
from flask import Blueprint, jsonify
|
|
|
|
api_openapi_bp = Blueprint('api_openapi', __name__, url_prefix='/api/v1')
|
|
|
|
OPENAPI_SPEC = {
|
|
"openapi": "3.0.3",
|
|
"info": {
|
|
"title": "Edu-Space REST API",
|
|
"description": "Enterprise Academic & Physical Space Management REST API with JWT Authentication and Role-Based Access Control.",
|
|
"version": "1.0.0"
|
|
},
|
|
"servers": [
|
|
{
|
|
"url": "http://127.0.0.1:5000",
|
|
"description": "Local Flask Backend Server"
|
|
}
|
|
],
|
|
"components": {
|
|
"securitySchemes": {
|
|
"bearerAuth": {
|
|
"type": "http",
|
|
"scheme": "bearer",
|
|
"bearerFormat": "JWT"
|
|
}
|
|
},
|
|
"schemas": {
|
|
"LoginRequest": {
|
|
"type": "object",
|
|
"required": ["email", "password"],
|
|
"properties": {
|
|
"email": {
|
|
"type": "string",
|
|
"format": "email",
|
|
"example": "admin@eduspace.com"
|
|
},
|
|
"password": {
|
|
"type": "string",
|
|
"format": "password",
|
|
"example": "Admin123!"
|
|
}
|
|
}
|
|
},
|
|
"LoginResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"access_token": {"type": "string"},
|
|
"refresh_token": {"type": "string"},
|
|
"token_type": {"type": "string", "example": "Bearer"},
|
|
"expires_in": {"type": "integer"},
|
|
"user": {"type": "object"}
|
|
}
|
|
},
|
|
"ErrorResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {"type": "string"},
|
|
"message": {"type": "string"}
|
|
}
|
|
},
|
|
"UserResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {"type": "integer"},
|
|
"email": {"type": "string"},
|
|
"first_name": {"type": "string"},
|
|
"last_name": {"type": "string"},
|
|
"role": {"type": "string"},
|
|
"is_active": {"type": "boolean"}
|
|
}
|
|
},
|
|
"SubjectResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {"type": "integer"},
|
|
"name": {"type": "string"},
|
|
"code": {"type": "string"},
|
|
"career": {"type": "string"}
|
|
}
|
|
},
|
|
"ClassroomResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {"type": "integer"},
|
|
"name": {"type": "string"},
|
|
"capacity": {"type": "integer"},
|
|
"building": {"type": "string"},
|
|
"floor": {"type": "string"}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"paths": {
|
|
"/api/v1/auth/login": {
|
|
"post": {
|
|
"summary": "Authenticate user and issue JWT tokens",
|
|
"tags": ["Authentication"],
|
|
"requestBody": {
|
|
"required": True,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/LoginRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Authentication successful",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/LoginResponse"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Validation error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {"$ref": "#/components/schemas/ErrorResponse"}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Unauthorized / Bad credentials",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {"$ref": "#/components/schemas/ErrorResponse"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/auth/me": {
|
|
"get": {
|
|
"summary": "Get authenticated user profile",
|
|
"tags": ["Authentication"],
|
|
"security": [{"bearerAuth": []}],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Current user profile",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {"$ref": "#/components/schemas/UserResponse"}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Missing or invalid token",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {"$ref": "#/components/schemas/ErrorResponse"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/classrooms": {
|
|
"get": {
|
|
"summary": "List all physical classrooms and facilities",
|
|
"tags": ["Classrooms"],
|
|
"security": [{"bearerAuth": []}],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of classrooms",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "array",
|
|
"items": {"$ref": "#/components/schemas/ClassroomResponse"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/admin/users": {
|
|
"get": {
|
|
"summary": "List all users (Admin only)",
|
|
"tags": ["Admin - Users"],
|
|
"security": [{"bearerAuth": []}],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of users",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "array",
|
|
"items": {"$ref": "#/components/schemas/UserResponse"}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Forbidden - Requires admin role"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/admin/subjects": {
|
|
"get": {
|
|
"summary": "List all academic subjects (Admin only)",
|
|
"tags": ["Admin - Academic"],
|
|
"security": [{"bearerAuth": []}],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of subjects",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "array",
|
|
"items": {"$ref": "#/components/schemas/SubjectResponse"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/v1/openapi.json": {
|
|
"get": {
|
|
"summary": "Get OpenAPI 3.0.3 specification JSON",
|
|
"tags": ["Documentation"],
|
|
"responses": {
|
|
"200": {
|
|
"description": "OpenAPI Specification"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@api_openapi_bp.route('/openapi.json', methods=['GET'])
|
|
def get_openapi_spec():
|
|
"""Serves the OpenAPI 3.0 specification for Schemathesis / DAST and Swagger UI."""
|
|
return jsonify(OPENAPI_SPEC)
|