Files
plexpy/docs/sdks/timeline/README.md
speakeasybot d0db038e53 ## Python SDK Changes:
* `plex_api.library_playlists.add_playlist_items()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.hubs.get_metadata_hubs()`: 
  *  `request.only_transient` **Changed**
  *  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library_collections.move_collection_item()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library_collections.delete_collection_item()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library_collections.add_collection_items()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.content.get_sonically_similar()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.butler.stop_task()`:  `request` **Changed** **Breaking** ⚠️
* `plex_api.butler.start_task()`:  `request` **Changed** **Breaking** ⚠️
* `plex_api.content.get_sonic_path()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.download_queue.get_item_decision()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.hubs.get_all_hubs()`: 
  *  `request.only_transient` **Changed**
  *  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.hubs.get_continue_watching()`:  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.hubs.get_promoted_hubs()`:  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.content.get_all_leaves()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.hubs.get_postplay_hubs()`: 
  *  `request.only_transient` **Changed**
  *  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.hubs.get_related_hubs()`: 
  *  `request.only_transient` **Changed**
  *  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.hubs.get_section_hubs()`: 
  *  `request.only_transient` **Changed**
  *  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.content.list_content()`: 
  *  `request` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.content.get_albums()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.search.search_hubs()`:  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.search.voice_search_hubs()`: 
  *  `request.type` **Changed** **Breaking** ⚠️
  *  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_library_items()`: 
  *  `request.media_query` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.ingest_transient_item()`: 
  *  `request` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_library_matches()`: 
  *  `request` **Changed** **Breaking** ⚠️
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.content.get_metadata_item()`: 
  *  `request` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_sections()`:  `response.media_container.directory.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.add_section()`: 
  *  `request` **Changed**
  *  `response.media_container.directory.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_tags()`: 
  *  `request.type` **Changed** **Breaking** ⚠️
