Skip to content

Commit

Permalink
Changed version to 1.0.4
Browse files Browse the repository at this point in the history
Added type hint for FortniteAPI class arguments
Added type check for API Key
Implemented type check for search parameters
Implemented MissingIDParameter and MissingSearchParameter errors
Errors are now a instance of FortniteAPIException
Added ServiceUnavailable check
Fixed error in async lib
Added keywords for lib
Added tests
Cleaned up some code

Took 3 hours 21 minutes
  • Loading branch information
Luc1412 committed Dec 12, 2019
1 parent ae2edfc commit 77ac924
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 171 deletions.
61 changes: 5 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ Get all Br cosmetics.
- `language` [GameLanguage] (Optional) - Specify the language of the shop. Default is set to english
###### Returns
Returns a list of `BrCosmetic` objects.
###### Raises
- `ServerOutage` when the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided

___

Expand All @@ -56,12 +52,6 @@ Search one o multiple items by their id.
- `language` [GameLanguage] (Optional) - Specify the language of the shop. Default is set to english
###### Returns
Returns a list of `BrCosmetic` objects.
###### Raises
- `ServerOutage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided
- `NotFound` if the cosmetic with the given id wasn't found
- `MissingIDParameter` if no id was provided

___

Expand All @@ -74,11 +64,6 @@ Search all cosmetics which fit to the search parameters
- `language` [GameLanguage] (Optional) - Specify the language of the shop. Default is set to english
###### Returns
Returns a list of `BrCosmetic` objects.
###### Raises
- `ServerOutage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided
- `MissingSearchParameter` if no search parameter was provided

___

Expand All @@ -91,11 +76,6 @@ Search the first cosmetics which fit to the search parameters
- `language` [GameLanguage] (Optional) - Specify the language of the shop. Default is set to english
###### Returns
Returns a `BrCosmetic` objects.
###### Raises
- `ServerOutage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided
- `MissingIDParameter` if no id was provided

___

Expand All @@ -107,11 +87,7 @@ Get the latest Fortnite shop.
###### Parameters
- `language` [GameLanguage] (Optional) - Specify the language of the shop. Default is set to english
###### Returns
Returns a `Shop` object.
###### Raises
- `Server Outage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided
Returns a `Shop` object.

___

Expand All @@ -124,10 +100,6 @@ Get the latest Fortnite news of all game modes.
- `language` [GameLanguage] (Optional) - Specify the language of the shop. Default is set to english
###### Returns
Returns a `News` object.
###### Raises
- `ServerOutage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided

___

Expand All @@ -141,10 +113,6 @@ Get the latest Fortnite news of a specified game mode.
- `language` [GameLanguage] (Optional) - Specify the language of the shop. Default is set to english
###### Returns
Returns a `GameModeNews` object.
###### Raises
- `ServerOutage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided

___

Expand All @@ -154,14 +122,9 @@ api.creator_code.fetch()
```
Get information about a creator code.
###### Parameters
- `creator_code` [str] - Specify a creator code.
- `slug` [str] - Specify a creator code.
###### Returns
Returns a `CreatorCode` object.
###### Raises
- `ServerOutage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided
- `NotFound` if the creator code wasn't found

___

Expand All @@ -170,13 +133,9 @@ api.creator_code.exists()
```
Check if a creator code exists.
###### Parameters
- `creator_code` [str] - Specify a creator code.
- `slug` [str] - Specify a creator code.
###### Returns
Returns a `bool` object.
###### Raises
- `ServerOutage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided

___

Expand All @@ -186,14 +145,9 @@ api.creator_code.search_all()
```
Search a creator code by name. All results are provided.
###### Parameters
- `creator_code` [str] - Specify a creator code.
- `slug` [str] - Specify a creator code.
###### Returns
Returns a `list` of `CreatorCode` objects.
###### Raises
- `ServerOutage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided
- `NotFound` if the creator code wasn't found

___

