deps: migrate from httpx to httpx2 (pydantic's maintained fork) (#15192)

* deps: migrate from httpx to httpx2 (pydantic's maintained fork)

Mechanical rename of httpx -> httpx2 (API-compatible fork of httpx 0.28.1):
pyproject.toml deps, PEP 723 inline-script headers, and all import/call sites.
Excludes uv.lock (the keeper's allow-list rejects .lock files); the lock
refresh needs a separate maintainer-merged PR.

Refs #15081

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* deps: drop tweepy + migrate remaining requests refs to httpx2

- maths/allocation_number.py: docstring example uses httpx2, not requests
- web_programming/get_imdbtop.py.DISABLED: import httpx2 instead of requests
- remove web_programming/get_user_tweets.py.DISABLED (a Twitter API how-to,
  not an algorithm) and drop the tweepy dependency that was its only user and
  the last high-level dep pulling in requests
- uv.lock intentionally untouched (keeper allow-list)

Refs #15081

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
priya-sundaram-dev
2026-09-05 09:26:45 +02:00
committed by GitHub
co-authored by pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
parent 99b391db8d
commit bfa655ecea
40 changed files with 131 additions and 191 deletions
+3 -3
View File
@@ -11,12 +11,12 @@ Rating). We try to best fit a line through dataset and estimate the parameters.
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# "numpy",
# ]
# ///
import httpx
import httpx2
import numpy as np
@@ -25,7 +25,7 @@ def collect_dataset():
The dataset contains ADR vs Rating of a Player
:return : dataset obtained from the link, as matrix
"""
response = httpx.get(
response = httpx2.get(
"https://raw.githubusercontent.com/yashLadha/The_Math_of_Intelligence/"
"master/Week1/ADRvsRating.csv",
timeout=10,
+1 -1
View File
@@ -3,7 +3,7 @@ In a multi-threaded download, this algorithm could be used to provide
each worker thread with a block of non-overlapping bytes to download.
For example:
for i in allocation_list:
requests.get(url,headers={'Range':f'bytes={i}'})
httpx2.get(url, headers={"Range": f"bytes={i}"})
"""
from __future__ import annotations
+2 -3
View File
@@ -13,7 +13,7 @@ dependencies = [
"beautifulsoup4>=4.15",
"cython>=3.1.2",
"fake-useragent>=1.5.1",
"httpx>=0.28.1",
"httpx2>=2.0.1",
"imageio>=2.36.1",
"keras>=3.7",
"lxml>=6",
@@ -26,7 +26,6 @@ dependencies = [
"scipy>=1.18.1",
"statsmodels>=0.14.4",
"sympy>=1.13.3",
"tweepy>=4.14",
"typing-extensions>=4.12.2",
"xgboost>=2.1.3",
]
@@ -50,7 +49,7 @@ cv = [
"opencv-python>=4.10.0.84",
]
euler-validate = [
"httpx>=0.28.1",
"httpx2>=2.0.1",
"numpy>=2.1.3",
]
# qiskit does not yet run on free-threaded CPython: its compiled core re-enables
+3 -3
View File
@@ -3,7 +3,7 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# "pytest",
# ]
# ///
@@ -15,7 +15,7 @@ import os
import pathlib
from types import ModuleType
import httpx
import httpx2
import pytest
PROJECT_EULER_DIR_PATH = pathlib.Path.cwd().joinpath("project_euler")
@@ -66,7 +66,7 @@ def added_solution_file_path() -> list[pathlib.Path]:
"Accept": "application/vnd.github.v3+json",
"Authorization": "token " + os.environ["GITHUB_TOKEN"],
}
files = httpx.get(get_files_url(), headers=headers, timeout=10).json()
files = httpx2.get(get_files_url(), headers=headers, timeout=10).json()
for file in files:
filepath = pathlib.Path.cwd().joinpath(file["filename"])
if (
+4 -4
View File
@@ -5,26 +5,26 @@ Get CO2 emission data from the UK CarbonIntensity API
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
from datetime import date
import httpx
import httpx2
BASE_URL = "https://api.carbonintensity.org.uk/intensity"
# Emission in the last half hour
def fetch_last_half_hour() -> str:
last_half_hour = httpx.get(BASE_URL, timeout=10).json()["data"][0]
last_half_hour = httpx2.get(BASE_URL, timeout=10).json()["data"][0]
return last_half_hour["intensity"]["actual"]
# Emissions in a specific date range
def fetch_from_to(start, end) -> list:
return httpx.get(f"{BASE_URL}/{start}/{end}", timeout=10).json()["data"]
return httpx2.get(f"{BASE_URL}/{start}/{end}", timeout=10).json()["data"]
if __name__ == "__main__":
+5 -5
View File
@@ -8,14 +8,14 @@ Flask).
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# "lxml",
# ]
# ///
from typing import NamedTuple
import httpx
import httpx2
from lxml import html
@@ -33,14 +33,14 @@ def covid_stats(
) -> CovidData:
xpath_str = '//div[@class = "maincounter-number"]/span/text()'
try:
response = httpx.get(url, timeout=10).raise_for_status()
except httpx.TimeoutException:
response = httpx2.get(url, timeout=10).raise_for_status()
except httpx2.TimeoutException:
print(
"Request timed out. Please check your network connection "
"or try again later."
)
return CovidData("N/A", "N/A", "N/A")
except httpx.HTTPStatusError as e:
except httpx2.HTTPStatusError as e:
print(f"HTTP error occurred: {e}")
return CovidData("N/A", "N/A", "N/A")
data = html.fromstring(response.content).xpath(xpath_str)
+3 -3
View File
@@ -3,21 +3,21 @@
# dependencies = [
# "beautifulsoup4",
# "fake-useragent",
# "httpx",
# "httpx2",
# ]
# ///
import sys
import webbrowser
import httpx
import httpx2
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
if __name__ == "__main__":
print("Googling.....")
url = "https://www.google.com/search?q=" + " ".join(sys.argv[1:])
res = httpx.get(
res = httpx2.get(
url,
headers={"UserAgent": UserAgent().random},
timeout=10,
@@ -7,11 +7,11 @@ using title and year of publication, and volume and pages of journal.
# requires-python = ">=3.13"
# dependencies = [
# "beautifulsoup4",
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
from bs4 import BeautifulSoup
@@ -20,7 +20,7 @@ def get_citation(base_url: str, params: dict) -> str:
Return the citation number.
"""
soup = BeautifulSoup(
httpx.get(base_url, params=params, timeout=10).content, "html.parser"
httpx2.get(base_url, params=params, timeout=10).content, "html.parser"
)
div = soup.find("div", attrs={"class": "gs_ri"})
anchors = div.find("div", attrs={"class": "gs_fl"}).find_all("a")
+3 -3
View File
@@ -6,13 +6,13 @@ https://www.amdoren.com
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
import os
import httpx
import httpx2
URL_BASE = "https://www.amdoren.com/api/currency.php"
@@ -183,7 +183,7 @@ def convert_currency(
params = locals()
# from is a reserved keyword
params["from"] = params.pop("from_")
res = httpx.get(URL_BASE, params=params, timeout=10).json()
res = httpx2.get(URL_BASE, params=params, timeout=10).json()
return str(res["amount"]) if res["error"] == 0 else res["error_message"]
+3 -3
View File
@@ -2,11 +2,11 @@
# requires-python = ">=3.13"
# dependencies = [
# "beautifulsoup4",
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
from bs4 import BeautifulSoup
"""
@@ -28,7 +28,7 @@ def stock_price(symbol: str = "AAPL") -> str:
True
"""
url = f"https://finance.yahoo.com/quote/{symbol}?p={symbol}"
yahoo_finance_source = httpx.get(
yahoo_finance_source = httpx2.get(
url, headers={"USER-AGENT": "Mozilla/5.0"}, timeout=10, follow_redirects=True
).text
soup = BeautifulSoup(yahoo_finance_source, "html.parser")
+4 -4
View File
@@ -1,11 +1,11 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
# Put your API key(s) here
OPENWEATHERMAP_API_KEY = ""
@@ -26,13 +26,13 @@ def current_weather(location: str) -> list[dict]:
weather_data = []
if OPENWEATHERMAP_API_KEY:
params_openweathermap = {"q": location, "appid": OPENWEATHERMAP_API_KEY}
response_openweathermap = httpx.get(
response_openweathermap = httpx2.get(
OPENWEATHERMAP_URL_BASE, params=params_openweathermap, timeout=10
)
weather_data.append({"OpenWeatherMap": response_openweathermap.json()})
if WEATHERSTACK_API_KEY:
params_weatherstack = {"query": location, "access_key": WEATHERSTACK_API_KEY}
response_weatherstack = httpx.get(
response_weatherstack = httpx2.get(
WEATHERSTACK_URL_BASE, params=params_weatherstack, timeout=10
)
weather_data.append({"Weatherstack": response_weatherstack.json()})
+3 -3
View File
@@ -2,11 +2,11 @@
# requires-python = ">=3.13"
# dependencies = [
# "beautifulsoup4",
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
from bs4 import BeautifulSoup
@@ -15,7 +15,7 @@ def horoscope(zodiac_sign: int, day: str) -> str:
"https://www.horoscope.com/us/horoscopes/general/"
f"horoscope-general-daily-{day}.aspx?sign={zodiac_sign}"
)
soup = BeautifulSoup(httpx.get(url, timeout=10).content, "html.parser")
soup = BeautifulSoup(httpx2.get(url, timeout=10).content, "html.parser")
return soup.find("div", class_="main-horoscope").p.text
@@ -2,7 +2,7 @@
# requires-python = ">=3.13"
# dependencies = [
# "beautifulsoup4",
# "httpx",
# "httpx2",
# ]
# ///
@@ -12,7 +12,7 @@ import re
import sys
import urllib.request
import httpx
import httpx2
from bs4 import BeautifulSoup
headers = {
@@ -47,7 +47,7 @@ def download_images_from_google_query(query: str = "dhaka", max_images: int = 5)
"ijn": "0",
}
html = httpx.get(
html = httpx2.get(
"https://www.google.com/search", params=params, headers=headers, timeout=10
)
soup = BeautifulSoup(html.text, "html.parser")
+4 -4
View File
@@ -3,7 +3,7 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
@@ -20,7 +20,7 @@ import re
from html.parser import HTMLParser
from urllib import parse
import httpx
import httpx2
class Parser(HTMLParser):
@@ -79,7 +79,7 @@ def emails_from_url(url: str = "https://github.com") -> list[str]:
try:
# Open URL
r = httpx.get(url, timeout=10, follow_redirects=True)
r = httpx2.get(url, timeout=10, follow_redirects=True)
# pass the raw HTML to the parser to get links
parser.feed(r.text)
@@ -96,7 +96,7 @@ def emails_from_url(url: str = "https://github.com") -> list[str]:
else:
link = parse.urljoin(f"https://{domain}", link)
try:
read = httpx.get(link, timeout=10, follow_redirects=True)
read = httpx2.get(link, timeout=10, follow_redirects=True)
# Get the valid email.
emails = re.findall("[a-zA-Z0-9]+@" + domain, read.text)
# If not in list then append it.
+5 -5
View File
@@ -3,11 +3,11 @@
# dependencies = [
# "beautifulsoup4",
# "fake-useragent",
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
from bs4 import BeautifulSoup, NavigableString, Tag
from fake_useragent import UserAgent
@@ -36,7 +36,7 @@ def search_scraper(anime_name: str) -> list:
# concat the name to form the search url.
search_url = f"{BASE_URL}/search?keyword={anime_name}"
response = httpx.get(
response = httpx2.get(
search_url, headers={"UserAgent": UserAgent().chrome}, timeout=10
) # request the url.
@@ -91,7 +91,7 @@ def search_anime_episode_list(episode_endpoint: str) -> list:
request_url = f"{BASE_URL}{episode_endpoint}"
response = httpx.get(
response = httpx2.get(
url=request_url, headers={"UserAgent": UserAgent().chrome}, timeout=10
)
response.raise_for_status()
@@ -142,7 +142,7 @@ def get_anime_episode(episode_endpoint: str) -> list:
episode_page_url = f"{BASE_URL}{episode_endpoint}"
response = httpx.get(
response = httpx2.get(
url=episode_page_url, headers={"User-Agent": UserAgent().chrome}, timeout=10
)
response.raise_for_status()
+3 -3
View File
@@ -3,18 +3,18 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
_NEWS_API = "https://newsapi.org/v1/articles?source=bbc-news&sortBy=top&apiKey="
def fetch_bbc_news(bbc_news_api_key: str) -> None:
# fetching a list of articles in json format
bbc_news_page = httpx.get(_NEWS_API + bbc_news_api_key, timeout=10).json()
bbc_news_page = httpx2.get(_NEWS_API + bbc_news_api_key, timeout=10).json()
# each article in the list is a dict
for i, article in enumerate(bbc_news_page["articles"], 1):
print(f"{i}.) {article['title']}")
+4 -4
View File
@@ -21,7 +21,7 @@ export USER_TOKEN=""
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
@@ -30,7 +30,7 @@ from __future__ import annotations
import os
from typing import Any
import httpx
import httpx2
BASE_URL = "https://api.github.com"
@@ -43,13 +43,13 @@ USER_TOKEN = os.environ.get("USER_TOKEN", "")
def fetch_github_info(auth_token: str) -> dict[Any, Any]:
"""
Fetch GitHub info of a user using the httpx module
Fetch GitHub info of a user using the httpx2 module
"""
headers = {
"Authorization": f"token {auth_token}",
"Accept": "application/vnd.github.v3+json",
}
return httpx.get(AUTHENTICATED_USER_ENDPOINT, headers=headers, timeout=10).json()
return httpx2.get(AUTHENTICATED_USER_ENDPOINT, headers=headers, timeout=10).json()
if __name__ == "__main__": # pragma: no cover
+3 -3
View File
@@ -6,7 +6,7 @@ Scraping jobs given job title and location from indeed website
# requires-python = ">=3.13"
# dependencies = [
# "beautifulsoup4",
# "httpx",
# "httpx2",
# ]
# ///
@@ -14,14 +14,14 @@ from __future__ import annotations
from collections.abc import Generator
import httpx
import httpx2
from bs4 import BeautifulSoup
url = "https://www.indeed.co.in/jobs?q=mobile+app+development&l="
def fetch_jobs(location: str = "mumbai") -> Generator[tuple[str, str]]:
soup = BeautifulSoup(httpx.get(url + location, timeout=10).content, "html.parser")
soup = BeautifulSoup(httpx2.get(url + location, timeout=10).content, "html.parser")
# This attribute finds out all the specifics listed in a job
for job in soup.find_all("div", attrs={"data-tn-component": "organicJob"}):
job_title = job.find("a", attrs={"data-tn-element": "jobTitle"}).text.strip()
+4 -4
View File
@@ -9,23 +9,23 @@ For more details and premium features visit:
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
import pprint
import httpx
import httpx2
API_ENDPOINT_URL = "https://zenquotes.io/api"
def quote_of_the_day() -> list:
return httpx.get(API_ENDPOINT_URL + "/today", timeout=10).json()
return httpx2.get(API_ENDPOINT_URL + "/today", timeout=10).json()
def random_quotes() -> list:
return httpx.get(API_ENDPOINT_URL + "/random", timeout=10).json()
return httpx2.get(API_ENDPOINT_URL + "/random", timeout=10).json()
if __name__ == "__main__":
+3 -3
View File
@@ -5,7 +5,7 @@ after providing the drug name and zipcode.
"""
import httpx
import httpx2
from bs4 import BeautifulSoup
BASE_URL = "https://www.wellrx.com/prescriptions/{}/{}/?freshSearch=true"
@@ -40,7 +40,7 @@ def fetch_pharmacy_and_price_list(drug_name: str, zip_code: str) -> list | None:
return None
request_url = BASE_URL.format(drug_name, zip_code)
response = httpx.get(request_url, timeout=10).raise_for_status()
response = httpx2.get(request_url, timeout=10).raise_for_status()
# Scrape the data using bs4
soup = BeautifulSoup(response.text, "html.parser")
@@ -67,7 +67,7 @@ def fetch_pharmacy_and_price_list(drug_name: str, zip_code: str) -> list | None:
return pharmacy_price_list
except httpx.HTTPError, ValueError:
except httpx2.HTTPError, ValueError:
return None
+3 -3
View File
@@ -8,14 +8,14 @@ information will include title, URL, price, ratings, and the discount available.
# requires-python = ">=3.13"
# dependencies = [
# "beautifulsoup4",
# "httpx",
# "httpx2",
# "pandas",
# ]
# ///
from itertools import zip_longest
import httpx
import httpx2
from bs4 import BeautifulSoup
from pandas import DataFrame
@@ -34,7 +34,7 @@ def get_amazon_product_data(product: str = "laptop") -> DataFrame:
"Accept-Language": "en-US, en;q=0.5",
}
soup = BeautifulSoup(
httpx.get(url, headers=header, timeout=10).text, features="lxml"
httpx2.get(url, headers=header, timeout=10).text, features="lxml"
)
# Initialize a Pandas dataframe with the column titles
data_frame = DataFrame(
@@ -2,7 +2,7 @@
# requires-python = ">=3.13"
# dependencies = [
# "beautifulsoup4",
# "httpx",
# "httpx2",
# ]
# ///
@@ -10,13 +10,13 @@ from __future__ import annotations
import csv
import httpx
import httpx2
from bs4 import BeautifulSoup
def get_imdb_top_250_movies(url: str = "") -> dict[str, float]:
url = url or "https://www.imdb.com/chart/top/?ref_=nv_mv_250"
soup = BeautifulSoup(httpx.get(url, timeout=10).text, "html.parser")
soup = BeautifulSoup(httpx2.get(url, timeout=10).text, "html.parser")
titles = soup.find_all("h3", class_="ipc-title__text")
ratings = soup.find_all("span", class_="ipc-rating-star--rating")
return {
+2 -2
View File
@@ -1,5 +1,5 @@
import bs4
import requests
import httpx2
def get_movie_data_from_soup(soup: bs4.element.ResultSet) -> dict[str, str]:
@@ -35,7 +35,7 @@ def get_imdb_top_movies(num_movies: int = 5) -> tuple:
"https://www.imdb.com/search/title?title_type="
f"feature&sort=num_votes,desc&count={num_movies}"
)
source = bs4.BeautifulSoup(requests.get(base_url).content, "html.parser")
source = bs4.BeautifulSoup(httpx2.get(base_url).content, "html.parser")
return tuple(
get_movie_data_from_soup(movie)
for movie in source.find_all("div", class_="lister-item mode-advanced")
+4 -4
View File
@@ -1,11 +1,11 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
# Function to get geolocation data for an IP address
@@ -15,7 +15,7 @@ def get_ip_geolocation(ip_address: str) -> str:
url = f"https://ipinfo.io/{ip_address}/json"
# Send a GET request to the API
response = httpx.get(url, timeout=10)
response = httpx2.get(url, timeout=10)
# Check if the HTTP request was successful
response.raise_for_status()
@@ -30,7 +30,7 @@ def get_ip_geolocation(ip_address: str) -> str:
location = "Location data not found."
return location
except httpx.RequestError as e:
except httpx2.RequestError as e:
# Handle network-related exceptions
return f"Request error: {e}"
except ValueError as e:
+3 -3
View File
@@ -6,14 +6,14 @@ This works for some of us but fails for others.
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# "rich",
# ]
# ///
from datetime import UTC, date, datetime
import httpx
import httpx2
from rich import box
from rich import console as rich_console
from rich import table as rich_table
@@ -65,7 +65,7 @@ def get_forbes_real_time_billionaires() -> list[dict[str, int | str]]:
Returns:
List of top 10 realtime billionaires data.
"""
response_json = httpx.get(API_URL, timeout=10).json()
response_json = httpx2.get(API_URL, timeout=10).json()
return [
{
"Name": person["personName"],
+4 -4
View File
@@ -1,18 +1,18 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
from __future__ import annotations
import httpx
import httpx2
def get_hackernews_story(story_id: str) -> dict:
url = f"https://hacker-news.firebaseio.com/v0/item/{story_id}.json?print=pretty"
return httpx.get(url, timeout=10).json()
return httpx2.get(url, timeout=10).json()
def hackernews_top_stories(max_stories: int = 10) -> list[dict]:
@@ -20,7 +20,7 @@ def hackernews_top_stories(max_stories: int = 10) -> list[dict]:
Get the top max_stories posts from HackerNews - https://news.ycombinator.com/
"""
url = "https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty"
story_ids = httpx.get(url, timeout=10).json()[:max_stories]
story_ids = httpx2.get(url, timeout=10).json()[:max_stories]
return [get_hackernews_story(story_id) for story_id in story_ids]
@@ -1,59 +0,0 @@
import csv
import tweepy
# Twitter API credentials
consumer_key = ""
consumer_secret = ""
access_key = ""
access_secret = ""
def get_all_tweets(screen_name: str) -> None:
# authorize twitter, initialize tweepy
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth)
# initialize a list to hold all the tweepy Tweets
alltweets = []
# make initial request for most recent tweets (200 is the maximum allowed count)
new_tweets = api.user_timeline(screen_name=screen_name, count=200)
# save most recent tweets
alltweets.extend(new_tweets)
# save the id of the oldest tweet less one
oldest = alltweets[-1].id - 1
# keep grabbing tweets until there are no tweets left to grab
while len(new_tweets) > 0:
print(f"getting tweets before {oldest}")
# all subsequent requests use the max_id param to prevent duplicates
new_tweets = api.user_timeline(
screen_name=screen_name, count=200, max_id=oldest
)
# save most recent tweets
alltweets.extend(new_tweets)
# update the id of the oldest tweet less one
oldest = alltweets[-1].id - 1
print(f"...{len(alltweets)} tweets downloaded so far")
# transform the tweepy tweets into a 2D array that will populate the csv
outtweets = [[tweet.id_str, tweet.created_at, tweet.text] for tweet in alltweets]
# write the csv
with open(f"new_{screen_name}_tweets.csv", "w") as f:
writer = csv.writer(f)
writer.writerow(["id", "created_at", "text"])
writer.writerows(outtweets)
if __name__ == "__main__":
# pass in the username of the account you want to download
get_all_tweets("FirePing32")
+3 -3
View File
@@ -3,11 +3,11 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
giphy_api_key = "YOUR API KEY"
# Can be fetched from https://developers.giphy.com/dashboard/
@@ -19,7 +19,7 @@ def get_gifs(query: str, api_key: str = giphy_api_key) -> list:
"""
formatted_query = "+".join(query.split())
url = f"https://api.giphy.com/v1/gifs/search?q={formatted_query}&api_key={api_key}"
gifs = httpx.get(url, timeout=10).json()["data"]
gifs = httpx2.get(url, timeout=10).json()["data"]
return [gif["url"] for gif in gifs]
+3 -3
View File
@@ -5,7 +5,7 @@
# dependencies = [
# "beautifulsoup4",
# "fake-useragent",
# "httpx",
# "httpx2",
# ]
# ///
@@ -13,7 +13,7 @@ from __future__ import annotations
import json
import httpx
import httpx2
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
@@ -49,7 +49,7 @@ class InstagramUser:
"""
Return a dict of user information
"""
html = httpx.get(self.url, headers=headers, timeout=10).text
html = httpx2.get(self.url, headers=headers, timeout=10).text
scripts = BeautifulSoup(html, "html.parser").find_all("script")
try:
return extract_user_profile(scripts[4])
+6 -6
View File
@@ -2,13 +2,13 @@
# requires-python = ">=3.13"
# dependencies = [
# "beautifulsoup4",
# "httpx",
# "httpx2",
# ]
# ///
from datetime import UTC, datetime
import httpx
import httpx2
from bs4 import BeautifulSoup
@@ -23,9 +23,9 @@ def download_image(url: str) -> str:
A message indicating the result of the operation.
"""
try:
response = httpx.get(url, timeout=10)
response = httpx2.get(url, timeout=10)
response.raise_for_status()
except httpx.RequestError as e:
except httpx2.RequestError as e:
return f"An error occurred during the HTTP request to {url}: {e!r}"
soup = BeautifulSoup(response.text, "html.parser")
@@ -38,8 +38,8 @@ def download_image(url: str) -> str:
return f"Image URL not found in meta tag {image_meta_tag}."
try:
image_data = httpx.get(image_url, timeout=10).content
except httpx.RequestError as e:
image_data = httpx2.get(image_url, timeout=10).content
except httpx2.RequestError as e:
return f"An error occurred during the HTTP request to {image_url}: {e!r}"
if not image_data:
return f"Failed to download the image from {image_url}."
+4 -4
View File
@@ -1,19 +1,19 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
from datetime import UTC, datetime
import httpx
import httpx2
def download_video(url: str) -> bytes:
base_url = "https://downloadgram.net/wp-json/wppress/video-downloader/video?url="
video_url = httpx.get(base_url + url, timeout=10)
return httpx.get(video_url, timeout=10).content
video_url = httpx2.get(base_url + url, timeout=10)
return httpx2.get(video_url, timeout=10).content
if __name__ == "__main__":
+5 -5
View File
@@ -1,11 +1,11 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
def get_apod_data(api_key: str) -> dict:
@@ -14,14 +14,14 @@ def get_apod_data(api_key: str) -> dict:
Get your API Key from: https://api.nasa.gov/
"""
url = "https://api.nasa.gov/planetary/apod"
return httpx.get(url, params={"api_key": api_key}, timeout=10).json()
return httpx2.get(url, params={"api_key": api_key}, timeout=10).json()
def save_apod(api_key: str, path: str = ".") -> dict:
apod_data = get_apod_data(api_key)
img_url = apod_data["url"]
img_name = img_url.split("/")[-1]
response = httpx.get(img_url, timeout=10)
response = httpx2.get(img_url, timeout=10)
with open(f"{path}/{img_name}", "wb+") as img_file:
img_file.write(response.content)
@@ -34,7 +34,7 @@ def get_archive_data(query: str) -> dict:
Get the data of a particular query from NASA archives
"""
url = "https://images-api.nasa.gov/search"
return httpx.get(url, params={"q": query}, timeout=10).json()
return httpx2.get(url, params={"q": query}, timeout=10).json()
if __name__ == "__main__":
+3 -3
View File
@@ -3,7 +3,7 @@
# dependencies = [
# "beautifulsoup4",
# "fake-useragent",
# "httpx",
# "httpx2",
# ]
# ///
@@ -11,7 +11,7 @@ import webbrowser
from sys import argv
from urllib.parse import parse_qs, quote
import httpx
import httpx2
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
@@ -22,7 +22,7 @@ if __name__ == "__main__":
url = f"https://www.google.com/search?q={query}&num=100"
res = httpx.get(
res = httpx2.get(
url,
headers={"User-Agent": str(UserAgent().random)},
timeout=10,
+4 -4
View File
@@ -3,13 +3,13 @@
# dependencies = [
# "beautifulsoup4",
# "fake-useragent",
# "httpx",
# "httpx2",
# ]
# ///
import os
import httpx
import httpx2
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
@@ -21,7 +21,7 @@ def save_image(image_url: str, image_title: str) -> None:
"""
Saves the image of anime character
"""
image = httpx.get(image_url, headers=headers, timeout=10)
image = httpx2.get(image_url, headers=headers, timeout=10)
with open(image_title, "wb") as file:
file.write(image.content)
@@ -31,7 +31,7 @@ def random_anime_character() -> tuple[str, str, str]:
Returns the Title, Description, and Image Title of a random anime character .
"""
soup = BeautifulSoup(
httpx.get(URL, headers=headers, timeout=10).text, "html.parser"
httpx2.get(URL, headers=headers, timeout=10).text, "html.parser"
)
title = soup.find("meta", attrs={"property": "og:title"}).attrs["content"]
image_url = soup.find("meta", attrs={"property": "og:image"}).attrs["content"]
+3 -3
View File
@@ -35,11 +35,11 @@ recaptcha verification.
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
try:
from django.contrib.auth import authenticate, login
@@ -63,7 +63,7 @@ def login_using_recaptcha(request):
client_key = request.POST.get("g-recaptcha-response")
# post recaptcha response to Google's recaptcha api
response = httpx.post(
response = httpx2.post(
url, data={"secret": secret_key, "response": client_key}, timeout=10
)
# if the recaptcha api verified our keys
+4 -4
View File
@@ -1,13 +1,13 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
from typing import Literal
import httpx
import httpx2
valid_terms = set(
"""approved_at_utc approved_by author_flair_background_color
@@ -38,10 +38,10 @@ def get_subreddit_data(
if invalid_search_terms := ", ".join(sorted(set(wanted_data) - valid_terms)):
msg = f"Invalid search term: {invalid_search_terms}"
raise ValueError(msg)
# raise_for_status() already raises httpx.HTTPStatusError for any 4xx/5xx
# raise_for_status() already raises httpx2.HTTPStatusError for any 4xx/5xx
# response (including 429), so no extra status check is needed here.
data = (
httpx.get(
httpx2.get(
f"https://www.reddit.com/r/{subreddit}/{age}.json?limit={limit}",
headers={"User-agent": "A random string"},
timeout=10,
+3 -3
View File
@@ -7,13 +7,13 @@ ISBN: https://en.wikipedia.org/wiki/International_Standard_Book_Number
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
from json import JSONDecodeError
import httpx
import httpx2
def get_openlibrary_data(olid: str = "isbn/0140328726") -> dict:
@@ -32,7 +32,7 @@ def get_openlibrary_data(olid: str = "isbn/0140328726") -> dict:
if new_olid.count("/") != 1:
msg = f"{olid} is not a valid Open Library olid"
raise ValueError(msg)
return httpx.get(
return httpx2.get(
f"https://openlibrary.org/{new_olid}.json", timeout=10, follow_redirects=True
).json()
+3 -3
View File
@@ -3,16 +3,16 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
def send_slack_message(message_body: str, slack_url: str) -> None:
headers = {"Content-Type": "application/json"}
response = httpx.post(
response = httpx2.post(
slack_url, json={"text": message_body}, headers=headers, timeout=10
)
if response.status_code != 200:
+2 -2
View File
@@ -1,6 +1,6 @@
import json
import httpx
import httpx2
from .fetch_github_info import AUTHENTICATED_USER_ENDPOINT, fetch_github_info
@@ -21,7 +21,7 @@ def test_fetch_github_info(monkeypatch):
assert "Accept" in kwargs["headers"]
return FakeResponse(b'{"login":"test","id":1}')
monkeypatch.setattr(httpx, "get", mock_response)
monkeypatch.setattr(httpx2, "get", mock_response)
result = fetch_github_info("token")
assert result["login"] == "test"
assert result["id"] == 1
+3 -3
View File
@@ -9,11 +9,11 @@ This data is being scrapped from 'https://www.worldometers.info/coronavirus/'.
# requires-python = ">=3.13"
# dependencies = [
# "beautifulsoup4",
# "httpx",
# "httpx2",
# ]
# ///
import httpx
import httpx2
from bs4 import BeautifulSoup
@@ -24,7 +24,7 @@ def world_covid19_stats(
Return a dict of current worldwide COVID-19 statistics
"""
soup = BeautifulSoup(
httpx.get(url, timeout=10, follow_redirects=True).text, "html.parser"
httpx2.get(url, timeout=10, follow_redirects=True).text, "html.parser"
)
keys = soup.find_all("h1")
values = soup.find_all("div", {"class": "maincounter-number"})