* `plex_api.content.get_collection_items()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_all_item_leaves()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.status.list_sessions()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.play_queue.move_play_queue_item()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_extras()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.play_queue.delete_play_queue_item()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.play_queue.unshuffle()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.list_matches()`: 
  *  `request.manual` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.list_sonically_similar()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.play_queue.reset_play_queue()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_related_items()`:  `response.media_container.hub.[].metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.list_similar()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.play_queue.clear_play_queue()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_item_tree()`:  `response.media_container.metadata_item.[]` **Changed** **Breaking** ⚠️
* `plex_api.play_queue.add_to_play_queue()`: 
  *  `request.next` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.play_queue.get_play_queue()`: 
  *  `request` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library_playlists.move_playlist_item()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_person()`:  `response.media_container.directory.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.list_person_media()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library_playlists.get_playlist_generator_items()`:  `response.media_container.metadata` **Changed** **Breaking** ⚠️
* `plex_api.library.get_library_details()`: 
  *  `request.include_details` **Changed**
  *  `response.media_container.directory.[]` **Changed** **Breaking** ⚠️
* `plex_api.library_playlists.modify_playlist_generator()`: 
  *  `request.item` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.autocomplete()`: 
  *  `request.media_query` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_collections()`: 
  *  `request.media_query` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.get_common()`: 
  *  `request.media_query` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library_playlists.delete_playlist_item()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library_playlists.clear_playlist_items()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.play_queue.shuffle()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library_playlists.create_playlist()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.playlist.get_playlist_items()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.playlist.get_playlist()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.collections.create_collection()`: 
  *  `request.type` **Changed** **Breaking** ⚠️
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.dv_rs.tune_channel()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.live_tv.get_sessions()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.live_tv.get_live_tv_session()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.playlist.list_playlists()`:  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.subscriptions.get_all_subscriptions()`: 
  *  `request` **Changed**
  *  `response.media_container.media_subscription.[].media_grab_operation.[].metadata` **Changed** **Breaking** ⚠️
* `plex_api.subscriptions.create_subscription()`:  `response.media_container.media_subscription.[].media_grab_operation.[].metadata` **Changed** **Breaking** ⚠️
* `plex_api.subscriptions.get_scheduled_recordings()`:  `response.media_container.media_grab_operation.[].metadata` **Changed** **Breaking** ⚠️
* `plex_api.subscriptions.get_template()`:  `response.media_container.subscription_template.[].media_subscription.[].media_grab_operation.[].metadata` **Changed** **Breaking** ⚠️
* `plex_api.subscriptions.get_subscription()`: 
  *  `request` **Changed**
  *  `response.media_container.media_subscription.[].media_grab_operation.[].metadata` **Changed** **Breaking** ⚠️
* `plex_api.subscriptions.edit_subscription_preferences()`:  `response.media_container.media_subscription.[].media_grab_operation.[].metadata` **Changed** **Breaking** ⚠️
* `plex_api.subscriptions.reorder_subscription()`:  `response.media_container.media_subscription.[].media_grab_operation.[].metadata` **Changed** **Breaking** ⚠️
* `plex_api.transcoder.make_decision()`: 
  *  `request` **Changed**
  *  `response.media_container.metadata.[]` **Changed** **Breaking** ⚠️
* `plex_api.library.refresh_items_metadata()`: 
  *  `request.mark_updated` **Changed**
* `plex_api.authentication.post-users-sign-in-data()`: **Added**
* `plex_api.transcoder.start_transcode_session()`:  `request` **Changed**
* `plex_api.devices.modify_device()`: 
  *  `request.enabled` **Changed**
* `plex_api.library.get_media_part()`: 
  *  `request.download` **Changed**
* `plex_api.library.detect_intros()`: 
  *  `request.force` **Changed**
* `plex_api.library.refresh_section()`: 
  *  `request.force` **Changed**
* `plex_api.library_playlists.upload_playlist()`: 
  *  `request.force` **Changed**
* `plex_api.library.delete_media_item()`: 
  *  `request.proxy` **Changed**
* `plex_api.authentication.get_token_details()`: **Added**
* `plex_api.library.get_first_characters()`: 
  *  `request.media_query` **Changed**
* `plex_api.library.update_items()`: 
  *  `request.field.locked` **Changed**
* `plex_api.library.delete_library_section()`: 
  *  `request.async` **Changed**
* `plex_api.library.set_stream_selection()`: 
  *  `request.all_parts` **Changed**
* `plex_api.play_queue.create_play_queue()`:  `request` **Changed**
* `plex_api.library.get_augmentation_status()`: 
  *  `request.wait` **Changed**
* `plex_api.library.detect_voice_activity()`:  `request` **Changed**
* `plex_api.transcoder.transcode_image()`:  `request` **Changed**
* `plex_api.transcoder.transcode_subtitles()`:  `request` **Changed**
* `plex_api.library.add_subtitles()`:  `request` **Changed**
* `plex_api.library.get_stream()`: 
  *  `request.auto_adjust_subtitle` **Changed**
* `plex_api.library.start_bif_generation()`: 
  *  `request.force` **Changed**
* `plex_api.library.detect_credits()`:  `request` **Changed**
* `plex_api.ultra_blur.get_image()`: 
  *  `request.noise` **Changed**
* `plex_api.library.generate_thumbs()`: 
  *  `request.force` **Changed**
* `plex_api.updater.apply_updates()`:  `request` **Changed**
* `plex_api.updater.check_updates()`: 
  *  `request.download` **Changed**
* `plex_api.library.delete_metadata_item()`: 
  *  `request.proxy` **Changed**
* `plex_api.library.optimize_database()`: 
  *  `request.async` **Changed**
* `plex_api.hubs.update_hub_visibility()`:  `request` **Changed**
* `plex_api.hubs.create_custom_hub()`:  `request` **Changed**
* `plex_api.library.get_section_image()`: 
  *  `request.media_query` **Changed**
* `plex_api.download_queue.add_download_queue_items()`:  `request` **Changed**
* `plex_api.timeline.report()`:  `request` **Changed**
* `plex_api.general.get_source_connection_information()`: 
  *  `request.refresh` **Changed**
* `plex_api.plex.get-server-resources()`: **Added**
* `plex_api.users.get-users()`: **Added**
2025-12-01 00:03:55 +00:00

194 lines
8.1 KiB
Markdown

# Timeline
(*timeline*)
## Overview
The actions feature within a media provider
### Available Operations
* [mark_played](#mark_played) - Mark an item as played
* [report](#report) - Report media timeline
* [unscrobble](#unscrobble) - Mark an item as unplayed
## mark_played
Mark an item as played. Note, this does not create any view history of this item but rather just sets the state as played. The client must provide either the `key` or `uri` query parameter
This API does respond to the GET verb but applications should use PUT
### Example Usage
<!-- UsageSnippet language="python" operationID="markPlayed" method="put" path="/:/scrobble" -->
```python
from plex_api_client import PlexAPI
from plex_api_client.models import components
with PlexAPI(
accepts=components.Accepts.APPLICATION_XML,
client_identifier="abc123",
product="Plex for Roku",
version="2.4.1",
platform="Roku",
platform_version="4.3 build 1057",
device="Roku 3",
model="4200X",
device_vendor="Roku",
device_name="Living Room TV",
marketplace="googlePlay",
token="<YOUR_API_KEY_HERE>",
) as plex_api:
res = plex_api.timeline.mark_played(request={
"identifier": "<value>",
"key": "59398",
})
assert res is not None
# Handle response
print(res)
```
### Parameters
| Parameter | Type | Required | Description |
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `request` | [operations.MarkPlayedRequest](../../models/operations/markplayedrequest.md) | :heavy_check_mark: | The request object to use for the request. |
| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
### Response
**[operations.MarkPlayedResponse](../../models/operations/markplayedresponse.md)**
### Errors
| Error Type | Status Code | Content Type |
| --------------- | --------------- | --------------- |
| errors.SDKError | 4XX, 5XX | \*/\* |
## report
This endpoint is hit during media playback for an item. It must be hit whenever the play state changes, or in the absence of a play state change, in a regular fashion (generally this means every 10 seconds on a LAN/WAN, and every 20 seconds over cellular).
### Example Usage
<!-- UsageSnippet language="python" operationID="report" method="post" path="/:/timeline" -->
```python
from plex_api_client import PlexAPI
from plex_api_client.models import components, operations
with PlexAPI(
accepts=components.Accepts.APPLICATION_XML,
client_identifier="abc123",
product="Plex for Roku",
version="2.4.1",
platform="Roku",
platform_version="4.3 build 1057",
device="Roku 3",
model="4200X",
device_vendor="Roku",
device_name="Living Room TV",
marketplace="googlePlay",
token="<YOUR_API_KEY_HERE>",
) as plex_api:
res = plex_api.timeline.report(request=operations.ReportRequest(
key="/foo",
rating_key="xyz",
state=operations.State.PLAYING,
play_queue_item_id="123",
time=0,
duration=10000,
continuing=components.BoolInt.TRUE,
updated=14200000,
offline=components.BoolInt.TRUE,
time_to_first_frame=1000,
time_stalled=1000,
bandwidth=100,
buffered_time=100,
buffered_size=1024,
))
assert res.object is not None
# Handle response
print(res.object)
```
### Parameters
| Parameter | Type | Required | Description |
| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `request` | [operations.ReportRequest](../../models/operations/reportrequest.md) | :heavy_check_mark: | The request object to use for the request. |
| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
### Response
**[operations.ReportResponse](../../models/operations/reportresponse.md)**
### Errors
| Error Type | Status Code | Content Type |
| --------------- | --------------- | --------------- |
| errors.SDKError | 4XX, 5XX | \*/\* |
## unscrobble
Mark an item as unplayed. The client must provide either the `key` or `uri` query parameter
This API does respond to the GET verb but applications should use PUT
### Example Usage
<!-- UsageSnippet language="python" operationID="unscrobble" method="put" path="/:/unscrobble" -->
```python
from plex_api_client import PlexAPI
from plex_api_client.models import components
with PlexAPI(
accepts=components.Accepts.APPLICATION_XML,
client_identifier="abc123",
product="Plex for Roku",
version="2.4.1",
platform="Roku",
platform_version="4.3 build 1057",
device="Roku 3",
model="4200X",
device_vendor="Roku",
device_name="Living Room TV",
marketplace="googlePlay",
token="<YOUR_API_KEY_HERE>",
) as plex_api:
res = plex_api.timeline.unscrobble(request={
"identifier": "<value>",
})
assert res is not None
# Handle response
print(res)
```
### Parameters
| Parameter | Type | Required | Description |
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `request` | [operations.UnscrobbleRequest](../../models/operations/unscrobblerequest.md) | :heavy_check_mark: | The request object to use for the request. |
| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
### Response
**[operations.UnscrobbleResponse](../../models/operations/unscrobbleresponse.md)**
### Errors
| Error Type | Status Code | Content Type |
| --------------- | --------------- | --------------- |
| errors.SDKError | 4XX, 5XX | \*/\* |