Coder Social home page Coder Social logo

pylotoncycle's Introduction

PylotonCycle

Python Library for getting your Peloton workout data.

Table of contents

General info

As someone who wants to see my progress over time, I've been wanting a way to pull and play with my ride data. However, I'm also cautious about linking myself to too many external parties. As I've been playing with other libraries out there, I wanted something that was a bit more intuitive and would play nicer with the rest of my python code. So, PylotonCycle is born.

Example Usage

import pylotoncycle

username = 'your username or email address'
password = 'your password'
conn = pylotoncycle.PylotonCycle(username, password)
workouts = conn.GetRecentWorkouts(5)

workouts is a list of workouts.

An example of a list element

{'achievement_templates': [{'description': 'Awarded for working out with a '
                                           'friend.',
                            'id': '<some id hash>',
                            'image_url': 'https://s3.amazonaws.com/peloton-achievement-images-prod/702495cd985d4791bfd3d25f36e0df72',
                            'name': 'Dynamic Duo',
                            'slug': 'two_to_tango'},
                           {'description': 'Awarded for achieving Silver in '
                                           'the May Cycling Challenge.',
                            'id': '<some id hash>',
                            'image_url': 'https://s3.amazonaws.com/challenges-and-tiers-image-prod/6b772477ccd04f189fba16f2f877faad',
                            'name': 'May Cycling Challenge',
                            'slug': 'may_cycling_challenge_silver'}],
 'created': 1589642476,
 'created_at': 1589642476,
 'device_time_created_at': 1589617276,
 'device_type': 'home_bike_v1',
 'device_type_display_name': 'Bike',
 'end_time': 1589644336,
 'fitbit_id': None,
 'fitness_discipline': 'cycling',
 'ftp_info': {'ftp': 111,
              'ftp_source': 'ftp_workout_source',
              'ftp_workout_id': '<some id hash>'},
 'has_leaderboard_metrics': True,
 'has_pedaling_metrics': True,
 'id': '<some id hash>',
 'instructor_name': 'Matt Wilpers',
 'is_total_work_personal_record': False,
 'leaderboard_rank': 5015,
 'metrics_type': 'cycling',
 'name': 'Cycling Workout',
 'overall_summary': {'avg_cadence': 85.48,
                     'avg_heart_rate': 0.0,
                     'avg_power': 179.24,
                     'avg_resistance': 47.61,
                     'avg_speed': 20.39,
                     'cadence': 0.0,
                     'calories': 496.71,
                     'distance': 10.19,
                     'heart_rate': 0.0,
                     'id': '<some id hash>',
                     'instant': 1589644336,
                     'max_cadence': 122.0,
                     'max_heart_rate': 0.0,
                     'max_power': 255.8,
                     'max_resistance': 60.95,
                     'max_speed': 23.48,
                     'power': 0.0,
                     'resistance': 0.0,
                     'seconds_since_pedaling_start': 0,
                     'speed': 0.0,
                     'total_work': 322417.21,
                     'workout_id': '<some id hash>'},
 'peloton_id': '<some id hash>',
 'platform': 'home_bike',
 'ride': {'captions': ['en-US'],
          'class_type_ids': ['<some id hash>'],
          'content_format': 'video',
          'content_provider': 'peloton',
          'description': 'Max out the effectiveness of your training with this '
                         'ride. Instructors will expertly guide you through '
                         'specific output ranges 1 through 7 to help you build '
                         'endurance, strength and speed.',
          'difficulty_estimate': 6.3779,
          'difficulty_level': None,
          'difficulty_rating_avg': 6.3779,
          'difficulty_rating_count': 17157,
          'duration': 1800,
          'equipment_ids': [],
          'equipment_tags': [],
          'excluded_platforms': [],
          'extra_images': [],
          'fitness_discipline': 'cycling',
          'fitness_discipline_display_name': 'Cycling',
          'has_closed_captions': True,
          'has_free_mode': False,
          'has_pedaling_metrics': True,
          'home_peloton_id': '<some id hash>',
          'id': '<some id hash>',
          'image_url': 'https://s3.amazonaws.com/peloton-ride-images/58aa8ebc7d51d09d6513e1a2fab53c4c62c076c6/img_1580922399_a5f1fd0e3a2e48d38ecdd6a3d874820f.png',
          'instructor_id': '<some id hash>',
          'is_archived': True,
          'is_closed_caption_shown': True,
          'is_explicit': False,
          'is_live_in_studio_only': False,
          'language': 'english',
          'length': 1940,
          'live_stream_id': '<some id hash>-live',
          'live_stream_url': None,
          'location': 'nyc',
          'metrics': ['heart_rate', 'cadence', 'calories'],
          'origin_locale': 'en-US',
          'original_air_time': 1580919480,
          'overall_estimate': 0.9956,
          'overall_rating_avg': 0.9956,
          'overall_rating_count': 20737,
          'pedaling_duration': 1800,
          'pedaling_end_offset': 1860,
          'pedaling_start_offset': 60,
          'rating': 0,
          'ride_type_id': '<some id hash>',
          'ride_type_ids': ['<some id hash>'],
          'sample_vod_stream_url': None,
          'scheduled_start_time': 1580920200,
          'series_id': '<some id hash>',
          'sold_out': False,
          'studio_peloton_id': '<some id hash>',
          'title': '30 min Power Zone Endurance Ride',
          'total_in_progress_workouts': 0,
          'total_ratings': 0,
          'total_workouts': 32489,
          'vod_stream_id': '<some id hash>-vod',
          'vod_stream_url': None},
 'start_time': 1589642537,
 'status': 'COMPLETE',
 'strava_id': None,
 'timezone': 'America/Los_Angeles',
 'title': None,
 'total_leaderboard_users': 31240,
 'total_work': 322417.21,
 'user_id': '<some id hash>',
 'workout_type': 'class'}

