Tadeas Kosek commited on
Commit
94a2fe4
·
1 Parent(s): dbe78dd
app.py CHANGED
@@ -76,14 +76,69 @@ app = FastAPI(
76
  3. **Check status**: Monitor progress with `/jobs/{job_id}`
77
  4. **Download result**: Get extracted audio with `/jobs/{job_id}/download`
78
  5. **Optional trimming**: Use `start` and `end` parameters to download specific segments
 
 
 
 
 
 
 
 
 
 
79
  """,
80
  version=settings.app_version,
81
  docs_url="/docs",
82
  redoc_url="/redoc",
83
  openapi_url="/openapi.json",
84
- lifespan=lifespan
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  )
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  # Configure middleware
88
  configure_cors(app)
89
  register_exception_handlers(app)
 
76
  3. **Check status**: Monitor progress with `/jobs/{job_id}`
77
  4. **Download result**: Get extracted audio with `/jobs/{job_id}/download`
78
  5. **Optional trimming**: Use `start` and `end` parameters to download specific segments
79
+
80
+ ### Authentication
81
+ Most endpoints require JWT Bearer token authentication. Include your token in the Authorization header:
82
+ ```
83
+ Authorization: Bearer <your-jwt-token>
84
+ ```
85
+
86
+ Public endpoints (no authentication required):
87
+ - `GET /api/v1/info` - API information
88
+ - `GET /api/v1/health` - Health check
89
  """,
90
  version=settings.app_version,
91
  docs_url="/docs",
92
  redoc_url="/redoc",
93
  openapi_url="/openapi.json",
94
+ lifespan=lifespan,
95
+ # Add OpenAPI security scheme for Bearer token authentication
96
+ openapi_tags=[
97
+ {
98
+ "name": "extraction",
99
+ "description": "Audio extraction operations (requires authentication)"
100
+ },
101
+ {
102
+ "name": "jobs",
103
+ "description": "Job management operations (requires authentication)"
104
+ },
105
+ {
106
+ "name": "info",
107
+ "description": "Public API information (no authentication required)"
108
+ }
109
+ ]
110
  )
111
 
112
+ # Configure OpenAPI security scheme
113
+ from fastapi.openapi.utils import get_openapi
114
+
115
+ def custom_openapi():
116
+ if app.openapi_schema:
117
+ return app.openapi_schema
118
+
119
+ openapi_schema = get_openapi(
120
+ title=app.title,
121
+ version=app.version,
122
+ description=app.description,
123
+ routes=app.routes,
124
+ tags=app.openapi_tags
125
+ )
126
+
127
+ # Add Bearer token security scheme
128
+ openapi_schema["components"]["securitySchemes"] = {
129
+ "bearerAuth": {
130
+ "type": "http",
131
+ "scheme": "bearer",
132
+ "bearerFormat": "JWT",
133
+ "description": "Enter your JWT Bearer token"
134
+ }
135
+ }
136
+
137
+ app.openapi_schema = openapi_schema
138
+ return app.openapi_schema
139
+
140
+ app.openapi = custom_openapi
141
+
142
  # Configure middleware
143
  configure_cors(app)
144
  register_exception_handlers(app)
application/dto/extraction_response.py CHANGED
@@ -16,10 +16,10 @@ class DirectExtractionResultDTO:
16
  class JobStatusDTO:
17
  """DTO for job status."""
18
  job_id: str
19
- external_job_id: Optional[str] = None
20
  status: str
21
  created_at: datetime
22
  updated_at: datetime
 
23
  filename: Optional[str] = None
24
  file_size_mb: Optional[float] = None
25
  output_format: Optional[str] = None
@@ -35,14 +35,14 @@ class DownloadResultDTO:
35
  media_type: str
36
  filename: str
37
  processing_time: float
38
- storage_key: str = None
39
 
40
  @dataclass
41
  class JobCreationDTO:
42
  """DTO for job creation."""
43
  job_id: str
44
- external_job_id: Optional[str] = None
45
  status: str
46
  message: str
47
  check_url: str
 
48
  file_size_mb: Optional[float] = None
 
16
  class JobStatusDTO:
17
  """DTO for job status."""
18
  job_id: str
 
19
  status: str
20
  created_at: datetime
21
  updated_at: datetime
22
+ external_job_id: Optional[str] = None
23
  filename: Optional[str] = None
24
  file_size_mb: Optional[float] = None
25
  output_format: Optional[str] = None
 
35
  media_type: str
36
  filename: str
37
  processing_time: float
38
+ storage_key: Optional[str] = None
39
 
40
  @dataclass
41
  class JobCreationDTO:
42
  """DTO for job creation."""
43
  job_id: str
 
44
  status: str
45
  message: str
46
  check_url: str
47
+ external_job_id: Optional[str] = None
48
  file_size_mb: Optional[float] = None
