arcade-mcp/toolkits/x/arcade_x/tools/utils.py
Nate Barbettini 894fa878f1
Fix ruff (#64)
On the last few PRs I have noticed two problems:
1. `ruff format` fails even though it seems OK on our local machines
(sometimes, not always)
2. Nate's and Sam's machines kept flip-flopping a specific piece of
formatting back and forth, indicating a subtle difference of config
hiding somewhere
3. This was reproducible by running `ruff format` in the terminal,
followed by `make check`. The former would edit files, and then `make
check` would edit them back!

This PR addresses both issues, and further standardizes our editor &
linter configs to be super stable.
Specifically:
1. The main fix for the above, the pre-commit hook was pinned to a super
old version of ruff.
This resulted in subtle differences in behavior between our machines,
and on CI.

2. Moved ruff settings from `pyproject.toml` to `.ruff.toml`
pyproject files in subdirectories (e.g. `toolkits/**`) were overriding
the main pyproject file and erasing the custom ruff config we set at the
root. This meant that our ruff config was applied to `arcade` but not to
any of the other packages.
By moving the config to `.ruff.toml` at the root, all projects will
inherit the same ruff linting & formatting config.

4. Un-ignored the `.vscode/` directory so that we can share
vscode/cursor workspace settings.
This is valuable for standardizing settings like the default formatter
(ruff) and default test framework (pytest).
However, it's important that going forward we _only_ commit things here
that should apply across all of our machines.

5. To avoid any conflict between prettier and ruff, prettier now
explicitly ignores *.py files

6. Finally, `ruff format` and `make check` agree. A number of files are
newly auto-formatted.
2024-09-25 09:47:30 -07:00

58 lines
1.8 KiB
Python

import json
from requests import Response
def get_tweet_url(tweet_id: str) -> str:
"""Get the URL of a tweet given its ID."""
return f"https://x.com/x/status/{tweet_id}"
def parse_search_recent_tweets_response(response: Response) -> str:
"""
Parses response from the X API search recent tweets endpoint.
Returns a JSON string with the tweets data.
Example parsed response:
"tweets": [
{
"author_id": "558248927",
"id": "1838272933141319832",
"edit_history_tweet_ids": [
"1838272933141319832"
],
"text": "PR pending on @LangChainAI, will be integrated there soon! https://t.co/DPWd4lccQo",
"tweet_url": "https://x.com/x/status/1838272933141319832",
"author_username": "tomas_hk",
"author_name": "Tomas Hernando Kofman"
},
]
"""
if response.status_code != 200:
return json.dumps({"tweets": []})
tweets_data = json.loads(response.text)
if not sanity_check_tweets_data(tweets_data):
return json.dumps({"tweets": []})
for tweet in tweets_data["data"]:
tweet["tweet_url"] = get_tweet_url(tweet["id"])
for tweet_data, user_data in zip(tweets_data["data"], tweets_data["includes"]["users"]):
tweet_data["author_username"] = user_data["username"]
tweet_data["author_name"] = user_data["name"]
return json.dumps({"tweets": tweets_data["data"]})
def sanity_check_tweets_data(tweets_data: dict) -> bool:
"""
Sanity check the tweets data.
Returns True if the tweets data is valid and contains tweets, False otherwise.
"""
if not tweets_data.get("data", []):
return False
if not tweets_data.get("includes", {}).get("users", []):
return False
return True