diff --git a/README.md b/README.md index a0c9774..5dc3f35 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # zpdatafetch -A python library for fetching data from zwiftpower +A python library and command-line tool for fetching data from zwiftpower. ## Installation @@ -12,13 +12,15 @@ pip install zpdatafetch zpdatafetch comes with a command-line tool named zpdata. This can be used to fetch data directly from zwiftpower. It sends the json response to stdout. It also acts as a guide for how to use the library in your own program. -For both command-line and library usage, you will need to have a zwiftpower account. You will need set up your credentials in the keyring. This can be done using the following commands: +For both command-line and library usage, you will need to have a zwiftpower account. You will need set up your credentials in your system keyring. This can be done using the following commands from they python keyring library (installed as part of zpdatafetch if not already available on your system): ```sh keyring set zpdatafetch username keyring set zpdatafetch password ``` +In principle, the library can use alternate backend keyrings, but this is not tested so far. At the moment, only the system keyring is used. See [the keyring docs](https://keyring.readthedocs.io/en/latest/) for more details on how to use the keyring and keyring library for your system. + ### Command-line example ```sh @@ -44,7 +46,7 @@ from zpdatafetch import Cyclist c = Cyclist() c.verbose = True c.fetch(12345) # fetch data for cyclist with zwift id 12345 -print(c.raw) +print(c.json()) ``` The interface for each of the objects is effectively the same as the example above, with the individual class and id number changed as appropriate. The available classes are as follows: @@ -57,6 +59,20 @@ The interface for each of the objects is effectively the same as the example abo The classes ZP class is the main driver for the library. It is used to fetch the data from zwiftpower. The other classes are used to parse the data into a more useful format. +### Object signature + +Each object has a common set of methods available: + +- fetch: fetch the data from zwiftpower. As argument, fetch expects a single ID or a list (tuple or array) of IDs. +- json: return the data as a json object +- asdict: return the data as a dictionary + +In addition, the object can be set to work in verbose mode, which it will pass to the ZP object which drives the interaction with the website, buy simply setting: + +```python +obj.verbose = True +``` + ## development 1. Install this package @@ -79,31 +95,33 @@ keyring set zpdatafetch password PYTHONPATH=`pwd`/src python src/zpdatafetch/zp.py ``` -## Cyclist example +Each object has a callable interface that can be used for simple direct access to experiment without additional code wrapped around it - yours or the provided command-line tool. They each respond to the -h flag to provide help. Basic examples follow. + +### Cyclist example ```shell PYTHONPATH=`pwd`/src python src/zpdatafetch/cyclist.py -v -r ``` -## Team example +### Team example ```shell PYTHONPATH=`pwd`/src python src/zpdatafetch/team.py -v -r ``` -## Signup example +### Signup example ```shell PYTHONPATH=`pwd`/src python src/zpdatafetch/signup.py -v -r ``` -## Result example +### Result example ```shell PYTHONPATH=`pwd`/src python src/zpdatafetch/result.py -v -r ``` -## Primes example +### Primes example ```shell PYTHONPATH=`pwd`/src python src/zpdatafetch/primes.py -v -r diff --git a/setup.cfg b/setup.cfg index 4561fda..9e81ab4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = zpdatafetch -version = 1.0.1 +version = 1.1.0 url = https://github.com/puckdoug/zpdatafetch author = Doug Morris author_email = "Doug Morris" diff --git a/src/zpdatafetch/cli.py b/src/zpdatafetch/cli.py index a282e49..c7686a2 100755 --- a/src/zpdatafetch/cli.py +++ b/src/zpdatafetch/cli.py @@ -1,5 +1,4 @@ import sys -import json from argparse import ArgumentParser from zpdatafetch import Config, Cyclist, Primes, Result, Signup, Team @@ -49,8 +48,7 @@ def main(): if args.verbose: x.verbose = True x.fetch(*args.id) - encoder = json.JSONEncoder(indent=2) - print(encoder.encode(x.raw)) + print(x.json()) # =============================================================================== diff --git a/src/zpdatafetch/cyclist.py b/src/zpdatafetch/cyclist.py index 3f2b1d0..0f2ef45 100755 --- a/src/zpdatafetch/cyclist.py +++ b/src/zpdatafetch/cyclist.py @@ -1,15 +1,14 @@ # import js2py from argparse import ArgumentParser from zpdatafetch.zp import ZP +from zpdatafetch.zp_obj import ZP_obj # =============================================================================== -class Cyclist: +class Cyclist(ZP_obj): _url = 'https://zwiftpower.com/cache3/profile/' _profile = 'https://zwiftpower.com/profile.php?z=' _url_end = '_all.json' - verbose = False - raw = {} # ------------------------------------------------------------------------------- # def extract_zp_vars(self, y): diff --git a/src/zpdatafetch/primes.py b/src/zpdatafetch/primes.py index ca3a3e0..754e8c7 100644 --- a/src/zpdatafetch/primes.py +++ b/src/zpdatafetch/primes.py @@ -2,10 +2,11 @@ import datetime from argparse import ArgumentParser from zpdatafetch.zp import ZP +from zpdatafetch.zp_obj import ZP_obj # =============================================================================== -class Primes: +class Primes(ZP_obj): # https://zwiftpower.com/api3.php?do=event_primes&zid={race_id}&category={cat}&prime_type={type} _url_base = 'https://zwiftpower.com/api3.php?do=event_primes' _url_race_id = '&zid=' @@ -13,8 +14,6 @@ class Primes: _url_primetype = '&prime_type=' _cat = ['A', 'B', 'C', 'D', 'E'] _type = ['msec', 'elapsed'] - raw = None - verbose = False # ------------------------------------------------------------------------------- @classmethod diff --git a/src/zpdatafetch/result.py b/src/zpdatafetch/result.py index d854584..2069d16 100644 --- a/src/zpdatafetch/result.py +++ b/src/zpdatafetch/result.py @@ -1,9 +1,10 @@ from argparse import ArgumentParser from zpdatafetch.zp import ZP +from zpdatafetch.zp_obj import ZP_obj # =============================================================================== -class Result: +class Result(ZP_obj): # race = "https://zwiftpower.com/cache3/results/3590800_view.json" _url = 'https://zwiftpower.com/cache3/results/' _url_end = '_view.json' diff --git a/src/zpdatafetch/signup.py b/src/zpdatafetch/signup.py index 69589d6..59d8884 100644 --- a/src/zpdatafetch/signup.py +++ b/src/zpdatafetch/signup.py @@ -1,14 +1,13 @@ from argparse import ArgumentParser from zpdatafetch.zp import ZP +from zpdatafetch.zp_obj import ZP_obj # =============================================================================== -class Signup: +class Signup(ZP_obj): # race = "https://zwiftpower.com/cache3/results/3590800_signups.json" _url = 'https://zwiftpower.com/cache3/results/' _url_end = '_signups.json' - raw = None - verbose = False # ------------------------------------------------------------------------------- def fetch(self, *race_id_list): diff --git a/src/zpdatafetch/team.py b/src/zpdatafetch/team.py index 02b51f1..a07268a 100644 --- a/src/zpdatafetch/team.py +++ b/src/zpdatafetch/team.py @@ -1,9 +1,10 @@ from argparse import ArgumentParser from zpdatafetch.zp import ZP +from zpdatafetch.zp_obj import ZP_obj # =============================================================================== -class Team: +class Team(ZP_obj): # "https://zwiftpower.com/cache3/teams/{team_id}_riders.json" _url = 'https://zwiftpower.com/cache3/teams/' _url_end = '_riders.json' diff --git a/src/zpdatafetch/zp_obj.py b/src/zpdatafetch/zp_obj.py new file mode 100644 index 0000000..aa81d4e --- /dev/null +++ b/src/zpdatafetch/zp_obj.py @@ -0,0 +1,15 @@ +import json + + +class ZP_obj: + raw = {} + verbose = False + + def __str__(self): + return str(self.raw) + + def json(self): + return json.JSONEncoder(indent=2).encode(self.raw) + + def asdict(self): + return self.raw