mwalker22 commited on
Commit
5150a1c
·
1 Parent(s): 3555aa6

Implementation of the seach_golfpedia_tool using the tavily.search(...) function. NOTE: This also includes pytest unit tests for the tool.

Browse files
backend/tests/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ """Test package for the golf agent backend."""
backend/tests/conftest.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ """Configuration file for pytest."""
2
+
3
+ import os
4
+ import sys
5
+
6
+ # Add the project root to the Python path
7
+ project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
8
+ sys.path.insert(0, project_root)
backend/tests/test_search_golfpedia_tool.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+ from unittest.mock import patch, MagicMock
3
+ from backend.tools.search_golfpedia_tool import search_golfpedia
4
+ from backend.tools.constants_tools import NO_SUMMARY_AVAILABLE
5
+
6
+ @pytest.fixture
7
+ def mock_tavily_response():
8
+ return {
9
+ "answer": "This is a mock golf answer"
10
+ }
11
+
12
+ @pytest.fixture
13
+ def mock_tavily_empty_response():
14
+ return {"results": []}
15
+
16
+ @pytest.fixture
17
+ def mock_tavily_client():
18
+ """Mock the TavilyClient to avoid API calls."""
19
+ with patch('backend.tools.search_golfpedia_tool.get_tavily_client') as mock:
20
+ mock_client = MagicMock()
21
+ mock.return_value = mock_client
22
+ yield mock_client
23
+
24
+ def test_search_golfpedia_successful(mock_tavily_response, mock_tavily_client):
25
+ """Test successful search with answer in response"""
26
+ mock_tavily_client.search.return_value = mock_tavily_response
27
+ result = search_golfpedia.invoke("What is golf?")
28
+ assert result == "This is a mock golf answer"
29
+
30
+ def test_search_golfpedia_no_answer(mock_tavily_empty_response, mock_tavily_client):
31
+ """Test search when an empty response is returned"""
32
+ mock_tavily_client.search.return_value = mock_tavily_empty_response
33
+ result = search_golfpedia.invoke("What is golf?")
34
+ assert result == NO_SUMMARY_AVAILABLE
35
+
36
+ def test_search_golfpedia_api_error(mock_tavily_client):
37
+ """Test handling of API error"""
38
+ mock_tavily_client.search.side_effect = Exception("API Error")
39
+ with pytest.raises(Exception) as exc_info:
40
+ search_golfpedia.invoke("What is golf?")
41
+ assert str(exc_info.value) == "API Error"
42
+
43
+ def test_search_golfpedia_empty_query(mock_tavily_empty_response, mock_tavily_client):
44
+ """Test handling of empty query"""
45
+ mock_tavily_client.search.return_value = mock_tavily_empty_response
46
+ result = search_golfpedia.invoke("")
47
+ assert result == NO_SUMMARY_AVAILABLE
48
+
49
+ @pytest.mark.parametrize("query", ["", " ", "\n", "\t"])
50
+ def test_search_golfpedia_blankish_queries(query, mock_tavily_empty_response, mock_tavily_client):
51
+ mock_tavily_client.search.return_value = mock_tavily_empty_response
52
+ result = search_golfpedia.invoke(query)
53
+ assert result == NO_SUMMARY_AVAILABLE
backend/tools/constants_tools.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ """Constants used across the golf agent tools."""
2
+
3
+ NO_SUMMARY_AVAILABLE = "No summary available."
backend/tools/registry.py CHANGED
@@ -3,14 +3,13 @@ Tool registry for the agent. Add tools here to make them available to your agent
3
  """
4
 
5
  from langchain.tools import Tool
6
- from backend.tools.dummy_tool import echo_tool
7
 
8
  tools = [
9
  Tool(
10
- name="echo",
11
- func=echo_tool,
12
- description="Repeats back what the user says. Used as a template tool."
13
- )
 
14
  ]
15
-
16
- # TODO: Add additional tools here as needed
 
3
  """
4
 
5
  from langchain.tools import Tool
6
+ from backend.tools.search_golfpedia_tool import search_golfpedia
7
 
8
  tools = [
9
  Tool(
10
+ name="search_golfpedia",
11
+ func=search_golfpedia,
12
+ description="Searches the web for general golf-related knowledge using Tavily.",
13
+ ),
14
+ # Add other tools here later
15
  ]
 
 
backend/tools/search_golfpedia_tool.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from tavily import TavilyClient
3
+ from langchain.tools import tool
4
+ from backend.tools.constants_tools import NO_SUMMARY_AVAILABLE
5
+
6
+ # Initialize the client lazily to allow for environment variable mocking in tests
7
+ def get_tavily_client():
8
+ return TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
9
+
10
+ @tool
11
+ def search_golfpedia(query: str) -> str:
12
+ """Searches the web for general golf-related knowledge using Tavily."""
13
+ tavily = get_tavily_client()
14
+ result = tavily.search(query=query, search_depth="basic")
15
+ return result["answer"] if "answer" in result else NO_SUMMARY_AVAILABLE
pyproject.toml CHANGED
@@ -15,6 +15,8 @@ dependencies = [
15
  "langchain>=0.1.0",
16
  "langchain-community>=0.0.22",
17
  "langchain-openai>=0.0.8",
 
 
18
  ]
19
 
20
  [build-system]
@@ -36,3 +38,10 @@ select = [
36
 
37
  [tool.hatch.build.targets.wheel]
38
  packages = ["backend"]
 
 
 
 
 
 
 
 
15
  "langchain>=0.1.0",
16
  "langchain-community>=0.0.22",
17
  "langchain-openai>=0.0.8",
18
+ "pytest>=7.0.0", # Added pytest dependency
19
+ "tavily-python>=0.3.0", # Added tavily dependency
20
  ]
21
 
22
  [build-system]
 
38
 
39
  [tool.hatch.build.targets.wheel]
40
  packages = ["backend"]
41
+
42
+ [tool.pytest.ini_options]
43
+ testpaths = ["backend/tests"]
44
+ python_files = ["test_*.py"]
45
+ python_functions = ["test_*"]
46
+ python_classes = ["Test*"]
47
+ addopts = "-v"
uv.lock CHANGED
@@ -657,6 +657,15 @@ wheels = [
657
  { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
658
  ]
659
 
 
 
 
 
 
 
 
 
 
660
  [[package]]
661
  name = "jiter"
662
  version = "0.9.0"
@@ -868,6 +877,7 @@ dependencies = [
868
  { name = "openai" },
869
  { name = "pypdf" },
870
  { name = "pypdf2" },
 
871
  { name = "python-dotenv" },
872
  { name = "python-multipart" },
873
  { name = "uvicorn", extra = ["standard"] },
@@ -883,6 +893,7 @@ requires-dist = [
883
  { name = "openai", specifier = ">=1.0.0" },
884
  { name = "pypdf" },
885
  { name = "pypdf2", specifier = ">=3.0.0" },
 
886
  { name = "python-dotenv" },
887
  { name = "python-multipart" },
888
  { name = "uvicorn", extras = ["standard"] },
@@ -1247,6 +1258,15 @@ wheels = [
1247
  { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
1248
  ]
1249
 
 
 
 
 
 
 
 
 
 
1250
  [[package]]
1251
  name = "propcache"
1252
  version = "0.3.1"
@@ -1523,6 +1543,23 @@ wheels = [
1523
  { url = "https://files.pythonhosted.org/packages/8e/5e/c86a5643653825d3c913719e788e41386bee415c2b87b4f955432f2de6b2/pypdf2-3.0.1-py3-none-any.whl", hash = "sha256:d16e4205cfee272fbdc0568b68d82be796540b1537508cef59388f839c191928", size = 232572 },
1524
  ]
1525
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1526
  [[package]]
1527
  name = "python-dotenv"
1528
  version = "1.1.0"
@@ -1832,6 +1869,45 @@ wheels = [
1832
  { url = "https://files.pythonhosted.org/packages/70/22/e8fc1bf9cdecc439b7ddc28a45b976a8c699a38874c070749d855696368a/tiktoken-0.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:26242ca9dc8b58e875ff4ca078b9a94d2f0813e6a535dcd2205df5d49d927cc7", size = 894215 },
1833
  ]
1834
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1835
  [[package]]
1836
  name = "tqdm"
1837
  version = "4.67.1"
 
657
  { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
658
  ]
659
 
660
+ [[package]]
661
+ name = "iniconfig"
662
+ version = "2.1.0"
663
+ source = { registry = "https://pypi.org/simple" }
664
+ sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793 }
665
+ wheels = [
666
+ { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050 },
667
+ ]
668
+
669
  [[package]]
670
  name = "jiter"
671
  version = "0.9.0"
 
877
  { name = "openai" },
878
  { name = "pypdf" },
879
  { name = "pypdf2" },
880
+ { name = "pytest" },
881
  { name = "python-dotenv" },
882
  { name = "python-multipart" },
883
  { name = "uvicorn", extra = ["standard"] },
 
893
  { name = "openai", specifier = ">=1.0.0" },
894
  { name = "pypdf" },
895
  { name = "pypdf2", specifier = ">=3.0.0" },
896
+ { name = "pytest", specifier = ">=7.0.0" },
897
  { name = "python-dotenv" },
898
  { name = "python-multipart" },
899
  { name = "uvicorn", extras = ["standard"] },
 
1258
  { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
1259
  ]
1260
 
1261
+ [[package]]
1262
+ name = "pluggy"
1263
+ version = "1.5.0"
1264
+ source = { registry = "https://pypi.org/simple" }
1265
+ sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 }
1266
+ wheels = [
1267
+ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 },
1268
+ ]
1269
+
1270
  [[package]]
1271
  name = "propcache"
1272
  version = "0.3.1"
 
1543
  { url = "https://files.pythonhosted.org/packages/8e/5e/c86a5643653825d3c913719e788e41386bee415c2b87b4f955432f2de6b2/pypdf2-3.0.1-py3-none-any.whl", hash = "sha256:d16e4205cfee272fbdc0568b68d82be796540b1537508cef59388f839c191928", size = 232572 },
1544
  ]