interfaces/api/dependencies.py CHANGED
@@ -71,6 +71,11 @@ async def validate_bearer_token(
71
  Raises:
72
  HTTPException: 401 if token is missing or invalid
73
  """
 
 
 
 
 
74
  if not authorization:
75
  raise HTTPException(
76
  status_code=401,
 
71
  Raises:
72
  HTTPException: 401 if token is missing or invalid
73
  """
74
+ from infrastructure.config.settings import settings
75
+
76
+ if not settings.enforce_authentication:
77
+ return "authentication-disabled"
78
+
79
  if not authorization:
80
  raise HTTPException(
81
  status_code=401,
interfaces/api/routes/extraction_routes.py CHANGED
@@ -1,6 +1,7 @@
1
  """Audio extraction API routes."""
2
- from fastapi import APIRouter, BackgroundTasks, UploadFile, Form, HTTPException
3
  from fastapi.responses import JSONResponse
 
4
  from dataclasses import asdict
5
  from typing import Optional
6
 
@@ -16,15 +17,21 @@ from domain.exceptions.domain_exceptions import (
16
 
17
  router = APIRouter()
18
 
 
 
 
19
  @router.post("/extract",
20
  response_model=JobCreatedResponse,
21
  summary="Extract Audio from Video",
22
  description="""
23
  Extract audio from uploaded video file.
24
 
 
 
25
  All files are processed asynchronously and return a job ID for tracking progress.
26
  Use the job status endpoint to check processing status and download the result when complete.
27
  """,
 
28
  responses={
29
  202: {
30
  "description": "Job created for async processing",
 
1
  """Audio extraction API routes."""
2
+ from fastapi import APIRouter, BackgroundTasks, UploadFile, Form, HTTPException, Security
3
  from fastapi.responses import JSONResponse
4
+ from fastapi.security import HTTPBearer
5
  from dataclasses import asdict
6
  from typing import Optional
7
 
 
17
 
18
  router = APIRouter()
19
 
20
+ # Security scheme for OpenAPI documentation
21
+ security = HTTPBearer()
22
+
23
  @router.post("/extract",
24
  response_model=JobCreatedResponse,
25
  summary="Extract Audio from Video",
26
  description="""
27
  Extract audio from uploaded video file.
28
 
29
+ **Authentication Required**: This endpoint requires a valid JWT Bearer token.
30
+
31
  All files are processed asynchronously and return a job ID for tracking progress.
32
  Use the job status endpoint to check processing status and download the result when complete.
33
  """,
34
+ dependencies=[Security(security)],
35
  responses={
36
  202: {
37
  "description": "Job created for async processing",
interfaces/api/routes/job_routes.py CHANGED
@@ -1,6 +1,7 @@
1
  """Job management API routes."""
2
- from fastapi import APIRouter, HTTPException, Path, Query, BackgroundTasks
3
  from fastapi.responses import FileResponse
 
4
  from typing import Any, Optional
5
  import logging
6
 
@@ -16,10 +17,14 @@ from domain.exceptions.domain_exceptions import (
16
  router = APIRouter()
17
  logger = logging.getLogger(__name__)
18
 
 
 
 
19
  @router.get("/jobs/{job_id}",
20
  response_model=JobStatusResponse,
21
  summary="Get Job Status",
22
- description="Check the status of an audio extraction job",
 
23
  responses={
24
  200: {"description": "Job status retrieved successfully"},
25
  401: {"description": "Authentication required", "content": {"application/json": {"example": {"error": "Authentication required", "code": "AUTHENTICATION_ERROR"}}}},
@@ -78,6 +83,8 @@ async def get_job_status(
78
  description="""
79
  Download the audio file from a completed extraction job.
80
 
 
 
81
  Optionally specify start and end times to download only a portion of the audio:
82
  - start: Start time in HH:MM:SS format (e.g., 00:01:30 for 1 minute 30 seconds)
83
  - end: End time in HH:MM:SS format (e.g., 00:03:45 for 3 minutes 45 seconds)
@@ -86,6 +93,7 @@ async def get_job_status(
86
  If only start is provided, audio from start time to the end is returned.
87
  If only end is provided, audio from beginning to end time is returned.
88
  """,
 
89
  responses={
90
  200: {
91
  "description": "Audio file",
 
1
  """Job management API routes."""
2
+ from fastapi import APIRouter, HTTPException, Path, Query, BackgroundTasks, Security
3
  from fastapi.responses import FileResponse
4
+ from fastapi.security import HTTPBearer
5
  from typing import Any, Optional
6
  import logging
7
 
 
17
  router = APIRouter()
18
  logger = logging.getLogger(__name__)
19
 
20
+ # Security scheme for OpenAPI documentation
21
+ security = HTTPBearer()
22
+
23
  @router.get("/jobs/{job_id}",
24
  response_model=JobStatusResponse,
25
  summary="Get Job Status",
26
+ description="Check the status of an audio extraction job. **Authentication Required**: This endpoint requires a valid JWT Bearer token.",
27
+ dependencies=[Security(security)],
28
  responses={
29
  200: {"description": "Job status retrieved successfully"},
30
  401: {"description": "Authentication required", "content": {"application/json": {"example": {"error": "Authentication required", "code": "AUTHENTICATION_ERROR"}}}},
 
83
  description="""
84
  Download the audio file from a completed extraction job.
85
 
86
+ **Authentication Required**: This endpoint requires a valid JWT Bearer token.
87
+
88
  Optionally specify start and end times to download only a portion of the audio:
89
  - start: Start time in HH:MM:SS format (e.g., 00:01:30 for 1 minute 30 seconds)
90
  - end: End time in HH:MM:SS format (e.g., 00:03:45 for 3 minutes 45 seconds)
 
93
  If only start is provided, audio from start time to the end is returned.
94
  If only end is provided, audio from beginning to end time is returned.
95
  """,
96
+ dependencies=[Security(security)],
97
  responses={
98
  200: {
99
  "description": "Audio file",