Spaces:
Runtime error
Runtime error
improve_ui
#12
by
RodDoSanz
- opened
- app.py +72 -5
- pyproject.toml +1 -0
- requirements-dev.txt +2 -0
- requirements.txt +2 -0
- tdagent/tools/get_domain_information.py +13 -8
- tdagent/tools/get_url_content.py +6 -3
- tdagent/tools/query_abuse_ip_db.py +4 -2
- tdagent/tools/rdap.py +3 -2
- tdagent/tools/retrieve_from_mitre_attack.py +9 -2
- tdagent/tools/virus_total.py +4 -2
- uv.lock +20 -0
app.py
CHANGED
@@ -1,6 +1,9 @@
|
|
|
|
1 |
from typing import NamedTuple
|
2 |
|
3 |
import gradio as gr
|
|
|
|
|
4 |
|
5 |
from tdagent.tools.get_domain_information import (
|
6 |
dns_enumeration_tool,
|
@@ -26,6 +29,21 @@ from tdagent.tools.virus_total import gr_virus_total_url_info
|
|
26 |
## Tools to load into the application interface ##
|
27 |
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
class ToolInfo(NamedTuple):
|
30 |
"""Gradio MCP tool info."""
|
31 |
|
@@ -55,11 +73,60 @@ TOOLS = (
|
|
55 |
)
|
56 |
|
57 |
## Application Interface ##
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
if __name__ == "__main__":
|
65 |
gr_app.launch(mcp_server=True)
|
|
|
1 |
+
from pathlib import Path
|
2 |
from typing import NamedTuple
|
3 |
|
4 |
import gradio as gr
|
5 |
+
import gradio.themes as gr_themes
|
6 |
+
import markdown
|
7 |
|
8 |
from tdagent.tools.get_domain_information import (
|
9 |
dns_enumeration_tool,
|
|
|
29 |
## Tools to load into the application interface ##
|
30 |
|
31 |
|
32 |
+
def _read_markdown_body_as_html(path: str = "README.md") -> str:
|
33 |
+
with Path(path).open(encoding="utf-8") as f: # Default mode is "r"
|
34 |
+
lines = f.readlines()
|
35 |
+
|
36 |
+
# Skip YAML front matter if present
|
37 |
+
if lines and lines[0].strip() == "---":
|
38 |
+
for i in range(1, len(lines)):
|
39 |
+
if lines[i].strip() == "---":
|
40 |
+
lines = lines[i + 1 :] # skip metadata block
|
41 |
+
break
|
42 |
+
|
43 |
+
markdown_body = "".join(lines).strip()
|
44 |
+
return markdown.markdown(markdown_body)
|
45 |
+
|
46 |
+
|
47 |
class ToolInfo(NamedTuple):
|
48 |
"""Gradio MCP tool info."""
|
49 |
|
|
|
73 |
)
|
74 |
|
75 |
## Application Interface ##
|
76 |
+
|
77 |
+
custom_css = """
|
78 |
+
.main-header {
|
79 |
+
background: linear-gradient(135deg, #00a388 0%, #ffae00 100%);
|
80 |
+
padding: 30px;
|
81 |
+
border-radius: 5px;
|
82 |
+
margin-bottom: 20px;
|
83 |
+
text-align: center;
|
84 |
+
}
|
85 |
+
"""
|
86 |
+
with (
|
87 |
+
gr.Blocks(
|
88 |
+
theme=gr_themes.Origin(
|
89 |
+
primary_hue="teal",
|
90 |
+
spacing_size="sm",
|
91 |
+
font="sans-serif",
|
92 |
+
),
|
93 |
+
title="TDAgent",
|
94 |
+
fill_height=True,
|
95 |
+
fill_width=True,
|
96 |
+
css=custom_css,
|
97 |
+
) as gr_app,
|
98 |
+
):
|
99 |
+
gr.HTML(
|
100 |
+
"""
|
101 |
+
<div class="main-header">
|
102 |
+
<h1>👩💻 TDAgentTools & TDAgent 👨💻</h1>
|
103 |
+
<p style="font-size: 1.2em; margin: 10px 0 0 0;">
|
104 |
+
Empowering Cybersecurity with Agentic AI
|
105 |
+
</p>
|
106 |
+
</div>
|
107 |
+
""",
|
108 |
+
)
|
109 |
+
with gr.Tabs():
|
110 |
+
with gr.TabItem("About"):
|
111 |
+
html_content = _read_markdown_body_as_html("README.md")
|
112 |
+
gr.Markdown(html_content)
|
113 |
+
with gr.TabItem("TDAgentTools"):
|
114 |
+
gr.TabbedInterface(
|
115 |
+
interface_list=[t_info.interface for t_info in TOOLS],
|
116 |
+
tab_names=[t_info.name for t_info in TOOLS],
|
117 |
+
title="TDAgentTools",
|
118 |
+
)
|
119 |
+
with gr.TabItem("Demo"):
|
120 |
+
gr.Markdown(
|
121 |
+
"""
|
122 |
+
This is a demo of TDAgentTools, a simple MCP server.
|
123 |
+
Be carefull with using well-known urls for malware distribution
|
124 |
+
when using the url content extractor tool.
|
125 |
+
""",
|
126 |
+
)
|
127 |
+
gr.HTML(
|
128 |
+
"""<iframe width="560" height="315" src="https://youtube.com/embed/c7Yg_jOD6J0" frameborder="0" allowfullscreen></iframe>""", # noqa: E501
|
129 |
+
)
|
130 |
|
131 |
if __name__ == "__main__":
|
132 |
gr_app.launch(mcp_server=True)
|
pyproject.toml
CHANGED
@@ -19,6 +19,7 @@ dependencies = [
|
|
19 |
"cachetools>=6.0.0",
|
20 |
"dnspython>=2.7.0",
|
21 |
"gradio[mcp]>=5.32.1",
|
|
|
22 |
"python-whois>=0.9.5",
|
23 |
"requests>=2.32.3",
|
24 |
"vt-py~=0.21.0",
|
|
|
19 |
"cachetools>=6.0.0",
|
20 |
"dnspython>=2.7.0",
|
21 |
"gradio[mcp]>=5.32.1",
|
22 |
+
"markdown>=3.8",
|
23 |
"python-whois>=0.9.5",
|
24 |
"requests>=2.32.3",
|
25 |
"vt-py~=0.21.0",
|
requirements-dev.txt
CHANGED
@@ -129,6 +129,8 @@ jinja2==3.1.6
|
|
129 |
# via gradio
|
130 |
license-expression==30.4.1
|
131 |
# via cyclonedx-python-lib
|
|
|
|
|
132 |
markdown-it-py==3.0.0
|
133 |
# via rich
|
134 |
markupsafe==3.0.2
|
|
|
129 |
# via gradio
|
130 |
license-expression==30.4.1
|
131 |
# via cyclonedx-python-lib
|
132 |
+
markdown==3.8
|
133 |
+
# via tdagent
|
134 |
markdown-it-py==3.0.0
|
135 |
# via rich
|
136 |
markupsafe==3.0.2
|
requirements.txt
CHANGED
@@ -110,6 +110,8 @@ iniconfig==2.1.0
|
|
110 |
# via pytest
|
111 |
jinja2==3.1.6
|
112 |
# via gradio
|
|
|
|
|
113 |
markdown-it-py==3.0.0 ; sys_platform != 'emscripten'
|
114 |
# via rich
|
115 |
markupsafe==3.0.2
|
|
|
110 |
# via pytest
|
111 |
jinja2==3.1.6
|
112 |
# via gradio
|
113 |
+
markdown==3.8
|
114 |
+
# via tdagent
|
115 |
markdown-it-py==3.0.0 ; sys_platform != 'emscripten'
|
116 |
# via rich
|
117 |
markupsafe==3.0.2
|
tdagent/tools/get_domain_information.py
CHANGED
@@ -325,39 +325,44 @@ def retrieve_ioc_from_threatfox(potentially_ioc: str) -> str:
|
|
325 |
|
326 |
geo_location_tool = gr.Interface(
|
327 |
fn=get_geolocation,
|
328 |
-
inputs=
|
329 |
-
outputs="
|
330 |
title="Domain Associated Geolocation Finder",
|
331 |
description="Retrieves the geolocation associated to an input ip address",
|
332 |
theme="default",
|
|
|
333 |
)
|
334 |
|
335 |
dns_enumeration_tool = gr.Interface(
|
336 |
fn=enumerate_dns,
|
337 |
-
inputs=
|
338 |
-
outputs="
|
339 |
title="DNS record enumerator of domains",
|
340 |
description="Retrieves several dns record types for the input domain names",
|
341 |
theme="default",
|
|
|
342 |
)
|
343 |
|
344 |
scrap_subdomains_tool = gr.Interface(
|
345 |
fn=scrap_subdomains_for_domain,
|
346 |
-
inputs=
|
347 |
-
outputs="
|
348 |
title="Subdomains Extractor of domains",
|
349 |
description="Retrieves the subdomains for the input domain if they are common",
|
350 |
theme="default",
|
|
|
351 |
)
|
352 |
|
353 |
extractor_of_ioc_from_threatfox_tool = gr.Interface(
|
354 |
fn=retrieve_ioc_from_threatfox,
|
355 |
-
inputs=
|
356 |
-
outputs="
|
357 |
title="IoC information extractor associated to particular entities",
|
358 |
description=(
|
359 |
"If information as an Indicator of Compromise (IoC) exists "
|
360 |
"for the input url, domain or hash, it retrieves it"
|
361 |
),
|
362 |
theme="default",
|
|
|
|
|
363 |
)
|
|
|
325 |
|
326 |
geo_location_tool = gr.Interface(
|
327 |
fn=get_geolocation,
|
328 |
+
inputs=gr.Textbox(label="ip"),
|
329 |
+
outputs=gr.JSON(label="Geolocation of IP"),
|
330 |
title="Domain Associated Geolocation Finder",
|
331 |
description="Retrieves the geolocation associated to an input ip address",
|
332 |
theme="default",
|
333 |
+
examples=["1.0.3.255", "59.34.7.3"],
|
334 |
)
|
335 |
|
336 |
dns_enumeration_tool = gr.Interface(
|
337 |
fn=enumerate_dns,
|
338 |
+
inputs=gr.Textbox(label="domain"),
|
339 |
+
outputs=gr.JSON(label="DNS records"),
|
340 |
title="DNS record enumerator of domains",
|
341 |
description="Retrieves several dns record types for the input domain names",
|
342 |
theme="default",
|
343 |
+
examples=["owasp.org", "nist.gov"],
|
344 |
)
|
345 |
|
346 |
scrap_subdomains_tool = gr.Interface(
|
347 |
fn=scrap_subdomains_for_domain,
|
348 |
+
inputs=gr.Textbox(label="domain"),
|
349 |
+
outputs=gr.JSON(label="Subdomains managed by domain"),
|
350 |
title="Subdomains Extractor of domains",
|
351 |
description="Retrieves the subdomains for the input domain if they are common",
|
352 |
theme="default",
|
353 |
+
examples=["github.com", "netacea.com"],
|
354 |
)
|
355 |
|
356 |
extractor_of_ioc_from_threatfox_tool = gr.Interface(
|
357 |
fn=retrieve_ioc_from_threatfox,
|
358 |
+
inputs=gr.Textbox(label="IoC - url, domains or hash"),
|
359 |
+
outputs=gr.Text(label="Entity information as an IoC"),
|
360 |
title="IoC information extractor associated to particular entities",
|
361 |
description=(
|
362 |
"If information as an Indicator of Compromise (IoC) exists "
|
363 |
"for the input url, domain or hash, it retrieves it"
|
364 |
),
|
365 |
theme="default",
|
366 |
+
examples=["advertipros.com", "dev.couplesparks.com"],
|
367 |
+
example_labels=["👾 IoC 1", "👾 IoC 2"],
|
368 |
)
|
tdagent/tools/get_url_content.py
CHANGED
@@ -51,13 +51,16 @@ def get_url_http_content(
|
|
51 |
|
52 |
gr_get_url_http_content = gr.Interface(
|
53 |
fn=get_url_http_content,
|
54 |
-
inputs=["
|
55 |
-
outputs="
|
56 |
title="Get the content of a URL using an HTTP GET request.",
|
57 |
description=(
|
58 |
"Get the content of a URL in one of the specified content types."
|
59 |
" The server may not honor the content type and if it fails the"
|
60 |
" reason should also be returned with the corresponding HTTP"
|
61 |
-
" error code."
|
62 |
),
|
|
|
|
|
|
|
63 |
)
|
|
|
51 |
|
52 |
gr_get_url_http_content = gr.Interface(
|
53 |
fn=get_url_http_content,
|
54 |
+
inputs=[gr.Textbox(label="url"), gr.Textbox(label="content type")],
|
55 |
+
outputs=gr.Text(label="content"),
|
56 |
title="Get the content of a URL using an HTTP GET request.",
|
57 |
description=(
|
58 |
"Get the content of a URL in one of the specified content types."
|
59 |
" The server may not honor the content type and if it fails the"
|
60 |
" reason should also be returned with the corresponding HTTP"
|
61 |
+
" error code. Be wary of retrieving the content of malicious urls."
|
62 |
),
|
63 |
+
examples=[
|
64 |
+
["https://google.com", "html"],
|
65 |
+
],
|
66 |
)
|
tdagent/tools/query_abuse_ip_db.py
CHANGED
@@ -156,11 +156,13 @@ def query_abuseipdb(ip_address: str, days: int = 30) -> str:
|
|
156 |
|
157 |
gr_query_abuseipdb = gr.Interface(
|
158 |
fn=query_abuseipdb,
|
159 |
-
inputs=
|
160 |
-
outputs="
|
161 |
title="AbuseIPDB IP Checker",
|
162 |
description=(
|
163 |
"Check if an IP address has been reported for abusive behavior"
|
164 |
" using AbuseIP DB API"
|
165 |
),
|
|
|
|
|
166 |
)
|
|
|
156 |
|
157 |
gr_query_abuseipdb = gr.Interface(
|
158 |
fn=query_abuseipdb,
|
159 |
+
inputs=gr.Textbox(label="ip"),
|
160 |
+
outputs=gr.Text(label="Report on abusive behaviour"),
|
161 |
title="AbuseIPDB IP Checker",
|
162 |
description=(
|
163 |
"Check if an IP address has been reported for abusive behavior"
|
164 |
" using AbuseIP DB API"
|
165 |
),
|
166 |
+
examples=["5.252.155.14", "77.239.99.248"],
|
167 |
+
example_labels=["👾 Malicious IP 1", "👾 Malicious IP 2"],
|
168 |
)
|
tdagent/tools/rdap.py
CHANGED
@@ -102,8 +102,9 @@ def query_rdap( # noqa: PLR0911
|
|
102 |
|
103 |
gr_query_rdap = gr.Interface(
|
104 |
fn=query_rdap,
|
105 |
-
inputs=
|
106 |
-
outputs="
|
107 |
title="Get RDAP information for a given URL.",
|
108 |
description="Query a RDAP database to gather information about a url or domain.",
|
|
|
109 |
)
|
|
|
102 |
|
103 |
gr_query_rdap = gr.Interface(
|
104 |
fn=query_rdap,
|
105 |
+
inputs=gr.Textbox(label="url or ip"),
|
106 |
+
outputs=gr.JSON(label="Report from RDAP"),
|
107 |
title="Get RDAP information for a given URL.",
|
108 |
description="Query a RDAP database to gather information about a url or domain.",
|
109 |
+
examples=["8.8.8.8", "pastebin.com"],
|
110 |
)
|
tdagent/tools/retrieve_from_mitre_attack.py
CHANGED
@@ -42,11 +42,18 @@ def get_stix_object_of_attack_id(
|
|
42 |
|
43 |
gr_get_stix_of_attack_id = gr.Interface(
|
44 |
fn=get_stix_object_of_attack_id,
|
45 |
-
inputs=[
|
46 |
-
|
|
|
|
|
|
|
47 |
title="MITRE ATT&CK STIX information",
|
48 |
description=(
|
49 |
"Retrieves a specific STIX object identified by an ATT&CK ID across all ATT&CK"
|
50 |
" matrices"
|
51 |
),
|
|
|
|
|
|
|
|
|
52 |
)
|
|
|
42 |
|
43 |
gr_get_stix_of_attack_id = gr.Interface(
|
44 |
fn=get_stix_object_of_attack_id,
|
45 |
+
inputs=[
|
46 |
+
gr.Textbox(label="Mitre technique ID"),
|
47 |
+
gr.Textbox(label="Mitre object type"),
|
48 |
+
],
|
49 |
+
outputs=gr.JSON(label="Mitre report"),
|
50 |
title="MITRE ATT&CK STIX information",
|
51 |
description=(
|
52 |
"Retrieves a specific STIX object identified by an ATT&CK ID across all ATT&CK"
|
53 |
" matrices"
|
54 |
),
|
55 |
+
examples=[
|
56 |
+
["T1568.002", "attack-pattern"],
|
57 |
+
["M1042", "course-of-action"],
|
58 |
+
],
|
59 |
)
|
tdagent/tools/virus_total.py
CHANGED
@@ -69,8 +69,10 @@ Cache Status: Hit
|
|
69 |
|
70 |
gr_virus_total_url_info = gr.Interface(
|
71 |
fn=get_virus_total_url_info,
|
72 |
-
inputs=
|
73 |
-
outputs="
|
74 |
title="VirusTotal URL Scanner",
|
75 |
description="Get URL Info from VirusTotal URL Scanner. Scan URL is not available",
|
|
|
|
|
76 |
)
|
|
|
69 |
|
70 |
gr_virus_total_url_info = gr.Interface(
|
71 |
fn=get_virus_total_url_info,
|
72 |
+
inputs=gr.Textbox(label="url"),
|
73 |
+
outputs=gr.Text(label="VirusTotal report"),
|
74 |
title="VirusTotal URL Scanner",
|
75 |
description="Get URL Info from VirusTotal URL Scanner. Scan URL is not available",
|
76 |
+
examples=["https://advertipros.com//?u=script", "https://google.com"],
|
77 |
+
example_labels=["👾 Malicious URL", "🧑💻 Benign URL"],
|
78 |
)
|
uv.lock
CHANGED
@@ -857,6 +857,15 @@ wheels = [
|
|
857 |
{ url = "https://files.pythonhosted.org/packages/53/84/8a89614b2e7eeeaf0a68a4046d6cfaea4544c8619ea02595ebeec9b2bae3/license_expression-30.4.1-py3-none-any.whl", hash = "sha256:679646bc3261a17690494a3e1cada446e5ee342dbd87dcfa4a0c24cc5dce13ee", size = 111457, upload-time = "2025-01-14T05:11:38.658Z" },
|
858 |
]
|
859 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
860 |
[[package]]
|
861 |
name = "markdown-it-py"
|
862 |
version = "3.0.0"
|
@@ -1324,26 +1333,35 @@ wheels = [
|
|
1324 |
{ url = "https://files.pythonhosted.org/packages/77/1c/3f8c331d223f86ba1d0ed7d3ed7fcf1501c6f250882489cc820d2567ddbf/pandas-2.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6872d695c896f00df46b71648eea332279ef4077a409e2fe94220208b6bb675", size = 10774764, upload-time = "2025-06-05T03:25:53.228Z" },
|
1325 |
{ url = "https://files.pythonhosted.org/packages/1b/45/d2599400fad7fe06b849bd40b52c65684bc88fbe5f0a474d0513d057a377/pandas-2.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4dd97c19bd06bc557ad787a15b6489d2614ddaab5d104a0310eb314c724b2d2", size = 11711963, upload-time = "2025-06-05T03:25:56.855Z" },
|
1326 |
{ url = "https://files.pythonhosted.org/packages/66/f8/5508bc45e994e698dbc93607ee6b9b6eb67df978dc10ee2b09df80103d9e/pandas-2.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:034abd6f3db8b9880aaee98f4f5d4dbec7c4829938463ec046517220b2f8574e", size = 12349446, upload-time = "2025-06-05T03:26:01.292Z" },
|
|
|
1327 |
{ url = "https://files.pythonhosted.org/packages/a1/9b/8743be105989c81fa33f8e2a4e9822ac0ad4aaf812c00fee6bb09fc814f9/pandas-2.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:39ff73ec07be5e90330cc6ff5705c651ace83374189dcdcb46e6ff54b4a72cd6", size = 13651218, upload-time = "2025-06-05T03:26:09.731Z" },
|
1328 |
{ url = "https://files.pythonhosted.org/packages/26/fa/8eeb2353f6d40974a6a9fd4081ad1700e2386cf4264a8f28542fd10b3e38/pandas-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:40cecc4ea5abd2921682b57532baea5588cc5f80f0231c624056b146887274d2", size = 11082485, upload-time = "2025-06-05T03:26:17.572Z" },
|
1329 |
{ url = "https://files.pythonhosted.org/packages/96/1e/ba313812a699fe37bf62e6194265a4621be11833f5fce46d9eae22acb5d7/pandas-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8adff9f138fc614347ff33812046787f7d43b3cef7c0f0171b3340cae333f6ca", size = 11551836, upload-time = "2025-06-05T03:26:22.784Z" },
|
|
|
1330 |
{ url = "https://files.pythonhosted.org/packages/ee/3e/8c0fb7e2cf4a55198466ced1ca6a9054ae3b7e7630df7757031df10001fd/pandas-2.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa35c266c8cd1a67d75971a1912b185b492d257092bdd2709bbdebe574ed228d", size = 11788230, upload-time = "2025-06-05T03:26:27.417Z" },
|
1331 |
{ url = "https://files.pythonhosted.org/packages/14/22/b493ec614582307faf3f94989be0f7f0a71932ed6f56c9a80c0bb4a3b51e/pandas-2.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a0cc77b0f089d2d2ffe3007db58f170dae9b9f54e569b299db871a3ab5bf46", size = 12370423, upload-time = "2025-06-05T03:26:34.142Z" },
|
|
|
1332 |
{ url = "https://files.pythonhosted.org/packages/95/81/b310e60d033ab64b08e66c635b94076488f0b6ce6a674379dd5b224fc51c/pandas-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ed16339bc354a73e0a609df36d256672c7d296f3f767ac07257801aa064ff73c", size = 13745952, upload-time = "2025-06-05T03:26:39.475Z" },
|
1333 |
{ url = "https://files.pythonhosted.org/packages/25/ac/f6ee5250a8881b55bd3aecde9b8cfddea2f2b43e3588bca68a4e9aaf46c8/pandas-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:fa07e138b3f6c04addfeaf56cc7fdb96c3b68a3fe5e5401251f231fce40a0d7a", size = 11094534, upload-time = "2025-06-05T03:26:43.23Z" },
|
1334 |
{ url = "https://files.pythonhosted.org/packages/94/46/24192607058dd607dbfacdd060a2370f6afb19c2ccb617406469b9aeb8e7/pandas-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2eb4728a18dcd2908c7fccf74a982e241b467d178724545a48d0caf534b38ebf", size = 11573865, upload-time = "2025-06-05T03:26:46.774Z" },
|
|
|
|
|
1335 |
{ url = "https://files.pythonhosted.org/packages/01/a5/931fc3ad333d9d87b10107d948d757d67ebcfc33b1988d5faccc39c6845c/pandas-2.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba24af48643b12ffe49b27065d3babd52702d95ab70f50e1b34f71ca703e2c0d", size = 11991493, upload-time = "2025-06-05T03:26:51.813Z" },
|
|
|
1336 |
{ url = "https://files.pythonhosted.org/packages/a4/0e/21eb48a3a34a7d4bac982afc2c4eb5ab09f2d988bdf29d92ba9ae8e90a79/pandas-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6021910b086b3ca756755e86ddc64e0ddafd5e58e076c72cb1585162e5ad259b", size = 13212406, upload-time = "2025-06-05T03:26:55.992Z" },
|
1337 |
{ url = "https://files.pythonhosted.org/packages/1f/d9/74017c4eec7a28892d8d6e31ae9de3baef71f5a5286e74e6b7aad7f8c837/pandas-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:094e271a15b579650ebf4c5155c05dcd2a14fd4fdd72cf4854b2f7ad31ea30be", size = 10976199, upload-time = "2025-06-05T03:26:59.594Z" },
|
1338 |
{ url = "https://files.pythonhosted.org/packages/d3/57/5cb75a56a4842bbd0511c3d1c79186d8315b82dac802118322b2de1194fe/pandas-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c7e2fc25f89a49a11599ec1e76821322439d90820108309bf42130d2f36c983", size = 11518913, upload-time = "2025-06-05T03:27:02.757Z" },
|
|
|
1339 |
{ url = "https://files.pythonhosted.org/packages/e8/6a/47fd7517cd8abe72a58706aab2b99e9438360d36dcdb052cf917b7bf3bdc/pandas-2.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb32dc743b52467d488e7a7c8039b821da2826a9ba4f85b89ea95274f863280f", size = 11328359, upload-time = "2025-06-05T03:27:06.431Z" },
|
1340 |
{ url = "https://files.pythonhosted.org/packages/2a/b3/463bfe819ed60fb7e7ddffb4ae2ee04b887b3444feee6c19437b8f834837/pandas-2.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:213cd63c43263dbb522c1f8a7c9d072e25900f6975596f883f4bebd77295d4f3", size = 12024789, upload-time = "2025-06-05T03:27:09.875Z" },
|
|
|
1341 |
{ url = "https://files.pythonhosted.org/packages/e9/df/815d6583967001153bb27f5cf075653d69d51ad887ebbf4cfe1173a1ac58/pandas-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:430a63bae10b5086995db1b02694996336e5a8ac9a96b4200572b413dfdfccb9", size = 13223381, upload-time = "2025-06-05T03:27:15.641Z" },
|
1342 |
{ url = "https://files.pythonhosted.org/packages/79/88/ca5973ed07b7f484c493e941dbff990861ca55291ff7ac67c815ce347395/pandas-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4930255e28ff5545e2ca404637bcc56f031893142773b3468dc021c6c32a1390", size = 10970135, upload-time = "2025-06-05T03:27:24.131Z" },
|
1343 |
{ url = "https://files.pythonhosted.org/packages/24/fb/0994c14d1f7909ce83f0b1fb27958135513c4f3f2528bde216180aa73bfc/pandas-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f925f1ef673b4bd0271b1809b72b3270384f2b7d9d14a189b12b7fc02574d575", size = 12141356, upload-time = "2025-06-05T03:27:34.547Z" },
|
1344 |
{ url = "https://files.pythonhosted.org/packages/9d/a2/9b903e5962134497ac4f8a96f862ee3081cb2506f69f8e4778ce3d9c9d82/pandas-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78ad363ddb873a631e92a3c063ade1ecfb34cae71e9a2be6ad100f875ac1042", size = 11474674, upload-time = "2025-06-05T03:27:39.448Z" },
|
1345 |
{ url = "https://files.pythonhosted.org/packages/81/3a/3806d041bce032f8de44380f866059437fb79e36d6b22c82c187e65f765b/pandas-2.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:951805d146922aed8357e4cc5671b8b0b9be1027f0619cea132a9f3f65f2f09c", size = 11439876, upload-time = "2025-06-05T03:27:43.652Z" },
|
1346 |
{ url = "https://files.pythonhosted.org/packages/15/aa/3fc3181d12b95da71f5c2537c3e3b3af6ab3a8c392ab41ebb766e0929bc6/pandas-2.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a881bc1309f3fce34696d07b00f13335c41f5f5a8770a33b09ebe23261cfc67", size = 11966182, upload-time = "2025-06-05T03:27:47.652Z" },
|
|
|
1347 |
{ url = "https://files.pythonhosted.org/packages/39/c2/646d2e93e0af70f4e5359d870a63584dacbc324b54d73e6b3267920ff117/pandas-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bb3be958022198531eb7ec2008cfc78c5b1eed51af8600c6c5d9160d89d8d249", size = 13231847, upload-time = "2025-06-05T03:27:51.465Z" },
|
1348 |
]
|
1349 |
|
@@ -2151,6 +2169,7 @@ dependencies = [
|
|
2151 |
{ name = "cachetools" },
|
2152 |
{ name = "dnspython" },
|
2153 |
{ name = "gradio", extra = ["mcp"] },
|
|
|
2154 |
{ name = "python-whois" },
|
2155 |
{ name = "requests" },
|
2156 |
{ name = "vt-py" },
|
@@ -2178,6 +2197,7 @@ requires-dist = [
|
|
2178 |
{ name = "cachetools", specifier = ">=6.0.0" },
|
2179 |
{ name = "dnspython", specifier = ">=2.7.0" },
|
2180 |
{ name = "gradio", extras = ["mcp"], specifier = ">=5.32.1" },
|
|
|
2181 |
{ name = "python-whois", specifier = ">=0.9.5" },
|
2182 |
{ name = "requests", specifier = ">=2.32.3" },
|
2183 |
{ name = "vt-py", specifier = "~=0.21.0" },
|
|
|
857 |
{ url = "https://files.pythonhosted.org/packages/53/84/8a89614b2e7eeeaf0a68a4046d6cfaea4544c8619ea02595ebeec9b2bae3/license_expression-30.4.1-py3-none-any.whl", hash = "sha256:679646bc3261a17690494a3e1cada446e5ee342dbd87dcfa4a0c24cc5dce13ee", size = 111457, upload-time = "2025-01-14T05:11:38.658Z" },
|
858 |
]
|
859 |
|
860 |
+
[[package]]
|
861 |
+
name = "markdown"
|
862 |
+
version = "3.8"
|
863 |
+
source = { registry = "https://pypi.org/simple" }
|
864 |
+
sdist = { url = "https://files.pythonhosted.org/packages/2f/15/222b423b0b88689c266d9eac4e61396fe2cc53464459d6a37618ac863b24/markdown-3.8.tar.gz", hash = "sha256:7df81e63f0df5c4b24b7d156eb81e4690595239b7d70937d0409f1b0de319c6f", size = 360906, upload-time = "2025-04-11T14:42:50.928Z" }
|
865 |
+
wheels = [
|
866 |
+
{ url = "https://files.pythonhosted.org/packages/51/3f/afe76f8e2246ffbc867440cbcf90525264df0e658f8a5ca1f872b3f6192a/markdown-3.8-py3-none-any.whl", hash = "sha256:794a929b79c5af141ef5ab0f2f642d0f7b1872981250230e72682346f7cc90dc", size = 106210, upload-time = "2025-04-11T14:42:49.178Z" },
|
867 |
+
]
|
868 |
+
|
869 |
[[package]]
|
870 |
name = "markdown-it-py"
|
871 |
version = "3.0.0"
|
|
|
1333 |
{ url = "https://files.pythonhosted.org/packages/77/1c/3f8c331d223f86ba1d0ed7d3ed7fcf1501c6f250882489cc820d2567ddbf/pandas-2.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6872d695c896f00df46b71648eea332279ef4077a409e2fe94220208b6bb675", size = 10774764, upload-time = "2025-06-05T03:25:53.228Z" },
|
1334 |
{ url = "https://files.pythonhosted.org/packages/1b/45/d2599400fad7fe06b849bd40b52c65684bc88fbe5f0a474d0513d057a377/pandas-2.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4dd97c19bd06bc557ad787a15b6489d2614ddaab5d104a0310eb314c724b2d2", size = 11711963, upload-time = "2025-06-05T03:25:56.855Z" },
|
1335 |
{ url = "https://files.pythonhosted.org/packages/66/f8/5508bc45e994e698dbc93607ee6b9b6eb67df978dc10ee2b09df80103d9e/pandas-2.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:034abd6f3db8b9880aaee98f4f5d4dbec7c4829938463ec046517220b2f8574e", size = 12349446, upload-time = "2025-06-05T03:26:01.292Z" },
|
1336 |
+
{ url = "https://files.pythonhosted.org/packages/f7/fc/17851e1b1ea0c8456ba90a2f514c35134dd56d981cf30ccdc501a0adeac4/pandas-2.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23c2b2dc5213810208ca0b80b8666670eb4660bbfd9d45f58592cc4ddcfd62e1", size = 12920002, upload-time = "2025-06-06T00:00:07.925Z" },
|
1337 |
{ url = "https://files.pythonhosted.org/packages/a1/9b/8743be105989c81fa33f8e2a4e9822ac0ad4aaf812c00fee6bb09fc814f9/pandas-2.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:39ff73ec07be5e90330cc6ff5705c651ace83374189dcdcb46e6ff54b4a72cd6", size = 13651218, upload-time = "2025-06-05T03:26:09.731Z" },
|
1338 |
{ url = "https://files.pythonhosted.org/packages/26/fa/8eeb2353f6d40974a6a9fd4081ad1700e2386cf4264a8f28542fd10b3e38/pandas-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:40cecc4ea5abd2921682b57532baea5588cc5f80f0231c624056b146887274d2", size = 11082485, upload-time = "2025-06-05T03:26:17.572Z" },
|
1339 |
{ url = "https://files.pythonhosted.org/packages/96/1e/ba313812a699fe37bf62e6194265a4621be11833f5fce46d9eae22acb5d7/pandas-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8adff9f138fc614347ff33812046787f7d43b3cef7c0f0171b3340cae333f6ca", size = 11551836, upload-time = "2025-06-05T03:26:22.784Z" },
|
1340 |
+
{ url = "https://files.pythonhosted.org/packages/1b/cc/0af9c07f8d714ea563b12383a7e5bde9479cf32413ee2f346a9c5a801f22/pandas-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e5f08eb9a445d07720776df6e641975665c9ea12c9d8a331e0f6890f2dcd76ef", size = 10807977, upload-time = "2025-06-05T16:50:11.109Z" },
|
1341 |
{ url = "https://files.pythonhosted.org/packages/ee/3e/8c0fb7e2cf4a55198466ced1ca6a9054ae3b7e7630df7757031df10001fd/pandas-2.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa35c266c8cd1a67d75971a1912b185b492d257092bdd2709bbdebe574ed228d", size = 11788230, upload-time = "2025-06-05T03:26:27.417Z" },
|
1342 |
{ url = "https://files.pythonhosted.org/packages/14/22/b493ec614582307faf3f94989be0f7f0a71932ed6f56c9a80c0bb4a3b51e/pandas-2.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a0cc77b0f089d2d2ffe3007db58f170dae9b9f54e569b299db871a3ab5bf46", size = 12370423, upload-time = "2025-06-05T03:26:34.142Z" },
|
1343 |
+
{ url = "https://files.pythonhosted.org/packages/9f/74/b012addb34cda5ce855218a37b258c4e056a0b9b334d116e518d72638737/pandas-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c06f6f144ad0a1bf84699aeea7eff6068ca5c63ceb404798198af7eb86082e33", size = 12990594, upload-time = "2025-06-06T00:00:13.934Z" },
|
1344 |
{ url = "https://files.pythonhosted.org/packages/95/81/b310e60d033ab64b08e66c635b94076488f0b6ce6a674379dd5b224fc51c/pandas-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ed16339bc354a73e0a609df36d256672c7d296f3f767ac07257801aa064ff73c", size = 13745952, upload-time = "2025-06-05T03:26:39.475Z" },
|
1345 |
{ url = "https://files.pythonhosted.org/packages/25/ac/f6ee5250a8881b55bd3aecde9b8cfddea2f2b43e3588bca68a4e9aaf46c8/pandas-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:fa07e138b3f6c04addfeaf56cc7fdb96c3b68a3fe5e5401251f231fce40a0d7a", size = 11094534, upload-time = "2025-06-05T03:26:43.23Z" },
|
1346 |
{ url = "https://files.pythonhosted.org/packages/94/46/24192607058dd607dbfacdd060a2370f6afb19c2ccb617406469b9aeb8e7/pandas-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2eb4728a18dcd2908c7fccf74a982e241b467d178724545a48d0caf534b38ebf", size = 11573865, upload-time = "2025-06-05T03:26:46.774Z" },
|
1347 |
+
{ url = "https://files.pythonhosted.org/packages/9f/cc/ae8ea3b800757a70c9fdccc68b67dc0280a6e814efcf74e4211fd5dea1ca/pandas-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9d8c3187be7479ea5c3d30c32a5d73d62a621166675063b2edd21bc47614027", size = 10702154, upload-time = "2025-06-05T16:50:14.439Z" },
|
1348 |
+
{ url = "https://files.pythonhosted.org/packages/d8/ba/a7883d7aab3d24c6540a2768f679e7414582cc389876d469b40ec749d78b/pandas-2.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ff730713d4c4f2f1c860e36c005c7cefc1c7c80c21c0688fd605aa43c9fcf09", size = 11262180, upload-time = "2025-06-05T16:50:17.453Z" },
|
1349 |
{ url = "https://files.pythonhosted.org/packages/01/a5/931fc3ad333d9d87b10107d948d757d67ebcfc33b1988d5faccc39c6845c/pandas-2.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba24af48643b12ffe49b27065d3babd52702d95ab70f50e1b34f71ca703e2c0d", size = 11991493, upload-time = "2025-06-05T03:26:51.813Z" },
|
1350 |
+
{ url = "https://files.pythonhosted.org/packages/d7/bf/0213986830a92d44d55153c1d69b509431a972eb73f204242988c4e66e86/pandas-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:404d681c698e3c8a40a61d0cd9412cc7364ab9a9cc6e144ae2992e11a2e77a20", size = 12470733, upload-time = "2025-06-06T00:00:18.651Z" },
|
1351 |
{ url = "https://files.pythonhosted.org/packages/a4/0e/21eb48a3a34a7d4bac982afc2c4eb5ab09f2d988bdf29d92ba9ae8e90a79/pandas-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6021910b086b3ca756755e86ddc64e0ddafd5e58e076c72cb1585162e5ad259b", size = 13212406, upload-time = "2025-06-05T03:26:55.992Z" },
|
1352 |
{ url = "https://files.pythonhosted.org/packages/1f/d9/74017c4eec7a28892d8d6e31ae9de3baef71f5a5286e74e6b7aad7f8c837/pandas-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:094e271a15b579650ebf4c5155c05dcd2a14fd4fdd72cf4854b2f7ad31ea30be", size = 10976199, upload-time = "2025-06-05T03:26:59.594Z" },
|
1353 |
{ url = "https://files.pythonhosted.org/packages/d3/57/5cb75a56a4842bbd0511c3d1c79186d8315b82dac802118322b2de1194fe/pandas-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c7e2fc25f89a49a11599ec1e76821322439d90820108309bf42130d2f36c983", size = 11518913, upload-time = "2025-06-05T03:27:02.757Z" },
|
1354 |
+
{ url = "https://files.pythonhosted.org/packages/05/01/0c8785610e465e4948a01a059562176e4c8088aa257e2e074db868f86d4e/pandas-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c6da97aeb6a6d233fb6b17986234cc723b396b50a3c6804776351994f2a658fd", size = 10655249, upload-time = "2025-06-05T16:50:20.17Z" },
|
1355 |
{ url = "https://files.pythonhosted.org/packages/e8/6a/47fd7517cd8abe72a58706aab2b99e9438360d36dcdb052cf917b7bf3bdc/pandas-2.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb32dc743b52467d488e7a7c8039b821da2826a9ba4f85b89ea95274f863280f", size = 11328359, upload-time = "2025-06-05T03:27:06.431Z" },
|
1356 |
{ url = "https://files.pythonhosted.org/packages/2a/b3/463bfe819ed60fb7e7ddffb4ae2ee04b887b3444feee6c19437b8f834837/pandas-2.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:213cd63c43263dbb522c1f8a7c9d072e25900f6975596f883f4bebd77295d4f3", size = 12024789, upload-time = "2025-06-05T03:27:09.875Z" },
|
1357 |
+
{ url = "https://files.pythonhosted.org/packages/04/0c/e0704ccdb0ac40aeb3434d1c641c43d05f75c92e67525df39575ace35468/pandas-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1d2b33e68d0ce64e26a4acc2e72d747292084f4e8db4c847c6f5f6cbe56ed6d8", size = 12480734, upload-time = "2025-06-06T00:00:22.246Z" },
|
1358 |
{ url = "https://files.pythonhosted.org/packages/e9/df/815d6583967001153bb27f5cf075653d69d51ad887ebbf4cfe1173a1ac58/pandas-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:430a63bae10b5086995db1b02694996336e5a8ac9a96b4200572b413dfdfccb9", size = 13223381, upload-time = "2025-06-05T03:27:15.641Z" },
|
1359 |
{ url = "https://files.pythonhosted.org/packages/79/88/ca5973ed07b7f484c493e941dbff990861ca55291ff7ac67c815ce347395/pandas-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4930255e28ff5545e2ca404637bcc56f031893142773b3468dc021c6c32a1390", size = 10970135, upload-time = "2025-06-05T03:27:24.131Z" },
|
1360 |
{ url = "https://files.pythonhosted.org/packages/24/fb/0994c14d1f7909ce83f0b1fb27958135513c4f3f2528bde216180aa73bfc/pandas-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f925f1ef673b4bd0271b1809b72b3270384f2b7d9d14a189b12b7fc02574d575", size = 12141356, upload-time = "2025-06-05T03:27:34.547Z" },
|
1361 |
{ url = "https://files.pythonhosted.org/packages/9d/a2/9b903e5962134497ac4f8a96f862ee3081cb2506f69f8e4778ce3d9c9d82/pandas-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78ad363ddb873a631e92a3c063ade1ecfb34cae71e9a2be6ad100f875ac1042", size = 11474674, upload-time = "2025-06-05T03:27:39.448Z" },
|
1362 |
{ url = "https://files.pythonhosted.org/packages/81/3a/3806d041bce032f8de44380f866059437fb79e36d6b22c82c187e65f765b/pandas-2.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:951805d146922aed8357e4cc5671b8b0b9be1027f0619cea132a9f3f65f2f09c", size = 11439876, upload-time = "2025-06-05T03:27:43.652Z" },
|
1363 |
{ url = "https://files.pythonhosted.org/packages/15/aa/3fc3181d12b95da71f5c2537c3e3b3af6ab3a8c392ab41ebb766e0929bc6/pandas-2.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a881bc1309f3fce34696d07b00f13335c41f5f5a8770a33b09ebe23261cfc67", size = 11966182, upload-time = "2025-06-05T03:27:47.652Z" },
|
1364 |
+
{ url = "https://files.pythonhosted.org/packages/37/e7/e12f2d9b0a2c4a2cc86e2aabff7ccfd24f03e597d770abfa2acd313ee46b/pandas-2.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e1991bbb96f4050b09b5f811253c4f3cf05ee89a589379aa36cd623f21a31d6f", size = 12547686, upload-time = "2025-06-06T00:00:26.142Z" },
|
1365 |
{ url = "https://files.pythonhosted.org/packages/39/c2/646d2e93e0af70f4e5359d870a63584dacbc324b54d73e6b3267920ff117/pandas-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bb3be958022198531eb7ec2008cfc78c5b1eed51af8600c6c5d9160d89d8d249", size = 13231847, upload-time = "2025-06-05T03:27:51.465Z" },
|
1366 |
]
|
1367 |
|
|
|
2169 |
{ name = "cachetools" },
|
2170 |
{ name = "dnspython" },
|
2171 |
{ name = "gradio", extra = ["mcp"] },
|
2172 |
+
{ name = "markdown" },
|
2173 |
{ name = "python-whois" },
|
2174 |
{ name = "requests" },
|
2175 |
{ name = "vt-py" },
|
|
|
2197 |
{ name = "cachetools", specifier = ">=6.0.0" },
|
2198 |
{ name = "dnspython", specifier = ">=2.7.0" },
|
2199 |
{ name = "gradio", extras = ["mcp"], specifier = ">=5.32.1" },
|
2200 |
+
{ name = "markdown", specifier = ">=3.8" },
|
2201 |
{ name = "python-whois", specifier = ">=0.9.5" },
|
2202 |
{ name = "requests", specifier = ">=2.32.3" },
|
2203 |
{ name = "vt-py", specifier = "~=0.21.0" },
|