stravalib


Namestravalib JSON
Version 1.6 PyPI version JSON
download
home_page
SummaryA Python package that makes it easy to access and download data from the Strava V3 REST API.
upload_time2024-01-27 20:52:04
maintainerLeah Wasser, Hans Lellelid, Jonatan Samoocha, Yihong, Émile Nadeau
docs_urlhttps://pythonhosted.org/stravalib/
author
requires_python>=3.9
licenseApache 2.0 License
keywords strava running cycling athletes
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            # Welcome to stravalib

[![DOI](https://zenodo.org/badge/8828908.svg)](https://zenodo.org/badge/latestdoi/8828908)
![PyPI](https://img.shields.io/pypi/v/stravalib?style=plastic) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/stravalib?style=plastic) [![Documentation Status](https://readthedocs.org/projects/stravalib/badge/?version=latest)](https://stravalib.readthedocs.io/en/latest/?badge=latest) ![Package Tests Status](https://github.com/stravalib/stravalib/actions/workflows/build-test.yml/badge.svg) ![PyPI - Downloads](https://img.shields.io/pypi/dm/stravalib?style=plastic) [![codecov](https://codecov.io/gh/stravalib/stravalib/branch/main/graph/badge.svg?token=sHbFJn7epy)](https://codecov.io/gh/stravalib/stravalib)

The **stravalib** Python package provides easy-to-use tools for accessing and
downloading Strava data from the Strava V3 web service. Stravalib provides a Client class that supports:

- Authenticating with stravalib
- Accessing and downloading Strava activity, club and profile data
- Making changes to account activities

It also provides support for working with date/time/temporal attributes
and quantities through the [Python Pint library](https://pypi.org/project/Pint/).

## Dependencies

- Python 3.9+
- Setuptools for installing dependencies
- Other Python libraries (installed automatically when using pip): requests, pytz, pint, arrow, pydantic

## Installation

The package is available on PyPI to be installed using `pip`:

`pip install stravalib`

## How to Contribute to Stravalib

### Get Started!

Ready to contribute? Here's how to set up Stravalib for local development.

1. Fork the repository on GitHub

---

To create your own copy of the repository on GitHub, navigate to the
`stravalib/stravalib <https://github.com/stravalib/stravalib>`\_ repository
and click the **Fork** button in the top-right corner of the page.

2. Clone your fork locally

---

Use `git clone` to get a local copy of your stravalib repository on your
local filesystem::

    $ git clone git@github.com:your_name_here/stravalib.git
    $ cd stravalib/

3. Set up your fork for local development

---

The docs for this library are created using `sphinx`.
To build the html version of the documentation, use the
command:

`$ make -C docs html`

### Building from sources

To build the project locally in editable mode,
access the project root directory and run:

```bash
$ pip install -e .
```

To execute **unit - or integration tests** you will need to run

```bash
$ make test
```

## Local Tests

To run **end-to-end** tests you will need to rename _test.ini-example_ (which you can find _<your-root-proj-dir>_/stravalib/tests/) to _test.ini_
In _test.ini_ provide your _access_token_ and _activity_id_. Now you can run

```
shell$ pytest stravalib/tests/functional
```

### Pull Requests and tests

Please add tests that cover your changes, these will greatly reduce the effort of reviewing
and merging your Pull Requests. In case you need it, there's a pytest fixture
`mock_strava_api` that is based on `RequestsMock` from the `responses` package. It prevents
requests being made to the actual Strava API and instead registers responses that are
based on examples from the published Strava API documentation. Example usages of this
fixture can be found in the `stravalib.tests.integration` package.

## Basic Usage

Please take a look at the source (in particular the stravalib.client.Client class, if you'd like to play around with the
API. Most of the Strava API is implemented at this point; however, certain features such as streams are still on the
to-do list.

### Authentication

In order to make use of this library, you will need to create an app in Strava
which is free to do. [Have a look at this tutorial for instructions on creating
an app with Strava - we will be updating our docs with this information soon.](https://medium.com/analytics-vidhya/accessing-user-data-via-the-strava-api-using-stravalib-d5bee7fdde17)

**NOTE** We will be updating our documentation with clear instructions to support this
in the upcoming months

Once you have created your app, stravalib have several helper methods to make
authentication easier.

```python
from stravalib.client import Client

client = Client()
authorize_url = client.authorization_url(
    client_id=1234, redirect_uri="http://localhost:8282/authorized"
)
# Have the user click the authorization URL, a 'code' param will be added to the redirect_uri
# .....

# Extract the code from your webapp response
code = requests.get("code")  # or whatever your framework does
token_response = client.exchange_code_for_token(
    client_id=1234, client_secret="asdf1234", code=code
)
access_token = token_response["access_token"]
refresh_token = token_response["refresh_token"]
expires_at = token_response["expires_at"]

# Now store that short-lived access token somewhere (a database?)
client.access_token = access_token
# You must also store the refresh token to be used later on to obtain another valid access token
# in case the current is already expired
client.refresh_token = refresh_token

# An access_token is only valid for 6 hours, store expires_at somewhere and
# check it before making an API call.
client.token_expires_at = expires_at

athlete = client.get_athlete()
print(
    "For {id}, I now have an access token {token}".format(
        id=athlete.id, token=access_token
    )
)

# ... time passes ...
if time.time() > client.token_expires_at:
    refresh_response = client.refresh_access_token(
        client_id=1234, client_secret="asdf1234", refresh_token=client.refresh_token
    )
    access_token = refresh_response["access_token"]
    refresh_token = refresh_response["refresh_token"]
    expires_at = refresh_response["expires_at"]
```

### Athletes and Activities

(This is a glimpse into what you can do.)

```python
# Currently-authenticated (based on provided token) athlete
# Will have maximum detail exposed (resource_state=3)
curr_athlete = client.get_athlete()

# Fetch another athlete
other_athlete = client.get_athlete(123)
# Will only have summary-level attributes exposed (resource_state=2)

# Get an activity
activity = client.get_activity(123)
# If activity is owned by current user, will have full detail (resource_state=3)
# otherwise summary-level detail.
```

### Streams

Streams represent the raw data of the uploaded file. Activities, efforts, and
segments all have streams. There are many types of streams, if activity does
not have requested stream type, returned set simply won't include it.

```python
# Activities can have many streams, you can request n desired stream types
types = [
    "time",
    "latlng",
    "altitude",
    "heartrate",
    "temp",
]

streams = client.get_activity_streams(123, types=types, resolution="medium")

#  Result is a dictionary object.  The dict's key are the stream type.
if "altitude" in streams.keys():
    print(streams["altitude"].data)
```

### Working with Units

stravalib uses the [python Pint library](https://pypi.org/project/Pint/) to facilitate working
with the values in the API that have associated units (e.g. distance, speed). You can use the pint library
directly or through the `stravalib.unithelper` module for shortcuts

```python
activity = client.get_activity(96089609)
assert isinstance(activity.distance, unithelper.Quantity)
print(activity.distance)
# 22530.80 m

# Meters!?

from stravalib import unithelper

print(unithelper.miles(activity.distance))
# 14.00 mi

# And to get the number:
num_value = float(unithelper.miles(activity.distance))
# Or:
num_value = unithelper.miles(activity.distance).num
```

## Still reading?

The [published sphinx documentation](https://stravalib.readthedocs.io/) provides much more.

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "stravalib",
    "maintainer": "Leah Wasser, Hans Lellelid, Jonatan Samoocha, Yihong, \u00c9mile Nadeau",
    "docs_url": "https://pythonhosted.org/stravalib/",
    "requires_python": ">=3.9",
    "maintainer_email": "",
    "keywords": "strava,running,cycling,athletes",
    "author": "",
    "author_email": "Hans Lellelid <hans@xmpl.org>",
    "download_url": "https://files.pythonhosted.org/packages/32/c2/17d3f7afb8e57ff28209ad572bf3a12bc211453b20548a6c9480fc33272d/stravalib-1.6.tar.gz",
    "platform": null,
    "description": "# Welcome to stravalib\n\n[![DOI](https://zenodo.org/badge/8828908.svg)](https://zenodo.org/badge/latestdoi/8828908)\n![PyPI](https://img.shields.io/pypi/v/stravalib?style=plastic) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/stravalib?style=plastic) [![Documentation Status](https://readthedocs.org/projects/stravalib/badge/?version=latest)](https://stravalib.readthedocs.io/en/latest/?badge=latest) ![Package Tests Status](https://github.com/stravalib/stravalib/actions/workflows/build-test.yml/badge.svg) ![PyPI - Downloads](https://img.shields.io/pypi/dm/stravalib?style=plastic) [![codecov](https://codecov.io/gh/stravalib/stravalib/branch/main/graph/badge.svg?token=sHbFJn7epy)](https://codecov.io/gh/stravalib/stravalib)\n\nThe **stravalib** Python package provides easy-to-use tools for accessing and\ndownloading Strava data from the Strava V3 web service. Stravalib provides a Client class that supports:\n\n- Authenticating with stravalib\n- Accessing and downloading Strava activity, club and profile data\n- Making changes to account activities\n\nIt also provides support for working with date/time/temporal attributes\nand quantities through the [Python Pint library](https://pypi.org/project/Pint/).\n\n## Dependencies\n\n- Python 3.9+\n- Setuptools for installing dependencies\n- Other Python libraries (installed automatically when using pip): requests, pytz, pint, arrow, pydantic\n\n## Installation\n\nThe package is available on PyPI to be installed using `pip`:\n\n`pip install stravalib`\n\n## How to Contribute to Stravalib\n\n### Get Started!\n\nReady to contribute? Here's how to set up Stravalib for local development.\n\n1. Fork the repository on GitHub\n\n---\n\nTo create your own copy of the repository on GitHub, navigate to the\n`stravalib/stravalib <https://github.com/stravalib/stravalib>`\\_ repository\nand click the **Fork** button in the top-right corner of the page.\n\n2. Clone your fork locally\n\n---\n\nUse `git clone` to get a local copy of your stravalib repository on your\nlocal filesystem::\n\n    $ git clone git@github.com:your_name_here/stravalib.git\n    $ cd stravalib/\n\n3. Set up your fork for local development\n\n---\n\nThe docs for this library are created using `sphinx`.\nTo build the html version of the documentation, use the\ncommand:\n\n`$ make -C docs html`\n\n### Building from sources\n\nTo build the project locally in editable mode,\naccess the project root directory and run:\n\n```bash\n$ pip install -e .\n```\n\nTo execute **unit - or integration tests** you will need to run\n\n```bash\n$ make test\n```\n\n## Local Tests\n\nTo run **end-to-end** tests you will need to rename _test.ini-example_ (which you can find _<your-root-proj-dir>_/stravalib/tests/) to _test.ini_\nIn _test.ini_ provide your _access_token_ and _activity_id_. Now you can run\n\n```\nshell$ pytest stravalib/tests/functional\n```\n\n### Pull Requests and tests\n\nPlease add tests that cover your changes, these will greatly reduce the effort of reviewing\nand merging your Pull Requests. In case you need it, there's a pytest fixture\n`mock_strava_api` that is based on `RequestsMock` from the `responses` package. It prevents\nrequests being made to the actual Strava API and instead registers responses that are\nbased on examples from the published Strava API documentation. Example usages of this\nfixture can be found in the `stravalib.tests.integration` package.\n\n## Basic Usage\n\nPlease take a look at the source (in particular the stravalib.client.Client class, if you'd like to play around with the\nAPI. Most of the Strava API is implemented at this point; however, certain features such as streams are still on the\nto-do list.\n\n### Authentication\n\nIn order to make use of this library, you will need to create an app in Strava\nwhich is free to do. [Have a look at this tutorial for instructions on creating\nan app with Strava - we will be updating our docs with this information soon.](https://medium.com/analytics-vidhya/accessing-user-data-via-the-strava-api-using-stravalib-d5bee7fdde17)\n\n**NOTE** We will be updating our documentation with clear instructions to support this\nin the upcoming months\n\nOnce you have created your app, stravalib have several helper methods to make\nauthentication easier.\n\n```python\nfrom stravalib.client import Client\n\nclient = Client()\nauthorize_url = client.authorization_url(\n    client_id=1234, redirect_uri=\"http://localhost:8282/authorized\"\n)\n# Have the user click the authorization URL, a 'code' param will be added to the redirect_uri\n# .....\n\n# Extract the code from your webapp response\ncode = requests.get(\"code\")  # or whatever your framework does\ntoken_response = client.exchange_code_for_token(\n    client_id=1234, client_secret=\"asdf1234\", code=code\n)\naccess_token = token_response[\"access_token\"]\nrefresh_token = token_response[\"refresh_token\"]\nexpires_at = token_response[\"expires_at\"]\n\n# Now store that short-lived access token somewhere (a database?)\nclient.access_token = access_token\n# You must also store the refresh token to be used later on to obtain another valid access token\n# in case the current is already expired\nclient.refresh_token = refresh_token\n\n# An access_token is only valid for 6 hours, store expires_at somewhere and\n# check it before making an API call.\nclient.token_expires_at = expires_at\n\nathlete = client.get_athlete()\nprint(\n    \"For {id}, I now have an access token {token}\".format(\n        id=athlete.id, token=access_token\n    )\n)\n\n# ... time passes ...\nif time.time() > client.token_expires_at:\n    refresh_response = client.refresh_access_token(\n        client_id=1234, client_secret=\"asdf1234\", refresh_token=client.refresh_token\n    )\n    access_token = refresh_response[\"access_token\"]\n    refresh_token = refresh_response[\"refresh_token\"]\n    expires_at = refresh_response[\"expires_at\"]\n```\n\n### Athletes and Activities\n\n(This is a glimpse into what you can do.)\n\n```python\n# Currently-authenticated (based on provided token) athlete\n# Will have maximum detail exposed (resource_state=3)\ncurr_athlete = client.get_athlete()\n\n# Fetch another athlete\nother_athlete = client.get_athlete(123)\n# Will only have summary-level attributes exposed (resource_state=2)\n\n# Get an activity\nactivity = client.get_activity(123)\n# If activity is owned by current user, will have full detail (resource_state=3)\n# otherwise summary-level detail.\n```\n\n### Streams\n\nStreams represent the raw data of the uploaded file. Activities, efforts, and\nsegments all have streams. There are many types of streams, if activity does\nnot have requested stream type, returned set simply won't include it.\n\n```python\n# Activities can have many streams, you can request n desired stream types\ntypes = [\n    \"time\",\n    \"latlng\",\n    \"altitude\",\n    \"heartrate\",\n    \"temp\",\n]\n\nstreams = client.get_activity_streams(123, types=types, resolution=\"medium\")\n\n#  Result is a dictionary object.  The dict's key are the stream type.\nif \"altitude\" in streams.keys():\n    print(streams[\"altitude\"].data)\n```\n\n### Working with Units\n\nstravalib uses the [python Pint library](https://pypi.org/project/Pint/) to facilitate working\nwith the values in the API that have associated units (e.g. distance, speed). You can use the pint library\ndirectly or through the `stravalib.unithelper` module for shortcuts\n\n```python\nactivity = client.get_activity(96089609)\nassert isinstance(activity.distance, unithelper.Quantity)\nprint(activity.distance)\n# 22530.80 m\n\n# Meters!?\n\nfrom stravalib import unithelper\n\nprint(unithelper.miles(activity.distance))\n# 14.00 mi\n\n# And to get the number:\nnum_value = float(unithelper.miles(activity.distance))\n# Or:\nnum_value = unithelper.miles(activity.distance).num\n```\n\n## Still reading?\n\nThe [published sphinx documentation](https://stravalib.readthedocs.io/) provides much more.\n",
    "bugtrack_url": null,
    "license": "Apache 2.0 License",
    "summary": "A Python package that makes it easy to access and download data from the Strava V3 REST API.",
    "version": "1.6",
    "project_urls": {
        "changelog": "https://github.com/stravalib/stravalib/blob/main/changelog.md",
        "documentation": "https://stravalib.readthedocs.io",
        "repository": "https://github.com/stravalib/stravalib"
    },
    "split_keywords": [
        "strava",
        "running",
        "cycling",
        "athletes"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2d718a1647c31ab5c011622f22ecb79c26d6e1e95d13519ae5e9b485dfbfc651",
                "md5": "f34c7dcadae28033010cb2d76aa74df0",
                "sha256": "ae866a9702778c90cfe8eb9af0e0c5ae42e7cf6c040e964aef02724317cfb049"
            },
            "downloads": -1,
            "filename": "stravalib-1.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f34c7dcadae28033010cb2d76aa74df0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 123416,
            "upload_time": "2024-01-27T20:52:02",
            "upload_time_iso_8601": "2024-01-27T20:52:02.950603Z",
            "url": "https://files.pythonhosted.org/packages/2d/71/8a1647c31ab5c011622f22ecb79c26d6e1e95d13519ae5e9b485dfbfc651/stravalib-1.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "32c217d3f7afb8e57ff28209ad572bf3a12bc211453b20548a6c9480fc33272d",
                "md5": "6820478285c70b80be3bd8fdfa8ba263",
                "sha256": "1f1c02de3543ffb14566e82371d67a6b823ba2e96aa93fd6dedfc15fa0e1821d"
            },
            "downloads": -1,
            "filename": "stravalib-1.6.tar.gz",
            "has_sig": false,
            "md5_digest": "6820478285c70b80be3bd8fdfa8ba263",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 232642,
            "upload_time": "2024-01-27T20:52:04",
            "upload_time_iso_8601": "2024-01-27T20:52:04.870185Z",
            "url": "https://files.pythonhosted.org/packages/32/c2/17d3f7afb8e57ff28209ad572bf3a12bc211453b20548a6c9480fc33272d/stravalib-1.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-27 20:52:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "stravalib",
    "github_project": "stravalib",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [],
    "lcname": "stravalib"
}
        
Elapsed time: 0.19518s