Skip to content

Commit

Permalink
Merge pull request #4 from Bot-detector/structural-changes
Browse files Browse the repository at this point in the history
Structural changes
  • Loading branch information
extreme4all authored Nov 5, 2024
2 parents fe84907 + 1268c5b commit f2bb080
Show file tree
Hide file tree
Showing 16 changed files with 175 additions and 57 deletions.
51 changes: 39 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import asyncio

from aiohttp import ClientSession

from osrs.async_api.osrs.hiscores import Mode, PlayerStats, Hiscore, RateLimiter
from osrs.asyncio import Hiscore, HSMode
from osrs.utils import RateLimiter
from osrs.exceptions import PlayerDoesNotExist


Expand All @@ -18,21 +19,31 @@ async def main():

async with ClientSession() as session:
player_stats = await hiscore_instance.get(
mode=Mode.OLDSCHOOL,
mode=HSMode.OLDSCHOOL,
player="extreme4all",
session=session,
)
print(player_stats)

# if you do not provide a session we'll make one for you, this session will not be reused
# for multiple requests we advice doing that within one session like the example above
player_stats = await hiscore_instance.get(
mode=HSMode.OLDSCHOOL,
player="extreme4all",
)
print(player_stats)
# Run the asynchronous main function
if __name__ == "__main__":
asyncio.run(main())
```
## osrs itemdb (Catalogue & Grand Exchange)
```py
import asyncio

from aiohttp import ClientSession
from osrs.async_api.osrs.itemdb import Mode, Catalogue, Graph, RateLimiter

from osrs.asyncio import ItemDBMode, Catalogue, Graph
from osrs.utils import RateLimiter

async def main():
# Initialize the Catalogue with optional proxy and rate limiter
Expand All @@ -49,7 +60,7 @@ async def main():
session,
alpha=alpha,
page=page,
mode=Mode.OLDSCHOOL,
mode=ItemDBMode.OLDSCHOOL,
category=category
)
print("Fetched Items:", items)
Expand All @@ -59,7 +70,7 @@ async def main():
item_detail = await catalogue_instance.get_detail(
session,
item_id=item_id,
mode=Mode.OLDSCHOOL
mode=ItemDBMode.OLDSCHOOL
)
print("Item Detail:", item_detail)

Expand All @@ -68,7 +79,7 @@ async def main():
trade_history = await graph_instance.get_graph(
session,
item_id=item_id,
mode=Mode.OLDSCHOOL
mode=ItemDBMode.OLDSCHOOL
)
print("Trade History:", trade_history)