Expand All @@ -203,14 +157,9 @@ api.creator_code.search_first()
```
Search a creator code by name. Only the first result is provided.
###### Parameters
- `creator_code` [str] - Specify a creator code.
- `slug` [str] - Specify a creator code.
###### Returns
Returns a `CreatorCode` object.
###### Raises
- `ServerOutage` if the servers are not available
- `RateLimted` when the rate limit has been hit
- `Unauthorized` when no or a wrong API key has been provided
- `NotFound` if the creator code wasn't found

## Contribute
Every type of contribution is appreciated!
Expand Down
2 changes: 1 addition & 1 deletion fortnite_api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '1.0.3'
__version__ = '1.0.4'

from .api import FortniteAPI
from .cosmetics import *
Expand Down
5 changes: 4 additions & 1 deletion fortnite_api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

class FortniteAPI:

def __init__(self, api_key, run_async=False):
def __init__(self, api_key: str, run_async: bool = False):
if type(api_key) is not str:
raise TypeError('api_key require a value of type {0}'.format(str(str)))
self.http = SyncHTTPClient() if not run_async else AsyncHTTPClient()
self.http.add_header('x-api-key', api_key)

self.cosmetics = SyncCosmeticsEndpoints(self) if not run_async else AsyncCosmeticsEndpoints(self)
self.creator_code = SyncCreatorCodeEndpoints(self) if not run_async else AsyncCreatorCodeEndpoints(self)
self.news = SyncNewsEndpoints(self) if not run_async else AsyncNewsEndpoints(self)
Expand Down
149 changes: 67 additions & 82 deletions fortnite_api/endpoints.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
import typing
from enum import Enum

from .creator_code import CreatorCode
from .enums import GameLanguage, MatchMethod, NewsType
from .errors import NotFound
from .errors import MissingSearchParameter, MissingIDParameter, NotFound
from .cosmetics import BrCosmetic
from .news import GameModeNews, News
from .shop import BrShop

_SEARCH_PARAMETERS = {
'language': [None, [GameLanguage]],
'search_language': ['searchLanguage', [GameLanguage]],
'match_method': ['matchMethod', [MatchMethod]],
'type': [None, [str, None]],
'backend_type': ['backendType', [str, None]],
'rarity': [None, [str, None]],
'display_rarity': ['displayRarity', [str, None]],
'backend_rarity': ['backendRarity', [str, None]],
'name': [None, [str, None]],
'short_description': ['shortDescription', [str, None]],
'description': [None, [str, None]],
'set': ['set', [str, None]],
'set_text': ['setText', [str, None]],
'series': [None, [str, None]],
'backend_series': ['backendSeries', [str, None]],
'has_small_icon': ['hasSmallIcon', [bool, None]],
'has_icon': ['hasIcon', [bool, None]],
'has_featured_image': ['hasFeaturedImage', [bool, None]],
'has_background_image': ['hasBackgroundImage', [bool, None]],
'has_cover_art': ['hasCoverArt', [bool, None]],
'has_decal': ['hasDecal', [bool, None]],
'has_variants': ['hasVariants', [bool, None]],
'has_gameplay_tags': ['hasGameplayTags', [bool, None]],
'gameplay_tag': ['gameplayTag', [str, None]]
}


def _parse_search_parameter(**search_parameters):
parameters = {
'language': search_parameters.get('language', GameLanguage.ENGLISH).value,
'searchLanguage': search_parameters.get('search_language', GameLanguage.ENGLISH).value,
'matchMethod': search_parameters.get('match_method', MatchMethod.FULL).value
}
if search_parameters.__contains__('type'):
parameters['type'] = search_parameters['type']
if search_parameters.__contains__('backend_type'):
parameters['backendType'] = search_parameters['backend_type']
if search_parameters.__contains__('rarity'):
parameters['rarity'] = search_parameters['rarity']
if search_parameters.__contains__('backend_rarity'):
parameters['backendRarity'] = search_parameters['backend_rarity']
if search_parameters.__contains__('name'):
parameters['name'] = search_parameters['name']
if search_parameters.__contains__('short_description'):
parameters['shortDescription'] = search_parameters['short_description']
if search_parameters.__contains__('description'):
parameters['description'] = search_parameters['description']
if search_parameters.__contains__('set'):
parameters['set'] = search_parameters['set']
if search_parameters.__contains__('series'):
parameters['series'] = search_parameters['series']
if search_parameters.__contains__('has_small_icon'):
parameters['hasSmallIcon'] = search_parameters['has_small_icon']
if search_parameters.__contains__('has_icon'):
parameters['hasIcon'] = search_parameters['has_icon']
if search_parameters.__contains__('has_featured_image'):
parameters['hasFeaturedImage'] = search_parameters['has_featured_image']
if search_parameters.__contains__('has_background_image'):
parameters['hasBackgroundImage'] = search_parameters['has_background_image']
if search_parameters.__contains__('has_cover_art'):
parameters['hasCoverArt'] = search_parameters['has_cover_art']
if search_parameters.__contains__('has_decal'):
parameters['hasDecal'] = search_parameters['has_decal']
if search_parameters.__contains__('has_variants'):
parameters['hasVariants'] = search_parameters['has_variants']
if search_parameters.__contains__('has_gameplay_tags'):
parameters['hasGameplayTags'] = search_parameters['has_gameplay_tags']
if search_parameters.__contains__('gameplay_tag'):
parameters['gameplayTag'] = search_parameters['gameplay_tag']
parameters = {} # TODO: Empty string as search parameter
for key, value in search_parameters.items():
search_parameter_data = _SEARCH_PARAMETERS.get(key)
if search_parameter_data is None:
continue
if type(value) not in search_parameter_data[1]:
types = ' or '.join([str(t) for t in search_parameter_data[1]])
raise TypeError('{0} require a value of type {1}'.format(key, types))
key = search_parameter_data[0] if search_parameter_data[0] else key
value = value if not isinstance(value, Enum) else value.value if value is not None else '<null>'
parameters[key] = str(value) if value is not None else '<null>'
if len(parameters) == 0:
raise MissingSearchParameter('at least one search parameter is required')
return parameters


Expand All @@ -67,8 +67,9 @@ def search_by_id(self, *cosmetic_id: str, language: GameLanguage = GameLanguage.
cosmetic_ids = list(cosmetic_id)
params = {'language': language.value}

if len(cosmetic_ids) < 1:
return None
if len(cosmetic_ids) == 0:
raise MissingIDParameter('at least one cosmetic id is required')

endpoint = 'cosmetics/br/search/ids'
endpoint += '?id=' + cosmetic_ids[0]
del cosmetic_ids[0]
Expand Down Expand Up @@ -101,8 +102,9 @@ async def search_by_id(self, *cosmetic_id: str, language: GameLanguage = GameLan
cosmetic_ids = list(cosmetic_id)
params = {'language': language.value}

if len(cosmetic_ids) < 1:
return None
if len(cosmetic_ids) == 0:
raise MissingIDParameter('at least one cosmetic id is required')

endpoint = 'cosmetics/br/search/ids'
endpoint += '?id=' + cosmetic_ids[0]
del cosmetic_ids[0]
Expand All @@ -116,10 +118,7 @@ async def search_all(self, **search_parameters) -> typing.List[BrCosmetic]:
return [BrCosmetic(item_data) for item_data in data['data']]

async def search_first(self, **search_parameters) -> BrCosmetic:
data = await self._client.http.get('cosmetics/br/search',
params=_parse_search_parameter(**search_parameters))
if data['status'] == 400:
raise NotFound('The requested cosmetic was not found.')
data = await self._client.http.get('cosmetics/br/search', params=_parse_search_parameter(**search_parameters))
return BrCosmetic(data['data'])


Expand All @@ -128,69 +127,55 @@ class SyncCreatorCodeEndpoints:
def __init__(self, client):
self._client = client

def fetch(self, creator_code: str) -> CreatorCode:
params = {'slug': creator_code}
def fetch(self, slug: str) -> CreatorCode:
params = {'slug': slug}
data = self._client.http.get('creatorcode', params=params)
if data['status'] == 400:
raise NotFound('The requested Creator Code was not found.')
return CreatorCode(data['data'])

def exists(self, creator_code: str) -> bool:
def exists(self, slug: str) -> bool:
try:
self.fetch(creator_code)
self.fetch(slug)
return True
except NotFound:
return False

def search_first(self, creator_code: str) -> CreatorCode:
params = {'slug': creator_code}
def search_first(self, slug: str) -> CreatorCode:
params = {'slug': slug}
data = self._client.http.get('creatorcode/search', params=params)
if data['status'] == 400:
raise NotFound('The requested Creator Code was not found.')
return CreatorCode(data['data'])

def search_all(self, creator_code: str) -> typing.List[CreatorCode]:
params = {'slug': creator_code}
def search_all(self, slug: str) -> typing.List[CreatorCode]:
params = {'slug': slug}
data = self._client.http.get('creatorcode/search/all', params=params)
creator_codes = [CreatorCode(creator_code_data) for creator_code_data in data['data']]
if len(creator_codes) == 0:
raise NotFound('The requested Creator Code was not found.')
return creator_codes
return [CreatorCode(creator_code_data) for creator_code_data in data['data']]


class AsyncCreatorCodeEndpoints:

def __init__(self, client):
self._client = client

async def fetch(self, creator_code: str) -> CreatorCode:
params = {'slug': creator_code}
async def fetch(self, slug: str) -> CreatorCode:
params = {'slug': slug}
data = await self._client.http.get('creatorcode', params=params)
if data['status'] == 400:
raise NotFound('The requested Creator Code was not found.')
return CreatorCode(data['data'])

async def exists(self, creator_code: str) -> bool:
async def exists(self, slug: str) -> bool:
try:
await self.fetch(creator_code)
await self.fetch(slug)
return True
except NotFound:
return False

async def search_first(self, creator_code: str) -> CreatorCode:
params = {'slug': creator_code}
async def search_first(self, slug: str) -> CreatorCode:
params = {'slug': slug}
data = await self._client.http.get('creatorcode/search', params=params)
if data['status'] == 400:
raise NotFound('The requested Creator Code was not found.')
return CreatorCode(data['data'])

async def search_all(self, creator_code: str) -> typing.List[CreatorCode]:
params = {'slug': creator_code}
async def search_all(self, slug: str) -> typing.List[CreatorCode]:
params = {'slug': slug}
data = await self._client.http.get('creatorcode/search/all', params=params)
creator_codes = [CreatorCode(creator_code_data) for creator_code_data in data['data']]
if len(creator_codes) == 0:
raise NotFound('The requested Creator Code was not found.')
return creator_codes
return [CreatorCode(creator_code_data) for creator_code_data in data['data']]


class SyncNewsEndpoints:
Expand Down
Loading

0 comments on commit 77ac924

Please sign in to comment.