Skip to main content

Unofficial Python client for the GoPro cloud API (api.gopro.com): sync and async clients, Pydantic models, and a CLI.

Project description

gopro-api

PyPI version Python versions License CI Release Docs

Unofficial Python client for the GoPro cloud / Quik HTTP API at api.gopro.com: search your library and fetch download metadata (CDN URLs, filenames, variants). Built with Pydantic models, plus sync (requests) and async (aiohttp) clients and a small gopro-api CLI.

This project is not affiliated with or endorsed by GoPro.

Features

  • GoProAPI — synchronous client (requests), with context manager
  • AsyncGoProAPI — async client (aiohttp), async with context manager
  • Pydantic request/response types in gopro_api.api.models
  • CLIgopro-api search, gopro-api info, gopro-api pull, gopro-api auth
  • GP_ACCESS_TOKEN from environment / .env (browser cookie value)

Requirements

Install

From the repository root:

python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt
pip install -e .

From a local wheel (name matches your build):

pip install ./dist/gopro_api-*-py3-none-any.whl

Published package on PyPI (distribution name gopro-api, import gopro_api):

pip install gopro-api

CLI

After install, gopro-api is on your PATH:

gopro-api --help
gopro-api --version
gopro-api search --start 2026-03-01 --end 2026-03-03 --per-page 30
gopro-api search --start 2026-03-01 --end 2026-03-03 --all-pages
gopro-api search --start 2026-03-01 --end 2026-03-03 --json
gopro-api info MEDIA_ID
gopro-api info MEDIA_ID --json
gopro-api pull MEDIA_ID ./downloads
gopro-api pull MEDIA_ID ./downloads --height 1080
gopro-api pull MEDIA_ID ./downloads --width 1920 --height 1080
gopro-api auth
gopro-api auth --json
Command Purpose
search List media in a capture range. Default: a # _pages summary line, a tab-separated header (id, type, captured_at, filename, …; not gopro_user_id / source_gumi / source_mgumi), then one row per item (other API fields in an extra JSON column). --json: full API-shaped response; with --all-pages, a JSON array of every page.
info Show download metadata for one media id (filename + file lines with size and URL), or --json for the full payload.
pull Download asset(s) for a media id into destination (directory; created if missing). Videos (.mp4 extension, case-insensitive): one variations entry — tallest by default, or closest to --height / --width (sum of squared pixel deltas; ties broken by larger resolution). Photos: uses files (one request per file).
auth Verify that GP_ACCESS_TOKEN is configured and accepted by the API. Default: Rich panel; --json / --tsv for scripting. Exit code 0 when authenticated, 2 when the token is missing, 1 otherwise.

Global --timeout (seconds, default 60) applies to API calls and to pull CDN downloads (requests.get).

Run without an installed script:

python -m gopro_api.cli search --start 2026-03-01 --end 2026-03-02
python -m gopro_api.cli info MEDIA_ID
python -m gopro_api.cli pull MEDIA_ID ./out
python -m gopro_api.cli pull MEDIA_ID ./out --height 720
python -m gopro_api.cli auth

Configuration

gopro_api.config reads settings from the environment and from a .env file in the current working directory via pydantic-settings. Use get_settings() to access the memoized singleton; the only required setting is GP_ACCESS_TOKEN.

Example .env:

GP_ACCESS_TOKEN=your_token_here

The clients send it as a cookie: gp_access_token=<value>. Put only the token string in GP_ACCESS_TOKEN (not the gp_access_token= prefix).

You can override the token in code: GoProAPI(access_token="...") or AsyncGoProAPI(access_token="...").

Retrieving gp_access_token from your browser

Sign in to the GoPro web app (e.g. gopro.com media / Quik). The site sets a cookie gp_access_token.

