X Toolkit: Handle no tweets returned in search (#256)
## PR Description Search ([see API docs here](https://docs.x.com/x-api/posts/recent-search)) returns a 'data' field that maps to a list of tweets returned. We've observed that the 'data' field is not present if no tweets match the search. This PR handles that case safely.
This commit is contained in:
parent
e636b686c1
commit
7d45a99722
2 changed files with 32 additions and 2 deletions
|
|
@ -94,7 +94,7 @@ async def search_recent_tweets_by_username(
|
||||||
|
|
||||||
response_data: dict[str, Any] = response.json()
|
response_data: dict[str, Any] = response.json()
|
||||||
|
|
||||||
for tweet in response_data["data"]:
|
for tweet in response_data.get("data", []):
|
||||||
expand_long_tweet(tweet)
|
expand_long_tweet(tweet)
|
||||||
|
|
||||||
# Expand the URLs that are in the tweets
|
# Expand the URLs that are in the tweets
|
||||||
|
|
@ -164,7 +164,7 @@ async def search_recent_tweets_by_keywords(
|
||||||
|
|
||||||
response_data: dict[str, Any] = response.json()
|
response_data: dict[str, Any] = response.json()
|
||||||
|
|
||||||
for tweet in response_data["data"]:
|
for tweet in response_data.get("data", []):
|
||||||
expand_long_tweet(tweet)
|
expand_long_tweet(tweet)
|
||||||
|
|
||||||
# Expand the URLs that are in the tweets
|
# Expand the URLs that are in the tweets
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,21 @@ async def test_search_recent_tweets_by_username_success(tool_context, mock_httpx
|
||||||
mock_httpx_client.get.assert_called_once()
|
mock_httpx_client.get.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_search_recent_tweets_by_username_no_tweets_found(tool_context, mock_httpx_client):
|
||||||
|
"""Test that the tool returns an empty list when no tweets are found."""
|
||||||
|
mock_response = MagicMock()
|
||||||
|
mock_response.status_code = 200
|
||||||
|
mock_response.json.return_value = {"next_token": ""}
|
||||||
|
mock_httpx_client.get.return_value = mock_response
|
||||||
|
|
||||||
|
username = "not_a_user_41"
|
||||||
|
result = await search_recent_tweets_by_username(tool_context, username)
|
||||||
|
|
||||||
|
assert "data" in result
|
||||||
|
assert len(result["data"]) == 0
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_search_recent_tweets_by_username_failure(tool_context, mock_httpx_client):
|
async def test_search_recent_tweets_by_username_failure(tool_context, mock_httpx_client):
|
||||||
"""Test failure when searching tweets due to API error."""
|
"""Test failure when searching tweets due to API error."""
|
||||||
|
|
@ -203,6 +218,21 @@ async def test_search_recent_tweets_by_keywords_success(tool_context, mock_httpx
|
||||||
mock_httpx_client.get.assert_called_once()
|
mock_httpx_client.get.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_search_recent_tweets_by_keywords_no_tweets_found(tool_context, mock_httpx_client):
|
||||||
|
"""Test that the tool returns an empty list when no tweets are found."""
|
||||||
|
mock_response = MagicMock()
|
||||||
|
mock_response.status_code = 200
|
||||||
|
mock_response.json.return_value = {"next_token": ""}
|
||||||
|
mock_httpx_client.get.return_value = mock_response
|
||||||
|
|
||||||
|
keywords = ["test", "keyword"]
|
||||||
|
result = await search_recent_tweets_by_keywords(context=tool_context, keywords=keywords)
|
||||||
|
|
||||||
|
assert "data" in result
|
||||||
|
assert len(result["data"]) == 0
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_search_recent_tweets_by_keywords_no_input(tool_context):
|
async def test_search_recent_tweets_by_keywords_no_input(tool_context):
|
||||||
"""Test error when no keywords or phrases are provided."""
|
"""Test error when no keywords or phrases are provided."""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue