Skip to content

Commit

Permalink
Kernel finalization (#130)
Browse files Browse the repository at this point in the history
* add tests for kernel integration

* documented kernel support, bumped version number
  • Loading branch information
pseudonym117 authored Jul 31, 2019
1 parent 288fa99 commit 0cc343b
Show file tree
Hide file tree
Showing 18 changed files with 223 additions and 172 deletions.
20 changes: 17 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
RiotWatcher v2.6.0
RiotWatcher v2.7.0
==================

|pypi| |docs| |build| |coverage| |lgmt| |black|
Expand All @@ -7,7 +7,7 @@ Check for full (read: slightly better) documentation `here <http://riot-watcher.

RiotWatcher is a thin wrapper on top of the `Riot Games API for League
of Legends <https://developer.riotgames.com/>`__. All public methods as
of 5/7/2019 are supported in full.
of 7/30/2019 are supported in full.

RiotWatcher by default supports a naive rate limiter. This rate limiter will
try to stop you from making too many requests, and in a single threaded test
Expand Down Expand Up @@ -80,6 +80,20 @@ raised as HTTPError exceptions from the Requests library.
else:
raise
Use with kernel
---------------

RiotWatcher can integrate with the API proxy/caching server `kernel <https://github.com/meraki-analytics/kernel/>`__.
This can be done by providing the ``kernel_url`` parameter to the ``RiotWatcher`` constructor.

.. code:: python
from riotwatcher import RiotWatcher, ApiError
watcher = RiotWatcher(kernel_url="https://your-kernel-instance") # should not contain trailing slash
# use watcher as normal
Advanced
--------

Expand Down Expand Up @@ -109,7 +123,7 @@ Rate limiter has some race conditions when used concurrently.

Changelog
---------
vNext - Unreleased
v2.7.0 - 7/30/2019
~~~~~~~~~~~~~~~~~~

Add support for connecting to `kernel <https://github.com/meraki-analytics/kernel/>`__.
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@
# built documents.
#
# The short X.Y version.
version = "2.6.0"
version = "2.7.0"
# The full version, including alpha/beta/rc tags.
release = "2.6.0"
release = "2.7.0"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
16 changes: 15 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Welcome to RiotWatcher's documentation!

RiotWatcher is a thin wrapper on top of the `Riot Games API for League
of Legends <https://developer.riotgames.com/>`__. All public methods as
of 5/7/2019 are supported in full.
of 7/30/2019 are supported in full.

RiotWatcher by default supports a naive rate limiter. This rate limiter will
try to stop you from making too many requests, and in a single threaded test
Expand Down Expand Up @@ -77,6 +77,20 @@ raised as HTTPError exceptions from the Requests library.
raise
Use with kernel
---------------

RiotWatcher can integrate with the API proxy/caching server `kernel <https://github.com/meraki-analytics/kernel/>`__.
This can be done by providing the ``kernel_url`` parameter to the ``RiotWatcher`` constructor.

.. code:: python
from riotwatcher import RiotWatcher, ApiError
watcher = RiotWatcher(kernel_url="https://your-kernel-instance") # should not contain trailing slash
# use watcher as normal
Main API and other topics
-------------------------

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import sys

__version__ = "2.6.0"
__version__ = "2.7.0"

descr_file = os.path.join(os.path.dirname(__file__), "README.rst")

Expand Down
2 changes: 1 addition & 1 deletion src/riotwatcher/_apis/urls/Endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def __call__(self, **kwargs):

class RegionEndpoint(object):
def __init__(self, url, **kwargs):
self._url = url
self._url = "/lol" + url

def __call__(self, **kwargs):
final_url = UrlConfig.root_url + self._url
Expand Down
2 changes: 1 addition & 1 deletion src/riotwatcher/_apis/urls/UrlConfig.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
class UrlConfig(object):
root_url = "https://{region}.api.riotgames.com/lol"
root_url = "https://{region}.api.riotgames.com"
3 changes: 2 additions & 1 deletion src/riotwatcher/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import requests

from .Handlers import ApiError
from .Handlers import ApiError as _ApiError

ApiError = _ApiError # should silence code analysis warning
TimeoutError = requests.exceptions.Timeout
11 changes: 9 additions & 2 deletions src/riotwatcher/riotwatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ class RiotWatcher(object):
RiotWatcher class is intended to be the main interaction point with the RiotAPI.
"""

def __init__(self, api_key, custom_handler_chain=None, timeout=None, **kwargs):
def __init__(
self, api_key=None, custom_handler_chain=None, timeout=None, kernel_url=None
):
"""
Initialize a new instance of the RiotWatcher class.
Expand All @@ -49,8 +51,11 @@ def __init__(self, api_key, custom_handler_chain=None, timeout=None, **kwargs):
]
:param int timeout: Time to wait for a response before timing out a connection to
the Riot API
:param string kernel_url: URL for the kernel instance to connect to, instead of the API.
See https://github.com/meraki-analytics/kernel for details.
"""
kernel_url = kwargs.get("kernel_url")
if not kernel_url and not api_key:
raise ValueError("Either api_key or kernel_url must be set!")

if custom_handler_chain is None:
if kernel_url:
Expand All @@ -71,6 +76,8 @@ def __init__(self, api_key, custom_handler_chain=None, timeout=None, **kwargs):

if kernel_url:
UrlConfig.root_url = kernel_url
else:
UrlConfig.root_url = "https://{region}.api.riotgames.com"

self._base_api = BaseApi(api_key, custom_handler_chain, timeout=timeout)

Expand Down
39 changes: 35 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,22 @@ def mock_get(monkeypatch):
yield mock_req


@pytest.fixture
def reset_globals():
from riotwatcher._apis.urls import UrlConfig

initial = UrlConfig.root_url
yield
UrlConfig.root_url = initial


class MockContext(object):
def __init__(self, api_key, mock_get, watcher):
def __init__(self, api_key, mock_get, watcher, kernel_url):
self._api_key = api_key
self._expected_response = {"has_value": "yes"}
self._get = mock_get
self._watcher = watcher
self._kernel_url = kernel_url

mock_response = mock.MagicMock()
mock_response.json.return_value = self._expected_response
Expand All @@ -80,10 +90,31 @@ def get(self):
def watcher(self):
return self._watcher

def verify_api_call(self, region, endpoint, query_params, actual_response):
assert self.expected_response == actual_response

@pytest.fixture
def mock_context(mock_get):
if self._kernel_url:
base_url = self._kernel_url
query_params["region"] = region
else:
base_url = "https://{region}.api.riotgames.com".format(region=region)

self.get.assert_called_once_with(
"{base_url}{endpoint}".format(base_url=base_url, endpoint=endpoint),
params=query_params,
headers={"X-Riot-Token": self.api_key},
)


@pytest.fixture(params=(None, "https://kernel-proxy:8080"))
@pytest.mark.usefixtures("reset_globals")
def mock_context(mock_get, request):
import riotwatcher

api_key = "abcdefg"
return MockContext(api_key, mock_get, riotwatcher.RiotWatcher(api_key))
yield MockContext(
api_key,
mock_get,
riotwatcher.RiotWatcher(api_key, kernel_url=request.param),
request.param,
)
9 changes: 2 additions & 7 deletions tests/integration/test_ChampionApiV3.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ class TestChampionApiV3(object):
def test_rotations(self, mock_context, region):
actual_response = mock_context.watcher.champion.rotations(region)

assert mock_context.expected_response == actual_response
mock_context.get.assert_called_once_with(
"https://{region}.api.riotgames.com/lol/platform/v3/champion-rotations".format(
region=region
),
params={},
headers={"X-Riot-Token": mock_context.api_key},
mock_context.verify_api_call(
region, "/lol/platform/v3/champion-rotations", {}, actual_response
)
38 changes: 18 additions & 20 deletions tests/integration/test_ChampionMasteryApiV4.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ def test_by_summoner(self, mock_context, region, encrypted_summoner_id):
region, encrypted_summoner_id
)

assert mock_context.expected_response == actual_response
mock_context.get.assert_called_once_with(
"https://{region}.api.riotgames.com/lol/champion-mastery/v4/champion-masteries/by-summoner/{encrypted_summoner_id}".format(
region=region, encrypted_summoner_id=encrypted_summoner_id
mock_context.verify_api_call(
region,
"/lol/champion-mastery/v4/champion-masteries/by-summoner/{encrypted_summoner_id}".format(
encrypted_summoner_id=encrypted_summoner_id
),
params={},
headers={"X-Riot-Token": mock_context.api_key},
{},
actual_response,
)

@pytest.mark.parametrize("champion_id", [0, 1, 9999999999, 150])
Expand All @@ -44,27 +44,25 @@ def test_by_summoner_by_champion(
region, encrypted_summoner_id, champion_id
)

assert mock_context.expected_response == actual_response
mock_context.get.assert_called_once_with(
"https://{region}.api.riotgames.com/lol/champion-mastery/v4/champion-masteries/by-summoner/{encrypted_summoner_id}/by-champion/{champion_id}".format(
region=region,
encrypted_summoner_id=encrypted_summoner_id,
champion_id=champion_id,
mock_context.verify_api_call(
region,
"/lol/champion-mastery/v4/champion-masteries/by-summoner/{encrypted_summoner_id}/by-champion/{champion_id}".format(
encrypted_summoner_id=encrypted_summoner_id, champion_id=champion_id
),
params={},
headers={"X-Riot-Token": mock_context.api_key},
{},
actual_response,
)

def test_scores_by_summoner(self, mock_context, region, encrypted_summoner_id):
actual_response = mock_context.watcher.champion_mastery.scores_by_summoner(
region, encrypted_summoner_id
)

assert mock_context.expected_response == actual_response
mock_context.get.assert_called_once_with(
"https://{region}.api.riotgames.com/lol/champion-mastery/v4/scores/by-summoner/{encrypted_summoner_id}".format(
region=region, encrypted_summoner_id=encrypted_summoner_id
mock_context.verify_api_call(
region,
"/lol/champion-mastery/v4/scores/by-summoner/{encrypted_summoner_id}".format(
encrypted_summoner_id=encrypted_summoner_id
),
params={},
headers={"X-Riot-Token": mock_context.api_key},
{},
actual_response,
)
Loading

0 comments on commit 0cc343b

Please sign in to comment.