Chrome / Edge / Brave

  1. Open the site while logged in.
  2. F12ApplicationCookies → choose the origin (often https://quik.gopro.com or another *.gopro.com host).
  3. Copy the Value of gp_access_token.

Firefox

F12StorageCookies → same idea.

Network panel (Chromium)

  1. Network → trigger requests to api.gopro.com.
  2. Pick a request → HeadersCookie.
  3. Copy the value after gp_access_token= up to the next ; (or end of string).

Notes

  • If the cookie is HttpOnly, use the Network method.
  • Tokens expire; refresh from the browser if you get 401.
  • Treat the token like a password.

Security: Do not commit .env or tokens. Keep .env in .gitignore.

Library usage

Async (AsyncGoProAPI)

import asyncio
from datetime import datetime

from gopro_api.api import AsyncGoProAPI
from gopro_api.api.models import CapturedRange, GoProMediaSearchParams


async def main() -> None:
    params = GoProMediaSearchParams(
        captured_range=CapturedRange(
            start=datetime.fromisoformat("2026-03-01"),
            end=datetime.fromisoformat("2026-03-02"),
        ),
        per_page=50,
        page=1,
    )

    async with AsyncGoProAPI() as api:
        search = await api.search(params)
        for item in search.embedded.media:
            meta = await api.download(item.id)
            print(meta.filename, len(meta.embedded.files), "files")


if __name__ == "__main__":
    asyncio.run(main())

Sync (GoProAPI)

from datetime import datetime

from gopro_api.api import GoProAPI
from gopro_api.api.models import CapturedRange, GoProMediaSearchParams


def main() -> None:
    params = GoProMediaSearchParams(
        captured_range=CapturedRange(
            start=datetime.fromisoformat("2026-03-01"),
            end=datetime.fromisoformat("2026-03-02"),
        ),
        per_page=50,
        page=1,
    )

    with GoProAPI() as api:
        search = api.search(params)
        for item in search.embedded.media:
            meta = api.download(item.id)
            print(meta.filename, len(meta.embedded.files), "files")


if __name__ == "__main__":
    main()

Models

  • Requests: GoProMediaSearchParams, CapturedRange, etc. in gopro_api.api.models.
  • Responses: search and download JSON shapes (including _embedded / _pages aliases).

List fields in search params are serialized to comma-separated strings when you call model_dump() (used by the HTTP clients).

Project layout

Path Role
gopro_api/api/gopro.py GoProAPI — sync search, download
gopro_api/api/async_gopro.py AsyncGoProAPI — async search, download
gopro_api/api/models.py Pydantic request/response models
gopro_api/api/__init__.py Re-exports GoProAPI, AsyncGoProAPI
gopro_api/config.py pydantic-settings Settings, lazy get_settings()
gopro_api/cli/ gopro-api CLI
setup.py Package metadata, dependencies, console entry point

CI and releases

.github/workflows/release.yml:

  • Push to main — builds wheel + source .zip, uploads workflow artifacts.
  • Push tag v* (e.g. v0.0.5) — attaches the same files to a GitHub Release.

License

MIT License.

GoPro, Quik, and related marks are trademarks of their respective owners.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gopro_api-0.0.10.tar.gz (143.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gopro_api-0.0.10-py3-none-any.whl (35.1 kB view details)

Uploaded Python 3

File details

Details for the file gopro_api-0.0.10.tar.gz.

File metadata

  • Download URL: gopro_api-0.0.10.tar.gz
  • Upload date:
  • Size: 143.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gopro_api-0.0.10.tar.gz
Algorithm Hash digest
SHA256 30c66e85a059d43cef7c3bf9a841c5ab4d0e2748bbae7a5e8a54697789eba16b
MD5 fdf4ecaa2ea25829f539015427b88072
BLAKE2b-256 9e603d280409f0f3a9d7fe8723a935793213eaeb2298279736725c38873b550d

See more details on using hashes here.

File details

Details for the file gopro_api-0.0.10-py3-none-any.whl.

File metadata

  • Download URL: gopro_api-0.0.10-py3-none-any.whl
  • Upload date:
  • Size: 35.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gopro_api-0.0.10-py3-none-any.whl
Algorithm Hash digest
SHA256 f7b827cfef6ea7f5bf121d70d1a6fbffdcb2f40cbb76a394488b9d9935fbd0ef
MD5 8599242fcc1f9e4323fe9d7bc56bf900
BLAKE2b-256 562daa8f8ca875f98f029b99d974e14949d52ce77c13b6ffb9f70ea1c8aad4c5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page