- Add ProgramSearchResultSerializer with nested channel/stream data - Implement ProgramSearchAPIView with comprehensive filtering: * Text search with AND/OR operators and parenthetical grouping * Regex pattern matching support * Whole word matching to avoid partial matches * Time-based filtering (airing_at, start/end ranges) * Channel/stream/group filtering * Configurable field selection for response customization * Pagination (50 default, 500 max per page) - Add /api/epg/programs/search/ endpoint - Add comprehensive API documentation - Enhanced Swagger/OpenAPI schema with examples Examples: - Complex queries: (Newcastle OR NEW) AND (Villa OR AST) - Whole words: title=NEW&title_whole_words=true - Regex: title=^Premier&title_regex=true - Time filtering: airing_at=2026-02-14T20:00:00Z
11 KiB
EPG Program Search API
Overview
The EPG Program Search API provides powerful filtering and search capabilities for EPG (Electronic Program Guide) program data. It supports complex text queries with AND/OR operators, parenthetical grouping, regex patterns, time-based filtering, and channel/stream matching.
Endpoint: GET /api/epg/programs/search/
Authentication: Required (JWT Bearer token)
Query Parameters
Text Search Parameters
title (string, optional)
Search program titles with support for:
- Simple terms:
title=football - AND operator:
title=premier AND league - OR operator:
title=Newcastle OR Villa - Nested groups with parentheses:
title=(Newcastle OR NEW) AND (Villa OR AST) - Default behavior: Space-separated terms use AND
Examples:
title=sports
title=premier AND league
title=Newcastle OR Villa
title=(Newcastle OR NEW) AND (Villa OR AST)
title_regex (boolean, optional)
When true, interprets the title parameter as a case-insensitive regex pattern.
Examples:
title=^The&title_regex=true # Programs starting with "The"
title=\d{4}&title_regex=true # Programs with 4-digit years
title=\b(United|City)\b&title_regex=true # Match "United" or "City" as whole words
title_whole_words (boolean, optional)
When true, matches only whole words. Prevents "NEW" from matching "News" or "Newcastle".
Examples:
title=NEW&title_whole_words=true # Matches "NEW" but not "News" or "Newsletter"
description (string, optional)
Search program descriptions. Supports the same features as title:
- AND/OR operators
- Parenthetical grouping
- Works with
description_regexanddescription_whole_words
description_regex (boolean, optional)
When true, interprets description as a case-insensitive regex pattern.
description_whole_words (boolean, optional)
When true, matches only whole words in descriptions.
Time Filtering Parameters
airing_at (ISO 8601 datetime, optional)
Find programs airing at a specific moment in time. Matches programs where:
start_time <= airing_at < end_time
Example:
airing_at=2026-02-14T20:00:00Z
start_after (ISO 8601 datetime, optional)
Programs starting at or after this time.
Example:
start_after=2026-02-14T18:00:00Z
start_before (ISO 8601 datetime, optional)
Programs starting at or before this time.
end_after (ISO 8601 datetime, optional)
Programs ending at or after this time.
end_before (ISO 8601 datetime, optional)
Programs ending at or before this time.
Combined time range example:
start_after=2026-02-14T19:00:00Z&start_before=2026-02-14T22:00:00Z
Channel & Stream Filtering
channel (string, optional)
Filter by channel name (case-insensitive substring match).
Example:
channel=BBC One
channel_id (integer, optional)
Filter by exact channel ID.
Example:
channel_id=123
stream (string, optional)
Filter by stream name (case-insensitive substring match).
Example:
stream=Sky Sports
group (string, optional)
Filter by channel group name OR stream group name (case-insensitive substring match).
Example:
group=Sports
epg_source (integer, optional)
Filter by EPG source ID.
Example:
epg_source=5
Response Customization
fields (string, optional)
Comma-separated list of fields to include in response. Reduces payload size for specific use cases.
Available fields:
id,title,sub_title,descriptionstart_time,end_time,tvg_id,custom_propertiesepg_source,epg_name,epg_icon_urlchannels,streams
Example:
fields=title,start_time,end_time,channels
Pagination Parameters
page (integer, optional, default: 1)
Page number for paginated results.
page_size (integer, optional, default: 50, max: 500)
Number of results per page.
Example:
page=2&page_size=100
Response Format
Standard Response (with pagination)
{
"count": 345,
"next": "http://example.com/api/epg/programs/search/?page=2&...",
"previous": null,
"results": [
{
"id": 21382804,
"title": "Premier League: Newcastle vs Aston Villa",
"sub_title": "Match Week 25",
"description": "LIVE coverage from St James' Park",
"start_time": "2026-02-14T20:00:00Z",
"end_time": "2026-02-14T22:00:00Z",
"tvg_id": "skysportspremierleague.uk",
"custom_properties": {"category": "Sports"},
"epg_source": "Sky EPG UK",
"epg_name": "Sky Sports Premier League",
"epg_icon_url": "https://example.com/icon.png",
"channels": [
{
"id": 14419,
"name": "Sky Sports Premier League",
"channel_number": 401.0,
"channel_group": "UK | Sky Sports",
"tvg_id": "skysportspremierleague.uk"
}
],
"streams": [
{
"id": 300,
"name": "Sky Sports PL HD",
"channel_group": "UK | Sports",
"tvg_id": "SkySportsPL.uk",
"m3u_account": "my_provider"
}
]
}
]
}
With Field Selection
Request: ?fields=title,start_time,end_time
{
"count": 345,
"next": "...",
"previous": null,
"results": [
{
"title": "Premier League: Newcastle vs Aston Villa",
"start_time": "2026-02-14T20:00:00Z",
"end_time": "2026-02-14T22:00:00Z"
}
]
}
Usage Examples
Example 1: Find football matches airing now
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:9191/api/epg/programs/search/?title=football&airing_at=2026-02-14T20:00:00Z"
Example 2: Complex team search with abbreviations
Find programs mentioning either full names or abbreviations:
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:9191/api/epg/programs/search/?title=(Newcastle%20OR%20NEW)%20AND%20(Villa%20OR%20AST)&airing_at=2026-02-14T20:00:00Z"
Example 3: Whole word matching to avoid false positives
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:9191/api/epg/programs/search/?title=NEW&title_whole_words=true&airing_at=2026-02-14T20:00:00Z"
This matches "NEW" but not "News", "Newcastle", or "Newsletter".
Example 4: Regex pattern for advanced matching
Find programs starting with "Premier" or "Champions":
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:9191/api/epg/programs/search/?title=^(Premier%7CChampions)&title_regex=true"
Example 5: Time window search on specific channel
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:9191/api/epg/programs/search/?channel=BBC%20One&start_after=2026-02-14T18:00:00Z&start_before=2026-02-14T23:00:00Z"
Example 6: Minimal response with field selection
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:9191/api/epg/programs/search/?title=sports&fields=title,start_time,end_time&page_size=10"
Example 7: Find programs by stream group
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:9191/api/epg/programs/search/?group=Sports&airing_at=2026-02-14T20:00:00Z"
Example 8: Find all news programs in next 2 hours
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:9191/api/epg/programs/search/?title=news&start_after=2026-02-14T20:00:00Z&start_before=2026-02-14T22:00:00Z"
Text Query Syntax
Operators
-
AND: Both terms must be present
- Example:
premier AND league
- Example:
-
OR: Either term must be present
- Example:
Newcastle OR Villa
- Example:
-
Parentheses: Group operations for complex logic
- Example:
(A OR B) AND (C OR D)
- Example:
Operator Precedence
Left-to-right evaluation with parentheses for grouping:
A AND B OR C → Evaluated as: (A AND B) OR C
(A OR B) AND C → A or B must match, AND C must match
A AND (B OR C) → A must match, AND either B or C must match
Default Behavior
Space-separated terms without explicit operators default to AND:
football premier league → football AND premier AND league
Performance Considerations
-
Text searches use database
LIKEqueries (or regex). For large datasets, consider:- Using more specific search terms
- Combining with time filters to reduce result set
- Using field selection to reduce response size
-
Pagination: Default page size is 50, max is 500. For large result sets, use pagination rather than increasing page_size to max.
-
Regex searches are more expensive than standard text searches. Use only when necessary.
-
Prefetching: The endpoint automatically prefetches related channels, streams, and groups to avoid N+1 queries.
-
Indexes: The following fields are indexed for fast queries:
ProgramData.start_time,end_timeEPGData.tvg_idChannel.channel_number
Error Handling
Authentication Required
{
"detail": "Authentication credentials were not provided."
}
Status: 401 Unauthorized
Invalid datetime format
Invalid ISO 8601 datetime values are silently ignored (filter not applied).
Invalid regex pattern
If title_regex=true and pattern is invalid, the query may fail at the database level. Ensure regex patterns are valid.
Integration Notes
Frontend Integration
// Example using fetch API
async function searchPrograms(query) {
const token = localStorage.getItem('accessToken');
const params = new URLSearchParams(query);
const response = await fetch(
`/api/epg/programs/search/?${params}`,
{
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json'
}
}
);
return await response.json();
}
// Usage
const results = await searchPrograms({
title: '(Newcastle OR NEW) AND (Villa OR AST)',
airing_at: new Date().toISOString(),
page_size: 20
});
Automation & Scripts
import requests
from datetime import datetime
# Get token
response = requests.post('http://localhost:9191/api/accounts/token/',
json={'username': 'user', 'password': 'pass'})
token = response.json()['access']
# Search programs
headers = {'Authorization': f'Bearer {token}'}
params = {
'title': 'football',
'airing_at': datetime.utcnow().isoformat() + 'Z',
'page_size': 50
}
response = requests.get(
'http://localhost:9191/api/epg/programs/search/',
headers=headers,
params=params
)
programs = response.json()
print(f"Found {programs['count']} matching programs")
API Versioning
This endpoint was introduced in version 1.0 and follows semantic versioning. Breaking changes will be announced with major version increments.
Related Endpoints
GET /api/epg/grid/- Get EPG grid view (24-hour window)POST /api/epg/current-programs/- Get currently airing programs for specific channelsGET /api/epg/programs/- List all programs (CRUD endpoint)GET /api/epg/sources/- Manage EPG sources
Support & Feedback
For issues, feature requests, or questions about this API, please file an issue on the GitHub repository or consult the project documentation.