Re-upload: CI infrastructure issue resolved, all tests verified passing

This commit is contained in:
Developer
2026-03-22 16:48:09 +00:00
parent 71bae33ea9
commit 24b94c12bc
165 changed files with 23945 additions and 436 deletions

View File

@@ -0,0 +1,196 @@
"""Traffic analyzer for filtering HTTP entries."""
import re
from collections.abc import Callable
from http_log_explorer.models import FilterCriteria, HTTPEntry
class TrafficAnalyzer:
"""Analyzer for filtering and searching HTTP entries."""
def __init__(self, entries: list[HTTPEntry]) -> None:
"""Initialize with HTTP entries.
Args:
entries: List of HTTPEntry objects to analyze
"""
self.entries = entries
def filter(self, criteria: FilterCriteria) -> list[HTTPEntry]:
"""Filter entries based on criteria.
Args:
criteria: FilterCriteria object with filtering rules
Returns:
Filtered list of HTTPEntry objects
"""
predicates: list[Callable[[HTTPEntry], bool]] = []
if criteria.methods:
predicates.append(lambda e: e.request.method in criteria.methods)
if criteria.status_codes:
predicates.append(lambda e: e.response.status in criteria.status_codes)
if criteria.url_pattern:
pattern = re.compile(criteria.url_pattern)
predicates.append(lambda e: bool(pattern.search(e.request.url)))
if criteria.content_types:
predicates.append(lambda e: bool(e.content_type and any(ct in e.content_type for ct in criteria.content_types)))
if criteria.start_time:
predicates.append(lambda e: bool(e.timestamp and e.timestamp >= criteria.start_time))
if criteria.end_time:
predicates.append(lambda e: bool(e.timestamp and e.timestamp <= criteria.end_time))
if criteria.min_response_time_ms is not None:
predicates.append(lambda e: bool(e.duration_ms and e.duration_ms >= criteria.min_response_time_ms))
if criteria.max_response_time_ms is not None:
predicates.append(lambda e: bool(e.duration_ms and e.duration_ms <= criteria.max_response_time_ms))
if criteria.request_body_contains:
predicates.append(
lambda e: bool(e.request.body and criteria.request_body_contains in e.request.body)
)
if criteria.response_body_contains:
predicates.append(
lambda e: bool(e.response.body and criteria.response_body_contains in e.response.body)
)
if not predicates:
return list(self.entries)
return [entry for entry in self.entries if all(pred(entry) for pred in predicates)]
def by_method(self, methods: list[str]) -> list[HTTPEntry]:
"""Filter by HTTP methods.
Args:
methods: List of methods (GET, POST, PUT, DELETE, etc.)
Returns:
Filtered entries
"""
criteria = FilterCriteria(methods=methods)
return self.filter(criteria)
def by_status(self, status_codes: list[int]) -> list[HTTPEntry]:
"""Filter by status codes.
Args:
status_codes: List of status codes to include
Returns:
Filtered entries
"""
criteria = FilterCriteria(status_codes=status_codes)
return self.filter(criteria)
def by_url(self, url_pattern: str) -> list[HTTPEntry]:
"""Filter by URL pattern.
Args:
url_pattern: Regular expression pattern to match URLs
Returns:
Filtered entries
"""
criteria = FilterCriteria(url_pattern=url_pattern)
return self.filter(criteria)
def by_content_type(self, content_types: list[str]) -> list[HTTPEntry]:
"""Filter by content types.
Args:
content_types: List of content type substrings to match
Returns:
Filtered entries
"""
criteria = FilterCriteria(content_types=content_types)
return self.filter(criteria)
def by_status_range(self, min_status: int, max_status: int) -> list[HTTPEntry]:
"""Filter by status code range.
Args:
min_status: Minimum status code (inclusive)
max_status: Maximum status code (inclusive)
Returns:
Filtered entries
"""
all_in_range = list(range(min_status, max_status + 1))
return self.by_status(all_in_range)
def successful_requests(self) -> list[HTTPEntry]:
"""Get all 2xx responses.
Returns:
Entries with 2xx status codes
"""
return self.by_status_range(200, 299)
def client_errors(self) -> list[HTTPEntry]:
"""Get all 4xx responses.
Returns:
Entries with 4xx status codes
"""
return self.by_status_range(400, 499)
def server_errors(self) -> list[HTTPEntry]:
"""Get all 5xx responses.
Returns:
Entries with 5xx status codes
"""
return self.by_status_range(500, 599)
def search(self, query: str, case_sensitive: bool = False) -> list[HTTPEntry]:
"""Search across URL, request body, and response body.
Args:
query: Search string
case_sensitive: Whether search should be case sensitive
Returns:
Entries matching the query
"""
search_query = query if case_sensitive else query.lower()
def matches(entry: HTTPEntry) -> bool:
url = entry.request.url if case_sensitive else entry.request.url.lower()
if search_query in url:
return True
if entry.request.body:
body = entry.request.body if case_sensitive else entry.request.body.lower()
if search_query in body:
return True
if entry.response.body:
body = entry.response.body if case_sensitive else entry.response.body.lower()
if search_query in body:
return True
return False
return [e for e in self.entries if matches(e)]
def get_entry_by_id(self, entry_id: str) -> HTTPEntry | None:
"""Get a specific entry by its ID.
Args:
entry_id: The entry ID to find
Returns:
The HTTPEntry or None if not found
"""
for entry in self.entries:
if entry.id == entry_id:
return entry
return None