Expand All @@ -80,28 +91,44 @@ if __name__ == "__main__":
the wiki via runelite collects item price, which they expose via an api.
```py
import asyncio

from aiohttp import ClientSession
from osrs.async_api.wiki.prices import WikiPrices, AveragePrices, LatestPrices, TimeSeries, ItemMapping

from osrs.asyncio import WikiPrices, Interval
from osrs.utils import RateLimiter

async def main():
wiki_prices_instance = WikiPrices(user_agent="Your User Agent")
limiter = RateLimiter(calls_per_interval=100, interval=60)
prices_instance = WikiPrices(user_agent="Your User Agent", rate_limiter=limiter)

async with ClientSession() as session:
# Fetch item mappings
mappings = await wiki_prices_instance.get_mapping(session=session)
mappings = await prices_instance.get_mapping(
session=session
)
print("Item Mappings:", mappings)

# Fetch latest prices
latest_prices = await wiki_prices_instance.get_latest_prices(session=session)
latest_prices = await prices_instance.get_latest_prices(
session=session
)
print("Latest Prices:", latest_prices)

# Fetch average prices
average_prices = await wiki_prices_instance.get_average_prices(session=session, interval=Interval.FIVE_MIN)
average_prices = await prices_instance.get_average_prices(
session=session,
interval=Interval.FIVE_MIN
)

print("Average Prices:", average_prices)

# Fetch time series data
item_id = 4151 # Example item ID (Abyssal whip in OSRS)
time_series = await wiki_prices_instance.get_time_series(session=session, item_id=item_id, timestep=Interval.ONE_HOUR)
time_series = await prices_instance.get_time_series(
session=session,
item_id=item_id,
timestep=Interval.ONE_HOUR
)
print("Time Series Data:", time_series)

# Run the asynchronous main function
Expand Down
4 changes: 0 additions & 4 deletions osrs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +0,0 @@
from osrs.async_api.osrs.hiscores import Hiscore
from osrs.utils import RateLimiter

__all__ = ["Hiscore", "RateLimiter"]
4 changes: 0 additions & 4 deletions osrs/async_api/osrs/__init__.py

This file was deleted.

23 changes: 23 additions & 0 deletions osrs/asyncio/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from osrs.asyncio.osrs.hiscores import Hiscore
from osrs.asyncio.osrs.hiscores import Mode as HSMode
from osrs.asyncio.osrs.itemdb import Catalogue, Graph
from osrs.asyncio.osrs.itemdb import Mode as ItemDBMode
from osrs.asyncio.wiki.prices import (
Interval,
WikiPrices,
)

__all__ = ["WikiPrices", "AveragePrices", "LatestPrices", "TimeSeries", "ItemMapping"]

__all__ = [
# osrs.hiscore
"Hiscore",
"HSMode",
# osrs.itemdb
"Catalogue",
"ItemDBMode",
"Graph",
# wiki
"Interval",
"WikiPrices",
]
4 changes: 4 additions & 0 deletions osrs/asyncio/osrs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from osrs.asyncio.osrs.hiscores import Hiscore
from osrs.asyncio.osrs.itemdb import Catalogue, Graph

__all__ = ["Hiscore", "Catalogue", "Graph"]
17 changes: 14 additions & 3 deletions osrs/async_api/osrs/hiscores.py → osrs/asyncio/osrs/hiscores.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ def __init__(
self.proxy = proxy
self.rate_limiter = rate_limiter

async def get(self, mode: Mode, player: str, session: ClientSession) -> PlayerStats:
async def get(
self,
player: str,
mode: Mode = Mode.OLDSCHOOL,
session: ClientSession | None = None,
) -> PlayerStats:
"""
Fetches player stats from the OSRS hiscores API.
Expand All @@ -73,7 +78,9 @@ async def get(self, mode: Mode, player: str, session: ClientSession) -> PlayerSt
url = f"{self.BASE_URL}/m={mode.value}/index_lite.json"
params = {"player": player}

async with session.get(url, proxy=self.proxy, params=params) as response:
_session = ClientSession() if session is None else session

async with _session.get(url, proxy=self.proxy, params=params) as response:
# when the HS are down it will redirect to the main page.
# after redirction it will return a 200, so we must check for redirection first
if response.history and any(r.status == 302 for r in response.history):
Expand All @@ -88,4 +95,8 @@ async def get(self, mode: Mode, player: str, session: ClientSession) -> PlayerSt
response.raise_for_status()
raise Undefined()
data = await response.json()
return PlayerStats(**data)

if session is None:
await _session.close()

return PlayerStats(**data)
39 changes: 29 additions & 10 deletions osrs/async_api/osrs/itemdb.py → osrs/asyncio/osrs/itemdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ def __init__(

async def get_items(
self,
session: ClientSession,
alpha: str,
page: int | None = 1,
mode: Mode = Mode.OLDSCHOOL,
session: ClientSession | None = None,
category: int = 1,
) -> Items:
"""Fetch items from the RuneScape item catalog based on alphabetical filter.
Expand All @@ -124,16 +124,22 @@ async def get_items(

logger.debug(f"[GET]: {url=}, {params=}")

async with session.get(url, proxy=self.proxy, params=params) as response:
_session = ClientSession() if session is None else session

async with _session.get(url, proxy=self.proxy, params=params) as response:
response.raise_for_status()
data = await response.text()
return Items(**json.loads(data))

if session is None:
await _session.close()

return Items(**json.loads(data))

async def get_detail(
self,
session: ClientSession,
item_id: int,
mode: Mode = Mode.OLDSCHOOL,
session: ClientSession | None = None,
) -> Detail:
"""Fetch detailed information about a specific item.
Expand All @@ -152,17 +158,24 @@ async def get_detail(

logger.debug(f"[GET]: {url=}, {params=}")

async with session.get(url, proxy=self.proxy, params=params) as response:
_session = ClientSession() if session is None else session

async with _session.get(url, proxy=self.proxy, params=params) as response:
response.raise_for_status()
data = await response.text()
return Detail(**json.loads(data))

if session is None:
await _session.close()
return Detail(**json.loads(data))


class Graph:
BASE_URL = "https://secure.runescape.com"

def __init__(
self, proxy: str = "", rate_limiter: RateLimiter = RateLimiter()
self,
proxy: str = "",
rate_limiter: RateLimiter = RateLimiter(),
) -> None:
"""Initialize the Catalogue with an optional proxy and rate limiter.
Expand All @@ -176,9 +189,9 @@ def __init__(

async def get_graph(
self,
session: ClientSession,
item_id: int,
mode: Mode = Mode.OLDSCHOOL,
session: ClientSession | None = None,
) -> TradeHistory:
"""Fetch trade history graph data for a specific item.
Expand All @@ -196,7 +209,13 @@ async def get_graph(

logger.debug(f"[GET]: {url=}")

async with session.get(url, proxy=self.proxy) as response:
_session = ClientSession() if session is None else session

async with _session.get(url, proxy=self.proxy) as response:
response.raise_for_status()
data = await response.text()
return TradeHistory(**json.loads(data))

if session is None:
await _session.close()

return TradeHistory(**json.loads(data))
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from osrs.async_api.wiki.prices import (
from osrs.asyncio.wiki.prices import (
AveragePrices,
ItemMapping,
LatestPrices,
Expand Down
28 changes: 21 additions & 7 deletions osrs/async_api/wiki/prices.py → osrs/asyncio/wiki/prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,12 @@ def __init__(
raise Exception("invalid input")
self.user_agent = inp

async def fetch_data(self, session: ClientSession, url: str, params: dict = {}):
async def fetch_data(
self,
url: str,
session: ClientSession | None = None,
params: dict = {},
):
"""
Utility method to fetch data from a specific endpoint, with ratelimiter,
and basic error handling
Expand All @@ -109,16 +114,23 @@ async def fetch_data(self, session: ClientSession, url: str, params: dict = {}):
"""
await self.rate_limiter.check()

async with session.get(url, proxy=self.proxy, params=params) as response:
_session = ClientSession() if session is None else session

async with _session.get(url, proxy=self.proxy, params=params) as response:
if response.status == 400:
error = await response.json()
raise Exception(error)
elif response.status != 200:
response.raise_for_status()
raise Undefined("Unexpected error.")
return await response.json()
data = await response.json()

if session is None:
await _session.close()

return data

async def get_mapping(self, session: ClientSession):
async def get_mapping(self, session: ClientSession | None = None):
"""
Fetches item mappings containing metadata.
Expand All @@ -138,7 +150,9 @@ async def get_mapping(self, session: ClientSession):
data = await self.fetch_data(session=session, url=url)
return [ItemMapping(**item) for item in data]

async def get_latest_prices(self, session: ClientSession) -> LatestPrices:
async def get_latest_prices(
self, session: ClientSession | None = None
) -> LatestPrices:
"""
Fetches the latest prices for all items.
Expand All @@ -160,8 +174,8 @@ async def get_latest_prices(self, session: ClientSession) -> LatestPrices:

async def get_average_prices(
self,
session: ClientSession,
interval: Interval,
session: ClientSession | None = None,
timestamp: int | None = None,
) -> AveragePrices:
"""
Expand All @@ -187,7 +201,7 @@ async def get_average_prices(
return AveragePrices(**data)

async def get_time_series(
self, session: ClientSession, item_id: int, timestep: Interval
self, item_id: int, timestep: Interval, session: ClientSession | None = None
) -> TimeSeries:
"""
Fetches time-series data for a specific item and timestep.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Empty file removed osrs/sync_api/runelite/__init__.py
Empty file.
Loading

0 comments on commit f2bb080

Please sign in to comment.