1545
 
1546
+ [[package]]
1547
+ name = "pytest"
1548
+ version = "8.3.5"
1549
+ source = { registry = "https://pypi.org/simple" }
1550
+ dependencies = [
1551
+ { name = "colorama", marker = "sys_platform == 'win32'" },
1552
+ { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
1553
+ { name = "iniconfig" },
1554
+ { name = "packaging" },
1555
+ { name = "pluggy" },
1556
+ { name = "tomli", marker = "python_full_version < '3.11'" },
1557
+ ]
1558
+ sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891 }
1559
+ wheels = [
1560
+ { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634 },
1561
+ ]
1562
+
1563
  [[package]]
1564
  name = "python-dotenv"
1565
  version = "1.1.0"
 
1869
  { url = "https://files.pythonhosted.org/packages/70/22/e8fc1bf9cdecc439b7ddc28a45b976a8c699a38874c070749d855696368a/tiktoken-0.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:26242ca9dc8b58e875ff4ca078b9a94d2f0813e6a535dcd2205df5d49d927cc7", size = 894215 },
1870
  ]
1871
 
1872
+ [[package]]
1873
+ name = "tomli"
1874
+ version = "2.2.1"
1875
+ source = { registry = "https://pypi.org/simple" }
1876
+ sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 }
1877
+ wheels = [
1878
+ { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 },
1879
+ { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 },
1880
+ { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 },
1881
+ { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 },
1882
+ { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 },
1883
+ { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 },
1884
+ { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 },
1885
+ { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 },
1886
+ { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 },
1887
+ { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 },
1888
+ { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 },
1889
+ { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 },
1890
+ { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 },
1891
+ { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 },
1892
+ { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 },
1893
+ { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 },
1894
+ { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 },
1895
+ { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 },
1896
+ { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 },
1897
+ { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 },
1898
+ { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 },
1899
+ { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 },
1900
+ { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 },
1901
+ { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 },
1902
+ { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 },
1903
+ { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 },
1904
+ { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 },
1905
+ { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 },
1906
+ { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 },
1907
+ { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 },
1908
+ { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 },
1909
+ ]
1910
+
1911
  [[package]]
1912
  name = "tqdm"
1913
  version = "4.67.1"