import gradio as gr import requests, time, socket, ssl, random from ping3 import ping import dns.resolver from bs4 import BeautifulSoup def dns_lookup(domain): try: start = time.time() dns.resolver.resolve(domain) return round((time.time() - start) * 1000, 2) except: return None def ssl_handshake(domain): try: ctx = ssl.create_default_context() sock = socket.create_connection((domain, 443), timeout=10) start = time.time() ssock = ctx.wrap_socket(sock, server_hostname=domain) t = (time.time() - start) * 1000 ssock.close() return round(t, 2) except: return None def test_speed(url): if not url.startswith("http"): url = "http://" + url domain = url.split("//")[1].split("/")[0] result = {} # DNS dns_time = dns_lookup(domain) result["DNS Lookup (ms)"] = dns_time # Ping p = ping(domain, timeout=1) result["Ping (ms)"] = round(p * 1000, 2) if p else None # SSL ssl_time = ssl_handshake(domain) result["SSL Handshake (ms)"] = ssl_time try: session = requests.Session() cache_bypass_url = url + "?" + str(random.randint(100000, 999999)) start_ttfb = time.time() r = session.get(cache_bypass_url, stream=True, timeout=20) ttfb = (time.time() - start_ttfb) * 1000 result["HTTP Status"] = r.status_code result["TTFB (ms)"] = round(ttfb, 2) result["Final URL"] = r.url result["Redirect Chain"] = [resp.url for resp in r.history] + [r.url] # Download start_dl = time.time() content = r.content download_time = (time.time() - start_dl) * 1000 result["Download Time (ms)"] = round(download_time, 2) result["Page Size (KB)"] = round(len(content) / 1024, 2) # ---- ASSET COUNT ---- soup = BeautifulSoup(content, "html.parser") images = soup.find_all("img") videos = soup.find_all("video") audios = soup.find_all("audio") result["Images Count"] = len(images) result["Videos Count"] = len(videos) result["Audios Count"] = len(audios) result["Total Assets"] = len(images) + len(videos) + len(audios) # Speed index speed_index = sum( x for x in [dns_time, ssl_time, ttfb, download_time * 0.5] if x ) result["Speed Index (ms)"] = round(speed_index, 2) result["Speed Index (s)"] = round(speed_index / 1000, 2) except Exception as e: return {"Error": str(e)} # Rating if ttfb < 200: rating = "Fast" elif ttfb < 600: rating = "Medium" else: rating = "Slow" result["Speed Rating"] = rating return result ui = gr.Interface( fn=test_speed, inputs=gr.Textbox(label="Enter URL"), outputs=gr.JSON(label="Result"), title="Complete Website Speed Tester", ) if __name__ == "__main__": ui.launch()