Skip to content

Commit

Permalink
4.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
fourjr committed Nov 11, 2018
1 parent 9ab1528 commit 6959e7e
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 714 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Changelog
All notable changes to this project will be documented in this file.

## [4.0.0] - Unreleased
## [Unreleased]
No changes yet

## [4.0.0] - 11/11/2018
### Added
- A changelog
- OfficialAPI: A way to iterate through paginated repsonses (i.e. search_clans, search_tournaments) using asynchronus generators.
- OfficialAPI: Tests for the pagination.
- Requirement: async_generator (For Python 3.5 support)
Expand All @@ -14,7 +16,6 @@ All notable changes to this project will be documented in this file.
- Repsonses with a `.items` will simply be returned as a list
- `OfficialAPI.get_cards()` -> `OfficialAPI.get_all_cards()` (Deprecated till v4.1.0)
- OfficialAPI: `before` and `after` are no longer valid parameters as pagination is natively supported
- MIT -> GNU GPL v3

### Fixed
- Client.close() now works if the client is async
Expand Down
695 changes: 21 additions & 674 deletions LICENSE

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ clashroyale
:target: https://pypi.org/project/clashroyale/
:alt: PyPi

.. image:: https://img.shields.io/pypi/pyversions/clashroyale.svg
:target: https://pypi.org/project/clashroyale/
:alt: Supported Versions

.. image:: https://travis-ci.com/cgrok/clashroyale.svg?branch=master
:target: https://travis-ci.com/cgrok/clashroyale
:alt: Travis CI Status

.. image:: https://img.shields.io/github/license/cgrok/clashroyale.svg
:target: https://github.com/cgrok/clashroyale/blob/master/LICENSE
:alt: MIT License


This library is currently an (a)sync wrapper for
https://royaleapi.com and the official Clash Royale API with
Expand All @@ -17,6 +25,12 @@ great functionality.
Installation
============

Development build
.. code-block:: python
pip install git+https://github.com/cgrok/clashroyale
Stable build
.. code-block:: python
pip install clashroyale
Expand Down
4 changes: 2 additions & 2 deletions clashroyale/official_api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
ServerError, Unauthorized, UnexpectedError, RatelimitError)
from .models import (BaseAttrDict, PaginatedAttrDict, Refreshable, FullClan, PartialTournament,
PartialClan, PartialPlayerClan, FullPlayer, rlist)
from .utils import API, SqliteDict, clansearch, tournamentsearch, crtag, keys, typecasted
from .utils import API, SqliteDict, clansearch, crtag, keys, typecasted

from_timestamp = datetime.fromtimestamp

Expand Down Expand Up @@ -409,7 +409,7 @@ def get_tournament(self, tag: crtag, timeout=0):
return self._get_model(url, PartialTournament, timeout=timeout)

@typecasted
def search_tournaments(self, name: str, **params: tournamentsearch):
def search_tournaments(self, name: str, **params: keys):
"""Search for a tournament by its name
Parameters
Expand Down
6 changes: 4 additions & 2 deletions clashroyale/official_api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ class BaseAttrDict:
Example
-------
Accessing data via dot notation: ::
Accessing data via dot notation:
.. code-block:: python
sample_data = {
"stats": {
"maxTrophies": 5724,
Expand Down Expand Up @@ -105,8 +106,9 @@ class PaginatedAttrDict(BaseAttrDict):
Example
-------
Searching clans with a limit of 3: ::
Searching clans with a limit of 3:
.. code-block:: python
>>> a_data = await a_client.search_clans(name='aaa', limit=3)
>>> b_data = b_client.search_clans(name='aaa', limit=3)
>>> len(a_data)
Expand Down
11 changes: 0 additions & 11 deletions clashroyale/official_api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,6 @@ def clansearch(k, v):
return k, v


def tournamentsearch(k, v):
valid = (
'name',
)
valid += BASE
k = to_camel_case(k)
if k not in valid:
raise ValueError('Invalid search parameter passed: {}'.format(k))
return k, v


def keys(k, v):
if k not in BASE:
raise ValueError('Invalid url parameter passed: {}'.format(k))
Expand Down
6 changes: 3 additions & 3 deletions clashroyale/royaleapi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
UnexpectedError, RatelimitError, RatelimitErrorDetected)
from .models import (BaseAttrDict, Refreshable, PartialTournament, PartialClan,
PartialPlayerClan, FullPlayer, FullClan, rlist)
from .utils import API, SqliteDict, clansearch, tournamentsearch, crtag, keys, tournamentfilter, typecasted
from .utils import API, SqliteDict, clansearch, crtag, keys, tournamentfilter, typecasted

from_timestamp = datetime.fromtimestamp
log = logging.getLogger(__name__)
Expand Down Expand Up @@ -191,7 +191,7 @@ def _convert_model(self, data, cached, ts, model, resp):
else:
return model(self, data, resp, cached=cached, ts=ts)

async def _aget_model(self, url, model=None, *, params={}):
async def _aget_model(self, url, model=None, **params):
try:
data, cached, ts, resp = await self._request(url, **params)
except Exception as e:
Expand Down Expand Up @@ -569,7 +569,7 @@ def get_tournament(self, tag: crtag, **params: keys):
return self._get_model(url, **params)

@typecasted
def search_tournaments(self, **params: tournamentsearch):
def search_tournaments(self, **params: keys):
"""Search for a tournament
Parameters
Expand Down
3 changes: 2 additions & 1 deletion clashroyale/royaleapi/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ class BaseAttrDict:
Example
-------
Accessing data via dot notation: ::
Accessing data via dot notation:
.. code-block:: python
sample_data = {
"stats": {
"maxTrophies": 5724,
Expand Down
11 changes: 0 additions & 11 deletions clashroyale/royaleapi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,6 @@ def clansearch(k, v):
return k, v


def tournamentsearch(k, v):
valid = (
'name',
)
valid += BASE
k = _to_camel_case(k)
if k not in valid:
raise ValueError('Invalid search parameter passed: {}'.format(k))
return k, v


def keys(k, v):
k = _to_camel_case(k)
if k not in BASE:
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# -- Project information -----------------------------------------------------

project = 'clashroyale'
copyright = '2018, fourjr, arq'
copyright = '2017-2018, fourjr, arq'
author = 'fourjr, arq'

# The short X.Y version
Expand Down
26 changes: 21 additions & 5 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
Welcome to clashroyale's documentation!
=======================================

Contents:
The clashroyale module is an easy to use, feature-rich and async ready API wrapper
for both the `Official API`_ and `RoyaleAPI`_

Features
~~~~~~~~

- Use the same client for sync/async operations.
- Implements the entire API.
- Easy to use with an object oriented design.
- Optional caching for reliability and performance.
- Continously maintained


Contents
~~~~~~~~

.. toctree::
:maxdepth: 2
:maxdepth: 3

api
logging



Indices and tables
==================
Indices
~~~~~~~

* :ref:`genindex`
* :ref:`search`

.. _Official API: https://developer.clashroyale.com
.. _RoyaleAPI: https://docs.royaleapi.com
50 changes: 50 additions & 0 deletions docs/logging.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
Setting Up Logging
==================

*clashroyale* logs errors and debug information via the :mod:`logging` python
module. It is strongly recommended that the logging module is
configured, as no errors or warnings will be output if it is not set up.
Configuration of the ``logging`` module can be as simple as

.. code-block:: python
import logging
logging.basicConfig(level=logging.INFO)
Placed at the start of the application. This will output the logs from
*clashroyale* as well as other libraries that uses the ``logging`` module
directly to the console.

The optional ``level`` argument specifies what level of events to log
out and can any of ``CRITICAL``, ``ERROR``, ``WARNING``, ``INFO``, and
``DEBUG`` and if not specified defaults to ``WARNING``.

More advance setups are possible with the :mod:`logging` module. To for
example write the logs to a file called ``clashroyale.log`` instead of
outputting them to to the console the following snippet can be used

.. code-block:: python
import clashroyale
import logging
logger = logging.getLogger('clashroyale')
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler(filename='clashroyale.log', encoding='utf-8', mode='w')
handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
logger.addHandler(handler)
This is recommended, especially at verbose levels such as ``INFO``,
and ``DEBUG`` as there are a lot of events logged and it would clog the
stdout of your program.


Currently, the following things are logged:

- ``DEBUG``: API Requests



For more information, check the documentation and tutorial of the
:mod:`logging` module.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'Topic :: Games/Entertainment :: Real Time Strategy',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
Expand Down
17 changes: 17 additions & 0 deletions tests/official_api/test_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,29 @@ async def test_get_top_players_timeout(self):
clan = await self.cr.get_top_players(self.location_id[1], timeout=100)
self.assertTrue(isinstance(clan, clashroyale.official_api.PaginatedAttrDict))

# Others

async def test_logging(self):
logger = 'clashroyale.official_api.client'
with self.assertLogs(logger=logger, level=logging.DEBUG) as cm:
await self.cr.get_player(self.player_tags[0])
self.assertEqual(len(cm.output), 1)

async def test_invalid_param(self):
async def request():
await self.cr.get_player_battles(self.player_tags[0], invalid=1)
self.assertAsyncRaises(ValueError, request)

async def test_invalid_tag(self):
async def request():
await self.cr.get_player(invalid_tag)
invalid_tag = 'P'
self.assertAsyncRaises(ValueError, request)
invalid_tag = 'AAA'
self.assertAsyncRaises(ValueError, request)
invalid_tag = '2PP0PP0PP'
self.assertAsyncRaises(clashroyale.NotFoundError, request)

# Utility Functions
async def test_get_clan_image(self):
clan = await self.cr.get_clan(self.clan_tags[0])
Expand Down
17 changes: 17 additions & 0 deletions tests/official_api/test_blocking.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,29 @@ def test_get_top_players_timeout(self):
clan = self.cr.get_top_players(self.location_id[1], timeout=100)
self.assertTrue(isinstance(clan, clashroyale.official_api.PaginatedAttrDict))

# Others

def test_logging(self):
logger = 'clashroyale.official_api.client'
with self.assertLogs(logger=logger, level=logging.DEBUG) as cm:
self.cr.get_player(self.player_tags[0])
self.assertEqual(len(cm.output), 1)

def test_invalid_param(self):
def request():
self.cr.get_player_battles(self.player_tags[0], invalid=1)
self.assertRaises(ValueError, request)

def test_invalid_tag(self):
def request():
self.cr.get_player(invalid_tag)
invalid_tag = 'P'
self.assertRaises(ValueError, request)
invalid_tag = 'AAA'
self.assertRaises(ValueError, request)
invalid_tag = '2PP0PP0PP'
self.assertRaises(clashroyale.NotFoundError, request)

# Utility Functions
def test_get_clan_image(self):
clan = self.cr.get_clan(self.clan_tags[0])
Expand Down

0 comments on commit 6959e7e

Please sign in to comment.