Skip to content

About

Upload activity to Strava using cookies, no subscription required

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

6 Commits

Folders and files

Repository files navigation

StravaUploaderPy

Upload an activity (.gpx or .fit) to Strava and update values

Python requirements

pip install -r requirements.txt

Or directly:

pip install requests requests-toolbelt

On Debian/Ubuntu where system Python is externally managed (PEP 668), use a virtual environment instead:

python3 -m venv .venv
.venv/bin/pip install requests requests-toolbelt
.venv/bin/python ./StravaUploader.py test.gpx

Usage

Upload an activity using a saved session:

./StravaUploader.py activity.gpx

The uploader sends the file as-is to Strava, which accepts common formats such as .gpx and .fit; the examples below use .gpx.

Options

Option Description
gpx (positional) Path to the activity file (.gpx/.fit) to upload.
--session PATH Path to the saved session-cookies JSON (default: session.json).
--name TEXT Rename the uploaded activity.
--type TYPE Set the activity type (e.g. GravelRide, VirtualRide, Run). Run --help for the full list.
--photos P1 [P2 ...] One or more image files to attach to the activity.
--tags TEXT Comma/space separated tags.
--private {everyone,followers,only_me} Activity visibility.
--mute Mute the activity from home and club feeds.

StravaUploader login

StravaUploader.py uploads to Strava using a saved session cookie. Login is only supported via a session file; automated Google email/password login is not available.

Sessions expire after some time. If uploads start failing with "No valid session found", re-export a fresh _strava4_session into session.json (see below).

Export a logged-in session once and reuse it:

  1. Log in to https://www.strava.com in a browser (via Google or otherwise).
  2. Open DevTools (F12) -> Console and run document.cookie.
  3. Copy the value of _strava4_session=... into session.json next to the script:
{
  "cookies": [
    {
      "name": "_strava4_session",
      "value": "PASTE_VALUE_HERE",
      "domain": ".strava.com",
      "path": "/"
    }
  ]
}
  1. Run ./StravaUploader.py out.gpx (no credentials needed while the session is valid).

Setting the activity name

StravaUploader.py names the activity after the uploaded file by default. To override it, pass --name; after the file finishes processing the activity is renamed on Strava:

./StravaUploader.py out.gpx --name "Morning Ride"

Setting the activity type

Pass --type to change the activity type after upload (e.g. GravelRide, VirtualRide, Run). Run ./StravaUploader.py --help to list all valid types:

./StravaUploader.py out.gpx --type GravelRide --name "Gravel Ride"

Attaching photos

Pass one or more image files with --photos to attach them to the uploaded activity. Images are uploaded through Strava's photo endpoint and then attached by submitting the activity edit form:

./StravaUploader.py out.gpx --photos screenshot1.jpg screenshot2.jpg

The name, type and photos are all applied in a single edit-form submission, so when --name/--type are combined with --photos they are saved together in one transaction.

Photo attachment is best-effort: if an individual image fails to upload or the final save fails, the already-uploaded activity is left untouched and the script just prints what went wrong.

Setting tags, privacy and mute

These are also applied via the activity edit form (the same /activities/<id>/edit submission used for name/type/photos), so they can be combined with any of the other options in one transaction.

  • --tags — comma or space separated tags, e.g. --tags "ride, commute" or --tags ride commute.
  • --private — activity visibility: everyone, followers, or only_me.
  • --mute — mute the activity from home and club feeds.
./StravaUploader.py out.gpx --tags "ride, commute" --private followers --mute

These map to Strava's edit-form fields: tags → activity[tag_list], privacy → activity[visibility] (everyone / followers_only / only_me), and mute → activity[hide_from_home]. If the mute checkbox is not present in the form (e.g. Strava changes its UI), the script prints a warning and skips that part of the update rather than failing.

Downloading activity photos

StravaPhotoDownloader.py downloads the photos attached to an existing activity. It uses the same saved session as the uploader, loads the activity page, reads the embedded photosJson data and downloads each photo's enhanced image when present, otherwise its large version:

./StravaPhotoDownloader.py 20629200268

Photos are saved into photos/ by default, skipping files that already exist. Videos are skipped unless --videos is passed, in which case the video file is downloaded instead of its poster image.

./StravaPhotoDownloader.py 20629200268 --videos

Options

Option Description
activity_id The activity id (or full activity URL) to download photos from.
--session PATH Path to the saved session-cookies JSON (default: session.json).
--outdir PATH Directory to download photos into (default: photos).
--videos Also download videos attached to the activity (skipped by default).

About

Upload activity to Strava using cookies, no subscription required

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages