From 93eb108ed7d1665d0b6f173cf3b71c581cdc36b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B2=E8=8F=AF?= <42814579+yunwah@users.noreply.github.com> Date: Sun, 2 May 2021 16:39:29 -0400 Subject: [PATCH] Initial commit and support 3.6 or greater Migrates the API out of the yunwah/tennoui repository. The warframe_api.py file is renamed to warpy.py and the API class has been renamed to Worldstate. This rename came about as a result of what parts of the API were implemented. Next steps may include the static data processing part of the API as its own class. Additionally this commit aims to make the library installable however there are no current test files so it may fail. From testing with the interface after installing this current state of warpy works as is. The following are changes made to the API wrapper: Exceptions - used for non valid platforms and languages. Language headers - API now supports getting back results in different languages, the default being en. --- .gitignore | 144 ++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + setup.py | 29 +++++++++ warpy/__init__.py | 5 ++ warpy/exceptions.py | 12 ++++ warpy/warpy.py | 138 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 329 insertions(+) create mode 100644 .gitignore create mode 100644 requirements.txt create mode 100644 setup.py create mode 100644 warpy/__init__.py create mode 100644 warpy/exceptions.py create mode 100644 warpy/warpy.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d8baa3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,144 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +.idea/ + +# Conda +.conda/ \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..475c033 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +aiohttp==3.7.4 \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..088a53d --- /dev/null +++ b/setup.py @@ -0,0 +1,29 @@ +import setuptools +import os +import codecs + +cwd = os.path.abspath(os.path.dirname(__file__)) + + +def read(rel_path): + here = os.path.abspath(os.path.dirname(__file__)) + with codecs.open(os.path.join(here, rel_path), 'r') as fp: + return fp.read() + +def get_version(rel_path): + for line in read(rel_path).splitlines(): + if line.startswith('__version__'): + delim = '"' if '"' in line else "'" + return line.split(delim)[1] + else: + raise RuntimeError("Unable to find version string.") + + +setuptools.setup( + name='warpy', + version=get_version('warpy/__init__.py'), + author='yunwah', + description='An asynchronous API wrapper for the unofficial WarframeStat.us API.', + url='https://github.com/yunwah/warpy', + packages=setuptools.find_packages() +) \ No newline at end of file diff --git a/warpy/__init__.py b/warpy/__init__.py new file mode 100644 index 0000000..c8d167c --- /dev/null +++ b/warpy/__init__.py @@ -0,0 +1,5 @@ +__version__ = "0.1a1.dev0" + +from .warpy import Worldstate +from .exceptions import * + diff --git a/warpy/exceptions.py b/warpy/exceptions.py new file mode 100644 index 0000000..f1e0cb0 --- /dev/null +++ b/warpy/exceptions.py @@ -0,0 +1,12 @@ +class NonPlatformError(Exception): + def __init__(self, platform): + self.platform = platform + self.message = str(platform) + ' is not a valid platform. The following platforms are supported: ' \ + '\'pc\', \'ps4\', \'xb1\', \'swi\'.' + + +class NonLanguageError(Exception): + def __init__(self, language): + self.language = language + self.message = str(language) + ' is not a valid language. The following languages are supported: ' \ + '\'de\', \'es\', \'fr\', \'it\', \'ko\', \'pl\', \'pt\', \'ru\', \'zh\', \'en\'.' diff --git a/warpy/warpy.py b/warpy/warpy.py new file mode 100644 index 0000000..cdd3c32 --- /dev/null +++ b/warpy/warpy.py @@ -0,0 +1,138 @@ +import asyncio +import aiohttp +from .exceptions import NonPlatformError, NonLanguageError + +WARFRAME_API = 'https://api.warframestat.us' + + +class Worldstate: + _platforms = ['pc', 'ps4', 'xb1', 'swi'] + _languages = ['de', 'es', 'fr', 'it', 'ko', 'pl', 'pt', 'ru', 'zh', 'en'] + + def __init__(self, platform: str, language: str = 'en', loop=None): + if platform not in self._platforms: + raise NonPlatformError(platform) + self.platform = platform + if language not in self._languages: + raise NonLanguageError(language) + self.language = language + self._loop = asyncio.get_event_loop() if loop is None else loop + self.session = aiohttp.ClientSession(loop=self._loop) + self._headers = self._generate_headers() + + def _generate_headers(self): + return { + 'Accept-Language': self.language + } + + async def _fetch(self, url): + async with self.session.get(url, headers=self._headers) as response: + resp = await response.json() + return resp + + async def worldstate(self): + url = WARFRAME_API + '/{platform}'.format(platform=self.platform) + return await self._fetch(url) + + async def alerts(self): + url = WARFRAME_API + '/{platform}/alerts'.format(platform=self.platform) + return await self._fetch(url) + + async def arbitration(self): + url = WARFRAME_API + '/{platform}/arbitration'.format(platform=self.platform) + return await self._fetch(url) + + async def cambion_status(self): + url = WARFRAME_API + '/{platform}/cambionCycle'.format(platform=self.platform) + return await self._fetch(url) + + async def cetus_status(self): + url = WARFRAME_API + '/{platform}/cetusCycle'.format(platform=self.platform) + return await self._fetch(url) + + async def conclave_challenges(self): + url = WARFRAME_API + '/{platform}/conclaveChallenges'.format(platform=self.platform) + return await self._fetch(url) + + async def construction_progress(self): + url = WARFRAME_API + '/{platform}/constructionProgress'.format(platform=self.platform) + return await self._fetch(url) + + async def darvo_deal(self): + url = WARFRAME_API + '/{platform}/dailyDeals'.format(platform=self.platform) + return await self._fetch(url) + + async def earth_cycle(self): + url = WARFRAME_API + '/{platform}/earthCycle'.format(platform=self.platform) + return await self._fetch(url) + + async def ongoing_events(self): + url = WARFRAME_API + '/{platform}/events'.format(platform=self.platform) + return await self._fetch(url) + + async def fissures(self): + url = WARFRAME_API + '/{platform}/fissures'.format(platform=self.platform) + return await self._fetch(url) + + async def darvo_flash_sale(self): + url = WARFRAME_API + '/{platform}/flashSales'.format(platform=self.platform) + return await self._fetch(url) + + async def global_upgrades(self): + url = WARFRAME_API + '/{platform}/globalUpgrades'.format(platform=self.platform) + return await self._fetch(url) + + async def invasions(self): + url = WARFRAME_API + '/{platform}/invasions'.format(platform=self.platform) + return await self._fetch(url) + + async def kuva_nodes(self): + url = WARFRAME_API + '/{platform}/kuva'.format(platform=self.platform) + return await self._fetch(url) + + async def news(self): + url = WARFRAME_API + '/{platform}/news'.format(platform=self.platform) + return await self._fetch(url) + + async def nightwave(self): + url = WARFRAME_API + '/{platform}/nightwave'.format(platform=self.platform) + return await self._fetch(url) + + async def persistent_enemy_data(self): + url = WARFRAME_API + '/{platform}/persistentEnemies'.format(platform=self.platform) + return await self._fetch(url) + + async def riven_stats(self, query: str = None): + if query: + url = WARFRAME_API + '/{platform}/rivens/search/{query}'.format(platform=self.platform, query=query) + else: + url = WARFRAME_API + '/{platform}/rivens'.format(platform=self.platform) + return await self._fetch(url) + + async def sentient_outpost(self): + url = WARFRAME_API + '/{platform}/sentientOutposts'.format(platform=self.platform) + return await self._fetch(url) + + async def sanctuary_status(self): + url = WARFRAME_API + '/{platform}/simaris'.format(platform=self.platform) + return await self._fetch(url) + + async def sortie(self): + url = WARFRAME_API + '/{platform}/sortie'.format(platform=self.platform) + return await self._fetch(url) + + async def syndicate_nodes(self): + url = WARFRAME_API + '/{platform}/syndicateMissions'.format(platform=self.platform) + return await self._fetch(url) + + async def worldstate_timestamp(self): + url = WARFRAME_API + '/{platform}/timestamp'.format(platform=self.platform) + return await self._fetch(url) + + async def vallis_status(self): + url = WARFRAME_API + '/{platform}/vallisCycle'.format(platform=self.platform) + return await self._fetch(url) + + async def void_trader(self): + url = WARFRAME_API + '/{platform}/voidTrader'.format(platform=self.platform) + return await self._fetch(url)