diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..260af94 --- /dev/null +++ b/.flake8 @@ -0,0 +1,5 @@ +[flake8] +exclude = .git,.nox,venv +max-line-length = 90 +select = E,F,W,C +ignore=E501,W503,E203 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b495b68 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +venv/ +*.egg-info/ +.vscode/ +dist/ +venv diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..8b035f7 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# Caiyun Weather API Python SDK + +## Install + +Python 3.6+ is required. + +```sh +pip install cy-weather-api +``` + +## Usage + +### Request Caiyun API + +```py +from cy_weather_api import CyWeatherAPIClient + +client = CyWeatherAPIClient(token="TAkhjf8d1nlSlspN") +apiResult = client.fetch(lng=101.8551, lat=26.6832, lang="zh_CN", alert=True) +print(apiResult.result.hourly.description) +apiResult = client.fetch(lng=-0.2008, lat=51.5024, lang="en_GB") +print(apiResult.result.hourly.description) +apiResult = client.fetch(lng=73.9808, lat=40.7648, lang="en_US") +print(apiResult.result.hourly.description) +``` + +Output sample: + +``` +晴,今天晚间20点钟后转小雨,其后多云 +clear weather over the next 24 hours +clear weather, overcast after 20 o'clock this afternoon, followed by cloudy +``` + +### Use our dataclass models + +The default HTTP client is requests, you can other HTTP cient to request API, +and pass the response dict to our models (based on `dataclasss`): + +```py +from cy_weather_api import initFromDict + +data = { + "status": "ok", + "api_version": "v2.5", + "api_status": "active", + "lang": "en_US", + "unit": "metric", + "tzshift": 28800, + "timezone": "Asia/Shanghai", + "server_time": 1589125757, + "location": [39.888888, 116.674501], + "result": {"forecast_keypoint": "test forecast_keypoint", "primary": 0}, +} +apiResult = initFromDict(data) +``` diff --git a/cy_weather_api/__init__.py b/cy_weather_api/__init__.py new file mode 100644 index 0000000..a7e98f3 --- /dev/null +++ b/cy_weather_api/__init__.py @@ -0,0 +1,4 @@ +from cyapi.client import CyAPIClient +from cyapi.models import initFromDict + +__all__ = ["CyAPIClient", "initFromDict"] diff --git a/cy_weather_api/client.py b/cy_weather_api/client.py new file mode 100644 index 0000000..a318465 --- /dev/null +++ b/cy_weather_api/client.py @@ -0,0 +1,94 @@ +from dataclasses import dataclass + +import requests +from cyapi.models import initFromDict, CyWeatherAPIResponseHandler + +API_BASE = ( + "http://api.caiyunapp.com/v2.5/{token}/{lng},{lat}/weather.json?" + "&lang={lang}" + "&unit={unit}" + "&dailysteps={dailysteps}" + "&hourlysteps={hourlysteps}" +) +VALID_UNIT_OPTIONS = ["metric", "metric:v1", "metric:v2", "imperial", "SI"] +VALID_GRANU_OPTIONS = ["realtime", "minutely", "hourly", "daily", "weather"] + + +@dataclass +class CyWeatherAPIClient: + token: str = "TAkhjf8d1nlSlspN" + session = requests.Session() + + def fetch( + self, + lng: float, + lat: float, + lang: str = "en_US", + begin: int = None, + alert: bool = False, + granu: str = None, + unit: str = "metric", + dailysteps: int = 5, + hourlysteps: int = 48, + ) -> CyWeatherAPIResponseHandler: + + if unit and unit not in VALID_UNIT_OPTIONS: + raise ValueError( + "Invaliad unit, got {}, expect one from {}".format( + unit, VALID_UNIT_OPTIONS + ) + ) + + if granu and granu not in VALID_GRANU_OPTIONS: + raise ValueError( + "Invaliad granu, got {}, expect one from {}".format( + unit, VALID_GRANU_OPTIONS + ) + ) + + if dailysteps < 1 or dailysteps > 15: + raise ValueError("dailysteps in range [1, 15]") + + if hourlysteps < 1 or hourlysteps > 360: + raise ValueError("hourlysteps in range [1, 360]") + + url = API_BASE.format( + token=self.token, + lng=lng, + lat=lat, + lang=lang, + unit=unit, + hourlysteps=hourlysteps, + dailysteps=dailysteps, + ) + + if granu: + url += "&granu={}".format(granu) + + if begin is not None: + try: + int(begin) + url += "&begin={}".format(begin) + except Exception: + raise ValueError("Invalid begin") + + _data = self.session.get(url).json() + if _data["status"] != "ok": + _mess = ( + "Calling Caiyun API Errored with {error_mess}, please check token status\n" + "url: {url}\n" + "data: {api_data}\n" + ) + mess = _mess.format(url=url, api_data=_data, error_mess=_data.get("error")) + raise ValueError(mess) + return initFromDict(_data) + + +if __name__ == "__main__": + client = CyWeatherAPIClient(token="TAkhjf8d1nlSlspN") + apiResult = client.fetch(lng=101.8551, lat=26.6832, lang="zh_CN", alert=True) + print(apiResult.result.hourly.description) + apiResult = client.fetch(lng=-0.2008, lat=51.5024, lang="en_GB") + print(apiResult.result.hourly.description) + apiResult = client.fetch(lng=73.9808, lat=40.7648, lang="en_US") + print(apiResult.result.hourly.description) diff --git a/cy_weather_api/models/__init__.py b/cy_weather_api/models/__init__.py new file mode 100644 index 0000000..1985f78 --- /dev/null +++ b/cy_weather_api/models/__init__.py @@ -0,0 +1,84 @@ +"""Dataclass for Caiyun Weather API. + +Below dataclasses arr based on Caiyun Weather API v2.5, the offical API docs: + + zh_CN: https://open.caiyunapp.com/通用预报接口/v2.5 + en_US: https://open.caiyunapp.com/General_weather_interface/v2.5 + +We encourage use Golang's coding style: + + 1. Use black as format tool. + 2. Use Camel-Case. + 3. Avoid complex oop tricks. +""" + +import json +from dataclasses import asdict, dataclass, is_dataclass +from typing import Dict, List + +import orjson +from dacite import from_dict + +from cyapi.models.result import cyWeatherAPIResponseResultStruct + + +class EnhancedJSONEncoder(json.JSONEncoder): + def default(self, o): + if is_dataclass(o): + return asdict(o) + return super().default(o) + + +@dataclass +class CyWeatherAPIResponseHandler: + status: str + api_version: str + api_status: str + lang: str + unit: str + tzshift: int + timezone: str + server_time: int + location: List[float] + result: cyWeatherAPIResponseResultStruct + + def __post_init__(self): + pass + + def dumps(self, ensure_text=True) -> bytes: + """Fast dumps via orjson. + + Check orjson docs for details: https://github.com/ijl/orjson#dataclass + """ + if ensure_text: + return orjson.dumps(self).decode("utf-8") + else: + return orjson.dumps(self) + + def dumps_pretty(self, **kwargs) -> str: + """Dumps JSON with indent. + + Note: please do not change `cls` option if you don't know it. + """ + return json.dumps(self, cls=EnhancedJSONEncoder, **kwargs) + + +def initFromDict(data: Dict) -> CyWeatherAPIResponseHandler: + return from_dict(data_class=CyWeatherAPIResponseHandler, data=data) + + +if __name__ == "__main__": + import requests + # from dacite import from_dict + + # NOTE: Test token, no one can ensure its availability. + TOKEN = "TAkhjf8d1nlSlspN" + LNG, LAT = 116.3883, 39.9289 + URL = "http://api.caiyunapp.com/v2.5/{TOKEN}/{LNG},{LAT}/weather".format( + TOKEN=TOKEN, LNG=LNG, LAT=LAT + ) + + apiResponseDataclass = from_dict( + data_class=CyWeatherAPIResponseHandler, data=requests.get(URL).json() + ) + print(apiResponseDataclass.dumps()) diff --git a/cy_weather_api/models/alert.py b/cy_weather_api/models/alert.py new file mode 100644 index 0000000..ee6a155 --- /dev/null +++ b/cy_weather_api/models/alert.py @@ -0,0 +1,31 @@ +from dataclasses import dataclass +from typing import List + + +@dataclass +class cyWeatherAPIResponseAlertContentItemStruct: + province: str + status: str + code: str + description: str + pubtimestamp: float + city: str + adcode: str + regionId: str + latlon: List[float] + county: str + alertId: str + request_status: str + source: str + title: str + location: str + + def __post__init(self): + self.lng = self.latlon[-1] + self.lat = self.latlon[0] + + +@dataclass +class cyWeatherAPIResponseAlertStruct: + status: str = None + content: List[cyWeatherAPIResponseAlertContentItemStruct] = None diff --git a/cy_weather_api/models/daily.py b/cy_weather_api/models/daily.py new file mode 100644 index 0000000..000551c --- /dev/null +++ b/cy_weather_api/models/daily.py @@ -0,0 +1,96 @@ +from dataclasses import dataclass +from typing import List, Any + + +@dataclass +class cyWeatherAPIResponseDailyAstroItemTimeStruct: + time: str + + +@dataclass +class cyWeatherAPIResponseDailyAstroItemStruct: + date: str + sunrise: cyWeatherAPIResponseDailyAstroItemTimeStruct + sunset: cyWeatherAPIResponseDailyAstroItemTimeStruct + + +@dataclass +class cyWeatherAPIResponseDailyMaxMinAvgItemStruct: + date: str + max: float + min: float + avg: float + + +@dataclass +class cyWeatherAPIResponseDailyWindItemPropertyStruct: + speed: float + direction: float + + +@dataclass +class cyWeatherAPIResponseDailyWindItemStruct: + date: str + max: cyWeatherAPIResponseDailyWindItemPropertyStruct + min: cyWeatherAPIResponseDailyWindItemPropertyStruct + avg: cyWeatherAPIResponseDailyWindItemPropertyStruct + + +@dataclass +class cyWeatherAPIResponseDailyAirQualityItemAQITypeStruct: + chn: float + usa: float + + +@dataclass +class cyWeatherAPIResponseDailyAirQualityItemAQIStruct: + date: str + max: cyWeatherAPIResponseDailyAirQualityItemAQITypeStruct + min: cyWeatherAPIResponseDailyAirQualityItemAQITypeStruct + avg: cyWeatherAPIResponseDailyAirQualityItemAQITypeStruct + + +@dataclass +class cyWeatherAPIResponseDailyAirQualityItemStruct: + aqi: List[cyWeatherAPIResponseDailyAirQualityItemAQIStruct] + pm25: List[cyWeatherAPIResponseDailyMaxMinAvgItemStruct] + + +@dataclass +class cyWeatherAPIResponseDailySkyconItemStruct: + date: str + value: str + + +@dataclass +class cyWeatherAPIResponseDailyDateIndexDescItemStruct: + date: str + index: Any + desc: str + + +@dataclass +class cyWeatherAPIResponseDailyLifeIndexItemStruct: + ultraviolet: List[cyWeatherAPIResponseDailyDateIndexDescItemStruct] + carWashing: List[cyWeatherAPIResponseDailyDateIndexDescItemStruct] + dressing: List[cyWeatherAPIResponseDailyDateIndexDescItemStruct] + comfort: List[cyWeatherAPIResponseDailyDateIndexDescItemStruct] + coldRisk: List[cyWeatherAPIResponseDailyDateIndexDescItemStruct] + + +@dataclass +class cyWeatherAPIResponseDailyStruct: + status: str + astro: List[cyWeatherAPIResponseDailyAstroItemStruct] + precipitation: List[cyWeatherAPIResponseDailyMaxMinAvgItemStruct] + temperature: List[cyWeatherAPIResponseDailyMaxMinAvgItemStruct] + humidity: List[cyWeatherAPIResponseDailyMaxMinAvgItemStruct] + cloudrate: List[cyWeatherAPIResponseDailyMaxMinAvgItemStruct] + pressure: List[cyWeatherAPIResponseDailyMaxMinAvgItemStruct] + visibility: List[cyWeatherAPIResponseDailyMaxMinAvgItemStruct] + dswrf: List[cyWeatherAPIResponseDailyMaxMinAvgItemStruct] + wind: List[cyWeatherAPIResponseDailyWindItemStruct] + skycon: List[cyWeatherAPIResponseDailySkyconItemStruct] + skycon_08h_20h: List[cyWeatherAPIResponseDailySkyconItemStruct] + skycon_20h_32h: List[cyWeatherAPIResponseDailySkyconItemStruct] + life_index: cyWeatherAPIResponseDailyLifeIndexItemStruct diff --git a/cy_weather_api/models/hourly.py b/cy_weather_api/models/hourly.py new file mode 100644 index 0000000..5388548 --- /dev/null +++ b/cy_weather_api/models/hourly.py @@ -0,0 +1,54 @@ +from dataclasses import dataclass +from typing import Any, List + + +@dataclass +class cyWeatherAPIResponseHourlyWindStruct: + datetime: str + speed: float + direction: float + + +@dataclass +class cyWeatherAPIResponseHourlyAirQualityItemValue: + chn: float + usa: float + + +@dataclass +class cyWeatherAPIResponseHourlyAirQualityItem: + datetime: str + value: cyWeatherAPIResponseHourlyAirQualityItemValue + + +@dataclass +class cyWeatherAPIResponseHourlyAirQualityPM25Item: + datetime: str + value: float + + +@dataclass +class cyWeatherAPIResponseHourlyAirQuality: + aqi: List[cyWeatherAPIResponseHourlyAirQualityItem] + pm25: List[cyWeatherAPIResponseHourlyAirQualityPM25Item] + + +@dataclass +class cyWeatherAPIResponseHourlySimpleDatetimeValuePair: + datetime: str + value: Any + + +@dataclass +class cyWeatherAPIResponseHourlyStruct: + status: str + description: str + precipitation: List[cyWeatherAPIResponseHourlySimpleDatetimeValuePair] + temperature: List[cyWeatherAPIResponseHourlySimpleDatetimeValuePair] + humidity: List[cyWeatherAPIResponseHourlySimpleDatetimeValuePair] + cloudrate: List[cyWeatherAPIResponseHourlySimpleDatetimeValuePair] + pressure: List[cyWeatherAPIResponseHourlySimpleDatetimeValuePair] + visibility: List[cyWeatherAPIResponseHourlySimpleDatetimeValuePair] + dswrf: List[cyWeatherAPIResponseHourlySimpleDatetimeValuePair] + wind: List[cyWeatherAPIResponseHourlyWindStruct] + air_quality: cyWeatherAPIResponseHourlyAirQuality diff --git a/cy_weather_api/models/minutely.py b/cy_weather_api/models/minutely.py new file mode 100644 index 0000000..71ffaeb --- /dev/null +++ b/cy_weather_api/models/minutely.py @@ -0,0 +1,12 @@ +from dataclasses import dataclass +from typing import List + + +@dataclass +class cyWeatherAPIResponseMinutelyStruct: + status: str + datasource: str + precipitation_2h: List[float] + precipitation: List[float] + probability: List[float] + description: str diff --git a/cy_weather_api/models/realtime.py b/cy_weather_api/models/realtime.py new file mode 100644 index 0000000..801f84d --- /dev/null +++ b/cy_weather_api/models/realtime.py @@ -0,0 +1,80 @@ +from dataclasses import dataclass + + +@dataclass +class cyWeatherAPIResponseRealtimeWindStruct: + speed: float + direction: float + + +@dataclass +class cyWeatherAPIResponseRealtimePrecipitationItemLocalStruct: + status: str + datasource: str + intensity: float + + +@dataclass +class cyWeatherAPIResponseRealtimePrecipitationItemNearestStruct: + status: str + distance: float + intensity: float + + +@dataclass +class cyWeatherAPIResponseRealtimePrecipitationStruct: + local: cyWeatherAPIResponseRealtimePrecipitationItemLocalStruct + nearest: cyWeatherAPIResponseRealtimePrecipitationItemNearestStruct = None + + +@dataclass +class cyWeatherAPIResponseRealtimeAirQualityAQIValueStruct: + chn: float + usa: float + + +@dataclass +class cyWeatherAPIResponseRealtimeAirQualityAQIDescStruct: + chn: str + usa: str + + +@dataclass +class cyWeatherAPIResponseRealtimeAirQualityStruct: + aqi: cyWeatherAPIResponseRealtimeAirQualityAQIValueStruct + description: cyWeatherAPIResponseRealtimeAirQualityAQIDescStruct + pm25: float = None + pm10: float = None + o3: float = None + so2: float = None + no2: float = None + co: float = None + + +@dataclass +class cyWeatherAPIResponseRealtimeLifeIndexItemStruct: + index: float + desc: str + + +@dataclass +class cyWeatherAPIResponseRealtimeLifeIndexStruct: + ultraviolet: cyWeatherAPIResponseRealtimeLifeIndexItemStruct + comfort: cyWeatherAPIResponseRealtimeLifeIndexItemStruct + + +@dataclass +class cyWeatherAPIResponseRealtimeStruct: + status: str + temperature: float + humidity: float + cloudrate: float + skycon: str + visibility: float + dswrf: float + wind: cyWeatherAPIResponseRealtimeWindStruct + pressure: float + apparent_temperature: float + precipitation: cyWeatherAPIResponseRealtimePrecipitationStruct + air_quality: cyWeatherAPIResponseRealtimeAirQualityStruct + life_index: cyWeatherAPIResponseRealtimeLifeIndexStruct diff --git a/cy_weather_api/models/result.py b/cy_weather_api/models/result.py new file mode 100644 index 0000000..724ef31 --- /dev/null +++ b/cy_weather_api/models/result.py @@ -0,0 +1,18 @@ +from dataclasses import dataclass + +from cyapi.models.alert import cyWeatherAPIResponseAlertStruct +from cyapi.models.hourly import cyWeatherAPIResponseHourlyStruct +from cyapi.models.minutely import cyWeatherAPIResponseMinutelyStruct +from cyapi.models.realtime import cyWeatherAPIResponseRealtimeStruct +from cyapi.models.daily import cyWeatherAPIResponseDailyStruct + + +@dataclass +class cyWeatherAPIResponseResultStruct: + primary: int + forecast_keypoint: str = None + realtime: cyWeatherAPIResponseRealtimeStruct = None + minutely: cyWeatherAPIResponseMinutelyStruct = None + hourly: cyWeatherAPIResponseHourlyStruct = None + daily: cyWeatherAPIResponseDailyStruct = None + alert: cyWeatherAPIResponseAlertStruct = None diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..6801ba5 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,561 @@ +[[package]] +category = "dev" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +name = "appdirs" +optional = false +python-versions = "*" +version = "1.4.4" + +[[package]] +category = "dev" +description = "Classes Without Boilerplate" +name = "attrs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "20.1.0" + +[package.extras] +dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] + +[[package]] +category = "dev" +description = "The uncompromising code formatter." +name = "black" +optional = false +python-versions = ">=3.6" +version = "19.10b0" + +[package.dependencies] +appdirs = "*" +attrs = ">=18.1.0" +click = ">=6.5" +pathspec = ">=0.6,<1" +regex = "*" +toml = ">=0.9.4" +typed-ast = ">=1.4.0" + +[package.extras] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] + +[[package]] +category = "main" +description = "Python package for providing Mozilla's CA Bundle." +name = "certifi" +optional = false +python-versions = "*" +version = "2020.6.20" + +[[package]] +category = "dev" +description = "Validate configuration and produce human readable error messages." +name = "cfgv" +optional = false +python-versions = ">=3.6.1" +version = "3.2.0" + +[[package]] +category = "main" +description = "Universal encoding detector for Python 2 and 3" +name = "chardet" +optional = false +python-versions = "*" +version = "3.0.4" + +[[package]] +category = "dev" +description = "Composable command line interface toolkit" +name = "click" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "7.1.2" + +[[package]] +category = "main" +description = "Simple creation of data classes from dictionaries." +name = "dacite" +optional = false +python-versions = ">=3.6" +version = "1.5.1" + +[package.dependencies] +[package.dependencies.dataclasses] +python = "<3.7" +version = "*" + +[package.extras] +dev = ["pytest (>=5)", "pytest-cov", "coveralls", "black", "mypy", "pylint"] + +[[package]] +category = "main" +description = "A backport of the dataclasses module for Python 3.6" +marker = "python_version < \"3.7\"" +name = "dataclasses" +optional = false +python-versions = "*" +version = "0.6" + +[[package]] +category = "dev" +description = "Distribution utilities" +name = "distlib" +optional = false +python-versions = "*" +version = "0.3.1" + +[[package]] +category = "dev" +description = "A platform independent file lock." +name = "filelock" +optional = false +python-versions = "*" +version = "3.0.12" + +[[package]] +category = "dev" +description = "the modular source code checker: pep8 pyflakes and co" +name = "flake8" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +version = "3.8.3" + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.6.0a1,<2.7.0" +pyflakes = ">=2.2.0,<2.3.0" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = "*" + +[[package]] +category = "dev" +description = "File identification library for Python" +name = "identify" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +version = "1.4.30" + +[package.extras] +license = ["editdistance"] + +[[package]] +category = "main" +description = "Internationalized Domain Names in Applications (IDNA)" +name = "idna" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.10" + +[[package]] +category = "dev" +description = "Read metadata from Python packages" +marker = "python_version < \"3.8\"" +name = "importlib-metadata" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +version = "1.7.0" + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "rst.linker"] +testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] + +[[package]] +category = "dev" +description = "Read resources from Python packages" +marker = "python_version < \"3.7\"" +name = "importlib-resources" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +version = "3.0.0" + +[package.dependencies] +[package.dependencies.zipp] +python = "<3.8" +version = ">=0.4" + +[package.extras] +docs = ["sphinx", "rst.linker", "jaraco.packaging"] + +[[package]] +category = "dev" +description = "McCabe checker, plugin for flake8" +name = "mccabe" +optional = false +python-versions = "*" +version = "0.6.1" + +[[package]] +category = "dev" +description = "Node.js virtual environment builder" +name = "nodeenv" +optional = false +python-versions = "*" +version = "1.5.0" + +[[package]] +category = "main" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +name = "orjson" +optional = false +python-versions = ">=3.6" +version = "3.3.1" + +[[package]] +category = "dev" +description = "Utility library for gitignore style pattern matching of file paths." +name = "pathspec" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.8.0" + +[[package]] +category = "dev" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +name = "pre-commit" +optional = false +python-versions = ">=3.6.1" +version = "2.7.1" + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +toml = "*" +virtualenv = ">=20.0.8" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = "*" + +[package.dependencies.importlib-resources] +python = "<3.7" +version = "*" + +[[package]] +category = "dev" +description = "Python style guide checker" +name = "pycodestyle" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.6.0" + +[[package]] +category = "dev" +description = "passive checker of Python programs" +name = "pyflakes" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.2.0" + +[[package]] +category = "dev" +description = "YAML parser and emitter for Python" +name = "pyyaml" +optional = false +python-versions = "*" +version = "5.3.1" + +[[package]] +category = "dev" +description = "Alternative regular expression module, to replace re." +name = "regex" +optional = false +python-versions = "*" +version = "2020.7.14" + +[[package]] +category = "main" +description = "Python HTTP for Humans." +name = "requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.24.0" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<4" +idna = ">=2.5,<3" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] + +[[package]] +category = "dev" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +version = "1.15.0" + +[[package]] +category = "dev" +description = "Python Library for Tom's Obvious, Minimal Language" +name = "toml" +optional = false +python-versions = "*" +version = "0.10.1" + +[[package]] +category = "dev" +description = "a fork of Python 2 and 3 ast modules with type comment support" +name = "typed-ast" +optional = false +python-versions = "*" +version = "1.4.1" + +[[package]] +category = "main" +description = "HTTP library with thread-safe connection pooling, file post, and more." +name = "urllib3" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +version = "1.25.10" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] + +[[package]] +category = "dev" +description = "Virtual Python Environment builder" +name = "virtualenv" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +version = "20.0.31" + +[package.dependencies] +appdirs = ">=1.4.3,<2" +distlib = ">=0.3.1,<1" +filelock = ">=3.0.0,<4" +six = ">=1.9.0,<2" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12,<2" + +[package.dependencies.importlib-resources] +python = "<3.7" +version = ">=1.0" + +[package.extras] +docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] +testing = ["coverage (>=5)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] + +[[package]] +category = "dev" +description = "Backport of pathlib-compatible object wrapper for zip files" +marker = "python_version < \"3.8\"" +name = "zipp" +optional = false +python-versions = ">=3.6" +version = "3.1.0" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["jaraco.itertools", "func-timeout"] + +[metadata] +content-hash = "449fd15953f2e8eab1256f64f1f7bb7308f165abd0cbb8f1f4434bee9e79e06b" +python-versions = "^3.6.1" + +[metadata.files] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] +attrs = [ + {file = "attrs-20.1.0-py2.py3-none-any.whl", hash = "sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff"}, + {file = "attrs-20.1.0.tar.gz", hash = "sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a"}, +] +black = [ + {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, + {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, +] +certifi = [ + {file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, + {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, +] +cfgv = [ + {file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"}, + {file = "cfgv-3.2.0.tar.gz", hash = "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1"}, +] +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] +click = [ + {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, + {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, +] +dacite = [ + {file = "dacite-1.5.1-py3-none-any.whl", hash = "sha256:f7f269647ede90f8702728eb7dcb972051511c81b853a93c962fbd31f1753b9f"}, + {file = "dacite-1.5.1.tar.gz", hash = "sha256:764c96e0304cb189628686689a163a6a3a8ce7bf3465f0a2d882a8b42f88108f"}, +] +dataclasses = [ + {file = "dataclasses-0.6-py3-none-any.whl", hash = "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f"}, + {file = "dataclasses-0.6.tar.gz", hash = "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84"}, +] +distlib = [ + {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"}, + {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"}, +] +filelock = [ + {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, + {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, +] +flake8 = [ + {file = "flake8-3.8.3-py2.py3-none-any.whl", hash = "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c"}, + {file = "flake8-3.8.3.tar.gz", hash = "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"}, +] +identify = [ + {file = "identify-1.4.30-py2.py3-none-any.whl", hash = "sha256:f9f84a4ff44e29b9cc23c4012c2c8954089860723f80ce63d760393e5f197108"}, + {file = "identify-1.4.30.tar.gz", hash = "sha256:e105a62fd3a496c701fd1bc4e24eb695455b5efb97e722816d5bd988c3344311"}, +] +idna = [ + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, +] +importlib-metadata = [ + {file = "importlib_metadata-1.7.0-py2.py3-none-any.whl", hash = "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070"}, + {file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"}, +] +importlib-resources = [ + {file = "importlib_resources-3.0.0-py2.py3-none-any.whl", hash = "sha256:d028f66b66c0d5732dae86ba4276999855e162a749c92620a38c1d779ed138a7"}, + {file = "importlib_resources-3.0.0.tar.gz", hash = "sha256:19f745a6eca188b490b1428c8d1d4a0d2368759f32370ea8fb89cad2ab1106c3"}, +] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] +nodeenv = [ + {file = "nodeenv-1.5.0-py2.py3-none-any.whl", hash = "sha256:5304d424c529c997bc888453aeaa6362d242b6b4631e90f3d4bf1b290f1c84a9"}, + {file = "nodeenv-1.5.0.tar.gz", hash = "sha256:ab45090ae383b716c4ef89e690c41ff8c2b257b85b309f01f3654df3d084bd7c"}, +] +orjson = [ + {file = "orjson-3.3.1-cp36-cp36m-macosx_10_7_x86_64.whl", hash = "sha256:0f33d28083819579976669f54ca79675d8e95fd5d75e7db21b798354ed8dd15b"}, + {file = "orjson-3.3.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4c290f1c0b6665d60181ee2f0ef631640d04ead2002ca4eadce4991ea5d6a4ed"}, + {file = "orjson-3.3.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:bf542f372162533550e86003d48664ab5fc1b44fb2b88923b9794cc8db6f0cf0"}, + {file = "orjson-3.3.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:28e6116ebd2082357bb9c66a76a3a1dc6aa4de0754801ac10b9903d31b752a1b"}, + {file = "orjson-3.3.1-cp36-none-win_amd64.whl", hash = "sha256:c4ac5a1d1767733708fd9b45cbbab3f8871af57b54b707a2dc6fddb47e51a81a"}, + {file = "orjson-3.3.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:0f11fd620b74fbdcf29021b3a9c36fb6e13efcdd63cbacc292d0786b54b4b2e8"}, + {file = "orjson-3.3.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e455c5b42a023f4777526c623d2e9ae415084de5130f93aefe689ea482de5f67"}, + {file = "orjson-3.3.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:8c90083c67653d88b132820719e604250f26ba04229efe3149bf82ba2a08f8cf"}, + {file = "orjson-3.3.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:bc23eed41167b4454cddd51f72a7ee4163c33565c509bb9469adf56384b1cce2"}, + {file = "orjson-3.3.1-cp37-none-win_amd64.whl", hash = "sha256:3bff4765281da6fa8ddbbe692e5061f950d11aabdfe64837fb53ead4756e9af6"}, + {file = "orjson-3.3.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:1e19907c1ccf82976c2d111f3914a2c0697720b91908e8ef02405e4dc21c662a"}, + {file = "orjson-3.3.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:aa8332a3ee0fa03a331bea4f28cdcc4d363b53af2ea41630d7eb580422514a1f"}, + {file = "orjson-3.3.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:4ab9536c3776136303ab9e6432691d970e6aa5d27dbc2b5e0ca0d0db3e12f1c4"}, + {file = "orjson-3.3.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:28dc7e1f89440a68c1ccb937f6f0ae40fa3875de84f747262c00bc18aa25c5ec"}, + {file = "orjson-3.3.1-cp38-none-win_amd64.whl", hash = "sha256:fa4d5d734e76d9f21a94444fbf1de7eea185b355b324d38c8a7456ce63c3bbeb"}, + {file = "orjson-3.3.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b0533d6719b781db7563c478672d91faeac9ea810f30f16ebb5e917c4451b098"}, + {file = "orjson-3.3.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:a7d634eb69083ca5a49baf412625604813f9e3365cb869f445c388d15fe60122"}, + {file = "orjson-3.3.1.tar.gz", hash = "sha256:149d6a2bc71514826979b9d053f3df0c2397a99e2b87213ba71605a1626d662c"}, +] +pathspec = [ + {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, + {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, +] +pre-commit = [ + {file = "pre_commit-2.7.1-py2.py3-none-any.whl", hash = "sha256:810aef2a2ba4f31eed1941fc270e72696a1ad5590b9751839c90807d0fff6b9a"}, + {file = "pre_commit-2.7.1.tar.gz", hash = "sha256:c54fd3e574565fe128ecc5e7d2f91279772ddb03f8729645fa812fe809084a70"}, +] +pycodestyle = [ + {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, + {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, +] +pyflakes = [ + {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, + {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, +] +pyyaml = [ + {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, + {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, + {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, + {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, +] +regex = [ + {file = "regex-2020.7.14-cp27-cp27m-win32.whl", hash = "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7"}, + {file = "regex-2020.7.14-cp27-cp27m-win_amd64.whl", hash = "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88"}, + {file = "regex-2020.7.14-cp36-cp36m-win32.whl", hash = "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4"}, + {file = "regex-2020.7.14-cp36-cp36m-win_amd64.whl", hash = "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89"}, + {file = "regex-2020.7.14-cp37-cp37m-win32.whl", hash = "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6"}, + {file = "regex-2020.7.14-cp37-cp37m-win_amd64.whl", hash = "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a"}, + {file = "regex-2020.7.14-cp38-cp38-win32.whl", hash = "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341"}, + {file = "regex-2020.7.14-cp38-cp38-win_amd64.whl", hash = "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840"}, + {file = "regex-2020.7.14.tar.gz", hash = "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb"}, +] +requests = [ + {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, + {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, +] +six = [ + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, +] +toml = [ + {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, + {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, +] +typed-ast = [ + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, + {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, + {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, + {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, + {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, + {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, + {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, +] +urllib3 = [ + {file = "urllib3-1.25.10-py2.py3-none-any.whl", hash = "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"}, + {file = "urllib3-1.25.10.tar.gz", hash = "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"}, +] +virtualenv = [ + {file = "virtualenv-20.0.31-py2.py3-none-any.whl", hash = "sha256:e0305af10299a7fb0d69393d8f04cb2965dda9351140d11ac8db4e5e3970451b"}, + {file = "virtualenv-20.0.31.tar.gz", hash = "sha256:43add625c53c596d38f971a465553f6318decc39d98512bc100fa1b1e839c8dc"}, +] +zipp = [ + {file = "zipp-3.1.0-py3-none-any.whl", hash = "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b"}, + {file = "zipp-3.1.0.tar.gz", hash = "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b8ad282 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[tool.poetry] +name = "cy-weather-api" +version = "0.1.3" +description = "Caiyun Weather API Python SDK" +authors = ["Caiyunapp "] +readme = "README.md" +repository = "https://github.com/caiyunapp/caiyun-weather-api-python-sdk" + +[tool.poetry.dependencies] +python = "^3.6.1" +requests = "^2.23.0" +orjson = "^3.0.0" +dacite = "^1.5.0" + +[tool.poetry.dev-dependencies] +pre-commit = "^2.3.0" +black = "^19.10b0" +flake8 = "isort" + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api"