File size: 2,993 Bytes
af3df29
 
 
 
fddc155
 
af3df29
 
 
 
 
 
 
 
 
fddc155
af3df29
 
 
 
 
 
 
 
 
 
 
 
fddc155
af3df29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fddc155
af3df29
 
 
 
 
fddc155
af3df29
 
 
 
 
 
 
 
 
 
fddc155
af3df29
 
 
 
 
 
 
fddc155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
af3df29
 
 
 
 
 
fddc155
af3df29
 
 
 
 
 
 
fddc155
af3df29
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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()