Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
| import uuid | |
| import hashlib | |
| import hmac | |
| import secrets | |
| import base64 | |
| import subprocess | |
| from typing import * | |
| import os | |
| import sys | |
| import re | |
| import json | |
| import time | |
| import urllib3 | |
| import requests | |
| import socket | |
| import logging | |
| import threading | |
| import concurrent.futures | |
| import ipaddress | |
| import ssl | |
| from urllib.parse import urlparse, urljoin, urlencode, quote | |
| from collections import defaultdict | |
| from bs4 import BeautifulSoup | |
| from datetime import datetime, timezone | |
| import statistics | |
| import math | |
| class MultiFeatureAnomaly: | |
| def __init__(self): | |
| self._baselines: dict[str, list[float]] = {} | |
| self._feature_names: list[str] = [] | |
| def record_baseline(self, feature: str, value: float): | |
| self._baselines.setdefault(feature, []).append(value) | |
| if feature not in self._feature_names: | |
| self._feature_names.append(feature) | |
| def ready(self) -> bool: | |
| return all(len(v) >= 5 for v in self._baselines.values()) | |
| def mean(self, feature: str) -> float: | |
| vals = self._baselines.get(feature, []) | |
| return statistics.mean(vals) if vals else 0.0 | |
| def stdev(self, feature: str) -> float: | |
| vals = self._baselines.get(feature, []) | |
| return statistics.stdev(vals) if len(vals) >= 2 else 0.0 | |
| def z_score(self, feature: str, value: float) -> float: | |
| sd = self.stdev(feature) | |
| return (value - self.mean(feature)) / sd if sd else 0.0 | |
| def _is_outlier(self, values: list[float]) -> list[bool]: | |
| q1 = statistics.median(sorted(values)[:len(values)//2]) | |
| q3 = statistics.median(sorted(values)[len(values)//2:]) | |
| iqr = q3 - q1 | |
| lower, upper = q1 - 1.5 * iqr, q3 + 1.5 * iqr | |
| return [v < lower or v > upper for v in values] | |
| def cluster_outliers(self, values: list[float]) -> list[int]: | |
| outliers = self._is_outlier(values) | |
| return [i for i, o in enumerate(outliers) if o] | |
| def score(self, timing: float, size: int, status: int, word_count: int, line_count: int) -> float: | |
| raw = 0.0 | |
| if abs(self.z_score("timing", timing)) > 2: | |
| raw += abs(self.z_score("timing", timing)) * 0.3 | |
| if abs(self.z_score("size", float(size))) > 2: | |
| raw += abs(self.z_score("size", float(size))) * 0.25 | |
| if abs(self.z_score("words", float(word_count))) > 2: | |
| raw += abs(self.z_score("words", float(word_count))) * 0.2 | |
| if abs(self.z_score("lines", float(line_count))) > 2: | |
| raw += abs(self.z_score("lines", float(line_count))) * 0.15 | |
| if status in (403, 500, 503, 429): | |
| raw += 2.0 | |
| return round(min(raw, 10.0), 2) | |
| class ResponseCluster: | |
| def __init__(self, n_init: int = 3): | |
| self._clusters: dict[int, list[tuple[float, int, int, int]]] = {} | |
| self._n_init = n_init | |
| def _distance(self, a: tuple[float, int, int, int], b: tuple[float, int, int, int]) -> float: | |
| return math.sqrt( | |
| (a[0] - b[0])**2 * 0.4 + | |
| (a[1] - b[1])**2 * 0.3 + | |
| (a[2] - b[2])**2 * 0.2 + | |
| (a[3] - b[3])**2 * 0.1 | |
| ) | |
| def fit(self, points: list[tuple[float, int, int, int]]): | |
| if len(points) < self._n_init: | |
| return | |
| self._clusters = {} | |
| centroids = points[:self._n_init] | |
| for _ in range(10): | |
| self._clusters = {i: [] for i in range(self._n_init)} | |
| for p in points: | |
| dists = [self._distance(p, c) for c in centroids] | |
| self._clusters[dists.index(min(dists))].append(p) | |
| for i in range(self._n_init): | |
| if self._clusters[i]: | |
| avg_t = statistics.mean(p[0] for p in self._clusters[i]) | |
| avg_s = int(statistics.mean(p[1] for p in self._clusters[i])) | |
| avg_w = int(statistics.mean(p[2] for p in self._clusters[i])) | |
| avg_l = int(statistics.mean(p[3] for p in self._clusters[i])) | |
| centroids[i] = (avg_t, avg_s, avg_w, avg_l) | |
| def predict(self, point: tuple[float, int, int, int]) -> tuple[int, int]: | |
| if not self._clusters: | |
| return -1, 0 | |
| centroid_indices = list(self._clusters.keys()) | |
| dists = [self._distance(point, self._cluster_center(i)) for i in centroid_indices] | |
| closest = centroid_indices[dists.index(min(dists))] | |
| if self._clusters[closest]: | |
| center = self._cluster_center(closest) | |
| d = self._distance(point, center) | |
| max_d = max(self._distance(p, center) for p in self._clusters[closest]) if self._clusters[closest] else 1 | |
| return (closest, int(min(d / max_d * 10, 10))) if max_d > 0 else (closest, 0) | |
| return closest, 0 | |
| def _cluster_center(self, idx: int) -> tuple[float, int, int, int]: | |
| pts = self._clusters.get(idx, []) | |
| if not pts: | |
| return (0.0, 0, 0, 0) | |
| return ( | |
| statistics.mean(p[0] for p in pts), | |
| int(statistics.mean(p[1] for p in pts)), | |
| int(statistics.mean(p[2] for p in pts)), | |
| int(statistics.mean(p[3] for p in pts)), | |
| ) | |
| def outlier_score(self, point: tuple[float, int, int, int]) -> float: | |
| cluster_id, distance = self.predict(point) | |
| if cluster_id < 0: | |
| return 0.0 | |
| return distance / 10.0 | |