Backend API (Python Serverless Function)
Relevant source files
The following files were used as context for generating this wiki page:The backend for youtube_notes is a lightweight Python serverless function built with the FastAPI framework. Its primary responsibility is to act as a secure and rate-limited proxy to the youtube-transcript-api library, fetching video transcripts for the frontend application. It is designed for deployment on Vercel and includes specific configurations for security, CORS, and optional proxy usage.
The API exposes a single main endpoint, /api/transcript, which takes a YouTube video ID and returns the raw transcript data. It also includes a health check endpoint. The system is designed to handle various errors from the YouTube API gracefully, returning appropriate HTTP status codes to the client.
Sources: api/index.py, vercel.json, README.md
Architecture and Deployment
The backend is a single-file FastAPI application defined in api/index.py. It is intended to be deployed as a Python serverless function on Vercel.
Sources: api/index.py, vercel.json
Dependencies
The core functionality relies on a small set of Python packages.
| Package | Purpose |
|---|---|
youtube-transcript-api | The library used to fetch transcripts from YouTube. |
fastapi | The web framework used to build the API. |
uvicorn | ASGI server for local development, as seen in package.json. |
pytest | The framework used for testing the API endpoints. |
httpx | A dependency for testing asynchronous API endpoints. |
Sources: requirements.txt, package.json:7
Vercel Configuration
The vercel.json file configures the build and routing on the Vercel platform.
- Builds: It defines two build steps: one for the Python backend using
@vercel/pythonand another for the static frontend. - Routes: It configures routing rules to direct any requests to
/api/*to the Python serverless function (api/index.py). All other requests are served from the static build output.
{
"builds": [
{
"src": "api/index.py",
"use": "@vercel/python"
},
{
"src": "package.json",
"use": "@vercel/static-build",
"config": { "distDir": "dist" }
}
],
"routes": [
{
"src": "/api/(.*)",
"dest": "/api/index.py"
},
{
"src": "/(.*)",
"dest": "/$1"
}
]
}
Sources: vercel.json:1-21
API Endpoints
The API provides two endpoints.
| Method | Path | Description |
|---|---|---|
GET | /api/health | A health check endpoint that returns the service status and proxy configuration. |
GET | /api/transcript | Fetches the transcript for a given YouTube video ID. |
Sources: api/index.py:72-75, api/index.py:77-99
GET /api/transcript
This is the main endpoint for fetching video transcripts. The frontend client calls this endpoint to retrieve data for a specific video.
Sources: api/index.py:77-99, tests/youtubeService.test.ts:27
Request Parameters
| Parameter | Type | Location | Constraints | Description |
|---|---|---|---|---|
videoId | string | Query | min_length=11, max_length=11 | The 11-character YouTube Video ID. |
Sources: api/index.py:77, tests/api_test.py:30-39
Responses
- 200 OK: Returns a JSON array of transcript segments.
- 404 Not Found: Returned if transcripts are disabled, not found, or the video is unavailable.
- 403 Forbidden: Returned if the service is temporarily blocked by YouTube (e.g., due to too many requests).
- 422 Unprocessable Entity: Returned if the
videoIdparameter is not 11 characters long. - 429 Too Many Requests: Returned if the client exceeds the rate limit.
- 500 Internal Server Error: Returned for any other unexpected server-side errors.
Sources: api/index.py:84-99, tests/api_test.py:41-78
Middleware and Security
The application uses a chain of FastAPI middleware to handle security, rate limiting, and CORS before the request reaches the endpoint logic.
The diagram below illustrates the order in which middleware processes an incoming request.
Sources: api/index.py:25-47, api/index.py:50-56
CORS (Cross-Origin Resource Sharing)
A strict CORS policy is implemented to control which origins can access the API. The allowed origins are configurable via the ALLOWED_ORIGINS environment variable.
- Allowed Methods:
GET,OPTIONS - Allowed Credentials:
True
Sources: api/index.py:18, api/index.py:50-56
Rate Limiting
A simple in-memory rate limiter is implemented as middleware to prevent abuse. It tracks the number of requests from each client IP address within a configured time window.
- Default Limit: 15 requests per 60 seconds.
- Configuration:
RATE_LIMIT_REQUESTSandRATE_LIMIT_WINDOWenvironment variables. - Behavior: If a client exceeds the limit, the API returns a
429 Too Many Requestsstatus code.
Sources: api/index.py:12-14, api/index.py:33-45
Security Headers
A middleware function adds several security-related HTTP headers to every response to mitigate common web vulnerabilities.
| Header | Value | Purpose |
|---|---|---|
X-Content-Type-Options | nosniff | Prevents MIME-type sniffing. |
X-Frame-Options | DENY | Prevents clickjacking. |
Strict-Transport-Security | max-age=31536000; includeSubDomains | Enforces HTTPS. |
Sources: api/index.py:25-30
Core Logic and Error Handling
The core logic resides in the get_transcript function, which uses the youtube-transcript-api library to fetch data.
Transcript Fetching Flow
The following sequence diagram shows the process of a successful transcript request.
Proxy Configuration
The API can be configured to use Webshare proxies to avoid IP-based blocking from YouTube. The get_youtube_api function checks for WEBSHARE_USER and WEBSHARE_PASS environment variables. If they are present, it initializes the YouTubeTranscriptApi with the proxy configuration. Otherwise, it falls back to a direct connection.
Sources: api/index.py:58-70
Error Handling
The get_transcript endpoint has a robust try...except block to handle specific errors from the youtube-transcript-api library and other potential issues.
This flowchart shows the error handling logic within the /api/transcript endpoint.
Sources: api/index.py:83-99, tests/api_test.py:41-78
Configuration
The API's behavior can be modified using environment variables.
| Environment Variable | Default Value | Description |
|---|---|---|
ALLOWED_ORIGINS | http://localhost:3000,http://localhost:5173 | Comma-separated list of allowed origins for CORS. |
RATE_LIMIT_REQUESTS | 15 | The number of requests allowed within the rate limit window. |
RATE_LIMIT_WINDOW | 60 | The time window in seconds for rate limiting. |
WEBSHARE_USER | None | The username for the Webshare proxy. If set, proxy will be used. |
WEBSHARE_PASS | None | The password for the Webshare proxy. |
Sources: api/index.py:12-14, api/index.py:18, api/index.py:59-60
Testing
The API is tested using pytest. The tests in tests/api_test.py cover:
- Successful transcript retrieval.
- Input validation for the
videoIdparameter (too short/long). - Correct handling of specific exceptions from the
youtube-transcript-apilibrary (TranscriptsDisabled,NoTranscriptFound,VideoUnavailable). - Graceful handling of generic, unexpected exceptions.
Sources: tests/api_test.py