An example of how you may fetch performance data for a ride

import pprint

conn = pylotoncycle.PylotonCycle(username, password)
workouts = conn.GetRecentWorkouts(5)
for w in workouts:
    workout_id = w['id']
    resp = conn.GetWorkoutMetricsById(workout_id)
    pprint.pprint(resp)

Install

This package is available via pip install.

pip install pylotoncycle

TODO

  • Lots more to cover. I want to find the right format for pulling in the ride performance data.
  • Pull in GPS data for outdoor runs

Note to folks who want to contribute

I'm very happy to take pull requests and fix bugs that come up. But, this is definitely a side project for me.

pylotoncycle's People

Contributors

ayn avatar carpii avatar craigk5n avatar fabaff avatar grandpoohbear avatar jramirez857 avatar justmedude avatar robertd502 avatar superm1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pylotoncycle's Issues

Interested in collaborating and contributing

Hello,

I have recently been working on a dashboard for my peloton workouts using csv format output from my peloton account. However, I am interested in extending it to be able to use the api using pylotoncycle. Would you be interested in collaborating on this project?

Either way, I look forward to hearing your thoughts!

total_heart_rate_zone_durations data isn't correct

I'm trying to figure out where this data is coming from or how it's getting generated.
Comparing the effort_zones data I pulled out of inspector vs what shows up in the JSON are very different.

For my recent 15 minute ride here's the data I get.

From Peloton performance_graph.json. The numbers here correlate to seconds.

{
	"effort_zones": {
		"total_effort_points": 29.4,
		"heart_rate_zone_durations": {
			"heart_rate_z1_duration": 0,
			"heart_rate_z2_duration": 94,
			"heart_rate_z3_duration": 187,
			"heart_rate_z4_duration": 617,
			"heart_rate_z5_duration": 0
		}
	}
}

From pylotoncycle I get the following. I can't tell what the numbers correlate to, and taken to percentages it's still not comparable to the peloton data.

"total_heart_rate_zone_durations": {
            "heart_rate_z1_duration": 299,
            "heart_rate_z2_duration": 505,
            "heart_rate_z3_duration": 1766,
            "heart_rate_z4_duration": 1112,
            "heart_rate_z5_duration": 0
        },

I checked my rides and it's not a one off it's consistently very different data.

Is this intentional? If so, what units are being used for the heart rate zones? Is there a way to convert or just get the raw data?

Thanks!

resp['user_data'] does not seem to exist anymore

When running a short debug script:

import pylotoncycle

username = 'x'
password = 'x'

conn = pylotoncycle.PylotonCycle(username, password)
workouts = conn.GetRecentWorkouts(5)
workout = workouts[0]

I get the following:

 % python3 ./pelo_debug.py 
Traceback (most recent call last):
  File "./pelo_debug.py", line 12, in <module>
    conn = pylotoncycle.PylotonCycle(username, password)
  File "/usr/local/lib/python3.9/site-packages/pylotoncycle/pylotoncycle.py", line 31, in __init__
    self.login(username, password)
  File "/usr/local/lib/python3.9/site-packages/pylotoncycle/pylotoncycle.py", line 52, in login
    self.total_workouts = resp['user_data']['total_workouts']
KeyError: 'user_data'

Commenting out line 52 in pylotoncycle.py resolves the issue. I'm not sure what else that impacts though. It appears that the [user_data] branch is no longer in the /auth/login/ response. It do see that the total_workouts still shows when using GetMe:

me = conn.GetMe()
print(me)

I've never submitted a github issue before, and my python is incredibly basic, so I'll leave it to you to resolve correctly!

Downloading more than 100 workouts results in duplicate entries

I have 105 workouts in my Peloton account and am pulling them all down to drive a local dashboard and merge some metrics with my Garmin Forerunner data. I printed the workout dates out as details were retrieved and got the following output:

2021-01-21 16:27:56
2021-01-16 12:39:43
2021-01-16 11:35:18
2021-01-14 09:40:26
2021-01-09 09:23:08
2021-01-05 07:47:43
2021-01-04 16:32:10
2021-01-03 10:52:17
2020-12-31 08:47:55
2020-12-31 08:24:22
...
2020-06-16 09:17:03
2020-06-14 10:16:44
2020-06-13 12:31:26
2021-01-05 07:47:43
2021-01-04 16:32:10
2021-01-03 10:52:17
2020-12-31 08:47:55
2020-12-31 08:24:22

In the database, I use the date as the primary key and end up with only 100 workouts. I noticed the dates in bold had been downloaded twice and as a result of using "REPLACE INTO" in mysql, no error was produced.

In GetWorkoutList, it appears that the limit value in the URL also determines the page size. I replaced range(0, pages) with range(0, pages+1) and removed the section handling the calculate remainder value. All workouts downloaded successfully.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.