Skip to content

Commit

Permalink
Merge pull request #17 from janaSunrise/dev
Browse files Browse the repository at this point in the history
Quick library patches and fixes
  • Loading branch information
janaSunrise authored Mar 24, 2021
2 parents 0fcb370 + 5065eab commit 41328d0
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 266 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.6](https://github.com/janaSunrise/HypixelIO/releases/tag/v1.2.6) - 24-03-2021

## Added

None

## Fixed

- Async caching removed due to bugs.
- Variables exposed and bugs not allowing fetching in async.
- Cleaned async client.

## [1.2.5](https://github.com/janaSunrise/HypixelIO/releases/tag/v1.2.5) - 23-03-2021

## Added
Expand All @@ -26,6 +38,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Made the documentation better, and changed the theme.
- Tweaked and fixed things here and there.

## Added

None

## Fixed

- Async caching removed due to bugginess
- Variables exposed and bugs not allowing fetching in async.
- Cleaned async client.

## [1.2.3](https://github.com/janaSunrise/HypixelIO/releases/tag/v1.2.3) - 11-03-2021

## Added
Expand Down
3 changes: 1 addition & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ hypixelio = {editable = true, extras = ["all"], path = "."}
[packages]
requests = "==2.25.1"
requests-cache = "==0.5.2"
aiohttp = {extras = ["speedups"], version = "*"}
aiohttp-client-cache = "*"
aiohttp = "==3.7.4post0"

[scripts]
lint = "pre-commit run --all-files"
Expand Down
193 changes: 3 additions & 190 deletions Pipfile.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ python3 -m pip install -U git+https://github.com/janaSunrise/HypixelIO

# Or use [speedups] to speed up only for async features
python3 -m pip install -U "HypixelIO[speedups]"

# Take advantage of caching
python3 -m pip install -U "HypixelIO[cache]"

# Or get all the features!
python3 -m pip install -U "HypixelIO[all]"
```

## Usage
Expand Down
2 changes: 1 addition & 1 deletion hypixelio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

__author__ = "Sunrit Jana"
__email__ = "warriordefenderz@gmail.com"
__version__ = "1.2.5"
__version__ = "1.2.6"
__license__ = "GPL-3.0 License"
__copyright__ = "Copyright 2021 Sunrit Jana"

Expand Down
121 changes: 50 additions & 71 deletions hypixelio/ext/asyncio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import typing as t
from datetime import datetime, timedelta

import aiohttp_client_cache
import aiohttp

from hypixelio.endpoints import API_PATH
from hypixelio.exceptions import (
Expand All @@ -18,7 +18,6 @@
from hypixelio.lib.converters import Converters
from hypixelio.models import (
boosters,
caching,
find_guild,
friends,
games,
Expand All @@ -33,7 +32,7 @@
)
from hypixelio.utils.constants import (
HYPIXEL_API,
TIMEOUT,
TIMEOUT
)
from hypixelio.utils.helpers import (
form_url
Expand All @@ -42,7 +41,13 @@

class AsyncClient:
"""The client for this wrapper, that handles the requests, authentication, loading and usages of the end user.
from hypixelio.ext.asyncio import AsyncClient
c = AsyncClient("1c30559c-ade3-47dd-9228-9d8c21ea7349")
import asyncio
async def main():
p = await c.get_player("Sadashi_")
return p
asyncio.run(main())
Examples
--------
Import the async client first.
Expand All @@ -57,20 +62,11 @@ class AsyncClient:
>>> client = AsyncClient(api_key=["123-456", "789-000", "568-908"])
f you want to enable caching, Here's how to do it
>>> client = AsyncClient(cache=True)
And configuring cache
>>> from hypixelio.models.caching import Caching, CacheBackend
>>> cache_cfg = Caching(cache_name="my-cache", backend=CacheBackend.sqlite, expire_after=10)
>>> client = AsyncClient(cache=True, cache_config=cache_cfg)
Notes
-----
Keep in mind that, your keys wouldn't work if you're banned from hypixel, or if they're expired.
"""
def __init__(self, api_key: t.Union[str, list], cache: bool = False, cache_config: caching.Caching = None) -> None:
def __init__(self, api_key: t.Union[str, list]) -> None:
"""
Parameters
----------
Expand All @@ -79,39 +75,20 @@ def __init__(self, api_key: t.Union[str, list], cache: bool = False, cache_confi
"""
self.url = API_PATH["HYPIXEL"]

self.__session = None
self.__lock = asyncio.Lock()

self.requests_remaining = -1
self.total_requests = 0

self._ratelimit_reset = datetime(1998, 1, 1)
self.retry_after = datetime(1998, 1, 1)

if not isinstance(api_key, list):
self.__api_key = [api_key]

self.cache = cache

if cache:
if cache_config is None:
cache_config = caching.Caching(expire_after=30, old_data_on_error=True)

if cache_config.backend == "sqlite":
self.cache = aiohttp_client_cache.backends.SQLiteBackend(
cache_name=cache_config.cache_name, expire_after=cache_config.expire_after
)
elif cache_config.backend == "redis":
self.cache = aiohttp_client_cache.backends.RedisBackend(
cache_name=cache_config.cache_name, expire_after=cache_config.expire_after
)
elif cache_config.backend == "mongodb":
self.cache = aiohttp_client_cache.backends.MongoDBBackend(
cache_name=cache_config.cache_name, expire_after=cache_config.expire_after
)
else:
self.cache = aiohttp_client_cache.backends.CacheBackend(
cache_name=cache_config.cache_name, expire_after=cache_config.expire_after
)
async def close(self) -> None:
"""Close the AIOHTTP sessions to prevent memory leaks."""
await self.__session.close()

def add_key(self, key: t.Union[str, list]) -> None:
if isinstance(key, str):
Expand Down Expand Up @@ -148,6 +125,9 @@ async def _fetch(self, url: str, data: dict = None, key: bool = True) -> t.Tuple
`t.Tuple[dict, bool]`
The JSON Response from the Fetch Done to the API and the SUCCESS Value from the Response.
"""
if not self.__session:
self.__session = aiohttp.ClientSession()

if (
self.requests_remaining != -1 and # noqa: W504
(self.requests_remaining == 0 and self._ratelimit_reset > datetime.now()) or # noqa: W504
Expand All @@ -166,40 +146,39 @@ async def _fetch(self, url: str, data: dict = None, key: bool = True) -> t.Tuple
url = form_url(HYPIXEL_API, url, data)

async with self.__lock:
async with aiohttp_client_cache.CachedSession(cache=self.cache) as session:
async with session.get(url, timeout=TIMEOUT, headers=headers) as response:
if response.status == 429:
self.requests_remaining = 0
self.retry_after = datetime.now() + timedelta(seconds=int(response.headers["Retry-After"]))
raise RateLimitError(
f"Out of Requests! "
f"{datetime.now() + timedelta(seconds=int(response.headers['Retry-After']))}"
)

if response.status == 400:
raise HypixelAPIError(reason="Invalid key specified!")

if key and "RateLimit-Limit" in response.headers:
if self.total_requests == 0:
self.total_requests = int(response.headers["RateLimit-Limit"])

self.requests_remaining = int(response.headers["RateLimit-Remaining"])
self._ratelimit_reset = datetime.now() + timedelta(
seconds=int(response.headers["RateLimit-Reset"]))

try:
json = await response.json()
except Exception as exception:
raise HypixelAPIError(f"{exception}")
else:
if not json["success"]:
reason = "Something in the API has problem."
if json["cause"] is not None:
reason += f" Reason given: {json['cause']}"

raise HypixelAPIError(reason=reason)

return json
async with self.__session.get(url, headers=headers, timeout=TIMEOUT) as response:
if response.status == 429:
self.requests_remaining = 0
self.retry_after = datetime.now() + timedelta(seconds=int(response.headers["Retry-After"]))
raise RateLimitError(
f"Out of Requests! "
f"{datetime.now() + timedelta(seconds=int(response.headers['Retry-After']))}"
)

if response.status == 400:
raise HypixelAPIError(reason="Invalid key specified!")

if key and "RateLimit-Limit" in response.headers:
if self.total_requests == 0:
self.total_requests = int(response.headers["RateLimit-Limit"])

self.requests_remaining = int(response.headers["RateLimit-Remaining"])
self._ratelimit_reset = datetime.now() + timedelta(
seconds=int(response.headers["RateLimit-Reset"]))

try:
json = await response.json()
except Exception as exception:
raise HypixelAPIError(f"{exception}")
else:
if not json["success"]:
reason = "Something in the API has problem."
if json["cause"] is not None:
reason += f" Reason given: {json['cause']}"

raise HypixelAPIError(reason=reason)

return json

@staticmethod
def _filter_name_uuid(name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str:
Expand Down
1 change: 0 additions & 1 deletion hypixelio/lib/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ def __init__(self, api_key: t.Union[str, list], cache: bool = False, cache_confi

self.requests_remaining = -1
self.total_requests = 0

self._ratelimit_reset = datetime(1998, 1, 1)
self.retry_after = datetime(1998, 1, 1)

Expand Down
1 change: 1 addition & 0 deletions hypixelio/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"GUILD_COLORS__TAG",
"SKYWARS_PRESTIGES_RANKS",
"SKYWARS_PRESTIGE_COLOR",
"TIMEOUT"
)

HYPIXEL_API = "https://api.hypixel.net"
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"cchardet",
],
"cache": ["requests-cache==0.5.2", 'boto3', 'pymongo', 'redis'],
"async-cache": ["aiohttp-client-cache==0.2.2", 'aiosqlite', 'boto3', 'motor', 'aioredis']
}
extras_require['all'] = list(chain.from_iterable(extras_require.values()))

Expand Down

0 comments on commit 41328d0

Please sign in to comment.