Skip to content

Commit

Permalink
Switch to HTTPX
Browse files Browse the repository at this point in the history
Signed-off-by: GitHub <[email protected]>
  • Loading branch information
shenanigansd authored Aug 1, 2023
1 parent d256ec5 commit 6bc8f17
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 46 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,25 @@ A wrapper for [PyPI's API and RSS feeds](https://warehouse.pypa.io/api-reference
### Sync client

```py
from requests import Session
from httpx import Client
from letsbuilda.pypi import PyPIServices

http_session = Session()
pypi_client = PyPIServices(http_session)
http_client = Client()
pypi_client = PyPIServices(http_client)

package_metadata = pypi_client.get_package_metadata("letsbuilda-pypi")
print(pypi_client.get_rss_feed(pypi_client.NEWEST_PACKAGES_FEED_URL))
print(pypi_client.get_package_metadata("letsbuilda-pypi"))
```

### Async client

```py
from aiohttp import ClientSession
from letsbuilda.pypi.clients.async_client import PyPIServices
from httpx import AsyncClient
from letsbuilda.pypi.async_client import PyPIServices

http_session = aiohttp.ClientSession()
http_client = AsyncClient()
pypi_client = PyPIServices(http_session)

package_metadata = await pypi_client.get_package_metadata("letsbuilda-pypi")
print(await pypi_client.get_rss_feed(pypi_client.NEWEST_PACKAGES_FEED_URL))
print(await pypi_client.get_package_metadata("letsbuilda-pypi"))
```
14 changes: 2 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "letsbuilda-pypi"
version = "5.0.0b3"
version = "5.0.0"
description = "A wrapper for PyPI's API and RSS feed"
authors = [
{ name = "Bradley Reynolds", email = "[email protected]" },
Expand All @@ -9,7 +9,7 @@ license = { text = "MIT" }
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"requests",
"httpx",
"xmltodict",
]

Expand All @@ -18,29 +18,19 @@ repository = "https://github.com/letsbuilda/letsbuilda-pypi/"
documentation = "https://docs.letsbuilda.dev/letsbuilda-pypi/"

[project.optional-dependencies]
async = [
"aiohttp",
]
dev = [
"pre-commit",
"black",
"ruff",
]
tests = [
"pytest",

# from async extra
"aiohttp",
]
docs = [
"sphinx",
"furo",
"sphinx-autoapi",
"releases",
"toml",

# from async extra
"aiohttp",
]

[build-system]
Expand Down
32 changes: 11 additions & 21 deletions src/letsbuilda/pypi/async_client.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
"""The async client."""

from http import HTTPStatus
from typing import Final
from typing import Final, Self

import xmltodict

try:
pass
except ImportError as error:
msg = "Please install letsbuilda[async] for async support!"
raise ImportError(msg) from error

from typing import Self

from aiohttp import ClientSession
from httpx import AsyncClient

from .exceptions import PackageNotFoundError
from .models import JSONPackageMetadata, Package, RSSPackageMetadata
Expand All @@ -25,15 +16,14 @@ class PyPIServices:
NEWEST_PACKAGES_FEED_URL: Final[str] = "https://pypi.org/rss/packages.xml"
PACKAGE_UPDATES_FEED_URL: Final[str] = "https://pypi.org/rss/updates.xml"

def __init__(self: Self, http_session: ClientSession) -> None:
self.http_session = http_session
def __init__(self: Self, http_client: AsyncClient) -> None:
self.http_client = http_client

async def get_rss_feed(self: Self, feed_url: str) -> list[RSSPackageMetadata]:
"""Get the new packages RSS feed."""
async with self.http_session.get(feed_url) as response:
response_text = await response.text()
rss_data = xmltodict.parse(response_text)["rss"]["channel"]["item"]
return [RSSPackageMetadata.build_from(package_data) for package_data in rss_data]
response = await self.http_client.get(feed_url)
rss_data = xmltodict.parse(response.text)["rss"]["channel"]["item"]
return [RSSPackageMetadata.build_from(package_data) for package_data in rss_data]

async def get_package_json_metadata(
self: Self,
Expand All @@ -45,10 +35,10 @@ async def get_package_json_metadata(
url = f"https://pypi.org/pypi/{package_title}/{package_version}/json"
else:
url = f"https://pypi.org/pypi/{package_title}/json"
async with self.http_session.get(url) as response:
if response.status == HTTPStatus.NOT_FOUND:
raise PackageNotFoundError(package_title, package_version)
return JSONPackageMetadata.from_dict(await response.json())
response = await self.http_client.get(url)
if response.status_code == HTTPStatus.NOT_FOUND:
raise PackageNotFoundError(package_title, package_version)
return JSONPackageMetadata.from_dict(response.json())

async def get_package_metadata(
self: Self,
Expand Down
10 changes: 5 additions & 5 deletions src/letsbuilda/pypi/sync_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import Final, Self

import xmltodict
from requests import Session
from httpx import Client

from .exceptions import PackageNotFoundError
from .models import JSONPackageMetadata, Package, RSSPackageMetadata
Expand All @@ -16,12 +16,12 @@ class PyPIServices:
NEWEST_PACKAGES_FEED_URL: Final[str] = "https://pypi.org/rss/packages.xml"
PACKAGE_UPDATES_FEED_URL: Final[str] = "https://pypi.org/rss/updates.xml"

def __init__(self: Self, http_session: Session) -> None:
self.http_session = http_session
def __init__(self: Self, http_client: Client) -> None:
self.http_client = http_client

def get_rss_feed(self: Self, feed_url: str) -> list[RSSPackageMetadata]:
"""Get the new packages RSS feed."""
response_text = self.http_session.get(feed_url).text
response_text = self.http_client.get(feed_url).text
rss_data = xmltodict.parse(response_text)["rss"]["channel"]["item"]
return [RSSPackageMetadata.build_from(package_data) for package_data in rss_data]

Expand All @@ -35,7 +35,7 @@ def get_package_json_metadata(
url = f"https://pypi.org/pypi/{package_title}/{package_version}/json"
else:
url = f"https://pypi.org/pypi/{package_title}/json"
response = self.http_session.get(url)
response = self.http_client.get(url)
if response.status_code == HTTPStatus.NOT_FOUND:
raise PackageNotFoundError(package_title, package_version)
return JSONPackageMetadata.from_dict(response.json())
Expand Down

0 comments on commit 6bc8f17

Please sign in to comment.