GoPro Photos HTTP¶
Low-level aiohttp wrapper for the Google Photos Library v1 API, OAuth helpers, and Pydantic models.
API client¶
q2google.gphotos.api
¶
Async client for Google Photos Library API v1 (uploads, batch create, media item lookup).
Use :class:GooglePhotosAPI only as an async context manager so an aiohttp session is opened
and closed correctly.
GooglePhotosAPI(credentials: GooglePhotosOAuth, timeout: float = 600.0)
¶
Thin aiohttp wrapper around selected Google Photos Library v1 endpoints.
Instantiate and use async with GooglePhotosAPI(...) as api to obtain a live session.
HTTP error responses are surfaced via response.raise_for_status() (aiohttp client errors).
Create a client; the HTTP session starts on async context enter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
credentials
|
GooglePhotosOAuth
|
OAuth credentials carrying a valid access token. |
required |
timeout
|
float
|
Per-request total timeout in seconds. Each resumable chunk is one request; large uploads often need a generous value. |
600.0
|
Source code in q2google/gphotos/api.py
base_url: str
property
¶
Root URL for Library API v1 resources for this client.
__aenter__() -> GooglePhotosAPI
async
¶
Open the underlying aiohttp client session.
__aexit__(exc_type: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None) -> None
async
¶
Close the client session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
type[BaseException] | None
|
Exception type if the context exited due to an error, else |
required |
exc
|
BaseException | None
|
Active exception instance when exiting with an error, else |
required |
tb
|
TracebackType | None
|
Traceback associated with |
required |
Source code in q2google/gphotos/api.py
create_media_item(media_item: MediaItemBatchCreateRequest) -> MediaItemBatchCreateResponse
async
¶
Call mediaItems:batchCreate with the given payload.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
media_item
|
MediaItemBatchCreateRequest
|
Batch create request body. |
required |
Returns:
| Type | Description |
|---|---|
MediaItemBatchCreateResponse
|
API batch create response. |
Source code in q2google/gphotos/api.py
get_media_item(media_item_id: str) -> dict[str, Any]
async
¶
GET a single media item by id (mediaItems/{mediaItemId}).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
media_item_id
|
str
|
Library media item id. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Parsed JSON object as returned by the API (shape matches the MediaItem resource). |
Source code in q2google/gphotos/api.py
init_upload_session(content_type: str, content_length: int) -> ResumableUploadSession
async
¶
Start a resumable upload; maps response headers to a session model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content_type
|
str
|
MIME type of the file to upload. |
required |
content_length
|
int
|
Total byte size of the file. |
required |
Returns:
| Type | Description |
|---|---|
ResumableUploadSession
|
Parsed upload session metadata from response headers. |
Source code in q2google/gphotos/api.py
query_upload_status(url: str) -> ResumableUploadSession
async
¶
Send an upload query command and return parsed header state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Resumable upload URL to query. |
required |
Returns:
| Type | Description |
|---|---|
ResumableUploadSession
|
Parsed session metadata from response headers. |
Source code in q2google/gphotos/api.py
upload_chunk(url: str, command: str, offset: int, content: bytes) -> ResumableUploadSession
async
¶
POST one chunk of a resumable upload.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Resumable upload URL from a prior session. |
required |
command
|
str
|
Google resumable upload command (e.g. |
required |
offset
|
int
|
Byte offset for this chunk. |
required |
content
|
bytes
|
Raw chunk bytes. |
required |
Returns:
| Type | Description |
|---|---|
ResumableUploadSession
|
Parsed session state; when the upload completes, |
ResumableUploadSession
|
the response body. |
Source code in q2google/gphotos/api.py
OAuth¶
q2google.gphotos.auth
¶
OAuth helpers for Google Photos Library API using installed-app credentials.
GooglePhotosOAuth(client_secrets_file: str, scopes: list[PhotosScopes], token_file: str | None = None)
dataclass
¶
Load, refresh, or obtain Google OAuth credentials for Photos scopes.
Attributes:
| Name | Type | Description |
|---|---|---|
client_secrets_file |
str
|
Path to the Google OAuth client secrets JSON (installed app). |
scopes |
list[PhotosScopes]
|
API scopes to request; values are sent to the authorization server. |
token_file |
str | None
|
Optional path to persist the authorized user token; parent dirs are created on save. If omitted, tokens are only kept in memory. |
authorize_interactive() -> Credentials
¶
Run the local-server OAuth flow and optionally persist the token.
Returns:
| Type | Description |
|---|---|
Credentials
|
Newly authorized credentials. |
Source code in q2google/gphotos/auth.py
ensure_credentials() -> Credentials
¶
Return stored valid credentials, or complete an interactive authorization.
Returns:
| Type | Description |
|---|---|
Credentials
|
Credentials that are valid for API calls (refreshed from disk when possible). |
Raises:
| Type | Description |
|---|---|
Various ``google_auth`` exceptions
|
If the OAuth flow or refresh fails in a way not
handled by :meth: |
Source code in q2google/gphotos/auth.py
load_saved_credentials() -> Credentials | None
¶
Load credentials from disk and refresh if expired.
Returns:
| Type | Description |
|---|---|
Credentials | None
|
Valid or refreshed credentials, or |
Credentials | None
|
if |
Credentials | None
|
or if stored credentials cannot be used. |
Source code in q2google/gphotos/auth.py
Models¶
q2google.gphotos.models
¶
Pydantic models and enums for Google Photos Library API payloads and upload headers.
Types mirror JSON resources and resumable-upload header fields.
MediaItem
¶
Bases: BaseModel
A media item resource as returned by the Library API.
Examples:
>>> MediaItem(
... id="ABC",
... productUrl="https://photos.google.com/lr/photo/ABC",
... mimeType="image/jpeg",
... )
baseUrl: str | None = None
class-attribute
instance-attribute
¶
Base URL for requesting image bytes with size parameters, when present.
description: str | None = None
class-attribute
instance-attribute
¶
User-visible description when present.
filename: str | None = None
class-attribute
instance-attribute
¶
Filename when available.
id: str
instance-attribute
¶
Opaque media item identifier.
mediaMetadata: MediaMetadata | None = None
class-attribute
instance-attribute
¶
Dimensions, timestamps, and other metadata.
mimeType: str
instance-attribute
¶
MIME type of the primary asset.
productUrl: str
instance-attribute
¶
URL to open the item in Google Photos.
MediaItemBatchCreateRequest
¶
MediaItemBatchCreateResponse
¶
Bases: BaseModel
Response body from mediaItems:batchCreate.
Examples:
newMediaItemResults: list[NewMediaItemResult]
instance-attribute
¶
Parallel list of results aligned with the request newMediaItems order.
MediaMetadata
¶
Bases: BaseModel
Subset of mediaMetadata returned on a media item; extra keys are preserved.
Examples:
NewMediaItem
¶
Bases: BaseModel
One new media item entry inside a batch create request.
Examples:
NewMediaItemResult
¶
Bases: BaseModel
Outcome for one entry in a mediaItems:batchCreate response.
Examples:
PhotosScopes
¶
Bases: str, Enum
OAuth 2.0 scope URLs accepted by the Google Photos Library API.
Examples:
LIBRARY_APPENDONLY = 'https://www.googleapis.com/auth/photoslibrary.appendonly'
class-attribute
instance-attribute
¶
Create albums and upload media; cannot read or delete unrelated library content.
LIBRARY_EDIT_APP_CREATED = 'https://www.googleapis.com/auth/photoslibrary.edit.appcreateddata'
class-attribute
instance-attribute
¶
Edit and delete media and albums created by this app.
LIBRARY_READONLY_APP_CREATED = 'https://www.googleapis.com/auth/photoslibrary.readonly.appcreateddata'
class-attribute
instance-attribute
¶
Read media and albums created by this app only.
ResumableUploadSession
¶
Bases: BaseModel
State parsed from Google resumable upload response headers (and optional body token).
Examples:
>>> ResumableUploadSession.model_validate(
... {
... "X-Goog-Upload-Status": "active",
... "X-GUploader-UploadID": "upload-id",
... "Date": "Mon, 01 Jan 2024 00:00:00 GMT",
... }
... )
date: datetime = Field(alias='Date')
class-attribute
instance-attribute
¶
Response Date header value, parsed to UTC-aware naive or as returned.
granularity: int | None = Field(alias='X-Goog-Upload-Chunk-Granularity', default=None)
class-attribute
instance-attribute
¶
Preferred chunk size in bytes, if the server advertises one.
status: str = Field(alias='X-Goog-Upload-Status')
class-attribute
instance-attribute
¶
Upload lifecycle status string from X-Goog-Upload-Status.
upload_id: str = Field(alias='X-GUploader-UploadID')
class-attribute
instance-attribute
¶
Server upload identifier from X-GUploader-UploadID.
upload_token: str | None = None
class-attribute
instance-attribute
¶
Raw upload token from the response body when the upload is complete.
upload_url: str | None = Field(alias='X-Goog-Upload-URL', default=None)
class-attribute
instance-attribute
¶
URL to POST the next chunk or query, when provided by the server.
parse_date(v: str) -> datetime
¶
Parse RFC 2822-style date strings from upload responses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
v
|
str
|
Date header value as returned by Google. |
required |
Returns:
| Type | Description |
|---|---|
datetime
|
Parsed datetime. |
Source code in q2google/gphotos/models.py
SimpleMediaItem
¶
Bases: BaseModel
Minimal media reference for batch create (upload token plus optional filename).
Examples:
Status
¶
Bases: BaseModel
Per-item status in a batch create response.
Examples: