├── .drone.yml ├── .gitignore ├── .isort.cfg ├── CHANGELOG.md ├── LICENSE.txt ├── MANIFEST.in ├── Makefile ├── README.md ├── drone.sh ├── examples └── game_data.py ├── pytest.ini ├── setup.py ├── spec ├── spec_checker.py ├── utils.py ├── wow-community-api.json └── wow-game-data-api.json ├── tests ├── __init__.py ├── conftest.py ├── fixtures.py ├── mixins │ ├── test_game_data.py │ └── test_profile.py └── test_api.py └── wowapi ├── __init__.py ├── api.py ├── exceptions.py └── mixins ├── __init__.py ├── game_data.py └── profile.py /.drone.yml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: pipeline 3 | type: docker 4 | name: python35 5 | 6 | steps: 7 | - name: test 8 | image: python:3.5-alpine3.12 9 | commands: 10 | - ./drone.sh 11 | 12 | --- 13 | kind: pipeline 14 | type: docker 15 | name: python36 16 | 17 | steps: 18 | - name: test 19 | image: python:3.6-alpine3.12 20 | commands: 21 | - ./drone.sh 22 | 23 | --- 24 | kind: pipeline 25 | type: docker 26 | name: python37 27 | 28 | steps: 29 | - name: test 30 | image: python:3.7-alpine3.12 31 | commands: 32 | - ./drone.sh 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | dist 4 | MANIFEST 5 | *.pyc 6 | *.egg-info 7 | *.egg 8 | docs/_build/ 9 | .coverage 10 | env/ 11 | .cache 12 | .vscode 13 | cov_html/ 14 | .pytest_cache -------------------------------------------------------------------------------- /.isort.cfg: -------------------------------------------------------------------------------- 1 | [settings] 2 | line_length=99 3 | multi_line_output=6 4 | lines_after_imports=2 -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 4.0.0 (15-06-2020) 4 | 5 | * Deprecate Community API 6 | * Update Data & Profile API and missing endpoints 7 | 8 | 9 | ## 3.0.0 10 | 11 | * Split community, game data and profile API's into separate mixins 12 | * Add flake8 and isort to test requirements 13 | * Drop support for python 2.7 14 | * Changes in game data endpoints: 15 | * `get_races` became `get_playable_race_index` 16 | * `get_race` became `get_playable_race` 17 | * `get_connected_realms` became `get_connected_realm_index` 18 | * `get_mythic_keystone_dungeon` became `get_mythic_keystone_dungeon_index` 19 | * `get_mythic_keystones` became `get_mythic_keystone_index` 20 | * `get_mythic_keystone_periods` became `get_mythic_keystone_period_index` 21 | * `get_mythic_keystone_seasons` became `get_mythic_keystone_season_index` 22 | * `get_mythic_keystone_leaderboards` became `get_mythic_keystone_leaderboard_index` 23 | * `get_playable_specializations` became `get_playable_specialization_index` 24 | * `get_power_types` became `get_power_type_index` 25 | * `get_realms` became `get_realm_index` 26 | * `get_regions` became `get_region_index` 27 | * `get_token` became `get_token_index` 28 | * new achievments endpoints 29 | * new creatures endpoints 30 | * new guild endpoints 31 | * new guild crest endpoints 32 | * new item endpoints 33 | * new mount endpoints 34 | * new pets endpoints 35 | * new pvp endpoints 36 | * new quest endpoints 37 | * new pvp season endpoints 38 | * new pvp tier endpoints 39 | * new titles endpoints 40 | * Changes in profile endpoints: 41 | * new character achievements endpoint 42 | * new character appearance endpoint 43 | * new character equipment endpoint 44 | * new character media endpoint 45 | * new character profile endpoint 46 | * new character pvp endpoints 47 | * new character specialization endpoint 48 | * new character statistics endpoint 49 | * new character titles endpoint 50 | * Changes in community endpoints: 51 | * new `get_oauth_profile` endpoint 52 | 53 | 54 | ## 2.3.1 (20-05-2019) 55 | 56 | * Added some leeway protection against expired tokens 57 | 58 | 59 | ## 2.3.0 (06-05-2019) 60 | 61 | * Add profile api 62 | 63 | 64 | ## 2.2.1 (16-02-2019) 65 | 66 | * Add functionality to retry failed connections 67 | 68 | 69 | ## 2.2.0 (25-12-2018) 70 | 71 | * Add new Game Data API's 72 | 73 | 74 | ## 2.1.0 (13-12-2018) 75 | 76 | * Add Game Data API methods 77 | * Token handling per region 78 | 79 | 80 | ## 2.0.1 (Unreleased) 81 | 82 | * Add drone cloud support for CI 83 | * Bump requests library to 2.20.1 84 | * Change packaging with setup.py 85 | 86 | 87 | ## 2.0.0 (14-10-2018) 88 | 89 | * Deprecate 1.0 WowApi 90 | * Implement client credentials flow for OAuth authentication 91 | * Add dronefile for testing against multiple python versions 92 | * Add coverage to pytest 93 | * Add logging 94 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | python-wowapi 2 | ----------------- 3 | Copyright (c) 2018 python-wowapi | Carlo Smouter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include setup.py 2 | include README.md 3 | include CHANGELOG.md 4 | include Makefile 5 | include MANIFEST.in 6 | include LICENSE.txt 7 | include Makefile 8 | include pytest.ini 9 | recursive-include docs * 10 | recursive-exclude * *.py[co] 11 | recursive-exclude * *.DS_Store 12 | recursive-exclude * *,cover 13 | recursive-exclude * __pycache__ -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: tests devinstall docinstall docs clean clean_build build test_publish publish 2 | 3 | 4 | devinstall: 5 | pip install -e . 6 | pip install -e .[tests] 7 | 8 | docinstall: 9 | pip install -e .[docs] 10 | 11 | docs: 12 | rm -rf docs 13 | mkdir docs 14 | pydocmd simple wowapi++ wowapi.api++ wowapi.mixins.game_data++ wowapi.mixins.profile++ > docs/api.md 15 | 16 | clean: 17 | rm -rf dist 18 | rm -rf build 19 | rm -rf cov_html 20 | rm -rf python_wowapi.egg-info 21 | rm -rf .coverage 22 | rm -rf docs 23 | 24 | build: 25 | make clean 26 | python setup.py sdist bdist_wheel 27 | 28 | test_publish: 29 | pip install --upgrade twine 30 | twine upload --repository-url https://test.pypi.org/legacy/ dist/* 31 | 32 | publish: 33 | pip install --upgrade twine 34 | twine upload dist/* 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python-wowapi 2 | 3 | 4 | [![](https://img.shields.io/pypi/v/python-wowapi.svg)]( [![](https://img.shields.io/pypi/pyversions/:python-wowapi.svg)](https://pypi.org/project/python-wowapi/)) 5 | [![](https://img.shields.io/pypi/pyversions/python-wowapi.svg)](https://pypi.org/project/python-wowapi/) 6 | [![Build Status](https://cloud.drone.io/api/badges/lockwooddev/python-wowapi/status.svg)](https://cloud.drone.io/lockwooddev/python-wowapi) 7 | 8 | 9 | 10 | Python-wowapi is a client library for interacting with the World of Warcraft endpoins of the [Blizzard API](https://develop.battle.net/documentation/guides/getting-started) 11 | 12 | Python-wowapi includes support for the following WoW API's: 13 | * Game data API 14 | * Character Profile API 15 | 16 | To interact with this library, you need to first get a client-id and client secret by [registering](https://develop.battle.net/access) your application. 17 | 18 | For more information about official World of Warcraft API's visit: 19 | * [Official API documentation](https://develop.battle.net/documentation) 20 | * [Official API Forum](https://us.forums.blizzard.com/en/blizzard/c/api-discussion) 21 | 22 | ## API Docs 23 | 24 | For examples and all available endpoints, visit the [API Documentation](docs/api.md) 25 | 26 | ## Installing 27 | 28 | ```bash 29 | pip install python-wowapi 30 | ``` 31 | 32 | ## WoW Classic API support 33 | 34 | According to this [Forum post](https://us.forums.blizzard.com/en/blizzard/t/world-of-warcraft-classic-api-endpoints/346), Blizzard is adding support for some game data API's. 35 | 36 | In order to use these endpoints, you need to provide the classic namespace: 37 | 38 | ```python 39 | api.get_item_class_index('us', 'static-classic-us') 40 | ``` 41 | 42 | ## Development & Testing 43 | 44 | ```bash 45 | make devinstall 46 | pytest 47 | ``` 48 | 49 | Alternatively you can also run the full [drone.io](https://drone.io) pipeline [locally](https://docs.drone.io/cli/install/) or [remote](https://cloud.drone.io/lockwooddev/python-wowapi/) 50 | 51 | ```bash 52 | drone exec 53 | ``` 54 | 55 | To build the docs: 56 | 57 | ```bash 58 | make docinstall 59 | make docs 60 | ``` 61 | -------------------------------------------------------------------------------- /drone.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | find . -name "*.py[co]" -delete 4 | apk --update upgrade 5 | apk add make 6 | make build 7 | pip install --upgrade pip 8 | make devinstall 9 | pytest 10 | find . -name "*.py[co]" -delete -------------------------------------------------------------------------------- /examples/game_data.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pprint import pprint 4 | 5 | from wowapi import WowApi 6 | 7 | 8 | logger = logging.getLogger('wowapi') 9 | logger.setLevel(logging.INFO) 10 | handler = logging.StreamHandler() 11 | handler.setLevel(logging.INFO) 12 | formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 13 | handler.setFormatter(formatter) 14 | logger.addHandler(handler) 15 | 16 | logger.info('Game Data API Example') 17 | 18 | # fetch token price for region 19 | api = WowApi(os.environ['WOW_CLIENT_ID'], os.environ['WOW_CLIENT_SECRET']) 20 | data = api.get_token_index('eu', namespace='dynamic-eu', locale='de_DE') 21 | pprint(data) 22 | 23 | # get realm list and request detail href with the get_data_resource method 24 | data = api.get_realm_index('eu', namespace='dynamic-eu', locale='de_DE') 25 | detail_url = data['realms'][0]['key']['href'] 26 | detail_data = api.get_data_resource(detail_url, region='eu', locale='de_DE') 27 | pprint(detail_data) 28 | 29 | # get playable specializations list and fetch a single specialization with the api 30 | data = api.get_playable_specialization_index( 31 | 'eu', namespace='static-eu', locale='de_DE' 32 | ) 33 | spec_id = data['character_specializations'][0]['id'] 34 | specialization = api.get_playable_specialization( 35 | 'eu', namespace='static-eu', spec_id=spec_id, locale='de_DE' 36 | ) 37 | pprint(specialization) 38 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | addopts = -vs --tb=short --cache-clear --flake8 --isort --cov=wowapi --cov-config .coveragerc --cov-report html:cov_html --cov-report term 3 | 4 | python_files = 5 | test_*.py 6 | 7 | norecursedirs = 8 | env/* 9 | docs/* 10 | build/* 11 | 12 | flake8-max-line-length = 99 13 | flake8-ignore = 14 | docs/* ALL 15 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | import os 3 | 4 | from setuptools import find_packages, setup 5 | 6 | 7 | __version__ = '4.0.0' 8 | 9 | 10 | def read(*parts): 11 | filename = os.path.join(os.path.dirname(__file__), *parts) 12 | with codecs.open(filename, encoding='utf-8') as fp: 13 | return fp.read() 14 | 15 | 16 | install_requirements = [ 17 | 'requests==2.23.0', 18 | ] 19 | 20 | test_requirements = [ 21 | 'pytest>=5.0,<6.0', 22 | 'pytest-flake8', 23 | 'pytest-isort==1.3.0', 24 | 'pytest-cov>=2.7,<3.0', 25 | 'pytest-mock==1.10.4', 26 | ] 27 | 28 | docs_requirements = [ 29 | 'pydoc-markdown==2.0.5', 30 | ] 31 | 32 | setup( 33 | name='python-wowapi', 34 | version=__version__, 35 | description=( 36 | "Python-wowapi is a client library for the " 37 | "World of Warcraft, Data and Profile API's." 38 | ), 39 | long_description=read('README.md'), 40 | long_description_content_type="text/markdown", 41 | author='Carlo Smouter', 42 | author_email='lockwooddev@gmail.com', 43 | url='https://github.com/lockwooddev/python-wowapi', 44 | packages=find_packages(exclude=['tests', 'tests.*']), 45 | include_package_data=True, 46 | install_requires=install_requirements, 47 | extras_require={ 48 | 'tests': test_requirements, 49 | 'docs': docs_requirements, 50 | }, 51 | license='MIT', 52 | keywords=[ 53 | 'warcraft', 54 | 'api', 55 | 'wow', 56 | 'auctionhouse', 57 | 'community', 58 | 'game', 59 | 'data', 60 | 'profile', 61 | 'blizzard', 62 | 'classic', 63 | 'wow', 64 | ], 65 | classifiers=[ 66 | 'Development Status :: 5 - Production/Stable', 67 | 'Intended Audience :: Developers', 68 | 'License :: OSI Approved :: MIT License', 69 | 'Operating System :: OS Independent', 70 | 'Programming Language :: Python', 71 | 'Programming Language :: Python :: 3.5', 72 | 'Programming Language :: Python :: 3.6', 73 | 'Programming Language :: Python :: 3.7', 74 | 'Topic :: Internet :: WWW/HTTP', 75 | ], 76 | ) 77 | -------------------------------------------------------------------------------- /spec/spec_checker.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import tempfile 3 | 4 | import requests 5 | 6 | 7 | def check_spec(id, spec_file): 8 | print('Detecting changes in the {0}'.format(id)) 9 | base_url = 'https://develop.battle.net/assets/api/' 10 | spec_url = '{0}{1}'.format(base_url, spec_file) 11 | 12 | response = requests.get(spec_url) 13 | new_spec_file = tempfile.NamedTemporaryFile() 14 | new_spec_file.write(response.content) 15 | new_spec_file.seek(0) 16 | 17 | result = subprocess.run(["diff", spec_file, new_spec_file.name], capture_output=True) 18 | changed = bool(result.stdout) 19 | if bool(result.stdout): 20 | print('Changes in the {0} have been detected since last release!'.format(id)) 21 | print('I need a human to look for possible deprecations..') 22 | print('-----------------------------------------------------') 23 | 24 | lines = result.stdout.decode('utf-8').split('\n') 25 | [print(line) for line in lines] 26 | print('-----------------------------------------------------') 27 | else: 28 | print('No API changes detected..') 29 | return changed 30 | 31 | 32 | if __name__ == '__main__': 33 | assert not check_spec('WoW Community API', 'wow-community-api.json') 34 | assert not check_spec('WoW Game Data API', 'wow-game-data-api.json') 35 | -------------------------------------------------------------------------------- /spec/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import requests 4 | 5 | 6 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 7 | 8 | 9 | def get_spec_resource(spec_file): 10 | base_url = 'https://develop.battle.net/assets/api/' 11 | url = '{0}{1}'.format(base_url, spec_file) 12 | response = requests.get(url) 13 | if response.ok: 14 | return response.text 15 | raise Exception('{0} returned wrong response: {1}'.format(url, response)) 16 | 17 | 18 | def save_spec_file(name, spec_file): 19 | print("saving spec for {0} to '{1}'".format(name, spec_file)) 20 | data = get_spec_resource(spec_file) 21 | location = os.path.join(BASE_DIR, 'live', spec_file) 22 | with open(location, 'w') as f: 23 | f.write(data) 24 | 25 | 26 | if __name__ == '__main__': 27 | save_spec_file('WoW Community API', 'wow-community-api.json') 28 | save_spec_file('WoW Game Data API', 'wow-game-data-api.json') 29 | -------------------------------------------------------------------------------- /spec/wow-community-api.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WoW Community APIs", 3 | "title": "WoW Community APIs", 4 | "description": "Endpoints for World of Warcraft player profiles.\n\n**Hosts**: note that Blizzard API request paths follow this format: `{region}.api.blizzard.com/{API path}` (or `gateway.battlenet.com.cn/{API path}` for China). For more information, see the [Getting Started guide](/documentation/guides/getting-started).", 5 | "version": "78", 6 | "protocol": "rest", 7 | "basePath": "https://__region__.api.blizzard.com", 8 | "headers": { 9 | "Accept": "application/json" 10 | }, 11 | "regionDefault": "us", 12 | "auth": { 13 | "oauth": { 14 | "version": "2.0", 15 | "base_uri": "https://us.battle.net", 16 | "authorize_uri": "/oauth/authorize", 17 | "access_token_uri": "/oauth/token", 18 | "auth_flows": [ 19 | "client_cred" 20 | ], 21 | "options": { 22 | "authorize": { 23 | "scope": [] 24 | } 25 | } 26 | } 27 | }, 28 | "resources": { 29 | "World of Warcraft Profile API": { 30 | "methods": { 31 | "World of Warcraft OAuth Profile": { 32 | "description": "This provides data about the current logged in OAuth user's WoW profile. Note that **GET /wow/user/characters** requires an access token obtained via the [authorization code flow](/documentation/guides/using-oauth/authorization-code-flow).", 33 | "path": "/wow/user/characters", 34 | "httpMethod": "GET", 35 | "parameters": {} 36 | } 37 | } 38 | }, 39 | "Achievement API": { 40 | "methods": { 41 | "Achievement": { 42 | "description": "Returns data about an individual achievement.", 43 | "path": "/wow/achievement/:id", 44 | "parameters": { 45 | ":id": { 46 | "type": "string", 47 | "required": true, 48 | "default": "2144", 49 | "description": "The ID of the achievement to retrieve.", 50 | "location": "pathReplace" 51 | }, 52 | "locale": { 53 | "type": "string", 54 | "required": false, 55 | "default": "en_US", 56 | "enum": [ 57 | "en_US", 58 | "pt_BR", 59 | "es_MX" 60 | ], 61 | "description": "The locale to reflect in localized data.", 62 | "location": "query" 63 | }, 64 | "jsonp": { 65 | "type": "string", 66 | "required": false, 67 | "default": "", 68 | "description": "Request for the data to be returned as a JSONP callback.", 69 | "location": "query" 70 | } 71 | }, 72 | "httpMethod": "GET" 73 | } 74 | } 75 | }, 76 | "Auction API": { 77 | "methods": { 78 | "Auction Data Status": { 79 | "description": "Auction APIs currently provide rolling batches of data about current auctions. Fetching auction dumps is a two-step process that involves checking a per-realm index file to determine if a recent dump has been generated and then fetching the most recently generated dump file (if necessary).\n\nThis API resource provides a per-realm list of recently generated auction house data dumps.", 80 | "path": "/wow/auction/data/:realm", 81 | "parameters": { 82 | ":realm": { 83 | "type": "string", 84 | "required": true, 85 | "default": "medivh", 86 | "description": "The realm to request.", 87 | "location": "pathReplace" 88 | }, 89 | "locale": { 90 | "type": "string", 91 | "required": false, 92 | "default": "en_US", 93 | "enum": [ 94 | "en_US", 95 | "pt_BR", 96 | "es_MX" 97 | ], 98 | "description": "The locale to reflect in localized data.", 99 | "location": "query" 100 | }, 101 | "jsonp": { 102 | "type": "string", 103 | "required": false, 104 | "default": "", 105 | "description": "Request for the data to be returned as a JSONP callback.", 106 | "location": "query" 107 | } 108 | }, 109 | "httpMethod": "GET" 110 | } 111 | } 112 | }, 113 | "Boss API": { 114 | "methods": { 115 | "Master List": { 116 | "description": "Returns a list of all supported bosses. A \"boss\" in this context should be considered a boss encounter, which may include more than one NPC.", 117 | "path": "/wow/boss/", 118 | "parameters": { 119 | "locale": { 120 | "type": "string", 121 | "required": false, 122 | "default": "en_US", 123 | "enum": [ 124 | "en_US", 125 | "pt_BR", 126 | "es_MX" 127 | ], 128 | "description": "The locale to reflect in localized data.", 129 | "location": "query" 130 | }, 131 | "jsonp": { 132 | "type": "string", 133 | "required": false, 134 | "default": "", 135 | "description": "Request for the data to be returned as a JSONP callback.", 136 | "location": "query" 137 | } 138 | }, 139 | "httpMethod": "GET" 140 | }, 141 | "Boss": { 142 | "description": "The boss API provides information about bosses. A \"boss\" in this context should be considered a boss encounter, which may include more than one NPC.", 143 | "path": "/wow/boss/:bossid", 144 | "parameters": { 145 | ":bossid": { 146 | "type": "string", 147 | "required": true, 148 | "default": "24723", 149 | "description": "The ID of the boss to retrieve.", 150 | "location": "pathReplace" 151 | }, 152 | "locale": { 153 | "type": "string", 154 | "required": false, 155 | "default": "en_US", 156 | "enum": [ 157 | "en_US", 158 | "pt_BR", 159 | "es_MX" 160 | ], 161 | "description": "The locale to reflect in localized data.", 162 | "location": "query" 163 | }, 164 | "jsonp": { 165 | "type": "string", 166 | "required": false, 167 | "default": "", 168 | "description": "Request for the data to be returned as a JSONP callback.", 169 | "location": "query" 170 | } 171 | }, 172 | "httpMethod": "GET" 173 | } 174 | } 175 | }, 176 | "Challenge Mode API": { 177 | "methods": { 178 | "Realm Leaderboard": { 179 | "description": "The request returns data for all nine challenge mode maps (currently). The map field includes the current medal times for each dungeon. Each ladder provides data about each character that was part of each run. The character data includes the current cached specialization of the character while the member field includes the specialization of the character during the challenge mode run.", 180 | "path": "/wow/challenge/:realm", 181 | "parameters": { 182 | ":realm": { 183 | "type": "string", 184 | "required": true, 185 | "default": "medivh", 186 | "description": "The realm to request.", 187 | "location": "pathReplace" 188 | }, 189 | "locale": { 190 | "type": "string", 191 | "required": false, 192 | "default": "en_US", 193 | "enum": [ 194 | "en_US", 195 | "pt_BR", 196 | "es_MX" 197 | ], 198 | "description": "The locale to reflect in localized data.", 199 | "location": "query" 200 | }, 201 | "jsonp": { 202 | "type": "string", 203 | "required": false, 204 | "default": "", 205 | "description": "Request for the data to be returned as a JSONP callback.", 206 | "location": "query" 207 | } 208 | }, 209 | "httpMethod": "GET" 210 | }, 211 | "Region Leaderboard": { 212 | "description": "The region leaderboard has the exact same data format as the realm leaderboards except there is no `realm` field. Instead, the response has the top 100 results gathered for each map for all of the available realm leaderboards in a region.", 213 | "path": "/wow/challenge/region", 214 | "httpMethod": "GET", 215 | "parameters": { 216 | "locale": { 217 | "type": "string", 218 | "required": false, 219 | "default": "en_US", 220 | "enum": [ 221 | "en_US", 222 | "pt_BR", 223 | "es_MX" 224 | ], 225 | "description": "The locale to reflect in localized data.", 226 | "location": "query" 227 | }, 228 | "jsonp": { 229 | "type": "string", 230 | "required": false, 231 | "default": "", 232 | "description": "Request for the data to be returned as a JSONP callback.", 233 | "location": "query" 234 | } 235 | } 236 | } 237 | } 238 | }, 239 | "Character Profile API": { 240 | "methods": { 241 | "Character Profile": { 242 | "description": "The Character Profile API is the primary way to access character information. This API can be used to fetch a single character at a time through an HTTP GET request to a URL describing the character profile resource. By default, these requests return a basic dataset, and each request can return zero or more additional fields. To access this API, craft a resource URL pointing to the desired character for which to retrieve information.", 243 | "path": "/wow/character/:realm/:characterName", 244 | "parameters": { 245 | ":realm": { 246 | "type": "string", 247 | "required": true, 248 | "default": "blackrock", 249 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 250 | "location": "pathReplace" 251 | }, 252 | ":characterName": { 253 | "type": "string", 254 | "required": true, 255 | "default": "Thrall", 256 | "description": "The name of the character to retrieve.", 257 | "location": "pathReplace" 258 | }, 259 | "fields": { 260 | "type": "string", 261 | "required": false, 262 | "default": "", 263 | "description": "The dataset to retrieve for the character. Each field value is explained in more detail in the following requests. If no fields are specified the API will only return basic data about the character.", 264 | "location": "pathReplace" 265 | }, 266 | "locale": { 267 | "type": "string", 268 | "required": false, 269 | "default": "en_US", 270 | "enum": [ 271 | "en_US", 272 | "pt_BR", 273 | "es_MX" 274 | ], 275 | "description": "The locale to reflect in localized data.", 276 | "location": "query" 277 | }, 278 | "jsonp": { 279 | "type": "string", 280 | "required": false, 281 | "default": "", 282 | "description": "Request for the data to be returned as a JSONP callback.", 283 | "location": "query" 284 | } 285 | }, 286 | "httpMethod": "GET" 287 | }, 288 | "Achievements": { 289 | "description": "Returns a map of achievement data including completion timestamps and criteria information.", 290 | "path": "/wow/character/:realm/:characterName", 291 | "parameters": { 292 | ":realm": { 293 | "type": "string", 294 | "required": true, 295 | "default": "blackrock", 296 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 297 | "location": "pathReplace" 298 | }, 299 | ":characterName": { 300 | "type": "string", 301 | "required": true, 302 | "default": "Thrall", 303 | "description": "The name of the character to retrieve.", 304 | "location": "pathReplace" 305 | }, 306 | "fields": { 307 | "type": "string", 308 | "required": true, 309 | "default": "achievements", 310 | "description": "Specifies the data to retrieve.", 311 | "location": "query" 312 | }, 313 | "locale": { 314 | "type": "string", 315 | "required": false, 316 | "default": "en_US", 317 | "enum": [ 318 | "en_US", 319 | "pt_BR", 320 | "es_MX" 321 | ], 322 | "description": "The locale to reflect in localized data.", 323 | "location": "query" 324 | }, 325 | "jsonp": { 326 | "type": "string", 327 | "required": false, 328 | "default": "", 329 | "description": "Request for the data to be returned as a JSONP callback.", 330 | "location": "query" 331 | } 332 | }, 333 | "httpMethod": "GET" 334 | }, 335 | "Appearance": { 336 | "description": "Returns a map of a character's appearance settings, such as which face texture they've selected and whether or not a helm is visible.", 337 | "path": "/wow/character/:realm/:characterName", 338 | "parameters": { 339 | ":realm": { 340 | "type": "string", 341 | "required": true, 342 | "default": "blackrock", 343 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 344 | "location": "pathReplace" 345 | }, 346 | ":characterName": { 347 | "type": "string", 348 | "required": true, 349 | "default": "Thrall", 350 | "description": "The name of the character to retrieve.", 351 | "location": "pathReplace" 352 | }, 353 | "fields": { 354 | "type": "string", 355 | "required": true, 356 | "default": "appearance", 357 | "description": "Specifies the data to retrieve.", 358 | "location": "query" 359 | }, 360 | "locale": { 361 | "type": "string", 362 | "required": false, 363 | "default": "en_US", 364 | "enum": [ 365 | "en_US", 366 | "pt_BR", 367 | "es_MX" 368 | ], 369 | "description": "The locale to reflect in localized data.", 370 | "location": "query" 371 | }, 372 | "jsonp": { 373 | "type": "string", 374 | "required": false, 375 | "default": "", 376 | "description": "Request for the data to be returned as a JSONP callback.", 377 | "location": "query" 378 | } 379 | }, 380 | "httpMethod": "GET" 381 | }, 382 | "Feed": { 383 | "description": "The character's activity feed.", 384 | "path": "/wow/character/:realm/:characterName", 385 | "parameters": { 386 | ":realm": { 387 | "type": "string", 388 | "required": true, 389 | "default": "blackrock", 390 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 391 | "location": "pathReplace" 392 | }, 393 | ":characterName": { 394 | "type": "string", 395 | "required": true, 396 | "default": "Thrall", 397 | "description": "The name of the character to retrieve.", 398 | "location": "pathReplace" 399 | }, 400 | "fields": { 401 | "type": "string", 402 | "required": true, 403 | "default": "feed", 404 | "description": "Specifies the data to retrieve.", 405 | "location": "query" 406 | }, 407 | "locale": { 408 | "type": "string", 409 | "required": false, 410 | "default": "en_US", 411 | "enum": [ 412 | "en_US", 413 | "pt_BR", 414 | "es_MX" 415 | ], 416 | "description": "The locale to reflect in localized data.", 417 | "location": "query" 418 | }, 419 | "jsonp": { 420 | "type": "string", 421 | "required": false, 422 | "default": "", 423 | "description": "Request for the data to be returned as a JSONP callback.", 424 | "location": "query" 425 | } 426 | }, 427 | "httpMethod": "GET" 428 | }, 429 | "Guild": { 430 | "description": "A summary of the guild to which the character belongs. If the character does not belong to a guild and this field is requested, this field will not be exposed.\n\nWhen a guild is requested, this resource returns a map with key-value pairs that describe a basic set of guild information. Note that the rank of the character is not included in this block as it describes a guild and not a membership of the guild. To retrieve the character's rank within the guild, make a specific, separate request to the guild profile resource.", 431 | "path": "/wow/character/:realm/:characterName", 432 | "parameters": { 433 | ":realm": { 434 | "type": "string", 435 | "required": true, 436 | "default": "blackrock", 437 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 438 | "location": "pathReplace" 439 | }, 440 | ":characterName": { 441 | "type": "string", 442 | "required": true, 443 | "default": "Thrall", 444 | "description": "The name of the character to retrieve.", 445 | "location": "pathReplace" 446 | }, 447 | "fields": { 448 | "type": "string", 449 | "required": true, 450 | "default": "guild", 451 | "description": "Specifies the data to retrieve.", 452 | "location": "query" 453 | }, 454 | "locale": { 455 | "type": "string", 456 | "required": false, 457 | "default": "en_US", 458 | "enum": [ 459 | "en_US", 460 | "pt_BR", 461 | "es_MX" 462 | ], 463 | "description": "The locale to reflect in localized data.", 464 | "location": "query" 465 | }, 466 | "jsonp": { 467 | "type": "string", 468 | "required": false, 469 | "default": "", 470 | "description": "Request for the data to be returned as a JSONP callback.", 471 | "location": "query" 472 | } 473 | }, 474 | "httpMethod": "GET" 475 | }, 476 | "Hunter Pets": { 477 | "description": "Returns a list of all combat pets the character has obtained.", 478 | "path": "/wow/character/:realm/:characterName", 479 | "parameters": { 480 | ":realm": { 481 | "type": "string", 482 | "required": true, 483 | "default": "blackrock", 484 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 485 | "location": "pathReplace" 486 | }, 487 | ":characterName": { 488 | "type": "string", 489 | "required": true, 490 | "default": "Thrall", 491 | "description": "The name of the character to retrieve.", 492 | "location": "pathReplace" 493 | }, 494 | "fields": { 495 | "type": "string", 496 | "required": true, 497 | "default": "hunterPets", 498 | "description": "Specifies the data to retrieve.", 499 | "location": "query" 500 | }, 501 | "locale": { 502 | "type": "string", 503 | "required": false, 504 | "default": "en_US", 505 | "enum": [ 506 | "en_US", 507 | "pt_BR", 508 | "es_MX" 509 | ], 510 | "description": "The locale to reflect in localized data.", 511 | "location": "query" 512 | }, 513 | "jsonp": { 514 | "type": "string", 515 | "required": false, 516 | "default": "", 517 | "description": "Request for the data to be returned as a JSONP callback.", 518 | "location": "query" 519 | } 520 | }, 521 | "httpMethod": "GET" 522 | }, 523 | "Items": { 524 | "description": "Returns a list of items equipped by the character. Use of this field will also include the average item level and average item level equipped for the character.\n\nWhen the `items` field is used, this resource returns a map structure containing information about the character's equipped items as well as their average item level.", 525 | "path": "/wow/character/:realm/:characterName", 526 | "parameters": { 527 | ":realm": { 528 | "type": "string", 529 | "required": true, 530 | "default": "blackrock", 531 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 532 | "location": "pathReplace" 533 | }, 534 | ":characterName": { 535 | "type": "string", 536 | "required": true, 537 | "default": "Thrall", 538 | "description": "The name of the character to retrieve.", 539 | "location": "pathReplace" 540 | }, 541 | "fields": { 542 | "type": "string", 543 | "required": true, 544 | "default": "items", 545 | "description": "Specifies the data to retrieve.", 546 | "location": "query" 547 | }, 548 | "locale": { 549 | "type": "string", 550 | "required": false, 551 | "default": "en_US", 552 | "enum": [ 553 | "en_US", 554 | "pt_BR", 555 | "es_MX" 556 | ], 557 | "description": "The locale to reflect in localized data.", 558 | "location": "query" 559 | }, 560 | "jsonp": { 561 | "type": "string", 562 | "required": false, 563 | "default": "", 564 | "description": "Request for the data to be returned as a JSONP callback.", 565 | "location": "query" 566 | } 567 | }, 568 | "httpMethod": "GET" 569 | }, 570 | "Mounts": { 571 | "description": "Returns a list of all mounts the character has obtained.", 572 | "path": "/wow/character/:realm/:characterName", 573 | "parameters": { 574 | ":realm": { 575 | "type": "string", 576 | "required": true, 577 | "default": "blackrock", 578 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 579 | "location": "pathReplace" 580 | }, 581 | ":characterName": { 582 | "type": "string", 583 | "required": true, 584 | "default": "Thrall", 585 | "description": "The name of the character to retrieve.", 586 | "location": "pathReplace" 587 | }, 588 | "fields": { 589 | "type": "string", 590 | "required": true, 591 | "default": "mounts", 592 | "description": "Specifies the data to retrieve.", 593 | "location": "query" 594 | }, 595 | "locale": { 596 | "type": "string", 597 | "required": false, 598 | "default": "en_US", 599 | "enum": [ 600 | "en_US", 601 | "pt_BR", 602 | "es_MX" 603 | ], 604 | "description": "The locale to reflect in localized data.", 605 | "location": "query" 606 | }, 607 | "jsonp": { 608 | "type": "string", 609 | "required": false, 610 | "default": "", 611 | "description": "Request for the data to be returned as a JSONP callback.", 612 | "location": "query" 613 | } 614 | }, 615 | "httpMethod": "GET" 616 | }, 617 | "Pets": { 618 | "description": "Returns a list of the battle pets the character has obtained.", 619 | "path": "/wow/character/:realm/:characterName", 620 | "parameters": { 621 | ":realm": { 622 | "type": "string", 623 | "required": true, 624 | "default": "blackrock", 625 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 626 | "location": "pathReplace" 627 | }, 628 | ":characterName": { 629 | "type": "string", 630 | "required": true, 631 | "default": "Thrall", 632 | "description": "The name of the character to retrieve.", 633 | "location": "pathReplace" 634 | }, 635 | "fields": { 636 | "type": "string", 637 | "required": true, 638 | "default": "pets", 639 | "description": "Specifies the data to retrieve.", 640 | "location": "query" 641 | }, 642 | "locale": { 643 | "type": "string", 644 | "required": false, 645 | "default": "en_US", 646 | "enum": [ 647 | "en_US", 648 | "pt_BR", 649 | "es_MX" 650 | ], 651 | "description": "The locale to reflect in localized data.", 652 | "location": "query" 653 | }, 654 | "jsonp": { 655 | "type": "string", 656 | "required": false, 657 | "default": "", 658 | "description": "Request for the data to be returned as a JSONP callback.", 659 | "location": "query" 660 | } 661 | }, 662 | "httpMethod": "GET" 663 | }, 664 | "Pet Slots": { 665 | "description": "Data about the character's current battle pet slots.\n\nThe response contains which slot a pet is in and whether the slot is empty or locked. The response also includes the `battlePetId`, which is unique for the character and can be used to match a `battlePetId` in the `pets` field for the character. The ability list is the list of three active abilities on a pet. If the pet is not high enough level for multiple abilities it will always be the pet's first three abilities.", 666 | "path": "/wow/character/:realm/:characterName", 667 | "parameters": { 668 | ":realm": { 669 | "type": "string", 670 | "required": true, 671 | "default": "blackrock", 672 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 673 | "location": "pathReplace" 674 | }, 675 | ":characterName": { 676 | "type": "string", 677 | "required": true, 678 | "default": "Thrall", 679 | "description": "The name of the character to retrieve.", 680 | "location": "pathReplace" 681 | }, 682 | "fields": { 683 | "type": "string", 684 | "required": true, 685 | "default": "petSlots", 686 | "description": "Specifies the data to retrieve.", 687 | "location": "query" 688 | }, 689 | "locale": { 690 | "type": "string", 691 | "required": false, 692 | "default": "en_US", 693 | "enum": [ 694 | "en_US", 695 | "pt_BR", 696 | "es_MX" 697 | ], 698 | "description": "The locale to reflect in localized data.", 699 | "location": "query" 700 | }, 701 | "jsonp": { 702 | "type": "string", 703 | "required": false, 704 | "default": "", 705 | "description": "Request for the data to be returned as a JSONP callback.", 706 | "location": "query" 707 | } 708 | }, 709 | "httpMethod": "GET" 710 | }, 711 | "Professions": { 712 | "description": "Returns a list of the character's professions. Does not include class professions.", 713 | "path": "/wow/character/:realm/:characterName", 714 | "parameters": { 715 | ":realm": { 716 | "type": "string", 717 | "required": true, 718 | "default": "blackrock", 719 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 720 | "location": "pathReplace" 721 | }, 722 | ":characterName": { 723 | "type": "string", 724 | "required": true, 725 | "default": "Thrall", 726 | "description": "The name of the character to retrieve.", 727 | "location": "pathReplace" 728 | }, 729 | "fields": { 730 | "type": "string", 731 | "required": true, 732 | "default": "professions", 733 | "description": "Specifies the data to retrieve.", 734 | "location": "query" 735 | }, 736 | "locale": { 737 | "type": "string", 738 | "required": false, 739 | "default": "en_US", 740 | "enum": [ 741 | "en_US", 742 | "pt_BR", 743 | "es_MX" 744 | ], 745 | "description": "The locale to reflect in localized data.", 746 | "location": "query" 747 | }, 748 | "jsonp": { 749 | "type": "string", 750 | "required": false, 751 | "default": "", 752 | "description": "Request for the data to be returned as a JSONP callback.", 753 | "location": "query" 754 | } 755 | }, 756 | "httpMethod": "GET" 757 | }, 758 | "Progression": { 759 | "description": "Returns a list of raids and bosses indicating raid progression and completeness.", 760 | "path": "/wow/character/:realm/:characterName", 761 | "parameters": { 762 | ":realm": { 763 | "type": "string", 764 | "required": true, 765 | "default": "blackrock", 766 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 767 | "location": "pathReplace" 768 | }, 769 | ":characterName": { 770 | "type": "string", 771 | "required": true, 772 | "default": "Thrall", 773 | "description": "The name of the character to retrieve.", 774 | "location": "pathReplace" 775 | }, 776 | "fields": { 777 | "type": "string", 778 | "required": true, 779 | "default": "progression", 780 | "description": "Specifies the data to retrieve.", 781 | "location": "query" 782 | }, 783 | "locale": { 784 | "type": "string", 785 | "required": false, 786 | "default": "en_US", 787 | "enum": [ 788 | "en_US", 789 | "pt_BR", 790 | "es_MX" 791 | ], 792 | "description": "The locale to reflect in localized data.", 793 | "location": "query" 794 | }, 795 | "jsonp": { 796 | "type": "string", 797 | "required": false, 798 | "default": "", 799 | "description": "Request for the data to be returned as a JSONP callback.", 800 | "location": "query" 801 | } 802 | }, 803 | "httpMethod": "GET" 804 | }, 805 | "PVP": { 806 | "description": "Returns a map of PvP information, including arena team membership and rated battlegrounds information.", 807 | "path": "/wow/character/:realm/:characterName", 808 | "parameters": { 809 | ":realm": { 810 | "type": "string", 811 | "required": true, 812 | "default": "blackrock", 813 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 814 | "location": "pathReplace" 815 | }, 816 | ":characterName": { 817 | "type": "string", 818 | "required": true, 819 | "default": "Thrall", 820 | "description": "The name of the character to retrieve.", 821 | "location": "pathReplace" 822 | }, 823 | "fields": { 824 | "type": "string", 825 | "required": true, 826 | "default": "pvp", 827 | "description": "Specifies the data to retrieve.", 828 | "location": "query" 829 | }, 830 | "locale": { 831 | "type": "string", 832 | "required": false, 833 | "default": "en_US", 834 | "enum": [ 835 | "en_US", 836 | "pt_BR", 837 | "es_MX" 838 | ], 839 | "description": "The locale to reflect in localized data.", 840 | "location": "query" 841 | }, 842 | "jsonp": { 843 | "type": "string", 844 | "required": false, 845 | "default": "", 846 | "description": "Request for the data to be returned as a JSONP callback.", 847 | "location": "query" 848 | } 849 | }, 850 | "httpMethod": "GET" 851 | }, 852 | "Quests": { 853 | "description": "Returns a list of quests the character has completed.", 854 | "path": "/wow/character/:realm/:characterName", 855 | "parameters": { 856 | ":realm": { 857 | "type": "string", 858 | "required": true, 859 | "default": "blackrock", 860 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 861 | "location": "pathReplace" 862 | }, 863 | ":characterName": { 864 | "type": "string", 865 | "required": true, 866 | "default": "Thrall", 867 | "description": "The name of the character to retrieve.", 868 | "location": "pathReplace" 869 | }, 870 | "fields": { 871 | "type": "string", 872 | "required": true, 873 | "default": "quests", 874 | "description": "Specifies the data to retrieve.", 875 | "location": "query" 876 | }, 877 | "locale": { 878 | "type": "string", 879 | "required": false, 880 | "default": "en_US", 881 | "enum": [ 882 | "en_US", 883 | "pt_BR", 884 | "es_MX" 885 | ], 886 | "description": "The locale to reflect in localized data.", 887 | "location": "query" 888 | }, 889 | "jsonp": { 890 | "type": "string", 891 | "required": false, 892 | "default": "", 893 | "description": "Request for the data to be returned as a JSONP callback.", 894 | "location": "query" 895 | } 896 | }, 897 | "httpMethod": "GET" 898 | }, 899 | "Reputation": { 900 | "description": "Returns a list of the factions with which the character has an associated reputation.", 901 | "path": "/wow/character/:realm/:characterName", 902 | "parameters": { 903 | ":realm": { 904 | "type": "string", 905 | "required": true, 906 | "default": "blackrock", 907 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 908 | "location": "pathReplace" 909 | }, 910 | ":characterName": { 911 | "type": "string", 912 | "required": true, 913 | "default": "Thrall", 914 | "description": "The name of the character to retrieve.", 915 | "location": "pathReplace" 916 | }, 917 | "fields": { 918 | "type": "string", 919 | "required": true, 920 | "default": "reputation", 921 | "description": "Specifies the data to retrieve.", 922 | "location": "query" 923 | }, 924 | "locale": { 925 | "type": "string", 926 | "required": false, 927 | "default": "en_US", 928 | "enum": [ 929 | "en_US", 930 | "pt_BR", 931 | "es_MX" 932 | ], 933 | "description": "The locale to reflect in localized data.", 934 | "location": "query" 935 | }, 936 | "jsonp": { 937 | "type": "string", 938 | "required": false, 939 | "default": "", 940 | "description": "Request for the data to be returned as a JSONP callback.", 941 | "location": "query" 942 | } 943 | }, 944 | "httpMethod": "GET" 945 | }, 946 | "Statistics": { 947 | "description": "Returns a map of character statistics.", 948 | "path": "/wow/character/:realm/:characterName", 949 | "parameters": { 950 | ":realm": { 951 | "type": "string", 952 | "required": true, 953 | "default": "blackrock", 954 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 955 | "location": "pathReplace" 956 | }, 957 | ":characterName": { 958 | "type": "string", 959 | "required": true, 960 | "default": "Thrall", 961 | "description": "The name of the character to retrieve.", 962 | "location": "pathReplace" 963 | }, 964 | "fields": { 965 | "type": "string", 966 | "required": true, 967 | "default": "statistics", 968 | "description": "Specifies the data to retrieve.", 969 | "location": "query" 970 | }, 971 | "locale": { 972 | "type": "string", 973 | "required": false, 974 | "default": "en_US", 975 | "enum": [ 976 | "en_US", 977 | "pt_BR", 978 | "es_MX" 979 | ], 980 | "description": "The locale to reflect in localized data.", 981 | "location": "query" 982 | }, 983 | "jsonp": { 984 | "type": "string", 985 | "required": false, 986 | "default": "", 987 | "description": "Request for the data to be returned as a JSONP callback.", 988 | "location": "query" 989 | } 990 | }, 991 | "httpMethod": "GET" 992 | }, 993 | "Stats": { 994 | "description": "Returns a map of character attributes and stats.", 995 | "path": "/wow/character/:realm/:characterName", 996 | "parameters": { 997 | ":realm": { 998 | "type": "string", 999 | "required": true, 1000 | "default": "blackrock", 1001 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 1002 | "location": "pathReplace" 1003 | }, 1004 | ":characterName": { 1005 | "type": "string", 1006 | "required": true, 1007 | "default": "Thrall", 1008 | "description": "The name of the character to retrieve.", 1009 | "location": "pathReplace" 1010 | }, 1011 | "fields": { 1012 | "type": "string", 1013 | "required": true, 1014 | "default": "stats", 1015 | "description": "Specifies the data to retrieve.", 1016 | "location": "query" 1017 | }, 1018 | "locale": { 1019 | "type": "string", 1020 | "required": false, 1021 | "default": "en_US", 1022 | "enum": [ 1023 | "en_US", 1024 | "pt_BR", 1025 | "es_MX" 1026 | ], 1027 | "description": "The locale to reflect in localized data.", 1028 | "location": "query" 1029 | }, 1030 | "jsonp": { 1031 | "type": "string", 1032 | "required": false, 1033 | "default": "", 1034 | "description": "Request for the data to be returned as a JSONP callback.", 1035 | "location": "query" 1036 | } 1037 | }, 1038 | "httpMethod": "GET" 1039 | }, 1040 | "Talents": { 1041 | "description": "Returns a list of the character's talent structures.", 1042 | "path": "/wow/character/:realm/:characterName", 1043 | "parameters": { 1044 | ":realm": { 1045 | "type": "string", 1046 | "required": true, 1047 | "default": "blackrock", 1048 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 1049 | "location": "pathReplace" 1050 | }, 1051 | ":characterName": { 1052 | "type": "string", 1053 | "required": true, 1054 | "default": "Thrall", 1055 | "description": "The name of the character to retrieve.", 1056 | "location": "pathReplace" 1057 | }, 1058 | "fields": { 1059 | "type": "string", 1060 | "required": true, 1061 | "default": "talents", 1062 | "description": "Specifies the data to retrieve.", 1063 | "location": "query" 1064 | }, 1065 | "locale": { 1066 | "type": "string", 1067 | "required": false, 1068 | "default": "en_US", 1069 | "enum": [ 1070 | "en_US", 1071 | "pt_BR", 1072 | "es_MX" 1073 | ], 1074 | "description": "The locale to reflect in localized data.", 1075 | "location": "query" 1076 | }, 1077 | "jsonp": { 1078 | "type": "string", 1079 | "required": false, 1080 | "default": "", 1081 | "description": "Request for the data to be returned as a JSONP callback.", 1082 | "location": "query" 1083 | } 1084 | }, 1085 | "httpMethod": "GET" 1086 | }, 1087 | "Titles": { 1088 | "description": "Returns a list of titles the character has obtained, including the currently selected title.", 1089 | "path": "/wow/character/:realm/:characterName", 1090 | "parameters": { 1091 | ":realm": { 1092 | "type": "string", 1093 | "required": true, 1094 | "default": "blackrock", 1095 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 1096 | "location": "pathReplace" 1097 | }, 1098 | ":characterName": { 1099 | "type": "string", 1100 | "required": true, 1101 | "default": "Thrall", 1102 | "description": "The name of the character to retrieve.", 1103 | "location": "pathReplace" 1104 | }, 1105 | "fields": { 1106 | "type": "string", 1107 | "required": true, 1108 | "default": "titles", 1109 | "description": "Specifies the data to retrieve.", 1110 | "location": "query" 1111 | }, 1112 | "locale": { 1113 | "type": "string", 1114 | "required": false, 1115 | "default": "en_US", 1116 | "enum": [ 1117 | "en_US", 1118 | "pt_BR", 1119 | "es_MX" 1120 | ], 1121 | "description": "The locale to reflect in localized data.", 1122 | "location": "query" 1123 | }, 1124 | "jsonp": { 1125 | "type": "string", 1126 | "required": false, 1127 | "default": "", 1128 | "description": "Request for the data to be returned as a JSONP callback.", 1129 | "location": "query" 1130 | } 1131 | }, 1132 | "httpMethod": "GET" 1133 | }, 1134 | "Audit": { 1135 | "description": "Raw character audit data that powers the character audit on the game site.", 1136 | "path": "/wow/character/:realm/:characterName", 1137 | "parameters": { 1138 | ":realm": { 1139 | "type": "string", 1140 | "required": true, 1141 | "default": "burning-legion", 1142 | "description": "The character's realm. Can be provided as the proper realm name or the normalized realm name.", 1143 | "location": "pathReplace" 1144 | }, 1145 | ":characterName": { 1146 | "type": "string", 1147 | "required": true, 1148 | "default": "Thrall", 1149 | "description": "The name of the character to retrieve.", 1150 | "location": "pathReplace" 1151 | }, 1152 | "fields": { 1153 | "type": "string", 1154 | "required": true, 1155 | "default": "audit", 1156 | "description": "Specifies the data to retrieve.", 1157 | "location": "query" 1158 | }, 1159 | "locale": { 1160 | "type": "string", 1161 | "required": false, 1162 | "default": "en_US", 1163 | "enum": [ 1164 | "en_US", 1165 | "pt_BR", 1166 | "es_MX" 1167 | ], 1168 | "description": "The locale to reflect in localized data.", 1169 | "location": "query" 1170 | }, 1171 | "jsonp": { 1172 | "type": "string", 1173 | "required": false, 1174 | "default": "", 1175 | "description": "Request for the data to be returned as a JSONP callback.", 1176 | "location": "query" 1177 | } 1178 | }, 1179 | "httpMethod": "GET" 1180 | } 1181 | } 1182 | }, 1183 | "Guild Profile API": { 1184 | "methods": { 1185 | "Guild Profile": { 1186 | "description": "The guild profile API is the primary way to access guild information. This API can fetch a single guild at a time through an HTTP GET request to a URL describing the guild profile resource. By default, these requests return a basic dataset and each request can retrieve zero or more additional fields.\n\nAlthough this endpoint has no required query string parameters, requests can optionally pass the `fields` query string parameter to indicate that one or more of the optional datasets is to be retrieved. Those additional fields are listed in the method titled \"Optional Fields\".", 1187 | "path": "/wow/guild/:realm/:guildName", 1188 | "parameters": { 1189 | ":realm": { 1190 | "type": "string", 1191 | "required": true, 1192 | "default": "Medivh", 1193 | "description": "The guild's realm.", 1194 | "location": "pathReplace" 1195 | }, 1196 | ":guildName": { 1197 | "type": "string", 1198 | "required": true, 1199 | "default": "Temp Guild Name", 1200 | "description": "The name of the guild to query.", 1201 | "location": "pathReplace" 1202 | }, 1203 | "fields": { 1204 | "type": "string", 1205 | "required": false, 1206 | "default": "achievements,challenge", 1207 | "description": "The optional data to retrieve about the guild. Each field value is explained in more detail in the following methods. If no fields are specified the API will only return basic guild data.", 1208 | "location": "query" 1209 | }, 1210 | "locale": { 1211 | "type": "string", 1212 | "required": false, 1213 | "default": "en_US", 1214 | "enum": [ 1215 | "en_US", 1216 | "pt_BR", 1217 | "es_MX" 1218 | ], 1219 | "description": "The locale to reflect in localized data.", 1220 | "location": "query" 1221 | }, 1222 | "jsonp": { 1223 | "type": "string", 1224 | "required": false, 1225 | "default": "", 1226 | "description": "Request for the data to be returned as a JSONP callback.", 1227 | "location": "query" 1228 | } 1229 | }, 1230 | "httpMethod": "GET" 1231 | }, 1232 | "Members": { 1233 | "description": "Returns a list of characters that are members of the guild. When the members list is requested, a list of character objects is returned. Each object in the returned members list contains a character block as well as a rank field.", 1234 | "path": "/wow/guild/:realm/:guildName", 1235 | "parameters": { 1236 | ":realm": { 1237 | "type": "string", 1238 | "required": true, 1239 | "default": "Medivh", 1240 | "description": "The guild's realm.", 1241 | "location": "pathReplace" 1242 | }, 1243 | ":guildName": { 1244 | "type": "string", 1245 | "required": true, 1246 | "default": "Temp Guild Name", 1247 | "description": "The name of the guild to query.", 1248 | "location": "pathReplace" 1249 | }, 1250 | "fields": { 1251 | "type": "string", 1252 | "required": true, 1253 | "default": "members", 1254 | "description": "A value of `members` tells the API to include guild's member list in the response.", 1255 | "location": "query" 1256 | }, 1257 | "locale": { 1258 | "type": "string", 1259 | "required": false, 1260 | "default": "en_US", 1261 | "enum": [ 1262 | "en_US", 1263 | "pt_BR", 1264 | "es_MX" 1265 | ], 1266 | "description": "The locale to reflect in localized data.", 1267 | "location": "query" 1268 | }, 1269 | "jsonp": { 1270 | "type": "string", 1271 | "required": false, 1272 | "default": "", 1273 | "description": "Request for the data to be returned as a JSONP callback.", 1274 | "location": "query" 1275 | } 1276 | }, 1277 | "httpMethod": "GET" 1278 | }, 1279 | "Achievements": { 1280 | "description": "A set of data structures that describe the achievements earned by the guild. When requesting achievement data, several sets of data will be returned.\n\n- `achievementsCompleted`: a list of achievement IDs.\n- `achievementsCompletedTimestamp`: a list of timestamps corresponding to the achievement IDs in the `achievementsCompleted` list. The value of each timestamp indicates when the related achievement was earned by the guild.\n- `criteria`: a list of criteria IDs used to determine the partial completeness of guild achievements.\n- `criteriaQuantity`: a list of values associated with a given achievement criteria. The position of a value corresponds to the position of a given achievement criteria.\n- `criteriaTimestamp`: a list of timestamps with values that represent when the criteria was considered complete. The position of a value corresponds to the position of a given achievement criteria.\n- `criteriaCreated`: a list of timestamps for which the value represents the time the criteria was considered started. The position of a value corresponds to the position of a given achievement criteria.\n\n", 1281 | "path": "/wow/guild/:realm/:guildName", 1282 | "parameters": { 1283 | ":realm": { 1284 | "type": "string", 1285 | "required": true, 1286 | "default": "Medivh", 1287 | "description": "The guild's realm.", 1288 | "location": "pathReplace" 1289 | }, 1290 | ":guildName": { 1291 | "type": "string", 1292 | "required": true, 1293 | "default": "Temp Guild Name", 1294 | "description": "The name of the guild to query.", 1295 | "location": "pathReplace" 1296 | }, 1297 | "fields": { 1298 | "type": "string", 1299 | "required": true, 1300 | "default": "achievements", 1301 | "description": "A value of `achievements` tells the API to include the guild's achievement data in the response.", 1302 | "location": "query" 1303 | }, 1304 | "locale": { 1305 | "type": "string", 1306 | "required": false, 1307 | "default": "en_US", 1308 | "enum": [ 1309 | "en_US", 1310 | "pt_BR", 1311 | "es_MX" 1312 | ], 1313 | "description": "The locale to reflect in localized data.", 1314 | "location": "query" 1315 | }, 1316 | "jsonp": { 1317 | "type": "string", 1318 | "required": false, 1319 | "default": "", 1320 | "description": "Request for the data to be returned as a JSONP callback.", 1321 | "location": "query" 1322 | } 1323 | }, 1324 | "httpMethod": "GET" 1325 | }, 1326 | "News": { 1327 | "description": "A set of data structures that describe the guild's news feed. When the news feed is requested, this resource returns a list of news objects. Each one has a type, a timestamp, and some other data depending on the type: `itemId`, an `achievement` object, and so on.", 1328 | "path": "/wow/guild/:realm/:guildName", 1329 | "parameters": { 1330 | ":realm": { 1331 | "type": "string", 1332 | "required": true, 1333 | "default": "Medivh", 1334 | "description": "The guild's realm.", 1335 | "location": "pathReplace" 1336 | }, 1337 | ":guildName": { 1338 | "type": "string", 1339 | "required": true, 1340 | "default": "Temp Guild Name", 1341 | "description": "The name of the guild to query.", 1342 | "location": "pathReplace" 1343 | }, 1344 | "fields": { 1345 | "type": "string", 1346 | "required": true, 1347 | "default": "news", 1348 | "description": "A value of `news` tells the API to include the guild's news feed in the response.", 1349 | "location": "query" 1350 | }, 1351 | "locale": { 1352 | "type": "string", 1353 | "required": false, 1354 | "default": "en_US", 1355 | "enum": [ 1356 | "en_US", 1357 | "pt_BR", 1358 | "es_MX" 1359 | ], 1360 | "description": "The locale to reflect in localized data.", 1361 | "location": "query" 1362 | }, 1363 | "jsonp": { 1364 | "type": "string", 1365 | "required": false, 1366 | "default": "", 1367 | "description": "Request for the data to be returned as a JSONP callback.", 1368 | "location": "query" 1369 | } 1370 | }, 1371 | "httpMethod": "GET" 1372 | }, 1373 | "Challenge": { 1374 | "description": "The top three challenge mode guild run times for each challenge mode map.", 1375 | "path": "/wow/guild/:realm/:guildName", 1376 | "parameters": { 1377 | ":realm": { 1378 | "type": "string", 1379 | "required": true, 1380 | "default": "Medivh", 1381 | "description": "The guild's realm.", 1382 | "location": "pathReplace" 1383 | }, 1384 | ":guildName": { 1385 | "type": "string", 1386 | "required": true, 1387 | "default": "", 1388 | "description": "The name of the guild to query.", 1389 | "location": "pathReplace" 1390 | }, 1391 | "fields": { 1392 | "type": "string", 1393 | "required": true, 1394 | "default": "challenge", 1395 | "description": "A value of `challenge` tells the API to include the guild's Challenge Mode data in the response.", 1396 | "location": "query" 1397 | }, 1398 | "locale": { 1399 | "type": "string", 1400 | "required": false, 1401 | "default": "en_US", 1402 | "enum": [ 1403 | "en_US", 1404 | "pt_BR", 1405 | "es_MX" 1406 | ], 1407 | "description": "The locale to reflect in localized data.", 1408 | "location": "query" 1409 | }, 1410 | "jsonp": { 1411 | "type": "string", 1412 | "required": false, 1413 | "default": "", 1414 | "description": "Request for the data to be returned as a JSONP callback.", 1415 | "location": "query" 1416 | } 1417 | }, 1418 | "httpMethod": "GET" 1419 | } 1420 | } 1421 | }, 1422 | "Item API": { 1423 | "methods": { 1424 | "Item": { 1425 | "description": "The item API provides detailed item information, including item set information.", 1426 | "path": "/wow/item/:itemId", 1427 | "parameters": { 1428 | ":itemId": { 1429 | "type": "number", 1430 | "required": true, 1431 | "default": "18803", 1432 | "description": "The requested item's unique ID.", 1433 | "location": "pathReplace" 1434 | }, 1435 | "locale": { 1436 | "type": "string", 1437 | "required": false, 1438 | "default": "en_US", 1439 | "enum": [ 1440 | "en_US", 1441 | "pt_BR", 1442 | "es_MX" 1443 | ], 1444 | "description": "The locale to reflect in localized data.", 1445 | "location": "query" 1446 | }, 1447 | "jsonp": { 1448 | "type": "string", 1449 | "required": false, 1450 | "default": "", 1451 | "description": "Request for the data to be returned as a JSONP callback.", 1452 | "location": "query" 1453 | } 1454 | }, 1455 | "httpMethod": "GET" 1456 | }, 1457 | "Item Set": { 1458 | "description": "The item API provides detailed item information, including item set information.", 1459 | "path": "/wow/item/set/:setId", 1460 | "parameters": { 1461 | ":setId": { 1462 | "type": "string", 1463 | "required": true, 1464 | "default": "1060", 1465 | "description": "The requested set's unique ID.", 1466 | "location": "pathReplace" 1467 | }, 1468 | "locale": { 1469 | "type": "string", 1470 | "required": false, 1471 | "default": "en_US", 1472 | "enum": [ 1473 | "en_US", 1474 | "pt_BR", 1475 | "es_MX" 1476 | ], 1477 | "description": "The locale to reflect in localized data.", 1478 | "location": "query" 1479 | }, 1480 | "jsonp": { 1481 | "type": "string", 1482 | "required": false, 1483 | "default": "", 1484 | "description": "Request for the data to be returned as a JSONP callback.", 1485 | "location": "query" 1486 | } 1487 | }, 1488 | "httpMethod": "GET" 1489 | } 1490 | } 1491 | }, 1492 | "Mount API": { 1493 | "methods": { 1494 | "Master List": { 1495 | "description": "Returns a list of all supported mounts.", 1496 | "path": "/wow/mount/", 1497 | "parameters": { 1498 | "locale": { 1499 | "type": "string", 1500 | "required": false, 1501 | "default": "en_US", 1502 | "enum": [ 1503 | "en_US", 1504 | "pt_BR", 1505 | "es_MX" 1506 | ], 1507 | "description": "The locale to reflect in localized data.", 1508 | "location": "query" 1509 | }, 1510 | "jsonp": { 1511 | "type": "string", 1512 | "required": false, 1513 | "default": "", 1514 | "description": "Request for the data to be returned as a JSONP callback.", 1515 | "location": "query" 1516 | } 1517 | }, 1518 | "httpMethod": "GET" 1519 | } 1520 | } 1521 | }, 1522 | "Pet API": { 1523 | "methods": { 1524 | "Master List": { 1525 | "description": "Returns a list of all supported battle and vanity pets.", 1526 | "path": "/wow/pet/", 1527 | "parameters": { 1528 | "locale": { 1529 | "type": "string", 1530 | "required": false, 1531 | "default": "en_US", 1532 | "enum": [ 1533 | "en_US", 1534 | "pt_BR", 1535 | "es_MX" 1536 | ], 1537 | "description": "The locale to reflect in localized data.", 1538 | "location": "query" 1539 | }, 1540 | "jsonp": { 1541 | "type": "string", 1542 | "required": false, 1543 | "default": "", 1544 | "description": "Request for the data to be returned as a JSONP callback.", 1545 | "location": "query" 1546 | } 1547 | }, 1548 | "httpMethod": "GET" 1549 | }, 1550 | "Abilities": { 1551 | "description": "Returns data about a individual battle pet ability ID. This resource does not provide ability tooltips.", 1552 | "path": "/wow/pet/ability/:abilityID", 1553 | "parameters": { 1554 | ":abilityID": { 1555 | "type": "string", 1556 | "required": true, 1557 | "default": "640", 1558 | "description": "The ID of the ability to retrieve.", 1559 | "location": "pathReplace" 1560 | }, 1561 | "locale": { 1562 | "type": "string", 1563 | "required": false, 1564 | "default": "en_US", 1565 | "enum": [ 1566 | "en_US", 1567 | "pt_BR", 1568 | "es_MX" 1569 | ], 1570 | "description": "The locale to reflect in localized data.", 1571 | "location": "query" 1572 | }, 1573 | "jsonp": { 1574 | "type": "string", 1575 | "required": false, 1576 | "default": "", 1577 | "description": "Request for the data to be returned as a JSONP callback.", 1578 | "location": "query" 1579 | } 1580 | }, 1581 | "httpMethod": "GET" 1582 | }, 1583 | "Species": { 1584 | "description": "Returns data about an individual pet species. Use `pets` as the `field` value in a character profile request to get species IDs. Each species also has data about its six abilities.", 1585 | "path": "/wow/pet/species/:speciesID", 1586 | "parameters": { 1587 | ":speciesID": { 1588 | "type": "string", 1589 | "required": true, 1590 | "default": "258", 1591 | "description": "The species for which to retrieve data.", 1592 | "location": "pathReplace" 1593 | }, 1594 | "locale": { 1595 | "type": "string", 1596 | "required": false, 1597 | "default": "en_US", 1598 | "enum": [ 1599 | "en_US", 1600 | "pt_BR", 1601 | "es_MX" 1602 | ], 1603 | "description": "The locale to reflect in localized data.", 1604 | "location": "query" 1605 | }, 1606 | "jsonp": { 1607 | "type": "string", 1608 | "required": false, 1609 | "default": "", 1610 | "description": "Request for the data to be returned as a JSONP callback.", 1611 | "location": "query" 1612 | } 1613 | }, 1614 | "httpMethod": "GET" 1615 | }, 1616 | "Stats": { 1617 | "description": "Returns detailed information about a given species of pet.", 1618 | "path": "/wow/pet/stats/:speciesID", 1619 | "parameters": { 1620 | ":speciesID": { 1621 | "type": "string", 1622 | "required": true, 1623 | "default": "258", 1624 | "description": "The pet's species ID. This can be found by querying a user's list of pets via the Character Profile API.", 1625 | "location": "pathReplace" 1626 | }, 1627 | "level": { 1628 | "type": "number", 1629 | "required": false, 1630 | "default": "25", 1631 | "description": "The pet's level. Pet levels max out at 25. If omitted, the API assumes a default value of 1. ", 1632 | "location": "query" 1633 | }, 1634 | "breedId": { 1635 | "type": "number", 1636 | "required": false, 1637 | "default": "5", 1638 | "description": "The pet's breed. Retrievable via the Character Profile API. If omitted the API assumes a default value of 3.", 1639 | "location": "query" 1640 | }, 1641 | "qualityId": { 1642 | "type": "number", 1643 | "required": false, 1644 | "default": "4", 1645 | "description": "The pet's quality. Retrievable via the Character Profile API. Pet quality can range from 0 to 5 (0 is poor quality and 5 is legendary). If omitted, the API will assume a default value of 1.", 1646 | "location": "query" 1647 | }, 1648 | "locale": { 1649 | "type": "string", 1650 | "required": false, 1651 | "default": "en_US", 1652 | "enum": [ 1653 | "en_US", 1654 | "pt_BR", 1655 | "es_MX" 1656 | ], 1657 | "description": "The locale to reflect in localized data.", 1658 | "location": "query" 1659 | }, 1660 | "jsonp": { 1661 | "type": "string", 1662 | "required": false, 1663 | "default": "", 1664 | "description": "Request for the data to be returned as a JSONP callback.", 1665 | "location": "query" 1666 | } 1667 | }, 1668 | "httpMethod": "GET" 1669 | } 1670 | } 1671 | }, 1672 | "PVP API": { 1673 | "methods": { 1674 | "Leaderboards": { 1675 | "description": "The Leaderboard API endpoint provides leaderboard information for the 2v2, 3v3, 5v5, and Rated Battleground leaderboards.", 1676 | "path": "/wow/leaderboard/:bracket", 1677 | "parameters": { 1678 | ":bracket": { 1679 | "type": "string", 1680 | "required": true, 1681 | "default": "2v2", 1682 | "enum": [ 1683 | "2v2", 1684 | "3v3", 1685 | "5v5", 1686 | "rbg" 1687 | ], 1688 | "description": "The type of leaderboard to retrieve. Valid entries are `2v2`, `3v3`, `5v5`, and `rbg`.", 1689 | "location": "pathReplace" 1690 | }, 1691 | "locale": { 1692 | "type": "string", 1693 | "required": false, 1694 | "default": "en_US", 1695 | "enum": [ 1696 | "en_US", 1697 | "pt_BR", 1698 | "es_MX" 1699 | ], 1700 | "description": "The locale to reflect in localized data.", 1701 | "location": "query" 1702 | }, 1703 | "jsonp": { 1704 | "type": "string", 1705 | "required": false, 1706 | "default": "", 1707 | "description": "Request for the data to be returned as a JSONP callback.", 1708 | "location": "query" 1709 | } 1710 | }, 1711 | "httpMethod": "GET" 1712 | } 1713 | } 1714 | }, 1715 | "Quest API": { 1716 | "methods": { 1717 | "Quest": { 1718 | "description": "Returns metadata for a specified quest.", 1719 | "path": "/wow/quest/:questId", 1720 | "parameters": { 1721 | ":questId": { 1722 | "type": "string", 1723 | "required": true, 1724 | "default": "13146", 1725 | "description": "The ID of the quest to retrieve.", 1726 | "location": "pathReplace" 1727 | }, 1728 | "locale": { 1729 | "type": "string", 1730 | "required": false, 1731 | "default": "en_US", 1732 | "enum": [ 1733 | "en_US", 1734 | "pt_BR", 1735 | "es_MX" 1736 | ], 1737 | "description": "The locale to reflect in localized data.", 1738 | "location": "query" 1739 | }, 1740 | "jsonp": { 1741 | "type": "string", 1742 | "required": false, 1743 | "default": "", 1744 | "description": "Request for the data to be returned as a JSONP callback.", 1745 | "location": "query" 1746 | } 1747 | }, 1748 | "httpMethod": "GET" 1749 | } 1750 | } 1751 | }, 1752 | "Realm Status API": { 1753 | "methods": { 1754 | "Realm Status": { 1755 | "description": "The realm status API allows developers to retrieve realm status information. This information is limited to whether or not the realm is up, the type and state of the realm, and the current population.\n\nAlthough this endpoint has no required query string parameters, use the optional `realms` parameter to limit the realms returned to a specific set of realms.", 1756 | "path": "/wow/realm/status", 1757 | "httpMethod": "GET", 1758 | "parameters": { 1759 | "locale": { 1760 | "type": "string", 1761 | "required": false, 1762 | "default": "en_US", 1763 | "enum": [ 1764 | "en_US", 1765 | "pt_BR", 1766 | "es_MX" 1767 | ], 1768 | "description": "The locale to reflect in localized data.", 1769 | "location": "query" 1770 | }, 1771 | "jsonp": { 1772 | "type": "string", 1773 | "required": false, 1774 | "default": "", 1775 | "description": "Request for the data to be returned as a JSONP callback.", 1776 | "location": "query" 1777 | } 1778 | } 1779 | } 1780 | } 1781 | }, 1782 | "Recipe API": { 1783 | "methods": { 1784 | "Recipe": { 1785 | "description": "Returns basic recipe information.", 1786 | "path": "/wow/recipe/:recipeId", 1787 | "parameters": { 1788 | ":recipeId": { 1789 | "type": "string", 1790 | "required": true, 1791 | "default": "33994", 1792 | "description": "Unique ID for the desired recipe.", 1793 | "location": "pathReplace" 1794 | }, 1795 | "locale": { 1796 | "type": "string", 1797 | "required": false, 1798 | "default": "en_US", 1799 | "enum": [ 1800 | "en_US", 1801 | "pt_BR", 1802 | "es_MX" 1803 | ], 1804 | "description": "The locale to reflect in localized data.", 1805 | "location": "query" 1806 | }, 1807 | "jsonp": { 1808 | "type": "string", 1809 | "required": false, 1810 | "default": "", 1811 | "description": "Request for the data to be returned as a JSONP callback.", 1812 | "location": "query" 1813 | } 1814 | }, 1815 | "httpMethod": "GET" 1816 | } 1817 | } 1818 | }, 1819 | "Spell API": { 1820 | "methods": { 1821 | "Spell": { 1822 | "description": "Returns information about spells.", 1823 | "path": "/wow/spell/:spellId", 1824 | "parameters": { 1825 | ":spellId": { 1826 | "type": "string", 1827 | "required": true, 1828 | "default": "17086", 1829 | "description": "The ID of the spell to retrieve.", 1830 | "location": "pathReplace" 1831 | }, 1832 | "locale": { 1833 | "type": "string", 1834 | "required": false, 1835 | "default": "en_US", 1836 | "enum": [ 1837 | "en_US", 1838 | "pt_BR", 1839 | "es_MX" 1840 | ], 1841 | "description": "The locale to reflect in localized data.", 1842 | "location": "query" 1843 | }, 1844 | "jsonp": { 1845 | "type": "string", 1846 | "required": false, 1847 | "default": "", 1848 | "description": "Request for the data to be returned as a JSONP callback.", 1849 | "location": "query" 1850 | } 1851 | }, 1852 | "httpMethod": "GET" 1853 | } 1854 | } 1855 | }, 1856 | "User API": { 1857 | "methods": { 1858 | "Characters": { 1859 | "description": "Returns a list of characters for an account.", 1860 | "path": "/wow/user/characters", 1861 | "parameters": { 1862 | "locale": { 1863 | "type": "string", 1864 | "required": false, 1865 | "default": "en_US", 1866 | "enum": [ 1867 | "en_US", 1868 | "pt_BR", 1869 | "es_MX" 1870 | ], 1871 | "description": "The locale to reflect in localized data.", 1872 | "location": "query" 1873 | }, 1874 | "jsonp": { 1875 | "type": "string", 1876 | "required": false, 1877 | "default": "", 1878 | "description": "Request for the data to be returned as a JSONP callback.", 1879 | "location": "query" 1880 | } 1881 | }, 1882 | "httpMethod": "GET" 1883 | } 1884 | } 1885 | }, 1886 | "Zone API": { 1887 | "methods": { 1888 | "Master List": { 1889 | "description": "Returns a list of all supported zones and their bosses. A \"zone\" in this context should be considered a dungeon or a raid, not a world zone. A \"boss\" in this context should be considered a boss encounter, which may include more than one NPC.", 1890 | "path": "/wow/zone/", 1891 | "parameters": { 1892 | "locale": { 1893 | "type": "string", 1894 | "required": false, 1895 | "default": "en_US", 1896 | "enum": [ 1897 | "en_US", 1898 | "pt_BR", 1899 | "es_MX" 1900 | ], 1901 | "description": "The locale to reflect in localized data.", 1902 | "location": "query" 1903 | }, 1904 | "jsonp": { 1905 | "type": "string", 1906 | "required": false, 1907 | "default": "", 1908 | "description": "Request for the data to be returned as a JSONP callback.", 1909 | "location": "query" 1910 | } 1911 | }, 1912 | "httpMethod": "GET" 1913 | }, 1914 | "Zone": { 1915 | "description": "Returns information about zones.", 1916 | "path": "/wow/zone/:zoneid", 1917 | "parameters": { 1918 | ":zoneid": { 1919 | "type": "string", 1920 | "required": true, 1921 | "default": "4131", 1922 | "description": "The ID of the zone to retrieve.", 1923 | "location": "pathReplace" 1924 | }, 1925 | "locale": { 1926 | "type": "string", 1927 | "required": false, 1928 | "default": "en_US", 1929 | "enum": [ 1930 | "en_US", 1931 | "pt_BR", 1932 | "es_MX" 1933 | ], 1934 | "description": "The locale to reflect in localized data.", 1935 | "location": "query" 1936 | }, 1937 | "jsonp": { 1938 | "type": "string", 1939 | "required": false, 1940 | "default": "", 1941 | "description": "Request for the data to be returned as a JSONP callback.", 1942 | "location": "query" 1943 | } 1944 | }, 1945 | "httpMethod": "GET" 1946 | } 1947 | } 1948 | }, 1949 | "Data Resources": { 1950 | "methods": { 1951 | "Battlegroups": { 1952 | "description": "Returns a list of battlegroups for the specified region. Note the trailing `/` on this request path.", 1953 | "path": "/wow/data/battlegroups/", 1954 | "httpMethod": "GET", 1955 | "parameters": { 1956 | "locale": { 1957 | "type": "string", 1958 | "required": false, 1959 | "default": "en_US", 1960 | "enum": [ 1961 | "en_US", 1962 | "pt_BR", 1963 | "es_MX" 1964 | ], 1965 | "description": "The locale to reflect in localized data.", 1966 | "location": "query" 1967 | }, 1968 | "jsonp": { 1969 | "type": "string", 1970 | "required": false, 1971 | "default": "", 1972 | "description": "Request for the data to be returned as a JSONP callback.", 1973 | "location": "query" 1974 | } 1975 | } 1976 | }, 1977 | "Character Races": { 1978 | "description": "Returns a list of races and their associated faction, name, unique ID, and skin.", 1979 | "path": "/wow/data/character/races", 1980 | "httpMethod": "GET", 1981 | "parameters": { 1982 | "locale": { 1983 | "type": "string", 1984 | "required": false, 1985 | "default": "en_US", 1986 | "enum": [ 1987 | "en_US", 1988 | "pt_BR", 1989 | "es_MX" 1990 | ], 1991 | "description": "The locale to reflect in localized data.", 1992 | "location": "query" 1993 | }, 1994 | "jsonp": { 1995 | "type": "string", 1996 | "required": false, 1997 | "default": "", 1998 | "description": "Request for the data to be returned as a JSONP callback.", 1999 | "location": "query" 2000 | } 2001 | } 2002 | }, 2003 | "Character Classes": { 2004 | "description": "Returns a list of character classes.", 2005 | "path": "/wow/data/character/classes", 2006 | "httpMethod": "GET", 2007 | "parameters": { 2008 | "locale": { 2009 | "type": "string", 2010 | "required": false, 2011 | "default": "en_US", 2012 | "enum": [ 2013 | "en_US", 2014 | "pt_BR", 2015 | "es_MX" 2016 | ], 2017 | "description": "The locale to reflect in localized data.", 2018 | "location": "query" 2019 | }, 2020 | "jsonp": { 2021 | "type": "string", 2022 | "required": false, 2023 | "default": "", 2024 | "description": "Request for the data to be returned as a JSONP callback.", 2025 | "location": "query" 2026 | } 2027 | } 2028 | }, 2029 | "Character Achievements": { 2030 | "description": "Returns a list of all achievements that characters can earn as well as the category structure and hierarchy.", 2031 | "path": "/wow/data/character/achievements", 2032 | "httpMethod": "GET", 2033 | "parameters": { 2034 | "locale": { 2035 | "type": "string", 2036 | "required": false, 2037 | "default": "en_US", 2038 | "enum": [ 2039 | "en_US", 2040 | "pt_BR", 2041 | "es_MX" 2042 | ], 2043 | "description": "The locale to reflect in localized data.", 2044 | "location": "query" 2045 | }, 2046 | "jsonp": { 2047 | "type": "string", 2048 | "required": false, 2049 | "default": "", 2050 | "description": "Request for the data to be returned as a JSONP callback.", 2051 | "location": "query" 2052 | } 2053 | } 2054 | }, 2055 | "Guild Rewards": { 2056 | "description": "The guild rewards data API provides a list of all guild rewards.", 2057 | "path": "/wow/data/guild/rewards", 2058 | "httpMethod": "GET", 2059 | "parameters": { 2060 | "locale": { 2061 | "type": "string", 2062 | "required": false, 2063 | "default": "en_US", 2064 | "enum": [ 2065 | "en_US", 2066 | "pt_BR", 2067 | "es_MX" 2068 | ], 2069 | "description": "The locale to reflect in localized data.", 2070 | "location": "query" 2071 | }, 2072 | "jsonp": { 2073 | "type": "string", 2074 | "required": false, 2075 | "default": "", 2076 | "description": "Request for the data to be returned as a JSONP callback.", 2077 | "location": "query" 2078 | } 2079 | } 2080 | }, 2081 | "Guild Perks": { 2082 | "description": "Returns a list of all guild perks.", 2083 | "path": "/wow/data/guild/perks", 2084 | "httpMethod": "GET", 2085 | "parameters": { 2086 | "locale": { 2087 | "type": "string", 2088 | "required": false, 2089 | "default": "en_US", 2090 | "enum": [ 2091 | "en_US", 2092 | "pt_BR", 2093 | "es_MX" 2094 | ], 2095 | "description": "The locale to reflect in localized data.", 2096 | "location": "query" 2097 | }, 2098 | "jsonp": { 2099 | "type": "string", 2100 | "required": false, 2101 | "default": "", 2102 | "description": "Request for the data to be returned as a JSONP callback.", 2103 | "location": "query" 2104 | } 2105 | } 2106 | }, 2107 | "Guild Achievements": { 2108 | "description": "Returns a list of all guild achievements as well as the category structure and hierarchy.", 2109 | "path": "/wow/data/guild/achievements", 2110 | "httpMethod": "GET", 2111 | "parameters": { 2112 | "locale": { 2113 | "type": "string", 2114 | "required": false, 2115 | "default": "en_US", 2116 | "enum": [ 2117 | "en_US", 2118 | "pt_BR", 2119 | "es_MX" 2120 | ], 2121 | "description": "The locale to reflect in localized data.", 2122 | "location": "query" 2123 | }, 2124 | "jsonp": { 2125 | "type": "string", 2126 | "required": false, 2127 | "default": "", 2128 | "description": "Request for the data to be returned as a JSONP callback.", 2129 | "location": "query" 2130 | } 2131 | } 2132 | }, 2133 | "Item Classes": { 2134 | "description": "Returns a list of item classes.", 2135 | "path": "/wow/data/item/classes", 2136 | "httpMethod": "GET", 2137 | "parameters": { 2138 | "locale": { 2139 | "type": "string", 2140 | "required": false, 2141 | "default": "en_US", 2142 | "enum": [ 2143 | "en_US", 2144 | "pt_BR", 2145 | "es_MX" 2146 | ], 2147 | "description": "The locale to reflect in localized data.", 2148 | "location": "query" 2149 | }, 2150 | "jsonp": { 2151 | "type": "string", 2152 | "required": false, 2153 | "default": "", 2154 | "description": "Request for the data to be returned as a JSONP callback.", 2155 | "location": "query" 2156 | } 2157 | } 2158 | }, 2159 | "Talents": { 2160 | "description": "Returns a list of talents, specs, and glyphs for each class.", 2161 | "path": "/wow/data/talents", 2162 | "httpMethod": "GET", 2163 | "parameters": { 2164 | "locale": { 2165 | "type": "string", 2166 | "required": false, 2167 | "default": "en_US", 2168 | "enum": [ 2169 | "en_US", 2170 | "pt_BR", 2171 | "es_MX" 2172 | ], 2173 | "description": "The locale to reflect in localized data.", 2174 | "location": "query" 2175 | }, 2176 | "jsonp": { 2177 | "type": "string", 2178 | "required": false, 2179 | "default": "", 2180 | "description": "Request for the data to be returned as a JSONP callback.", 2181 | "location": "query" 2182 | } 2183 | } 2184 | }, 2185 | "Pet Types": { 2186 | "description": "Returns a list of the different battle pet types, including what they are strong and weak against.", 2187 | "path": "/wow/data/pet/types", 2188 | "httpMethod": "GET", 2189 | "parameters": { 2190 | "locale": { 2191 | "type": "string", 2192 | "required": false, 2193 | "default": "en_US", 2194 | "enum": [ 2195 | "en_US", 2196 | "pt_BR", 2197 | "es_MX" 2198 | ], 2199 | "description": "The locale to reflect in localized data.", 2200 | "location": "query" 2201 | }, 2202 | "jsonp": { 2203 | "type": "string", 2204 | "required": false, 2205 | "default": "", 2206 | "description": "Request for the data to be returned as a JSONP callback.", 2207 | "location": "query" 2208 | } 2209 | } 2210 | } 2211 | } 2212 | } 2213 | } 2214 | } 2215 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lockwooddev/python-wowapi/580ff157db246a8e119e71076183044f818e3b41/tests/__init__.py -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | from .fixtures import * # noqa 2 | -------------------------------------------------------------------------------- /tests/fixtures.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import requests 3 | 4 | 5 | @pytest.fixture 6 | def session_get_mock(mocker): 7 | return mocker.patch('requests.Session.get') 8 | 9 | 10 | @pytest.fixture 11 | def utc_mock(mocker): 12 | return mocker.patch('wowapi.api.WowApi._utcnow') 13 | 14 | 15 | def get_success_response(): 16 | mock = requests.models.Response() 17 | mock.status_code = 200 18 | mock._content = b'{}' 19 | return mock 20 | 21 | 22 | class ResponseMock(object): 23 | 24 | def __call__(self, status_code, content): 25 | mock = requests.models.Response() 26 | mock.status_code = status_code 27 | mock._content = content 28 | return mock 29 | 30 | 31 | @pytest.fixture 32 | def response_mock(mocker): 33 | return mocker.patch('requests.Session.get', return_value=get_success_response()) 34 | -------------------------------------------------------------------------------- /tests/mixins/test_game_data.py: -------------------------------------------------------------------------------- 1 | import copy 2 | from datetime import datetime, timedelta 3 | 4 | from wowapi import WowApi 5 | 6 | 7 | class TestGameDataMixin: 8 | 9 | def setup(self): 10 | self.params = {'access_token': 'secret'} 11 | 12 | self.api = WowApi('client-id', 'client-secret') 13 | self.api._access_tokens = { 14 | 'us': { 15 | 'token': 'secret', 16 | 'expiration': datetime.utcnow() + timedelta(hours=1) 17 | } 18 | } 19 | 20 | # Achievement API 21 | 22 | def test_get_achievement_category_index(self, response_mock): 23 | self.api.get_achievement_category_index('us', 'dynamic-us') 24 | params = copy.deepcopy(self.params) 25 | params['namespace'] = 'dynamic-us' 26 | response_mock.assert_called_with( 27 | 'https://us.api.blizzard.com/data/wow/achievement-category/index', params=params) 28 | 29 | def test_get_achievement_category(self, response_mock): 30 | self.api.get_achievement_category('us', 'dynamic-us', 81) 31 | params = copy.deepcopy(self.params) 32 | params['namespace'] = 'dynamic-us' 33 | response_mock.assert_called_with( 34 | 'https://us.api.blizzard.com/data/wow/achievement-category/81', params=params) 35 | 36 | def test_get_achievement_index(self, response_mock): 37 | self.api.get_achievement_index('us', 'dynamic-us') 38 | params = copy.deepcopy(self.params) 39 | params['namespace'] = 'dynamic-us' 40 | response_mock.assert_called_with( 41 | 'https://us.api.blizzard.com/data/wow/achievement/index', params=params) 42 | 43 | def test_get_achievement_data(self, response_mock): 44 | self.api.get_achievement_data('us', 'dynamic-us', 6) 45 | params = copy.deepcopy(self.params) 46 | params['namespace'] = 'dynamic-us' 47 | response_mock.assert_called_with( 48 | 'https://us.api.blizzard.com/data/wow/achievement/6', params=params) 49 | 50 | def test_get_achievement_media(self, response_mock): 51 | self.api.get_achievement_media('us', 'dynamic-us', 6) 52 | params = copy.deepcopy(self.params) 53 | params['namespace'] = 'dynamic-us' 54 | response_mock.assert_called_with( 55 | 'https://us.api.blizzard.com/data/wow/media/achievement/6', params=params) 56 | 57 | # Auction House API 58 | 59 | def test_get_auctions(self, response_mock): 60 | self.api.get_auctions('us', 'dynamic-us', 1146) 61 | params = copy.deepcopy(self.params) 62 | params['namespace'] = 'dynamic-us' 63 | response_mock.assert_called_with( 64 | 'https://us.api.blizzard.com/data/wow/connected-realm/1146/auctions', params=params) 65 | 66 | # Azerite Essence API 67 | 68 | def test_get_azerite_essence_index(self, response_mock): 69 | self.api.get_azerite_essence_index('us', 'dynamic-us') 70 | params = copy.deepcopy(self.params) 71 | params['namespace'] = 'dynamic-us' 72 | response_mock.assert_called_with( 73 | 'https://us.api.blizzard.com/data/wow/azerite-essence/index', params=params) 74 | 75 | def test_get_azerite_essence(self, response_mock): 76 | self.api.get_azerite_essence('us', 'dynamic-us', 2) 77 | params = copy.deepcopy(self.params) 78 | params['namespace'] = 'dynamic-us' 79 | response_mock.assert_called_with( 80 | 'https://us.api.blizzard.com/data/wow/azerite-essence/2', params=params) 81 | 82 | def test_get_azerite_essence_media(self, response_mock): 83 | self.api.get_azerite_essence_media('us', 'dynamic-us', 2) 84 | params = copy.deepcopy(self.params) 85 | params['namespace'] = 'dynamic-us' 86 | response_mock.assert_called_with( 87 | 'https://us.api.blizzard.com/data/wow/media/azerite-essence/2', params=params) 88 | 89 | # Connected Realm API 90 | 91 | def test_get_connected_realm_index(self, response_mock): 92 | self.api.get_connected_realm_index('us', 'dynamic-us') 93 | params = copy.deepcopy(self.params) 94 | params['namespace'] = 'dynamic-us' 95 | response_mock.assert_called_with( 96 | 'https://us.api.blizzard.com/data/wow/connected-realm/index', params=params) 97 | 98 | def test_get_connected_realm(self, response_mock): 99 | self.api.get_connected_realm('us', 'dynamic-us', 1) 100 | params = copy.deepcopy(self.params) 101 | params['namespace'] = 'dynamic-us' 102 | response_mock.assert_called_with( 103 | 'https://us.api.blizzard.com/data/wow/connected-realm/1', params=params) 104 | 105 | # Creature API 106 | 107 | def test_get_creature_family_index(self, response_mock): 108 | self.api.get_creature_family_index('us', 'dynamic-us') 109 | params = copy.deepcopy(self.params) 110 | params['namespace'] = 'dynamic-us' 111 | response_mock.assert_called_with( 112 | 'https://us.api.blizzard.com/data/wow/creature-family/index', params=params) 113 | 114 | def test_get_creature_family(self, response_mock): 115 | self.api.get_creature_family('us', 'dynamic-us', 1) 116 | params = copy.deepcopy(self.params) 117 | params['namespace'] = 'dynamic-us' 118 | response_mock.assert_called_with( 119 | 'https://us.api.blizzard.com/data/wow/creature-family/1', params=params) 120 | 121 | def test_get_creature_type_index(self, response_mock): 122 | self.api.get_creature_type_index('us', 'dynamic-us') 123 | params = copy.deepcopy(self.params) 124 | params['namespace'] = 'dynamic-us' 125 | response_mock.assert_called_with( 126 | 'https://us.api.blizzard.com/data/wow/creature-type/index', params=params) 127 | 128 | def test_get_creature_type(self, response_mock): 129 | self.api.get_creature_type('us', 'dynamic-us', 1) 130 | params = copy.deepcopy(self.params) 131 | params['namespace'] = 'dynamic-us' 132 | response_mock.assert_called_with( 133 | 'https://us.api.blizzard.com/data/wow/creature-type/1', params=params) 134 | 135 | def test_get_creature(self, response_mock): 136 | self.api.get_creature('us', 'dynamic-us', 1) 137 | params = copy.deepcopy(self.params) 138 | params['namespace'] = 'dynamic-us' 139 | response_mock.assert_called_with( 140 | 'https://us.api.blizzard.com/data/wow/creature/1', params=params) 141 | 142 | def test_get_creature_display_media(self, response_mock): 143 | self.api.get_creature_display_media('us', 'dynamic-us', 1) 144 | params = copy.deepcopy(self.params) 145 | params['namespace'] = 'dynamic-us' 146 | response_mock.assert_called_with( 147 | 'https://us.api.blizzard.com/data/wow/media/creature-display/1', params=params) 148 | 149 | def test_get_creature_family_media(self, response_mock): 150 | self.api.get_creature_family_media('us', 'dynamic-us', 1) 151 | params = copy.deepcopy(self.params) 152 | params['namespace'] = 'dynamic-us' 153 | response_mock.assert_called_with( 154 | 'https://us.api.blizzard.com/data/wow/media/creature-family/1', params=params) 155 | 156 | # Guild Crest API 157 | 158 | def test_get_guild_crest_index(self, response_mock): 159 | self.api.get_guild_crest_index('us', 'dynamic-us') 160 | params = copy.deepcopy(self.params) 161 | params['namespace'] = 'dynamic-us' 162 | response_mock.assert_called_with( 163 | 'https://us.api.blizzard.com/data/wow/guild-crest/index', params=params) 164 | 165 | def test_get_guild_crest_border_media(self, response_mock): 166 | self.api.get_guild_crest_border_media('us', 'dynamic-us', 0) 167 | params = copy.deepcopy(self.params) 168 | params['namespace'] = 'dynamic-us' 169 | response_mock.assert_called_with( 170 | 'https://us.api.blizzard.com/data/wow/media/guild-crest/border/0', params=params) 171 | 172 | def test_get_guild_crest_emblem_media(self, response_mock): 173 | self.api.get_guild_crest_emblem_media('us', 'dynamic-us', 0) 174 | params = copy.deepcopy(self.params) 175 | params['namespace'] = 'dynamic-us' 176 | response_mock.assert_called_with( 177 | 'https://us.api.blizzard.com/data/wow/media/guild-crest/emblem/0', params=params) 178 | 179 | # Item API 180 | 181 | def test_get_item_class_index(self, response_mock): 182 | self.api.get_item_class_index('us', 'dynamic-us') 183 | params = copy.deepcopy(self.params) 184 | params['namespace'] = 'dynamic-us' 185 | response_mock.assert_called_with( 186 | 'https://us.api.blizzard.com/data/wow/item-class/index', params=params) 187 | 188 | def test_get_item_class(self, response_mock): 189 | self.api.get_item_class('us', 'dynamic-us', 2) 190 | params = copy.deepcopy(self.params) 191 | params['namespace'] = 'dynamic-us' 192 | response_mock.assert_called_with( 193 | 'https://us.api.blizzard.com/data/wow/item-class/2', params=params) 194 | 195 | def test_get_item_set_index(self, response_mock): 196 | self.api.get_item_set_index('us', 'dynamic-us') 197 | params = copy.deepcopy(self.params) 198 | params['namespace'] = 'dynamic-us' 199 | response_mock.assert_called_with( 200 | 'https://us.api.blizzard.com/data/wow/item-set/index', params=params) 201 | 202 | def test_get_item_set(self, response_mock): 203 | self.api.get_item_set('us', 'dynamic-us', 1) 204 | params = copy.deepcopy(self.params) 205 | params['namespace'] = 'dynamic-us' 206 | response_mock.assert_called_with( 207 | 'https://us.api.blizzard.com/data/wow/item-set/1', params=params) 208 | 209 | def test_get_item_subclass(self, response_mock): 210 | self.api.get_item_subclass('us', 'dynamic-us', 2, 1) 211 | params = copy.deepcopy(self.params) 212 | params['namespace'] = 'dynamic-us' 213 | response_mock.assert_called_with( 214 | 'https://us.api.blizzard.com/data/wow/item-class/2/item-subclass/1', params=params) 215 | 216 | def test_get_item_data(self, response_mock): 217 | self.api.get_item_data('us', 'dynamic-us', 9999) 218 | params = copy.deepcopy(self.params) 219 | params['namespace'] = 'dynamic-us' 220 | response_mock.assert_called_with( 221 | 'https://us.api.blizzard.com/data/wow/item/9999', params=params) 222 | 223 | def test_get_item_media(self, response_mock): 224 | self.api.get_item_media('us', 'dynamic-us', 9999) 225 | params = copy.deepcopy(self.params) 226 | params['namespace'] = 'dynamic-us' 227 | response_mock.assert_called_with( 228 | 'https://us.api.blizzard.com/data/wow/media/item/9999', params=params) 229 | 230 | # Journal API 231 | 232 | def test_get_journal_index(self, response_mock): 233 | self.api.get_journal_index('us', 'dynamic-us') 234 | params = copy.deepcopy(self.params) 235 | params['namespace'] = 'dynamic-us' 236 | response_mock.assert_called_with( 237 | 'https://us.api.blizzard.com/data/wow/journal-expansion/index', params=params) 238 | 239 | def test_get_journal_expansion(self, response_mock): 240 | self.api.get_journal_expansion('us', 'dynamic-us', 68) 241 | params = copy.deepcopy(self.params) 242 | params['namespace'] = 'dynamic-us' 243 | response_mock.assert_called_with( 244 | 'https://us.api.blizzard.com/data/wow/journal-expansion/68', params=params) 245 | 246 | def test_get_journal_encounter_index(self, response_mock): 247 | self.api.get_journal_encounter_index('us', 'dynamic-us') 248 | params = copy.deepcopy(self.params) 249 | params['namespace'] = 'dynamic-us' 250 | response_mock.assert_called_with( 251 | 'https://us.api.blizzard.com/data/wow/journal-encounter/index', params=params) 252 | 253 | def test_get_journal_encounter(self, response_mock): 254 | self.api.get_journal_encounter('us', 'dynamic-us', 89) 255 | params = copy.deepcopy(self.params) 256 | params['namespace'] = 'dynamic-us' 257 | response_mock.assert_called_with( 258 | 'https://us.api.blizzard.com/data/wow/journal-encounter/89', params=params) 259 | 260 | def test_get_journal_instance_index(self, response_mock): 261 | self.api.get_journal_instance_index('us', 'dynamic-us') 262 | params = copy.deepcopy(self.params) 263 | params['namespace'] = 'dynamic-us' 264 | response_mock.assert_called_with( 265 | 'https://us.api.blizzard.com/data/wow/journal-instance/index', params=params) 266 | 267 | def test_get_journal_instance(self, response_mock): 268 | self.api.get_journal_instance('us', 'dynamic-us', 63) 269 | params = copy.deepcopy(self.params) 270 | params['namespace'] = 'dynamic-us' 271 | response_mock.assert_called_with( 272 | 'https://us.api.blizzard.com/data/wow/journal-instance/63', params=params) 273 | 274 | def test_get_journal_instance_media(self, response_mock): 275 | self.api.get_journal_instance_media('us', 'dynamic-us', 63) 276 | params = copy.deepcopy(self.params) 277 | params['namespace'] = 'dynamic-us' 278 | response_mock.assert_called_with( 279 | 'https://us.api.blizzard.com/data/wow/media/journal-instance/63', params=params) 280 | 281 | # Mount API 282 | 283 | def test_get_mount_index(self, response_mock): 284 | self.api.get_mount_index('us', 'dynamic-us') 285 | params = copy.deepcopy(self.params) 286 | params['namespace'] = 'dynamic-us' 287 | response_mock.assert_called_with( 288 | 'https://us.api.blizzard.com/data/wow/mount/index', 289 | params=params 290 | ) 291 | 292 | def test_get_mount_data(self, response_mock): 293 | self.api.get_mount_data('us', 'dynamic-us', 6) 294 | params = copy.deepcopy(self.params) 295 | params['namespace'] = 'dynamic-us' 296 | response_mock.assert_called_with( 297 | 'https://us.api.blizzard.com/data/wow/mount/6', 298 | params=params 299 | ) 300 | 301 | # Mythic Keystone Affix API 302 | 303 | def test_get_mythic_keystone_affixes(self, response_mock): 304 | self.api.get_mythic_keystone_affixes('us', 'dynamic-us') 305 | params = copy.deepcopy(self.params) 306 | params['namespace'] = 'dynamic-us' 307 | response_mock.assert_called_with( 308 | 'https://us.api.blizzard.com/data/wow/keystone-affix/index', params=params) 309 | 310 | def test_get_mythic_keystone_affix(self, response_mock): 311 | self.api.get_mythic_keystone_affix('us', 'dynamic-us', 3) 312 | params = copy.deepcopy(self.params) 313 | params['namespace'] = 'dynamic-us' 314 | response_mock.assert_called_with( 315 | 'https://us.api.blizzard.com/data/wow/keystone-affix/3', params=params) 316 | 317 | def test_get_mythic_keystone_affix_media(self, response_mock): 318 | self.api.get_mythic_keystone_affix_media('us', 'dynamic-us', 1) 319 | params = copy.deepcopy(self.params) 320 | params['namespace'] = 'dynamic-us' 321 | response_mock.assert_called_with( 322 | 'https://us.api.blizzard.com/data/wow/media/keystone-affix/1', params=params) 323 | 324 | # Mythic Keystone Dungeon API 325 | 326 | def test_get_mythic_keystone_dungeon_index(self, response_mock): 327 | self.api.get_mythic_keystone_dungeon_index('us', 'dynamic-us') 328 | params = copy.deepcopy(self.params) 329 | params['namespace'] = 'dynamic-us' 330 | response_mock.assert_called_with( 331 | 'https://us.api.blizzard.com/data/wow/mythic-keystone/dungeon/index', params=params) 332 | 333 | def test_get_mythic_keystone_dungeon(self, response_mock): 334 | self.api.get_mythic_keystone_dungeon('us', 'dynamic-us', 5) 335 | params = copy.deepcopy(self.params) 336 | params['namespace'] = 'dynamic-us' 337 | response_mock.assert_called_with( 338 | 'https://us.api.blizzard.com/data/wow/mythic-keystone/dungeon/5', params=params) 339 | 340 | def test_get_mythic_keystone_index(self, response_mock): 341 | self.api.get_mythic_keystone_index('us', 'dynamic-us') 342 | params = copy.deepcopy(self.params) 343 | params['namespace'] = 'dynamic-us' 344 | response_mock.assert_called_with( 345 | 'https://us.api.blizzard.com/data/wow/mythic-keystone/index', params=params) 346 | 347 | def test_get_mythic_keystone_period_index(self, response_mock): 348 | self.api.get_mythic_keystone_period_index('us', 'dynamic-us') 349 | params = copy.deepcopy(self.params) 350 | params['namespace'] = 'dynamic-us' 351 | response_mock.assert_called_with( 352 | 'https://us.api.blizzard.com/data/wow/mythic-keystone/period/index', params=params) 353 | 354 | def test_get_mythic_keystone_period(self, response_mock): 355 | self.api.get_mythic_keystone_period('us', 'dynamic-us', 641) 356 | params = copy.deepcopy(self.params) 357 | params['namespace'] = 'dynamic-us' 358 | response_mock.assert_called_with( 359 | 'https://us.api.blizzard.com/data/wow/mythic-keystone/period/641', params=params) 360 | 361 | def test_get_mythic_keystone_season_index(self, response_mock): 362 | self.api.get_mythic_keystone_season_index('us', 'dynamic-us') 363 | params = copy.deepcopy(self.params) 364 | params['namespace'] = 'dynamic-us' 365 | response_mock.assert_called_with( 366 | 'https://us.api.blizzard.com/data/wow/mythic-keystone/season/index', params=params) 367 | 368 | def test_get_mythic_keystone_season(self, response_mock): 369 | self.api.get_mythic_keystone_season('us', 'dynamic-us', 1) 370 | params = copy.deepcopy(self.params) 371 | params['namespace'] = 'dynamic-us' 372 | response_mock.assert_called_with( 373 | 'https://us.api.blizzard.com/data/wow/mythic-keystone/season/1', params=params) 374 | 375 | # Mythic Keystone Leaderboard API 376 | 377 | def test_get_mythic_keystone_leaderboard_index(self, response_mock): 378 | self.api.get_mythic_keystone_leaderboard_index('us', 'dynamic-us', 1) 379 | params = copy.deepcopy(self.params) 380 | params['namespace'] = 'dynamic-us' 381 | response_mock.assert_called_with( 382 | 'https://us.api.blizzard.com/data/wow/connected-realm/1/mythic-leaderboard/index', 383 | params=params 384 | ) 385 | 386 | def test_get_mythic_keystone_leaderboard(self, response_mock): 387 | self.api.get_mythic_keystone_leaderboard('us', 'dynamic-us', 1, 2, 3) 388 | params = copy.deepcopy(self.params) 389 | params['namespace'] = 'dynamic-us' 390 | response_mock.assert_called_with( 391 | 'https://us.api.blizzard.com/data/wow/connected-realm/1/mythic-leaderboard/2/period/3', 392 | params=params 393 | ) 394 | 395 | # Mythic Raid Leaderboard API 396 | 397 | def test_get_mythic_raid_leaderboard(self, response_mock): 398 | self.api.get_mythic_raid_leaderboard('us', 'dynamic-us', 'uldir', 'horde') 399 | params = copy.deepcopy(self.params) 400 | params['namespace'] = 'dynamic-us' 401 | response_mock.assert_called_with( 402 | 'https://us.api.blizzard.com/data/wow/leaderboard/hall-of-fame/uldir/horde', 403 | params=params 404 | ) 405 | 406 | # Pet API 407 | 408 | def test_get_pet_index(self, response_mock): 409 | self.api.get_pet_index('us', 'dynamic-us') 410 | params = copy.deepcopy(self.params) 411 | params['namespace'] = 'dynamic-us' 412 | response_mock.assert_called_with( 413 | 'https://us.api.blizzard.com/data/wow/pet/index', 414 | params=params 415 | ) 416 | 417 | def test_get_pet_data(self, response_mock): 418 | self.api.get_pet_data('us', 'dynamic-us', 39) 419 | params = copy.deepcopy(self.params) 420 | params['namespace'] = 'dynamic-us' 421 | response_mock.assert_called_with( 422 | 'https://us.api.blizzard.com/data/wow/pet/39', 423 | params=params 424 | ) 425 | 426 | # Playable Class API 427 | 428 | def test_get_playable_class_index(self, response_mock): 429 | self.api.get_playable_class_index('us', 'static-us') 430 | params = copy.deepcopy(self.params) 431 | params['namespace'] = 'static-us' 432 | response_mock.assert_called_with( 433 | 'https://us.api.blizzard.com/data/wow/playable-class/index', 434 | params=params 435 | ) 436 | 437 | def test_get_playable_class(self, response_mock): 438 | self.api.get_playable_class('us', 'static-us', 7) 439 | params = copy.deepcopy(self.params) 440 | params['namespace'] = 'static-us' 441 | response_mock.assert_called_with( 442 | 'https://us.api.blizzard.com/data/wow/playable-class/7', 443 | params=params 444 | ) 445 | 446 | def test_get_playable_class_media(self, response_mock): 447 | self.api.get_playable_class_media('us', 'static-us', 7) 448 | params = copy.deepcopy(self.params) 449 | params['namespace'] = 'static-us' 450 | response_mock.assert_called_with( 451 | 'https://us.api.blizzard.com/data/wow/media/playable-class/7', 452 | params=params 453 | ) 454 | 455 | def test_get_playable_class_pvp_talent_slots(self, response_mock): 456 | self.api.get_playable_class_pvp_talent_slots('us', 'static-us', 7) 457 | params = copy.deepcopy(self.params) 458 | params['namespace'] = 'static-us' 459 | response_mock.assert_called_with( 460 | 'https://us.api.blizzard.com/data/wow/playable-class/7/pvp-talent-slots', 461 | params=params 462 | ) 463 | 464 | # Playable Race API 465 | 466 | def test_get_playable_race_index(self, response_mock): 467 | self.api.get_playable_race_index('us', 'static-us') 468 | params = copy.deepcopy(self.params) 469 | params['namespace'] = 'static-us' 470 | response_mock.assert_called_with( 471 | 'https://us.api.blizzard.com/data/wow/playable-race/index', 472 | params=params 473 | ) 474 | 475 | def test_get_playable_race(self, response_mock): 476 | self.api.get_playable_race('us', 'static-us', 2) 477 | params = copy.deepcopy(self.params) 478 | params['namespace'] = 'static-us' 479 | response_mock.assert_called_with( 480 | 'https://us.api.blizzard.com/data/wow/playable-race/2', 481 | params=params 482 | ) 483 | 484 | # Playable Specialization API 485 | 486 | def test_get_playable_specialization_index(self, response_mock): 487 | self.api.get_playable_specialization_index('us', 'static-us') 488 | params = copy.deepcopy(self.params) 489 | params['namespace'] = 'static-us' 490 | response_mock.assert_called_with( 491 | 'https://us.api.blizzard.com/data/wow/playable-specialization/index', 492 | params=params 493 | ) 494 | 495 | def test_get_playable_specialization(self, response_mock): 496 | self.api.get_playable_specialization('us', 'static-us', 262) 497 | params = copy.deepcopy(self.params) 498 | params['namespace'] = 'static-us' 499 | response_mock.assert_called_with( 500 | 'https://us.api.blizzard.com/data/wow/playable-specialization/262', 501 | params=params 502 | ) 503 | 504 | def test_get_playable_specialization_media(self, response_mock): 505 | self.api.get_playable_specialization_media('us', 'static-us', 262) 506 | params = copy.deepcopy(self.params) 507 | params['namespace'] = 'static-us' 508 | response_mock.assert_called_with( 509 | 'https://us.api.blizzard.com/data/wow/media/playable-specialization/262', 510 | params=params 511 | ) 512 | 513 | # Power Type API 514 | 515 | def test_get_power_type_index(self, response_mock): 516 | self.api.get_power_type_index('us', 'static-us') 517 | params = copy.deepcopy(self.params) 518 | params['namespace'] = 'static-us' 519 | response_mock.assert_called_with( 520 | 'https://us.api.blizzard.com/data/wow/power-type/index', 521 | params=params 522 | ) 523 | 524 | def test_get_power_type(self, response_mock): 525 | self.api.get_power_type('us', 'static-us', 0) 526 | params = copy.deepcopy(self.params) 527 | params['namespace'] = 'static-us' 528 | response_mock.assert_called_with( 529 | 'https://us.api.blizzard.com/data/wow/power-type/0', 530 | params=params 531 | ) 532 | 533 | # Profession API 534 | 535 | def test_get_profession_index(self, response_mock): 536 | self.api.get_profession_index('us', 'static-us') 537 | params = copy.deepcopy(self.params) 538 | params['namespace'] = 'static-us' 539 | response_mock.assert_called_with( 540 | 'https://us.api.blizzard.com/data/wow/profession/index', 541 | params=params 542 | ) 543 | 544 | def test_get_profession(self, response_mock): 545 | self.api.get_profession('us', 'static-us', 164) 546 | params = copy.deepcopy(self.params) 547 | params['namespace'] = 'static-us' 548 | response_mock.assert_called_with( 549 | 'https://us.api.blizzard.com/data/wow/profession/164', 550 | params=params 551 | ) 552 | 553 | def test_get_profession_media(self, response_mock): 554 | self.api.get_profession_media('us', 'static-us', 164) 555 | params = copy.deepcopy(self.params) 556 | params['namespace'] = 'static-us' 557 | response_mock.assert_called_with( 558 | 'https://us.api.blizzard.com/data/wow/media/profession/164', 559 | params=params 560 | ) 561 | 562 | def test_get_profession_skill_tier(self, response_mock): 563 | self.api.get_profession_skill_tier('us', 'static-us', 164, 2477) 564 | params = copy.deepcopy(self.params) 565 | params['namespace'] = 'static-us' 566 | response_mock.assert_called_with( 567 | 'https://us.api.blizzard.com/data/wow/profession/164/skill-tier/2477', 568 | params=params 569 | ) 570 | 571 | def test_get_recipe(self, response_mock): 572 | self.api.get_recipe('us', 'static-us', 1631) 573 | params = copy.deepcopy(self.params) 574 | params['namespace'] = 'static-us' 575 | response_mock.assert_called_with( 576 | 'https://us.api.blizzard.com/data/wow/recipe/1631', 577 | params=params 578 | ) 579 | 580 | def test_get_recipe_media(self, response_mock): 581 | self.api.get_recipe_media('us', 'static-us', 1631) 582 | params = copy.deepcopy(self.params) 583 | params['namespace'] = 'static-us' 584 | response_mock.assert_called_with( 585 | 'https://us.api.blizzard.com/data/wow/media/recipe/1631', 586 | params=params 587 | ) 588 | 589 | # PvP Season API 590 | 591 | def test_get_pvp_season_index(self, response_mock): 592 | self.api.get_pvp_season_index('us', 'static-us') 593 | params = copy.deepcopy(self.params) 594 | params['namespace'] = 'static-us' 595 | response_mock.assert_called_with( 596 | 'https://us.api.blizzard.com/data/wow/pvp-season/index', 597 | params=params 598 | ) 599 | 600 | def test_get_pvp_season(self, response_mock): 601 | self.api.get_pvp_season('us', 'static-us', 27) 602 | params = copy.deepcopy(self.params) 603 | params['namespace'] = 'static-us' 604 | response_mock.assert_called_with( 605 | 'https://us.api.blizzard.com/data/wow/pvp-season/27', 606 | params=params 607 | ) 608 | 609 | def test_get_pvp_leaderboard_index(self, response_mock): 610 | self.api.get_pvp_leaderboard_index('us', 'static-us', 27) 611 | params = copy.deepcopy(self.params) 612 | params['namespace'] = 'static-us' 613 | response_mock.assert_called_with( 614 | 'https://us.api.blizzard.com/data/wow/pvp-season/27/pvp-leaderboard/index', 615 | params=params 616 | ) 617 | 618 | def test_get_pvp_leaderboard(self, response_mock): 619 | self.api.get_pvp_leaderboard('us', 'static-us', 27, '3v3') 620 | params = copy.deepcopy(self.params) 621 | params['namespace'] = 'static-us' 622 | response_mock.assert_called_with( 623 | 'https://us.api.blizzard.com/data/wow/pvp-season/27/pvp-leaderboard/3v3', 624 | params=params 625 | ) 626 | 627 | def test_get_pvp_rewards_index(self, response_mock): 628 | self.api.get_pvp_rewards_index('us', 'static-us', 27) 629 | params = copy.deepcopy(self.params) 630 | params['namespace'] = 'static-us' 631 | response_mock.assert_called_with( 632 | 'https://us.api.blizzard.com/data/wow/pvp-season/27/pvp-reward/index', 633 | params=params 634 | ) 635 | 636 | # PvP Tier API 637 | 638 | def test_get_pvp_tier_media(self, response_mock): 639 | self.api.get_pvp_tier_media('us', 'static-us', 1) 640 | params = copy.deepcopy(self.params) 641 | params['namespace'] = 'static-us' 642 | response_mock.assert_called_with( 643 | 'https://us.api.blizzard.com/data/wow/media/pvp-tier/1', 644 | params=params 645 | ) 646 | 647 | def test_get_pvp_tier_index(self, response_mock): 648 | self.api.get_pvp_tier_index('us', 'static-us') 649 | params = copy.deepcopy(self.params) 650 | params['namespace'] = 'static-us' 651 | response_mock.assert_called_with( 652 | 'https://us.api.blizzard.com/data/wow/pvp-tier/index', 653 | params=params 654 | ) 655 | 656 | def test_get_pvp_tier(self, response_mock): 657 | self.api.get_pvp_tier('us', 'static-us', 1) 658 | params = copy.deepcopy(self.params) 659 | params['namespace'] = 'static-us' 660 | response_mock.assert_called_with( 661 | 'https://us.api.blizzard.com/data/wow/pvp-tier/1', 662 | params=params 663 | ) 664 | 665 | # Quest API 666 | 667 | def test_get_quest_index(self, response_mock): 668 | self.api.get_quest_index('us', 'dynamic-us') 669 | params = copy.deepcopy(self.params) 670 | params['namespace'] = 'dynamic-us' 671 | response_mock.assert_called_with( 672 | 'https://us.api.blizzard.com/data/wow/quest/index', 673 | params=params 674 | ) 675 | 676 | def test_get_quest(self, response_mock): 677 | self.api.get_quest('us', 'dynamic-us', 2) 678 | params = copy.deepcopy(self.params) 679 | params['namespace'] = 'dynamic-us' 680 | response_mock.assert_called_with( 681 | 'https://us.api.blizzard.com/data/wow/quest/2', 682 | params=params 683 | ) 684 | 685 | def test_get_quest_categories_index(self, response_mock): 686 | self.api.get_quest_categories_index('us', 'dynamic-us') 687 | params = copy.deepcopy(self.params) 688 | params['namespace'] = 'dynamic-us' 689 | response_mock.assert_called_with( 690 | 'https://us.api.blizzard.com/data/wow/quest/category/index', 691 | params=params 692 | ) 693 | 694 | def test_get_quest_catagory(self, response_mock): 695 | self.api.get_quest_catagory('us', 'dynamic-us', 1) 696 | params = copy.deepcopy(self.params) 697 | params['namespace'] = 'dynamic-us' 698 | response_mock.assert_called_with( 699 | 'https://us.api.blizzard.com/data/wow/quest/category/1', 700 | params=params 701 | ) 702 | 703 | def test_get_quest_area_index(self, response_mock): 704 | self.api.get_quest_area_index('us', 'dynamic-us') 705 | params = copy.deepcopy(self.params) 706 | params['namespace'] = 'dynamic-us' 707 | response_mock.assert_called_with( 708 | 'https://us.api.blizzard.com/data/wow/quest/area/index', 709 | params=params 710 | ) 711 | 712 | def test_get_quest_area(self, response_mock): 713 | self.api.get_quest_area('us', 'dynamic-us', 1) 714 | params = copy.deepcopy(self.params) 715 | params['namespace'] = 'dynamic-us' 716 | response_mock.assert_called_with( 717 | 'https://us.api.blizzard.com/data/wow/quest/area/1', 718 | params=params 719 | ) 720 | 721 | def test_get_quest_types_index(self, response_mock): 722 | self.api.get_quest_types_index('us', 'dynamic-us') 723 | params = copy.deepcopy(self.params) 724 | params['namespace'] = 'dynamic-us' 725 | response_mock.assert_called_with( 726 | 'https://us.api.blizzard.com/data/wow/quest/type/index', 727 | params=params 728 | ) 729 | 730 | def test_get_quest_type(self, response_mock): 731 | self.api.get_quest_type('us', 'dynamic-us', 1) 732 | params = copy.deepcopy(self.params) 733 | params['namespace'] = 'dynamic-us' 734 | response_mock.assert_called_with( 735 | 'https://us.api.blizzard.com/data/wow/quest/type/1', 736 | params=params 737 | ) 738 | 739 | # Realm API 740 | 741 | def test_get_realm_index(self, response_mock): 742 | self.api.get_realm_index('us', 'dynamic-us') 743 | params = copy.deepcopy(self.params) 744 | params['namespace'] = 'dynamic-us' 745 | response_mock.assert_called_with( 746 | 'https://us.api.blizzard.com/data/wow/realm/index', 747 | params=params 748 | ) 749 | 750 | def test_get_realm(self, response_mock): 751 | self.api.get_realm('us', 'dynamic-us', 'tichondrius') 752 | params = copy.deepcopy(self.params) 753 | params['namespace'] = 'dynamic-us' 754 | response_mock.assert_called_with( 755 | 'https://us.api.blizzard.com/data/wow/realm/tichondrius', 756 | params=params 757 | ) 758 | 759 | # Region API 760 | 761 | def test_get_region_index(self, response_mock): 762 | self.api.get_region_index('us', 'dynamic-us') 763 | params = copy.deepcopy(self.params) 764 | params['namespace'] = 'dynamic-us' 765 | response_mock.assert_called_with( 766 | 'https://us.api.blizzard.com/data/wow/region/index', 767 | params=params 768 | ) 769 | 770 | def test_get_region(self, response_mock): 771 | self.api.get_region('us', 'dynamic-us', 1) 772 | params = copy.deepcopy(self.params) 773 | params['namespace'] = 'dynamic-us' 774 | response_mock.assert_called_with( 775 | 'https://us.api.blizzard.com/data/wow/region/1', 776 | params=params 777 | ) 778 | 779 | # Reputations API 780 | 781 | def test_get_reputation_faction_index(self, response_mock): 782 | self.api.get_reputation_faction_index('us', 'dynamic-us') 783 | params = copy.deepcopy(self.params) 784 | params['namespace'] = 'dynamic-us' 785 | response_mock.assert_called_with( 786 | 'https://us.api.blizzard.com/data/wow/reputation-faction/index', 787 | params=params 788 | ) 789 | 790 | def test_get_reputation_faction(self, response_mock): 791 | self.api.get_reputation_faction('us', 'dynamic-us', 21) 792 | params = copy.deepcopy(self.params) 793 | params['namespace'] = 'dynamic-us' 794 | response_mock.assert_called_with( 795 | 'https://us.api.blizzard.com/data/wow/reputation-faction/21', 796 | params=params 797 | ) 798 | 799 | def test_get_reputation_tier_index(self, response_mock): 800 | self.api.get_reputation_tier_index('us', 'dynamic-us') 801 | params = copy.deepcopy(self.params) 802 | params['namespace'] = 'dynamic-us' 803 | response_mock.assert_called_with( 804 | 'https://us.api.blizzard.com/data/wow/reputation-tiers/index', 805 | params=params 806 | ) 807 | 808 | def test_get_reputation_tier(self, response_mock): 809 | self.api.get_reputation_tier('us', 'dynamic-us', 2) 810 | params = copy.deepcopy(self.params) 811 | params['namespace'] = 'dynamic-us' 812 | response_mock.assert_called_with( 813 | 'https://us.api.blizzard.com/data/wow/reputation-tiers/2', 814 | params=params 815 | ) 816 | 817 | # Spell API 818 | 819 | def test_get_spell(self, response_mock): 820 | self.api.get_spell('us', 'dynamic-us', 196607) 821 | params = copy.deepcopy(self.params) 822 | params['namespace'] = 'dynamic-us' 823 | response_mock.assert_called_with( 824 | 'https://us.api.blizzard.com/data/wow/spell/196607', params=params 825 | ) 826 | 827 | def test_get_spell_media(self, response_mock): 828 | self.api.get_spell_media('us', 'dynamic-us', 196607) 829 | params = copy.deepcopy(self.params) 830 | params['namespace'] = 'dynamic-us' 831 | response_mock.assert_called_with( 832 | 'https://us.api.blizzard.com/data/wow/media/spell/196607', params=params 833 | ) 834 | 835 | # Talent API 836 | 837 | def test_get_talent_index(self, response_mock): 838 | self.api.get_talent_index('us', 'dynamic-us') 839 | params = copy.deepcopy(self.params) 840 | params['namespace'] = 'dynamic-us' 841 | response_mock.assert_called_with( 842 | 'https://us.api.blizzard.com/data/wow/talent/index', params=params 843 | ) 844 | 845 | def test_get_talent(self, response_mock): 846 | self.api.get_talent('us', 'dynamic-us', 23106) 847 | params = copy.deepcopy(self.params) 848 | params['namespace'] = 'dynamic-us' 849 | response_mock.assert_called_with( 850 | 'https://us.api.blizzard.com/data/wow/talent/23106', params=params 851 | ) 852 | 853 | def test_get_pvp_talent_index(self, response_mock): 854 | self.api.get_pvp_talent_index('us', 'dynamic-us') 855 | params = copy.deepcopy(self.params) 856 | params['namespace'] = 'dynamic-us' 857 | response_mock.assert_called_with( 858 | 'https://us.api.blizzard.com/data/wow/pvp-talent/index', params=params 859 | ) 860 | 861 | def test_get_pvp_talent(self, response_mock): 862 | self.api.get_pvp_talent('us', 'dynamic-us', 3) 863 | params = copy.deepcopy(self.params) 864 | params['namespace'] = 'dynamic-us' 865 | response_mock.assert_called_with( 866 | 'https://us.api.blizzard.com/data/wow/pvp-talent/3', params=params 867 | ) 868 | 869 | # Title API 870 | 871 | def test_get_title_index(self, response_mock): 872 | self.api.get_title_index('us', 'dynamic-us') 873 | params = copy.deepcopy(self.params) 874 | params['namespace'] = 'dynamic-us' 875 | response_mock.assert_called_with( 876 | 'https://us.api.blizzard.com/data/wow/title/index', 877 | params=params 878 | ) 879 | 880 | def test_get_title(self, response_mock): 881 | self.api.get_title('us', 'dynamic-us', 1) 882 | params = copy.deepcopy(self.params) 883 | params['namespace'] = 'dynamic-us' 884 | response_mock.assert_called_with( 885 | 'https://us.api.blizzard.com/data/wow/title/1', 886 | params=params 887 | ) 888 | 889 | # WoW Token API 890 | 891 | def test_get_token_index(self, response_mock): 892 | self.api.get_token_index('us', 'dynamic-us') 893 | params = copy.deepcopy(self.params) 894 | params['namespace'] = 'dynamic-us' 895 | response_mock.assert_called_with( 896 | 'https://us.api.blizzard.com/data/wow/token/index', params=params) 897 | -------------------------------------------------------------------------------- /tests/mixins/test_profile.py: -------------------------------------------------------------------------------- 1 | import copy 2 | from datetime import datetime, timedelta 3 | 4 | from wowapi import WowApi 5 | 6 | 7 | class TestProfileMixin(object): 8 | 9 | def setup(self): 10 | self.params = {'access_token': 'secret'} 11 | 12 | self.api = WowApi('client-id', 'client-secret') 13 | self.api._access_tokens = { 14 | 'us': { 15 | 'token': 'secret', 16 | 'expiration': datetime.utcnow() + timedelta(hours=1) 17 | } 18 | } 19 | 20 | # Account Profile API 21 | 22 | def test_get_account_profile_summary(self, response_mock): 23 | self.api.get_account_profile_summary( 24 | 'us', 'dynamic-us', 'profile-token' 25 | ) 26 | 27 | params = { 28 | 'namespace': 'dynamic-us', 29 | 'access_token': 'profile-token' 30 | } 31 | 32 | response_mock.assert_called_with( 33 | 'https://us.api.blizzard.com/profile/user/wow', 34 | params=params 35 | ) 36 | 37 | def test_get_protected_character_profile_summary(self, response_mock): 38 | self.api.get_protected_character_profile_summary( 39 | 'us', 'dynamic-us', 'profile-token', 1, 9000 40 | ) 41 | 42 | params = { 43 | 'namespace': 'dynamic-us', 44 | 'access_token': 'profile-token' 45 | } 46 | 47 | response_mock.assert_called_with( 48 | 'https://us.api.blizzard.com/profile/user/wow/protected-character/1-9000', 49 | params=params 50 | ) 51 | 52 | def test_get_account_collection_index(self, response_mock): 53 | self.api.get_account_collection_index('us', 'dynamic-us', 'profile-token') 54 | 55 | params = { 56 | 'namespace': 'dynamic-us', 57 | 'access_token': 'profile-token' 58 | } 59 | 60 | response_mock.assert_called_with( 61 | 'https://us.api.blizzard.com/profile/user/wow/collections', 62 | params=params 63 | ) 64 | 65 | def test_get_mount_collection_summary(self, response_mock): 66 | self.api.get_mount_collection_summary('us', 'dynamic-us', 'profile-token') 67 | 68 | params = { 69 | 'namespace': 'dynamic-us', 70 | 'access_token': 'profile-token' 71 | } 72 | 73 | response_mock.assert_called_with( 74 | 'https://us.api.blizzard.com/profile/user/wow/collections/mounts', 75 | params=params 76 | ) 77 | 78 | def test_get_pet_collection_summary(self, response_mock): 79 | self.api.get_pet_collection_summary('us', 'dynamic-us', 'profile-token') 80 | 81 | params = { 82 | 'namespace': 'dynamic-us', 83 | 'access_token': 'profile-token' 84 | } 85 | 86 | response_mock.assert_called_with( 87 | 'https://us.api.blizzard.com/profile/user/wow/collections/pets', 88 | params=params 89 | ) 90 | 91 | # Character Achievements API 92 | 93 | def test_get_character_achievements_summary(self, response_mock): 94 | self.api.get_character_achievements_summary( 95 | 'us', 'dynamic-us', 'khadgar', 'asmon' 96 | ) 97 | params = copy.deepcopy(self.params) 98 | params['namespace'] = 'dynamic-us' 99 | response_mock.assert_called_with( 100 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/achievements', 101 | params=params 102 | ) 103 | 104 | def test_get_character_achievements_statistics(self, response_mock): 105 | self.api.get_character_achievements_statistics( 106 | 'us', 'dynamic-us', 'moon', 'asmon' 107 | ) 108 | params = copy.deepcopy(self.params) 109 | params['namespace'] = 'dynamic-us' 110 | response_mock.assert_called_with( 111 | 'https://us.api.blizzard.com/profile/wow/character/moon/asmon/achievements/statistics', 112 | params=params 113 | ) 114 | 115 | # Character Appearance API 116 | 117 | def test_get_character_appearance_summary(self, response_mock): 118 | self.api.get_character_appearance_summary( 119 | 'us', 'dynamic-us', 'khadgar', 'asmon' 120 | ) 121 | params = copy.deepcopy(self.params) 122 | params['namespace'] = 'dynamic-us' 123 | response_mock.assert_called_with( 124 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/appearance', 125 | params=params 126 | ) 127 | 128 | # Character Collections API 129 | 130 | def test_get_character_collection_index(self, response_mock): 131 | self.api.get_character_collection_index('us', 'dynamic-us', 'khadgar', 'asmon') 132 | 133 | params = copy.deepcopy(self.params) 134 | params['namespace'] = 'dynamic-us' 135 | response_mock.assert_called_with( 136 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/collections', 137 | params=params 138 | ) 139 | 140 | def test_get_character_mount_collection_index(self, response_mock): 141 | self.api.get_character_mount_collection_index('us', 'dynamic-us', 'khadgar', 'asmon') 142 | 143 | params = copy.deepcopy(self.params) 144 | params['namespace'] = 'dynamic-us' 145 | response_mock.assert_called_with( 146 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/collections/mounts', 147 | params=params 148 | ) 149 | 150 | def test_get_character_pet_collection_index(self, response_mock): 151 | self.api.get_character_pet_collection_index('us', 'dynamic-us', 'khadgar', 'asmon') 152 | 153 | params = copy.deepcopy(self.params) 154 | params['namespace'] = 'dynamic-us' 155 | response_mock.assert_called_with( 156 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/collections/pets', 157 | params=params 158 | ) 159 | 160 | # Character Encounters API 161 | 162 | def test_get_character_encounters_summary(self, response_mock): 163 | self.api.get_character_encounters_summary('us', 'dynamic-us', 'khadgar', 'asmon') 164 | 165 | params = copy.deepcopy(self.params) 166 | params['namespace'] = 'dynamic-us' 167 | response_mock.assert_called_with( 168 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/encounters', 169 | params=params 170 | ) 171 | 172 | def test_get_character_dungeons(self, response_mock): 173 | self.api.get_character_dungeons('us', 'dynamic-us', 'khadgar', 'asmon') 174 | 175 | params = copy.deepcopy(self.params) 176 | params['namespace'] = 'dynamic-us' 177 | response_mock.assert_called_with( 178 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/encounters/dungeons', 179 | params=params 180 | ) 181 | 182 | def test_get_character_raids(self, response_mock): 183 | self.api.get_character_raids('us', 'dynamic-us', 'khadgar', 'asmon') 184 | 185 | params = copy.deepcopy(self.params) 186 | params['namespace'] = 'dynamic-us' 187 | response_mock.assert_called_with( 188 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/encounters/raids', 189 | params=params 190 | ) 191 | 192 | # Character Equipment API 193 | 194 | def test_get_character_equipment_summary(self, response_mock): 195 | self.api.get_character_equipment_summary( 196 | 'us', 'dynamic-us', 'khadgar', 'asmon' 197 | ) 198 | params = copy.deepcopy(self.params) 199 | params['namespace'] = 'dynamic-us' 200 | response_mock.assert_called_with( 201 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/equipment', 202 | params=params 203 | ) 204 | 205 | # Character Hunter Pets API 206 | 207 | def test_get_character_hunter_pets_summary(self, response_mock): 208 | self.api.get_character_hunter_pets_summary( 209 | 'us', 'dynamic-us', 'khadgar', 'asmon' 210 | ) 211 | params = copy.deepcopy(self.params) 212 | params['namespace'] = 'dynamic-us' 213 | response_mock.assert_called_with( 214 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/hunter-pets', 215 | params=params 216 | ) 217 | 218 | # Character Media API 219 | 220 | def test_get_character_media_summary(self, response_mock): 221 | self.api.get_character_media_summary( 222 | 'us', 'dynamic-us', 'khadgar', 'asmon' 223 | ) 224 | params = copy.deepcopy(self.params) 225 | params['namespace'] = 'dynamic-us' 226 | response_mock.assert_called_with( 227 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/character-media', 228 | params=params 229 | ) 230 | 231 | # WoW Mythic Keystone Character Profile API 232 | 233 | def test_get_character_mythic_keystone_profile(self, response_mock): 234 | self.api.get_character_mythic_keystone_profile( 235 | 'us', 'profile-us', 'blackmoore', 'ayanda' 236 | ) 237 | 238 | params = copy.deepcopy(self.params) 239 | params['namespace'] = 'profile-us' 240 | 241 | response_mock.assert_called_with( 242 | '{0}/profile/wow/character/blackmoore/ayanda/mythic-keystone-profile'.format( 243 | 'https://us.api.blizzard.com' 244 | ), 245 | params=params) 246 | 247 | def test_get_character_mythic_keystone_profile_season(self, response_mock): 248 | self.api.get_character_mythic_keystone_profile_season( 249 | 'us', 'profile-us', 'blackmoore', 'ayanda', '1' 250 | ) 251 | 252 | params = copy.deepcopy(self.params) 253 | params['namespace'] = 'profile-us' 254 | 255 | response_mock.assert_called_with( 256 | '{0}/profile/wow/character/blackmoore/ayanda/mythic-keystone-profile/season/1'.format( 257 | 'https://us.api.blizzard.com' 258 | ), 259 | params=params 260 | ) 261 | 262 | # Character Professions API 263 | 264 | def test_get_character_professions_summary(self, response_mock): 265 | self.api.get_character_professions_summary( 266 | 'us', 'dynamic-us', 'khadgar', 'asmon' 267 | ) 268 | params = copy.deepcopy(self.params) 269 | params['namespace'] = 'dynamic-us' 270 | response_mock.assert_called_with( 271 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/professions', 272 | params=params 273 | ) 274 | 275 | # Character Profile API 276 | 277 | def test_get_character_profile_summary(self, response_mock): 278 | self.api.get_character_profile_summary( 279 | 'us', 'dynamic-us', 'khadgar', 'asmon' 280 | ) 281 | params = copy.deepcopy(self.params) 282 | params['namespace'] = 'dynamic-us' 283 | response_mock.assert_called_with( 284 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon', 285 | params=params 286 | ) 287 | 288 | def test_get_character_profile_status(self, response_mock): 289 | self.api.get_character_profile_status( 290 | 'us', 'dynamic-us', 'khadgar', 'asmon' 291 | ) 292 | params = copy.deepcopy(self.params) 293 | params['namespace'] = 'dynamic-us' 294 | response_mock.assert_called_with( 295 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/status', 296 | params=params 297 | ) 298 | 299 | # Character PvP API 300 | 301 | def test_get_character_pvp_bracket_stats(self, response_mock): 302 | self.api.get_character_pvp_bracket_stats( 303 | 'us', 'dynamic-us', 'khadgar', 'asmon', '3v3' 304 | ) 305 | params = copy.deepcopy(self.params) 306 | params['namespace'] = 'dynamic-us' 307 | response_mock.assert_called_with( 308 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/pvp-bracket/3v3', 309 | params=params 310 | ) 311 | 312 | def test_get_character_pvp_summary(self, response_mock): 313 | self.api.get_character_pvp_summary( 314 | 'us', 'dynamic-us', 'khadgar', 'asmon', 315 | ) 316 | params = copy.deepcopy(self.params) 317 | params['namespace'] = 'dynamic-us' 318 | response_mock.assert_called_with( 319 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/pvp-summary', 320 | params=params 321 | ) 322 | 323 | # Character Quests API 324 | 325 | def test_get_character_quests(self, response_mock): 326 | self.api.get_character_quests( 327 | 'us', 'dynamic-us', 'khadgar', 'asmon', 328 | ) 329 | params = copy.deepcopy(self.params) 330 | params['namespace'] = 'dynamic-us' 331 | response_mock.assert_called_with( 332 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/quests', 333 | params=params 334 | ) 335 | 336 | def test_get_character_completed_quests(self, response_mock): 337 | self.api.get_character_completed_quests( 338 | 'us', 'dynamic-us', 'khadgar', 'asmon', 339 | ) 340 | params = copy.deepcopy(self.params) 341 | params['namespace'] = 'dynamic-us' 342 | response_mock.assert_called_with( 343 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/quests/completed', 344 | params=params 345 | ) 346 | 347 | # Character Reputations API 348 | 349 | def test_get_character_reputations_summary(self, response_mock): 350 | self.api.get_character_reputations_summary( 351 | 'us', 'dynamic-us', 'khadgar', 'asmon', 352 | ) 353 | params = copy.deepcopy(self.params) 354 | params['namespace'] = 'dynamic-us' 355 | response_mock.assert_called_with( 356 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/reputations', 357 | params=params 358 | ) 359 | 360 | # Character Specializations API 361 | 362 | def test_get_character_specializations_summary(self, response_mock): 363 | self.api.get_character_specializations_summary( 364 | 'us', 'dynamic-us', 'khadgar', 'asmon', 365 | ) 366 | params = copy.deepcopy(self.params) 367 | params['namespace'] = 'dynamic-us' 368 | response_mock.assert_called_with( 369 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/specializations', 370 | params=params 371 | ) 372 | 373 | # Character Statistics API 374 | 375 | def test_get_character_stats_summary(self, response_mock): 376 | self.api.get_character_stats_summary( 377 | 'us', 'dynamic-us', 'khadgar', 'asmon', 378 | ) 379 | params = copy.deepcopy(self.params) 380 | params['namespace'] = 'dynamic-us' 381 | response_mock.assert_called_with( 382 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/statistics', 383 | params=params 384 | ) 385 | 386 | # Character Titles API 387 | 388 | def test_get_character_titles_summary(self, response_mock): 389 | self.api.get_character_titles_summary( 390 | 'us', 'dynamic-us', 'khadgar', 'asmon', 391 | ) 392 | params = copy.deepcopy(self.params) 393 | params['namespace'] = 'dynamic-us' 394 | response_mock.assert_called_with( 395 | 'https://us.api.blizzard.com/profile/wow/character/khadgar/asmon/titles', 396 | params=params 397 | ) 398 | 399 | # Guild API 400 | 401 | def test_get_guild(self, response_mock): 402 | self.api.get_guild('us', 'dynamic-us', 'khadgar', 'bestguild') 403 | params = copy.deepcopy(self.params) 404 | params['namespace'] = 'dynamic-us' 405 | response_mock.assert_called_with( 406 | 'https://us.api.blizzard.com/data/wow/guild/khadgar/bestguild', params=params) 407 | 408 | def test_get_guild_activity(self, response_mock): 409 | self.api.get_guild_activity('us', 'dynamic-us', 'khadgar', 'bestguild') 410 | params = copy.deepcopy(self.params) 411 | params['namespace'] = 'dynamic-us' 412 | response_mock.assert_called_with( 413 | 'https://us.api.blizzard.com/data/wow/guild/khadgar/bestguild/activity', 414 | params=params 415 | ) 416 | 417 | def test_get_guild_achievements(self, response_mock): 418 | self.api.get_guild_achievements('us', 'dynamic-us', 'khadgar', 'bestguild') 419 | params = copy.deepcopy(self.params) 420 | params['namespace'] = 'dynamic-us' 421 | response_mock.assert_called_with( 422 | 'https://us.api.blizzard.com/data/wow/guild/khadgar/bestguild/achievements', 423 | params=params 424 | ) 425 | 426 | def test_get_guild_roster(self, response_mock): 427 | self.api.get_guild_roster('us', 'dynamic-us', 'khadgar', 'bestguild') 428 | params = copy.deepcopy(self.params) 429 | params['namespace'] = 'dynamic-us' 430 | response_mock.assert_called_with( 431 | 'https://us.api.blizzard.com/data/wow/guild/khadgar/bestguild/roster', params=params) 432 | -------------------------------------------------------------------------------- /tests/test_api.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, timedelta 2 | 3 | import pytest 4 | from requests.exceptions import RequestException 5 | 6 | from wowapi import WowApi, WowApiException, WowApiOauthException 7 | 8 | from .fixtures import ResponseMock 9 | 10 | 11 | class TestWowApi(object): 12 | 13 | def setup(self): 14 | self.params = {'access_token': 'secret'} 15 | 16 | self.api = WowApi('client-id', 'client-secret') 17 | 18 | self.authorized_api = WowApi('client-id', 'client-secret') 19 | self.authorized_api._access_tokens = { 20 | 'us': { 21 | 'token': 'secret', 22 | 'expiration': datetime.utcnow() + timedelta(hours=1) 23 | }, 24 | 'cn': { 25 | 'token': 'secret', 26 | 'expiration': datetime.utcnow() + timedelta(hours=1) 27 | } 28 | } 29 | 30 | self.test_url = 'http://example.com' 31 | self.default_region = 'us' 32 | 33 | def test_instance(self): 34 | assert not self.api._access_tokens 35 | 36 | def test_handle_request_success(self, session_get_mock): 37 | session_get_mock.return_value = ResponseMock()(200, b'{}') 38 | data = self.api._handle_request(self.test_url) 39 | assert data == {} 40 | session_get_mock.assert_called_with(self.test_url) 41 | 42 | def test_handle_request_request_exception(self, session_get_mock): 43 | session_get_mock.side_effect = RequestException('Error') 44 | with pytest.raises(WowApiException) as exc: 45 | self.api._handle_request(self.test_url) 46 | 47 | assert 'Error' in str(exc.value) 48 | 49 | def test_handle_request_invalid_json(self, session_get_mock): 50 | session_get_mock.return_value = ResponseMock()(200, b'{"foo": "bar"},') 51 | with pytest.raises(WowApiException) as exc: 52 | self.api._handle_request(self.test_url) 53 | 54 | assert 'Invalid Json' in str(exc.value) 55 | 56 | def test_handle_request_404(self, session_get_mock): 57 | session_get_mock.return_value = ResponseMock()(404, b'{}') 58 | with pytest.raises(WowApiException) as exc: 59 | self.api._handle_request(self.test_url) 60 | 61 | assert '404' in str(exc.value) 62 | 63 | def test_get_data_resource_authorized(self, session_get_mock): 64 | session_get_mock.return_value = ResponseMock()(200, b'{}') 65 | self.authorized_api.get_data_resource('https://us.api.blizzard.com/profile/wow/test', 'us') 66 | session_get_mock.assert_called_with( 67 | 'https://us.api.blizzard.com/profile/wow/test', 68 | params={'access_token': 'secret'} 69 | ) 70 | 71 | def test_get_data_resource_unauthorized(self, session_get_mock): 72 | session_get_mock.return_value = ResponseMock()(200, b'{}') 73 | self.api.get_data_resource('https://us.api.blizzard.com/profile/wow/test', 'us') 74 | session_get_mock.assert_called_with( 75 | 'https://us.api.blizzard.com/profile/wow/test', 76 | params={} 77 | ) 78 | 79 | def test_get_data_resource_filters(self, session_get_mock): 80 | session_get_mock.return_value = ResponseMock()(200, b'{}') 81 | self.authorized_api.get_data_resource( 82 | 'https://us.api.blizzard.com/profile/wow/test', 83 | 'us', 84 | locale='de_DE', 85 | ) 86 | 87 | session_get_mock.assert_called_with( 88 | 'https://us.api.blizzard.com/profile/wow/test', 89 | params={ 90 | 'access_token': 'secret', 91 | 'locale': 'de_DE', 92 | } 93 | ) 94 | 95 | def test_get_resource_call(self, response_mock): 96 | self.authorized_api.get_resource( 97 | 'resource/{0}', 'us', 1, locale='en_US', fields='pets,stats', breedId=9999) 98 | 99 | response_mock.assert_called_with( 100 | 'https://us.api.blizzard.com/resource/1', 101 | params={ 102 | 'access_token': 'secret', 103 | 'locale': 'en_US', 104 | 'fields': 'pets,stats', 105 | 'breedId': 9999 106 | } 107 | ) 108 | 109 | def test_get_resource_call_china(self, response_mock): 110 | self.authorized_api.get_resource('resource/{0}', 'cn', 1) 111 | 112 | response_mock.assert_called_with( 113 | 'https://www.gateway.battlenet.com.cn/resource/1', 114 | params={ 115 | 'access_token': 'secret', 116 | } 117 | ) 118 | 119 | def test_get_resource_no_access_token(self, session_get_mock, utc_mock): 120 | now = datetime.utcnow() 121 | utc_mock.return_value = now 122 | 123 | session_get_mock.side_effect = [ 124 | ResponseMock()(200, b'{"access_token": "111", "expires_in": 60}'), 125 | ResponseMock()(200, b'{"response": "ok"}'), 126 | ] 127 | with pytest.raises(WowApiOauthException): 128 | data = self.api.get_resource('foo', 'eu') 129 | 130 | assert data == {'response': 'ok'} 131 | assert self.api._access_tokens == { 132 | 'eu': { 133 | 'token': '111', 134 | 'expiration': now + timedelta(seconds=60) 135 | } 136 | } 137 | 138 | def test_get_resource_no_access_expired(self, session_get_mock, utc_mock): 139 | now = datetime.utcnow() 140 | utc_mock.return_value = now 141 | 142 | self.api._access_tokens = { 143 | 'eu': { 144 | 'token': '222', 145 | 'expiration': now 146 | } 147 | } 148 | 149 | session_get_mock.side_effect = [ 150 | ResponseMock()(200, b'{"access_token": "333", "expires_in": 60}'), 151 | ResponseMock()(200, b'{"response": "ok"}'), 152 | ] 153 | with pytest.raises(WowApiOauthException): 154 | data = self.api.get_resource('foo', 'eu') 155 | 156 | assert data == {'response': 'ok'} 157 | assert self.api._access_tokens == { 158 | 'eu': { 159 | 'token': '333', 160 | 'expiration': now + timedelta(seconds=60) 161 | } 162 | } 163 | 164 | def test_format_base_url(self): 165 | assert self.api._format_base_url('test', 'us') == 'https://us.api.blizzard.com/test' 166 | assert self.api._format_base_url('test', 'cn') == ( 167 | 'https://www.gateway.battlenet.com.cn/test' 168 | ) 169 | -------------------------------------------------------------------------------- /wowapi/__init__.py: -------------------------------------------------------------------------------- 1 | from .api import WowApi # noqa 2 | from .exceptions import WowApiException, WowApiOauthException # noqa 3 | -------------------------------------------------------------------------------- /wowapi/api.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from datetime import datetime, timedelta 3 | 4 | import requests 5 | from requests.adapters import HTTPAdapter 6 | from requests.auth import HTTPBasicAuth 7 | from requests.exceptions import RequestException 8 | from requests.packages.urllib3.util.retry import Retry 9 | 10 | from .exceptions import WowApiException, WowApiOauthException 11 | from .mixins import GameDataMixin, ProfileMixin 12 | 13 | 14 | logger = logging.getLogger('wowapi') 15 | logger.addHandler(logging.NullHandler()) 16 | 17 | 18 | class WowApi(GameDataMixin, ProfileMixin): 19 | """ 20 | ```python 21 | import os 22 | 23 | from wowapi import WowApi 24 | 25 | api = WowApi('client_id', 'client_secret') 26 | 27 | # Token price 28 | api.get_token('eu', namespace='dynamic-eu', locale='de_DE') 29 | 30 | # Auctions 31 | api.get_auctions('eu', 'silvermoon', locale='de_DE') 32 | ``` 33 | """ 34 | 35 | __base_url = '{0}.api.blizzard.com' 36 | 37 | def __init__(self, client_id, client_secret, retry_conn_failures=False): 38 | self._client_id = client_id 39 | self._client_secret = client_secret 40 | 41 | self._session = requests.Session() 42 | 43 | # Use default retry setup 44 | if retry_conn_failures: 45 | self.retry_conn_failures() 46 | 47 | self._access_tokens = {} 48 | 49 | def _utcnow(self): 50 | return datetime.utcnow() 51 | 52 | def retry_conn_failures(self, total=5, backoff_factor=1, 53 | status_forcelist=[443, 500, 502, 503, 504]): 54 | # Allows a user to control how retries function 55 | retries = Retry(total=total, backoff_factor=backoff_factor, 56 | status_forcelist=status_forcelist) 57 | self._session.mount('http://', HTTPAdapter(max_retries=retries)) 58 | self._session.mount('https://', HTTPAdapter(max_retries=retries)) 59 | 60 | def _get_client_credentials(self, region): 61 | path = '/oauth/token' 62 | data = {'grant_type': 'client_credentials'} 63 | auth = HTTPBasicAuth(self._client_id, self._client_secret) 64 | 65 | url = 'https://{0}.battle.net{1}'.format(region, path) 66 | if region == 'cn': 67 | url = 'https://www.battlenet.com.cn{0}'.format(path) 68 | 69 | logger.info('Fetching new token from: {0}'.format(url)) 70 | 71 | now = self._utcnow() 72 | try: 73 | response = self._session.post(url, data=data, auth=auth) 74 | except RequestException as exc: 75 | logger.exception(str(exc)) 76 | raise WowApiOauthException(str(exc)) 77 | 78 | if not response.ok: 79 | msg = 'Invalid response - {0} for {1}'.format(response.status_code, url) 80 | logger.warning(msg) 81 | raise WowApiOauthException(msg) 82 | 83 | try: 84 | json = response.json() 85 | except Exception: 86 | msg = 'Invalid Json in OAuth response: {0} for {1}'.format(response.content, url) 87 | logger.exception(msg) 88 | raise WowApiOauthException(msg) 89 | 90 | token = json['access_token'] 91 | expiration = now + timedelta(seconds=json['expires_in']) 92 | logger.info('New token {0} expires at {1} UTC'.format(token, expiration)) 93 | 94 | self._access_tokens[region] = { 95 | 'token': token, 96 | 'expiration': expiration 97 | } 98 | 99 | def get_data_resource(self, url, region, **filters): 100 | """ 101 | Some endpoints return a url pointing to another resource. 102 | These urls do not include OAuth tokens. 103 | `api.get_data_resource` takes care of this. 104 | 105 | ```python 106 | auctions_ref = api.get_auctions('eu', 'silvermoon', locale='de_DE') 107 | api.get_data_resource(auctions_ref['files'][0]['url'], 'eu') 108 | ``` 109 | """ 110 | access_token = self._access_tokens.get(region, {}).get('token', '') 111 | if access_token: 112 | filters['access_token'] = access_token 113 | 114 | return self._handle_request(url, params=filters) 115 | 116 | def _handle_request(self, url, **kwargs): 117 | try: 118 | response = self._session.get(url, **kwargs) 119 | except RequestException as exc: 120 | logger.exception(str(exc)) 121 | raise WowApiException(str(exc)) 122 | 123 | if not response.ok: 124 | msg = 'Invalid response - {0} - {1}'.format(url, response.status_code) 125 | logger.warning(msg) 126 | raise WowApiException(msg) 127 | 128 | try: 129 | return response.json() 130 | except Exception: 131 | msg = 'Invalid Json: {0} for {1}'.format(response.content, url) 132 | logger.exception(msg) 133 | raise WowApiException(msg) 134 | 135 | def get_resource(self, resource, region, *args, **filters): 136 | resource = resource.format(*args) 137 | 138 | # fetch access token on first run for region 139 | if region not in self._access_tokens: 140 | logger.info('Fetching access token..') 141 | self._get_client_credentials(region) 142 | else: 143 | now = self._utcnow() 144 | # refresh access token if expiring in the next 30 seconds. 145 | # this protects against the rare occurrence of hitting 146 | # the API right as your token expires, causing errors. 147 | if now >= self._access_tokens[region]['expiration'] - timedelta(seconds=30): 148 | logger.info('Access token expired. Fetching new token..') 149 | self._get_client_credentials(region) 150 | 151 | filters['access_token'] = self._access_tokens[region]['token'] 152 | url = self._format_base_url(resource, region) 153 | logger.info('Requesting resource: {0} with parameters: {1}'.format(url, filters)) 154 | return self._handle_request(url, params=filters) 155 | 156 | def get_oauth_resource(self, resource, region, token, *args, **filters): 157 | filters['access_token'] = token 158 | 159 | resource = resource.format(*args) 160 | 161 | url = self._format_base_url(resource, region) 162 | logger.info('Requesting resource: {0} with parameters: {1}'.format(url, filters)) 163 | return self._handle_request(url, params=filters) 164 | 165 | def _format_base_url(self, resource, region): 166 | base_url = self.__base_url.format(region) 167 | if region == 'cn': 168 | base_url = 'www.gateway.battlenet.com.cn' 169 | 170 | return 'https://{0}/{1}'.format(base_url, resource) 171 | -------------------------------------------------------------------------------- /wowapi/exceptions.py: -------------------------------------------------------------------------------- 1 | class WowApiException(Exception): 2 | pass 3 | 4 | 5 | class WowApiOauthException(WowApiException): 6 | pass 7 | -------------------------------------------------------------------------------- /wowapi/mixins/__init__.py: -------------------------------------------------------------------------------- 1 | from .game_data import GameDataMixin # noqa 2 | from .profile import ProfileMixin # noqa 3 | -------------------------------------------------------------------------------- /wowapi/mixins/game_data.py: -------------------------------------------------------------------------------- 1 | class GameDataMixin: 2 | """All Game Data API methods""" 3 | 4 | # Achievement API 5 | 6 | def get_achievement_category_index(self, region, namespace, **filters): 7 | """ 8 | Data Achievement API - Returns an index of achievement categories 9 | """ 10 | filters['namespace'] = namespace 11 | return self.get_resource('data/wow/achievement-category/index', region, **filters) 12 | 13 | def get_achievement_category(self, region, namespace, id, **filters): 14 | """ 15 | Data Achievement API - Returns an achievement category by id 16 | """ 17 | filters['namespace'] = namespace 18 | return self.get_resource('data/wow/achievement-category/{0}', region, *[id], **filters) 19 | 20 | def get_achievement_index(self, region, namespace, **filters): 21 | """ 22 | Data Achievement API - Returns an index of achievements 23 | """ 24 | filters['namespace'] = namespace 25 | return self.get_resource('data/wow/achievement/index', region, **filters) 26 | 27 | def get_achievement_data(self, region, namespace, id, **filters): 28 | """ 29 | Data Achievement API - Returns an achievement by id 30 | """ 31 | filters['namespace'] = namespace 32 | return self.get_resource('data/wow/achievement/{0}', region, *[id], **filters) 33 | 34 | def get_achievement_media(self, region, namespace, id, **filters): 35 | """ 36 | Data Achievement API - Returns media for an achievement by id 37 | """ 38 | filters['namespace'] = namespace 39 | return self.get_resource('data/wow/media/achievement/{0}', region, *[id], **filters) 40 | 41 | # Auction House API 42 | 43 | def get_auctions(self, region, namespace, connected_realm_id, **filters): 44 | """ 45 | Auction House API - Returns all active auctions for a connected realm 46 | """ 47 | filters['namespace'] = namespace 48 | return self.get_resource( 49 | 'data/wow/connected-realm/{0}/auctions', 50 | region, 51 | *[connected_realm_id], 52 | **filters 53 | ) 54 | 55 | # Azerite Essence API 56 | 57 | def get_azerite_essence_index(self, region, namespace, **filters): 58 | """ 59 | Data Azerite Essence API - Returns an index of azerite essences 60 | """ 61 | filters['namespace'] = namespace 62 | return self.get_resource('data/wow/azerite-essence/index', region, **filters) 63 | 64 | def get_azerite_essence(self, region, namespace, id, **filters): 65 | """ 66 | Data Azerite Essence API - Returns an azerite essence by id 67 | """ 68 | filters['namespace'] = namespace 69 | return self.get_resource('data/wow/azerite-essence/{0}', region, *[id], **filters) 70 | 71 | def get_azerite_essence_media(self, region, namespace, id, **filters): 72 | """ 73 | Data Azerite Essence API - Returns media for an azerite essence by id 74 | """ 75 | filters['namespace'] = namespace 76 | return self.get_resource('data/wow/media/azerite-essence/{0}', region, *[id], **filters) 77 | 78 | # Connected Realm API 79 | 80 | def get_connected_realm_index(self, region, namespace, **filters): 81 | """ 82 | Data Connected Realm API - Returns an index of connected realms 83 | """ 84 | filters['namespace'] = namespace 85 | return self.get_resource('data/wow/connected-realm/index', region, **filters) 86 | 87 | def get_connected_realm(self, region, namespace, id, **filters): 88 | """ 89 | Data Connected Realm API - Returns a connected realm by id 90 | """ 91 | filters['namespace'] = namespace 92 | return self.get_resource('data/wow/connected-realm/{0}', region, *[id], **filters) 93 | 94 | # Creature API 95 | 96 | def get_creature_family_index(self, region, namespace, **filters): 97 | """ 98 | Data Creature API - Returns an index of creature families 99 | """ 100 | filters['namespace'] = namespace 101 | return self.get_resource('data/wow/creature-family/index', region, **filters) 102 | 103 | def get_creature_family(self, region, namespace, id, **filters): 104 | """ 105 | Data Creature API - Returns a creature family by id 106 | """ 107 | filters['namespace'] = namespace 108 | return self.get_resource('data/wow/creature-family/{0}', region, *[id], **filters) 109 | 110 | def get_creature_type_index(self, region, namespace, **filters): 111 | """ 112 | Data Creature API - Returns an index of creature types 113 | """ 114 | filters['namespace'] = namespace 115 | return self.get_resource('data/wow/creature-type/index', region, **filters) 116 | 117 | def get_creature_type(self, region, namespace, id, **filters): 118 | """ 119 | Data Creature API - Returns a creature type by id 120 | """ 121 | filters['namespace'] = namespace 122 | return self.get_resource('data/wow/creature-type/{0}', region, *[id], **filters) 123 | 124 | def get_creature(self, region, namespace, id, **filters): 125 | """ 126 | Data Creature API - Returns a creature by id 127 | """ 128 | filters['namespace'] = namespace 129 | return self.get_resource('data/wow/creature/{0}', region, *[id], **filters) 130 | 131 | def get_creature_display_media(self, region, namespace, id, **filters): 132 | """ 133 | Data Creature API - Returns media for a creature display by id 134 | """ 135 | filters['namespace'] = namespace 136 | return self.get_resource('data/wow/media/creature-display/{0}', region, *[id], **filters) 137 | 138 | def get_creature_family_media(self, region, namespace, id, **filters): 139 | """ 140 | Data Creature API - Returns media for a creature family by id 141 | """ 142 | filters['namespace'] = namespace 143 | return self.get_resource('data/wow/media/creature-family/{0}', region, *[id], **filters) 144 | 145 | # Guild Crest API 146 | 147 | def get_guild_crest_index(self, region, namespace, **filters): 148 | """ 149 | Guild Crest API - Returns an index of guild crest media 150 | """ 151 | filters['namespace'] = namespace 152 | return self.get_resource('data/wow/guild-crest/index', region, **filters) 153 | 154 | def get_guild_crest_border_media(self, region, namespace, id, **filters): 155 | """ 156 | Guild Crest API - Returns media for a guild crest border by id 157 | """ 158 | filters['namespace'] = namespace 159 | return self.get_resource('data/wow/media/guild-crest/border/{0}', region, *[id], **filters) 160 | 161 | def get_guild_crest_emblem_media(self, region, namespace, id, **filters): 162 | """ 163 | Guild Crest API - Returns media for a guild crest emblem by id 164 | """ 165 | filters['namespace'] = namespace 166 | return self.get_resource('data/wow/media/guild-crest/emblem/{0}', region, *[id], **filters) 167 | 168 | # Item API 169 | 170 | def get_item_class_index(self, region, namespace, **filters): 171 | """ 172 | Item API - Returns an index of item classes 173 | """ 174 | filters['namespace'] = namespace 175 | return self.get_resource('data/wow/item-class/index', region, **filters) 176 | 177 | def get_item_class(self, region, namespace, id, **filters): 178 | """ 179 | Item API - Returns an item class by id 180 | """ 181 | filters['namespace'] = namespace 182 | return self.get_resource('data/wow/item-class/{0}', region, *[id], **filters) 183 | 184 | def get_item_set_index(self, region, namespace, **filters): 185 | """ 186 | Item API - Returns an index of item sets 187 | """ 188 | filters['namespace'] = namespace 189 | return self.get_resource('data/wow/item-set/index', region, **filters) 190 | 191 | def get_item_set(self, region, namespace, id, **filters): 192 | """ 193 | Item API - Returns an item set by ID 194 | """ 195 | filters['namespace'] = namespace 196 | return self.get_resource('data/wow/item-set/{0}', region, *[id], **filters) 197 | 198 | def get_item_subclass(self, region, namespace, class_id, subclass_id, **filters): 199 | """ 200 | Item API - Returns an item subclass by id 201 | """ 202 | filters['namespace'] = namespace 203 | params = [class_id, subclass_id] 204 | resource = 'data/wow/item-class/{0}/item-subclass/{1}' 205 | return self.get_resource(resource, region, *params, **filters) 206 | 207 | def get_item_data(self, region, namespace, id, **filters): 208 | """ 209 | Item API - Returns an item by id 210 | """ 211 | filters['namespace'] = namespace 212 | return self.get_resource('data/wow/item/{0}', region, *[id], **filters) 213 | 214 | def get_item_media(self, region, namespace, id, **filters): 215 | """ 216 | Item API - Returns media for an item by id 217 | """ 218 | filters['namespace'] = namespace 219 | return self.get_resource('data/wow/media/item/{0}', region, *[id], **filters) 220 | 221 | # Journal API 222 | 223 | def get_journal_index(self, region, namespace, **filters): 224 | """ 225 | Item API - Returns an index of journal expansions 226 | """ 227 | filters['namespace'] = namespace 228 | return self.get_resource('data/wow/journal-expansion/index', region, **filters) 229 | 230 | def get_journal_expansion(self, region, namespace, id, **filters): 231 | """ 232 | Item API - Returns a journal expansion by ID 233 | """ 234 | filters['namespace'] = namespace 235 | return self.get_resource('data/wow/journal-expansion/{0}', region, *[id], **filters) 236 | 237 | def get_journal_encounter_index(self, region, namespace, **filters): 238 | """ 239 | Item API - Returns an index of journal encounters 240 | """ 241 | filters['namespace'] = namespace 242 | return self.get_resource('data/wow/journal-encounter/index', region, **filters) 243 | 244 | def get_journal_encounter(self, region, namespace, id, **filters): 245 | """ 246 | Item API - Returns a journal encounter by ID 247 | """ 248 | filters['namespace'] = namespace 249 | return self.get_resource('data/wow/journal-encounter/{0}', region, *[id], **filters) 250 | 251 | def get_journal_instance_index(self, region, namespace, **filters): 252 | """ 253 | Item API - Returns an index of journal instances 254 | """ 255 | filters['namespace'] = namespace 256 | return self.get_resource('data/wow/journal-instance/index', region, **filters) 257 | 258 | def get_journal_instance(self, region, namespace, id, **filters): 259 | """ 260 | Item API - Returns a journal instance 261 | """ 262 | filters['namespace'] = namespace 263 | return self.get_resource('data/wow/journal-instance/{0}', region, *[id], **filters) 264 | 265 | def get_journal_instance_media(self, region, namespace, id, **filters): 266 | """ 267 | Item API - Returns media for a journal instance by ID 268 | """ 269 | filters['namespace'] = namespace 270 | return self.get_resource('data/wow/media/journal-instance/{0}', region, *[id], **filters) 271 | 272 | # Mount API 273 | 274 | def get_mount_index(self, region, namespace, **filters): 275 | """ 276 | Mount API - Returns an index of mounts 277 | """ 278 | filters['namespace'] = namespace 279 | return self.get_resource('data/wow/mount/index', region, **filters) 280 | 281 | def get_mount_data(self, region, namespace, id, **filters): 282 | """ 283 | Mount API - Returns a mount by id 284 | """ 285 | filters['namespace'] = namespace 286 | return self.get_resource('data/wow/mount/{0}', region, *[id], **filters) 287 | 288 | # Mythic Keystone Affix API 289 | 290 | def get_mythic_keystone_affixes(self, region, namespace, **filters): 291 | """ 292 | Mythic Keystone Affix API - get mythic keystone affixes 293 | """ 294 | filters['namespace'] = namespace 295 | return self.get_resource('data/wow/keystone-affix/index', region, **filters) 296 | 297 | def get_mythic_keystone_affix(self, region, namespace, affix_id, **filters): 298 | """ 299 | Mythic Keystone Affix API - get mythic keystone affix by id 300 | """ 301 | filters['namespace'] = namespace 302 | return self.get_resource('data/wow/keystone-affix/{0}', region, *[affix_id], **filters) 303 | 304 | def get_mythic_keystone_affix_media(self, region, namespace, affix_id, **filters): 305 | """ 306 | Mythic Keystone Affix API - get mythic keystone affix by id 307 | """ 308 | filters['namespace'] = namespace 309 | return self.get_resource( 310 | 'data/wow/media/keystone-affix/{0}', 311 | region, 312 | *[affix_id], 313 | **filters 314 | ) 315 | 316 | # Mythic Keystone Dungeon API 317 | 318 | def get_mythic_keystone_dungeon_index(self, region, namespace, **filters): 319 | """ 320 | Mythic Keystone Dungeon API - get all mythic keystone dungeons 321 | """ 322 | filters['namespace'] = namespace 323 | return self.get_resource('data/wow/mythic-keystone/dungeon/index', region, **filters) 324 | 325 | def get_mythic_keystone_dungeon(self, region, namespace, dungeon_id, **filters): 326 | """ 327 | Mythic Keystone Dungeon API - get mythic keystone dungeon by id 328 | """ 329 | filters['namespace'] = namespace 330 | return self.get_resource( 331 | 'data/wow/mythic-keystone/dungeon/{0}', region, *[dungeon_id], **filters) 332 | 333 | def get_mythic_keystone_index(self, region, namespace, **filters): 334 | """ 335 | Mythic Keystone Dungeon API - get links to documents related to mythic keystone dungeons 336 | """ 337 | filters['namespace'] = namespace 338 | return self.get_resource('data/wow/mythic-keystone/index', region, **filters) 339 | 340 | def get_mythic_keystone_period_index(self, region, namespace, **filters): 341 | """ 342 | Mythic Keystone Dungeon API - get all mythic keystone periods 343 | """ 344 | filters['namespace'] = namespace 345 | return self.get_resource('data/wow/mythic-keystone/period/index', region, **filters) 346 | 347 | def get_mythic_keystone_period(self, region, namespace, period_id, **filters): 348 | """ 349 | Mythic Keystone Dungeon API - get mythic keystone period by id 350 | """ 351 | filters['namespace'] = namespace 352 | return self.get_resource( 353 | 'data/wow/mythic-keystone/period/{0}', region, *[period_id], **filters) 354 | 355 | def get_mythic_keystone_season_index(self, region, namespace, **filters): 356 | """ 357 | Mythic Keystone Dungeon API - get all mythic keystone seasons 358 | """ 359 | filters['namespace'] = namespace 360 | return self.get_resource('data/wow/mythic-keystone/season/index', region, **filters) 361 | 362 | def get_mythic_keystone_season(self, region, namespace, season_id, **filters): 363 | """ 364 | Mythic Keystone Dungeon API - get mythic keystone season by id 365 | """ 366 | filters['namespace'] = namespace 367 | return self.get_resource( 368 | 'data/wow/mythic-keystone/season/{0}', region, *[season_id], **filters) 369 | 370 | # Mythic Keystone Leaderboard API 371 | 372 | def get_mythic_keystone_leaderboard_index( 373 | self, region, namespace, connected_realm_id, **filters 374 | ): 375 | """ 376 | Mythic Keystone Leaderboard API 377 | Returns an index of Mythic Keystone Leaderboard dungeon instances for a connected realm 378 | """ 379 | filters['namespace'] = namespace 380 | resource = 'data/wow/connected-realm/{0}/mythic-leaderboard/index' 381 | return self.get_resource(resource, region, *[connected_realm_id], **filters) 382 | 383 | def get_mythic_keystone_leaderboard( 384 | self, region, namespace, connected_realm_id, dungeon_id, period, **filters 385 | ): 386 | """ 387 | Mythic Keystone Leaderboard API - get a weekly mythic keystone leaderboard by period 388 | """ 389 | filters['namespace'] = namespace 390 | resource = 'data/wow/connected-realm/{0}/mythic-leaderboard/{1}/period/{2}' 391 | params = [connected_realm_id, dungeon_id, period] 392 | return self.get_resource(resource, region, *params, **filters) 393 | 394 | # Mythic Raid Leaderboard API 395 | 396 | def get_mythic_raid_leaderboard(self, region, namespace, raid, faction, **filters): 397 | """ 398 | Mythic Raid Leaderboard API - get mythic raid leaderboard of specific faction 399 | """ 400 | filters['namespace'] = namespace 401 | return self.get_resource( 402 | 'data/wow/leaderboard/hall-of-fame/{0}/{1}', 403 | region, 404 | *[raid, faction], 405 | **filters 406 | ) 407 | 408 | # Pet API 409 | 410 | def get_pet_index(self, region, namespace, **filters): 411 | """ 412 | Pet API - Returns an index of pets 413 | """ 414 | filters['namespace'] = namespace 415 | return self.get_resource('data/wow/pet/index', region, **filters) 416 | 417 | def get_pet_data(self, region, namespace, id, **filters): 418 | """ 419 | Pet API - Returns a pet by id 420 | """ 421 | filters['namespace'] = namespace 422 | return self.get_resource('data/wow/pet/{0}', region, *[id], **filters) 423 | 424 | # Playable Class API 425 | 426 | def get_playable_class_index(self, region, namespace, **filters): 427 | """ 428 | Playable Class API - Returns an index of playable classes 429 | """ 430 | filters['namespace'] = namespace 431 | return self.get_resource('data/wow/playable-class/index', region, **filters) 432 | 433 | def get_playable_class(self, region, namespace, class_id, **filters): 434 | """ 435 | Playable Class API - Returns a playable class by ID 436 | """ 437 | filters['namespace'] = namespace 438 | return self.get_resource('data/wow/playable-class/{0}', region, *[class_id], **filters) 439 | 440 | def get_playable_class_media(self, region, namespace, class_id, **filters): 441 | """ 442 | Playable Class API - Returns a playable class media by ID 443 | """ 444 | filters['namespace'] = namespace 445 | return self.get_resource( 446 | 'data/wow/media/playable-class/{0}', 447 | region, 448 | *[class_id], 449 | **filters 450 | ) 451 | 452 | def get_playable_class_pvp_talent_slots(self, region, namespace, class_id, **filters): 453 | """ 454 | Playable Class API - Returns the PvP talent slots for a playable class by ID 455 | """ 456 | filters['namespace'] = namespace 457 | return self.get_resource( 458 | 'data/wow/playable-class/{0}/pvp-talent-slots', region, *[class_id], **filters) 459 | 460 | # Playable Race API 461 | 462 | def get_playable_race_index(self, region, namespace, **filters): 463 | """ 464 | Playable Race API - Returns an index of playable races 465 | """ 466 | filters['namespace'] = namespace 467 | return self.get_resource('data/wow/playable-race/index', region, **filters) 468 | 469 | def get_playable_race(self, region, namespace, race_id, **filters): 470 | """ 471 | Playable Race API - Returns a playable race by ID 472 | """ 473 | filters['namespace'] = namespace 474 | return self.get_resource('data/wow/playable-race/{0}', region, *[race_id], **filters) 475 | 476 | # Playable Specialization API 477 | 478 | def get_playable_specialization_index(self, region, namespace, **filters): 479 | """ 480 | Playable Specialization API - get playable specializations 481 | """ 482 | filters['namespace'] = namespace 483 | return self.get_resource('data/wow/playable-specialization/index', region, **filters) 484 | 485 | def get_playable_specialization(self, region, namespace, spec_id, **filters): 486 | """ 487 | Playable Specialization API - get playable specialization by spec id 488 | """ 489 | filters['namespace'] = namespace 490 | return self.get_resource( 491 | 'data/wow/playable-specialization/{0}', 492 | region, 493 | *[spec_id], 494 | **filters 495 | ) 496 | 497 | def get_playable_specialization_media(self, region, namespace, spec_id, **filters): 498 | """ 499 | Playable Specialization API - Returns media for a playable specialization by ID 500 | """ 501 | filters['namespace'] = namespace 502 | return self.get_resource( 503 | 'data/wow/media/playable-specialization/{0}', 504 | region, 505 | *[spec_id], 506 | **filters 507 | ) 508 | 509 | # Power Type API 510 | 511 | def get_power_type_index(self, region, namespace, **filters): 512 | """ 513 | Power Type API - get power types 514 | """ 515 | filters['namespace'] = namespace 516 | return self.get_resource('data/wow/power-type/index', region, **filters) 517 | 518 | def get_power_type(self, region, namespace, power_type_id, **filters): 519 | """ 520 | Power Type API - get power type by id 521 | """ 522 | filters['namespace'] = namespace 523 | return self.get_resource('data/wow/power-type/{0}', region, *[power_type_id], **filters) 524 | 525 | # Profession API 526 | 527 | def get_profession_index(self, region, namespace, **filters): 528 | """ 529 | Profession API - Returns an index of professions 530 | """ 531 | filters['namespace'] = namespace 532 | return self.get_resource('data/wow/profession/index', region, **filters) 533 | 534 | def get_profession(self, region, namespace, id, **filters): 535 | """ 536 | Profession API - Returns a profession by ID 537 | """ 538 | filters['namespace'] = namespace 539 | return self.get_resource('data/wow/profession/{0}', region, *[id], **filters) 540 | 541 | def get_profession_media(self, region, namespace, id, **filters): 542 | """ 543 | Profession API - Returns media for a profession by ID 544 | """ 545 | filters['namespace'] = namespace 546 | return self.get_resource('data/wow/media/profession/{0}', region, *[id], **filters) 547 | 548 | def get_profession_skill_tier(self, region, namespace, prof_id, tier_id, **filters): 549 | """ 550 | Profession API - Returns a skill tier for a profession by ID 551 | """ 552 | filters['namespace'] = namespace 553 | return self.get_resource( 554 | 'data/wow/profession/{0}/skill-tier/{1}', region, *[prof_id, tier_id], **filters) 555 | 556 | def get_recipe(self, region, namespace, id, **filters): 557 | """ 558 | Profession API - Returns a recipe by ID 559 | """ 560 | filters['namespace'] = namespace 561 | return self.get_resource('data/wow/recipe/{0}', region, *[id], **filters) 562 | 563 | def get_recipe_media(self, region, namespace, id, **filters): 564 | """ 565 | Profession API - Returns media for a recipe by ID 566 | """ 567 | filters['namespace'] = namespace 568 | return self.get_resource('data/wow/media/recipe/{0}', region, *[id], **filters) 569 | 570 | # PvP Season API 571 | 572 | def get_pvp_season_index(self, region, namespace, **filters): 573 | """ 574 | PvP Season API - Returns an index of PvP seasons 575 | """ 576 | filters['namespace'] = namespace 577 | return self.get_resource('data/wow/pvp-season/index', region, **filters) 578 | 579 | def get_pvp_season(self, region, namespace, season_id, **filters): 580 | """ 581 | PvP Season API - Returns a PvP season by ID 582 | """ 583 | filters['namespace'] = namespace 584 | return self.get_resource('data/wow/pvp-season/{0}', region, *[season_id], **filters) 585 | 586 | def get_pvp_leaderboard_index(self, region, namespace, season_id, **filters): 587 | """ 588 | PvP Season API - Returns an index of PvP leaderboards for a PvP season 589 | """ 590 | filters['namespace'] = namespace 591 | resource = 'data/wow/pvp-season/{0}/pvp-leaderboard/index' 592 | return self.get_resource(resource, region, *[season_id], **filters) 593 | 594 | def get_pvp_leaderboard(self, region, namespace, season_id, bracket, **filters): 595 | """ 596 | PvP Season API - Returns the PvP leaderboard of a specific PvP bracket for a PvP season 597 | """ 598 | filters['namespace'] = namespace 599 | resource = 'data/wow/pvp-season/{0}/pvp-leaderboard/{1}' 600 | return self.get_resource(resource, region, *[season_id, bracket], **filters) 601 | 602 | def get_pvp_rewards_index(self, region, namespace, season_id, **filters): 603 | """ 604 | PvP Season API - Returns an index of PvP rewards for a PvP season 605 | """ 606 | filters['namespace'] = namespace 607 | resource = 'data/wow/pvp-season/{0}/pvp-reward/index' 608 | return self.get_resource(resource, region, *[season_id], **filters) 609 | 610 | # PvP Tier API 611 | 612 | def get_pvp_tier_media(self, region, namespace, tier_id, **filters): 613 | """ 614 | PvP Tier API - Returns media for a PvP tier by ID 615 | """ 616 | filters['namespace'] = namespace 617 | resource = 'data/wow/media/pvp-tier/{0}' 618 | return self.get_resource(resource, region, *[tier_id], **filters) 619 | 620 | def get_pvp_tier_index(self, region, namespace, **filters): 621 | """ 622 | PvP Tier API - Returns an index of PvP tiers 623 | """ 624 | filters['namespace'] = namespace 625 | resource = 'data/wow/pvp-tier/index' 626 | return self.get_resource(resource, region, **filters) 627 | 628 | def get_pvp_tier(self, region, namespace, tier_id, **filters): 629 | """ 630 | PvP Tier API - Returns a PvP tier by ID 631 | """ 632 | filters['namespace'] = namespace 633 | resource = 'data/wow/pvp-tier/{0}' 634 | return self.get_resource(resource, region, *[tier_id], **filters) 635 | 636 | # Quest API 637 | 638 | def get_quest_index(self, region, namespace, **filters): 639 | """ 640 | Quest API - Returns an index of quests 641 | """ 642 | filters['namespace'] = namespace 643 | return self.get_resource('data/wow/quest/index', region, **filters) 644 | 645 | def get_quest(self, region, namespace, id, **filters): 646 | """ 647 | Quest API - Returns a quest by ID 648 | """ 649 | filters['namespace'] = namespace 650 | return self.get_resource('data/wow/quest/{0}', region, *[id], **filters) 651 | 652 | def get_quest_categories_index(self, region, namespace, **filters): 653 | """ 654 | Quest API - Returns an index of quest categories 655 | 656 | (such as quests for a specific class, profession, or storyline) 657 | """ 658 | filters['namespace'] = namespace 659 | return self.get_resource('data/wow/quest/category/index', region, **filters) 660 | 661 | def get_quest_catagory(self, region, namespace, id, **filters): 662 | """ 663 | Quest API - Returns a quest category by ID 664 | """ 665 | filters['namespace'] = namespace 666 | return self.get_resource('data/wow/quest/category/{0}', region, *[id], **filters) 667 | 668 | def get_quest_area_index(self, region, namespace, **filters): 669 | """ 670 | Quest API - Returns an index of quest areas 671 | """ 672 | filters['namespace'] = namespace 673 | return self.get_resource('data/wow/quest/area/index', region, **filters) 674 | 675 | def get_quest_area(self, region, namespace, id, **filters): 676 | """ 677 | Quest API - Returns a quest area by ID 678 | """ 679 | filters['namespace'] = namespace 680 | return self.get_resource('data/wow/quest/area/{0}', region, *[id], **filters) 681 | 682 | def get_quest_types_index(self, region, namespace, **filters): 683 | """ 684 | Quest API - Returns an index of quest types 685 | 686 | (such as PvP quests, raid quests, or account quests) 687 | """ 688 | filters['namespace'] = namespace 689 | return self.get_resource('data/wow/quest/type/index', region, **filters) 690 | 691 | def get_quest_type(self, region, namespace, id, **filters): 692 | """ 693 | Quest API - Returns a quest type by ID 694 | """ 695 | filters['namespace'] = namespace 696 | return self.get_resource('data/wow/quest/type/{0}', region, *[id], **filters) 697 | 698 | # Realm API 699 | 700 | def get_realm_index(self, region, namespace, **filters): 701 | """ 702 | Realm API - get realms 703 | """ 704 | filters['namespace'] = namespace 705 | return self.get_resource('data/wow/realm/index', region, **filters) 706 | 707 | def get_realm(self, region, namespace, realm_slug, **filters): 708 | """ 709 | Realm API - get realm by realm slug 710 | """ 711 | filters['namespace'] = namespace 712 | return self.get_resource('data/wow/realm/{0}', region, *[realm_slug], **filters) 713 | 714 | # Region API 715 | 716 | def get_region_index(self, region, namespace, **filters): 717 | """ 718 | Region API - get regions 719 | """ 720 | filters['namespace'] = namespace 721 | return self.get_resource('data/wow/region/index', region, **filters) 722 | 723 | def get_region(self, region, namespace, region_id, **filters): 724 | """ 725 | Region API - get region by region id 726 | """ 727 | filters['namespace'] = namespace 728 | return self.get_resource('data/wow/region/{0}', region, *[region_id], **filters) 729 | 730 | # Reputations API 731 | 732 | def get_reputation_faction_index(self, region, namespace, **filters): 733 | """ 734 | Reputations API - Returns an index of reputation factions 735 | """ 736 | filters['namespace'] = namespace 737 | return self.get_resource('data/wow/reputation-faction/index', region, **filters) 738 | 739 | def get_reputation_faction(self, region, namespace, id, **filters): 740 | """ 741 | Reputations API - Returns a single reputation faction by ID. 742 | """ 743 | filters['namespace'] = namespace 744 | return self.get_resource('data/wow/reputation-faction/{0}', region, *[id], **filters) 745 | 746 | def get_reputation_tier_index(self, region, namespace, **filters): 747 | """ 748 | Reputations API - Returns an index of reputation tiers 749 | """ 750 | filters['namespace'] = namespace 751 | return self.get_resource('data/wow/reputation-tiers/index', region, **filters) 752 | 753 | def get_reputation_tier(self, region, namespace, id, **filters): 754 | """ 755 | Reputations API - Returns a single set of reputation tiers by ID 756 | """ 757 | filters['namespace'] = namespace 758 | return self.get_resource('data/wow/reputation-tiers/{0}', region, *[id], **filters) 759 | 760 | # Spell API 761 | 762 | def get_spell(self, region, namespace, id, **filters): 763 | """ 764 | Spell API - Returns a spell by ID 765 | """ 766 | filters['namespace'] = namespace 767 | return self.get_resource('data/wow/spell/{0}', region, *[id], **filters) 768 | 769 | def get_spell_media(self, region, namespace, id, **filters): 770 | """ 771 | Spell API - Returns media for a spell by ID 772 | """ 773 | filters['namespace'] = namespace 774 | return self.get_resource('data/wow/media/spell/{0}', region, *[id], **filters) 775 | 776 | # Talent API 777 | 778 | def get_talent_index(self, region, namespace, **filters): 779 | """ 780 | Talent API - Returns an index of talents 781 | """ 782 | filters['namespace'] = namespace 783 | return self.get_resource('data/wow/talent/index', region, **filters) 784 | 785 | def get_talent(self, region, namespace, id, **filters): 786 | """ 787 | Talent API - Returns a talent by ID 788 | """ 789 | filters['namespace'] = namespace 790 | return self.get_resource('data/wow/talent/{0}', region, *[id], **filters) 791 | 792 | def get_pvp_talent_index(self, region, namespace, **filters): 793 | """ 794 | Talent API - Returns an index of PvP talents 795 | """ 796 | filters['namespace'] = namespace 797 | return self.get_resource('data/wow/pvp-talent/index', region, **filters) 798 | 799 | def get_pvp_talent(self, region, namespace, id, **filters): 800 | """ 801 | Talent API - Returns a PvP talent by ID 802 | """ 803 | filters['namespace'] = namespace 804 | return self.get_resource('data/wow/pvp-talent/{0}', region, *[id], **filters) 805 | 806 | # Title API 807 | 808 | def get_title_index(self, region, namespace, **filters): 809 | """ 810 | Title API - Returns an index of titles 811 | """ 812 | filters['namespace'] = namespace 813 | return self.get_resource('data/wow/title/index', region, **filters) 814 | 815 | def get_title(self, region, namespace, id, **filters): 816 | """ 817 | Title API - Returns a title by id 818 | """ 819 | filters['namespace'] = namespace 820 | return self.get_resource('data/wow/title/{0}', region, *[id], **filters) 821 | 822 | # WoW Token API 823 | 824 | def get_token_index(self, region, namespace, **filters): 825 | """ 826 | WoW Token API - Returns the WoW Token index 827 | """ 828 | filters['namespace'] = namespace 829 | return self.get_resource('data/wow/token/index', region, **filters) 830 | -------------------------------------------------------------------------------- /wowapi/mixins/profile.py: -------------------------------------------------------------------------------- 1 | class ProfileMixin: 2 | """All Profile API methods""" 3 | 4 | # Account Profile API (requiring Authorization Code Flow token) 5 | 6 | def get_account_profile_summary( 7 | self, region, namespace, token, **filters 8 | ): 9 | """ 10 | Returns a profile summary for an account 11 | """ 12 | filters['namespace'] = namespace 13 | resource = 'profile/user/wow' 14 | return self.get_oauth_resource(resource, region, token, **filters) 15 | 16 | def get_protected_character_profile_summary( 17 | self, region, namespace, token, realm_id, character_id, **filters 18 | ): 19 | """ 20 | Returns a protected profile summary for a character 21 | """ 22 | filters['namespace'] = namespace 23 | resource = 'profile/user/wow/protected-character/{0}-{1}' 24 | return self.get_oauth_resource( 25 | resource, 26 | region, 27 | token, 28 | *[realm_id, character_id], 29 | **filters 30 | ) 31 | 32 | def get_account_collection_index(self, region, namespace, token, **filters): 33 | """ 34 | Returns an index of collection types for an account 35 | """ 36 | filters['namespace'] = namespace 37 | resource = 'profile/user/wow/collections' 38 | return self.get_oauth_resource(resource, region, token, **filters) 39 | 40 | def get_mount_collection_summary(self, region, namespace, token, **filters): 41 | """ 42 | Returns a summary of the mounts an account has obtained 43 | """ 44 | filters['namespace'] = namespace 45 | resource = 'profile/user/wow/collections/mounts' 46 | return self.get_oauth_resource(resource, region, token, **filters) 47 | 48 | def get_pet_collection_summary(self, region, namespace, token, **filters): 49 | """ 50 | Returns a summary of the pets an account has obtained 51 | """ 52 | filters['namespace'] = namespace 53 | resource = 'profile/user/wow/collections/pets' 54 | return self.get_oauth_resource(resource, region, token, **filters) 55 | 56 | # Character Achievements API 57 | 58 | def get_character_achievements_summary( 59 | self, region, namespace, realm_slug, character_name, **filters 60 | ): 61 | """ 62 | Character Achievements API 63 | Returns a summary of the achievements a character has completed 64 | """ 65 | filters['namespace'] = namespace 66 | resource = 'profile/wow/character/{0}/{1}/achievements' 67 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 68 | 69 | def get_character_achievements_statistics( 70 | self, region, namespace, realm_slug, character_name, **filters 71 | ): 72 | """ 73 | Character Achievements API 74 | Returns a character's statistics as they pertain to achievements 75 | """ 76 | filters['namespace'] = namespace 77 | resource = 'profile/wow/character/{0}/{1}/achievements/statistics' 78 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 79 | 80 | # Character Appearance API 81 | 82 | def get_character_appearance_summary( 83 | self, region, namespace, realm_slug, character_name, **filters 84 | ): 85 | """ 86 | Character Appearance API - Returns a summary of a character's appearance settings 87 | """ 88 | filters['namespace'] = namespace 89 | resource = 'profile/wow/character/{0}/{1}/appearance' 90 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 91 | 92 | # Character Collections API 93 | 94 | def get_character_collection_index( 95 | self, region, namespace, realm_slug, character_name, **filters 96 | ): 97 | """ 98 | Character Collections API - Returns an index of collection types for a character 99 | """ 100 | filters['namespace'] = namespace 101 | resource = 'profile/wow/character/{0}/{1}/collections' 102 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 103 | 104 | def get_character_mount_collection_index( 105 | self, region, namespace, realm_slug, character_name, **filters 106 | ): 107 | """ 108 | Character Collections API - Returns a summary of the mounts a character has obtained 109 | """ 110 | filters['namespace'] = namespace 111 | resource = 'profile/wow/character/{0}/{1}/collections/mounts' 112 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 113 | 114 | def get_character_pet_collection_index( 115 | self, region, namespace, realm_slug, character_name, **filters 116 | ): 117 | """ 118 | Character Collections API - Returns a summary of the pets a character has obtained 119 | """ 120 | filters['namespace'] = namespace 121 | resource = 'profile/wow/character/{0}/{1}/collections/pets' 122 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 123 | 124 | # Character Encounters API 125 | 126 | def get_character_encounters_summary( 127 | self, region, namespace, realm_slug, character_name, **filters 128 | ): 129 | """ 130 | Character Encounters API - Returns a summary of a character's encounters 131 | """ 132 | filters['namespace'] = namespace 133 | resource = 'profile/wow/character/{0}/{1}/encounters' 134 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 135 | 136 | def get_character_dungeons( 137 | self, region, namespace, realm_slug, character_name, **filters 138 | ): 139 | """ 140 | Character Encounters API - Returns a summary of a character's completed dungeons 141 | """ 142 | filters['namespace'] = namespace 143 | resource = 'profile/wow/character/{0}/{1}/encounters/dungeons' 144 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 145 | 146 | def get_character_raids( 147 | self, region, namespace, realm_slug, character_name, **filters 148 | ): 149 | """ 150 | Character Encounters API - Returns a summary of a character's completed raids 151 | """ 152 | filters['namespace'] = namespace 153 | resource = 'profile/wow/character/{0}/{1}/encounters/raids' 154 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 155 | 156 | # Character Equipment API 157 | 158 | def get_character_equipment_summary( 159 | self, region, namespace, realm_slug, character_name, **filters 160 | ): 161 | """ 162 | Character Equipment API - Returns a summary of the items equipped by a character 163 | """ 164 | filters['namespace'] = namespace 165 | resource = 'profile/wow/character/{0}/{1}/equipment' 166 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 167 | 168 | # Character Hunter Pets API 169 | 170 | def get_character_hunter_pets_summary( 171 | self, region, namespace, realm_slug, character_name, **filters 172 | ): 173 | """ 174 | Character Hunter Pets API - Returns a summary of the items equipped by a character 175 | """ 176 | filters['namespace'] = namespace 177 | resource = 'profile/wow/character/{0}/{1}/hunter-pets' 178 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 179 | 180 | # Character Media API 181 | 182 | def get_character_media_summary( 183 | self, region, namespace, realm_slug, character_name, **filters 184 | ): 185 | """ 186 | Character Media API - Returns a summary of the media assets available for a character 187 | """ 188 | filters['namespace'] = namespace 189 | resource = 'profile/wow/character/{0}/{1}/character-media' 190 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 191 | 192 | # WoW Mythic Keystone Character Profile API 193 | 194 | def get_character_mythic_keystone_profile( 195 | self, region, namespace, realm_slug, character_name, **filters 196 | ): 197 | """ 198 | Profile API - Mythic Keystone Character Profile Index 199 | """ 200 | filters['namespace'] = namespace 201 | resource = 'profile/wow/character/{0}/{1}/mythic-keystone-profile' 202 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 203 | 204 | def get_character_mythic_keystone_profile_season( 205 | self, region, namespace, realm_slug, character_name, season_id, **filters 206 | ): 207 | """ 208 | Profile API - Returns the Mythic Keystone season details for a character 209 | """ 210 | filters['namespace'] = namespace 211 | resource = 'profile/wow/character/{0}/{1}/mythic-keystone-profile/season/{2}' 212 | params = [realm_slug, character_name, season_id] 213 | return self.get_resource(resource, region, *params, **filters) 214 | 215 | # Character Professions API 216 | 217 | def get_character_professions_summary( 218 | self, region, namespace, realm_slug, character_name, **filters 219 | ): 220 | """ 221 | Character Professions API - Returns a summary of professions for a character 222 | """ 223 | filters['namespace'] = namespace 224 | resource = 'profile/wow/character/{0}/{1}/professions' 225 | params = [realm_slug, character_name] 226 | return self.get_resource(resource, region, *params, **filters) 227 | 228 | # Character Profile API 229 | 230 | def get_character_profile_summary( 231 | self, region, namespace, realm_slug, character_name, **filters 232 | ): 233 | """ 234 | Character Profile API - Returns a profile summary for a character 235 | """ 236 | filters['namespace'] = namespace 237 | resource = 'profile/wow/character/{0}/{1}' 238 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 239 | 240 | def get_character_profile_status( 241 | self, region, namespace, realm_slug, character_name, **filters 242 | ): 243 | """ 244 | Character Profile API - Returns the status and a unique ID for a character 245 | """ 246 | filters['namespace'] = namespace 247 | resource = 'profile/wow/character/{0}/{1}/status' 248 | return self.get_resource(resource, region, *[realm_slug, character_name], **filters) 249 | 250 | # Character PvP API 251 | 252 | def get_character_pvp_bracket_stats( 253 | self, region, namespace, realm_slug, character_name, bracket, **filters 254 | ): 255 | """ 256 | Character PvP API - Returns the PvP bracket statistics for a character 257 | """ 258 | filters['namespace'] = namespace 259 | resource = 'profile/wow/character/{0}/{1}/pvp-bracket/{2}' 260 | params = [realm_slug, character_name, bracket] 261 | return self.get_resource(resource, region, *params, **filters) 262 | 263 | def get_character_pvp_summary(self, region, namespace, realm_slug, character_name, **filters): 264 | """ 265 | Character PvP API - Returns a PvP summary for a character 266 | """ 267 | filters['namespace'] = namespace 268 | resource = 'profile/wow/character/{0}/{1}/pvp-summary' 269 | params = [realm_slug, character_name] 270 | return self.get_resource(resource, region, *params, **filters) 271 | 272 | # Character Quests API 273 | 274 | def get_character_quests(self, region, namespace, realm_slug, character_name, **filters): 275 | """ 276 | Character Quests API 277 | Returns a character's active quests as well as a link to the character's completed quests 278 | """ 279 | filters['namespace'] = namespace 280 | resource = 'profile/wow/character/{0}/{1}/quests' 281 | params = [realm_slug, character_name] 282 | return self.get_resource(resource, region, *params, **filters) 283 | 284 | def get_character_completed_quests( 285 | self, region, namespace, realm_slug, character_name, **filters 286 | ): 287 | """ 288 | Character Quests API - Returns a list of quests that a character has completed 289 | """ 290 | filters['namespace'] = namespace 291 | resource = 'profile/wow/character/{0}/{1}/quests/completed' 292 | params = [realm_slug, character_name] 293 | return self.get_resource(resource, region, *params, **filters) 294 | 295 | # Character Reputations API 296 | 297 | def get_character_reputations_summary( 298 | self, region, namespace, realm_slug, character_name, **filters 299 | ): 300 | """ 301 | Character Reputations API - Returns a summary of a character's reputations 302 | """ 303 | filters['namespace'] = namespace 304 | resource = 'profile/wow/character/{0}/{1}/reputations' 305 | params = [realm_slug, character_name] 306 | return self.get_resource(resource, region, *params, **filters) 307 | 308 | # Character Specializations API 309 | 310 | def get_character_specializations_summary( 311 | self, region, namespace, realm_slug, character_name, **filters 312 | ): 313 | """ 314 | Character Specializations API - Returns a summary of a character's specializations 315 | """ 316 | filters['namespace'] = namespace 317 | resource = 'profile/wow/character/{0}/{1}/specializations' 318 | params = [realm_slug, character_name] 319 | return self.get_resource(resource, region, *params, **filters) 320 | 321 | # Character Statistics API 322 | 323 | def get_character_stats_summary( 324 | self, region, namespace, realm_slug, character_name, **filters 325 | ): 326 | """ 327 | Character Statistics API - Returns a statistics summary for a character 328 | """ 329 | filters['namespace'] = namespace 330 | resource = 'profile/wow/character/{0}/{1}/statistics' 331 | params = [realm_slug, character_name] 332 | return self.get_resource(resource, region, *params, **filters) 333 | 334 | # Character Titles API 335 | 336 | def get_character_titles_summary( 337 | self, region, namespace, realm_slug, character_name, **filters 338 | ): 339 | """ 340 | Character Titles API - Returns a summary of titles a character has obtained 341 | """ 342 | filters['namespace'] = namespace 343 | resource = 'profile/wow/character/{0}/{1}/titles' 344 | params = [realm_slug, character_name] 345 | return self.get_resource(resource, region, *params, **filters) 346 | 347 | # Guild API 348 | 349 | def get_guild(self, region, namespace, realm_slug, guild_slug, **filters): 350 | """ 351 | Guild API - Returns a single guild by its name and realm 352 | """ 353 | filters['namespace'] = namespace 354 | params = [realm_slug, guild_slug] 355 | return self.get_resource('data/wow/guild/{0}/{1}', region, *params, **filters) 356 | 357 | def get_guild_activity(self, region, namespace, realm_slug, guild_slug, **filters): 358 | """ 359 | Guild API - Returns a single guild's activity by name and realm 360 | """ 361 | filters['namespace'] = namespace 362 | params = [realm_slug, guild_slug] 363 | return self.get_resource('data/wow/guild/{0}/{1}/activity', region, *params, **filters) 364 | 365 | def get_guild_achievements(self, region, namespace, realm_slug, guild_slug, **filters): 366 | """ 367 | Guild API - Returns a single guild's achievements by name and realm 368 | """ 369 | filters['namespace'] = namespace 370 | params = [realm_slug, guild_slug] 371 | return self.get_resource('data/wow/guild/{0}/{1}/achievements', region, *params, **filters) 372 | 373 | def get_guild_roster(self, region, namespace, realm_slug, guild_slug, **filters): 374 | """ 375 | Guild API - Returns a single guild's roster by its name and realm 376 | """ 377 | filters['namespace'] = namespace 378 | params = [realm_slug, guild_slug] 379 | return self.get_resource('data/wow/guild/{0}/{1}/roster', region, *params, **filters) 380 | --------------------------------------------------------------------------------