jellyfin / jellyfin-apiclient-python

Python API Client for Jellyfin
GNU General Public License v3.0
91 stars 31 forks source link

[WIP] Development Branch #35

Open Erotemic opened 10 months ago

Erotemic commented 10 months ago

This is a development branch where I'm hacking on the API. I will separate out individual features as smaller PRs to make review and merger easier. This branch is a single location where they all come together for my own use. I'm posting it as a PR for reference.

Contains:

thornbill commented 9 months ago

Sounds like this should probably be a draft if there is no plan for it to be merged as is.

Erotemic commented 9 months ago

Yes, this is a draft. I'm hacking on this branch to suite my own needs, but then separating out useful bits as standalone PRs. I marked the PR [WIP] for work in progress, but if there is a better way of marking it as a draft, let me know.

thornbill commented 9 months ago

No worries. There is a dropdown when you open a PR where you can choose to open it as a draft.

Erotemic commented 4 months ago

Some news on this. I've written code that creates an test server for testing and demo environments.

I'm surprised how difficult it was to programatically setup a jellyfin server. It seems that the only official way to initialize a server is via manual interaction with the web-UI. However, I was able to work around this by discovering the REST calls the web-UI makes and replicating them in Python code. The function MediaGraph.ensure_demo_server (could probably go in a separate testing module) will check that docker or podman exists, and then setup a demo jellyfin server on port 8097. It will execute a few special REST calls to initialize it, and then it will add some creative commons media as test items. From here, any method in the API can be tested.

The first test I wrote with this demos the MediaGraph I've been working on:

        >>> from jellyfin_apiclient_python.media_graph import MediaGraph
        >>> MediaGraph.ensure_demo_server()
        >>> client = MediaGraph.demo_client()
        >>> self = MediaGraph(client)
        >>> self.walk_config['initial_depth'] = None
        >>> self.setup()
        >>> self.tree()

And this prints:

╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ {                                                                                                                                                                                                       │
│     'node_types': {                                                                                                                                                                                     │
│         'Movie': 1,                                                                                                                                                                                     │
│         'Audio': 2,                                                                                                                                                                                     │
│     },                                                                                                                                                                                                  │
│     'edge_types': {                                                                                                                                                                                     │
│         ('CollectionFolder', 'Movie'): 1,                                                                                                                                                               │
│         ('CollectionFolder', 'Audio'): 2,                                                                                                                                                               │
│     },                                                                                                                                                                                                  │
│     'nondag_edge_types': {},                                                                                                                                                                            │
│     'total': 3,                                                                                                                                                                                         │
│     'latest_name': 'Playlists',                                                                                                                                                                         │
│     'latest_path': '/config/data/playlists',                                                                                                                                                            │
│ }                                                                                                                                                                                                       │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Media Folders        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 3/3 151929.37 Hz eta 0:00:00 total 0:00:00
Walk Media Folders   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 3/3 71.75 Hz     eta 0:00:00 total 0:00:00
Walking Movies     ⠋ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━   0% 1/? ?            eta         total 0:00:00
Walking Music      ⠋ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━   0% 1/? ?            eta         total 0:00:00
Walking Playlists  ⠋ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━   0% 1/? ?            eta         total 0:00:00
╟──  f137a2dd21bbc1b99aa5c0f6bf02a805 : 📂 CollectionFolder - Movies 
╎   └─╼  0a8c358081cc4bf1eb74a660ca8616f4 : 🎥 Movie - File:Zur%C3%BCck_in_die_Zukunft_(Film)_01 
╟──  7e64e319657a9516ec78490da03edccb : 📂 CollectionFolder - Music 
╎   ├─╼  76ed290f795e4a24a9cceba4aa8bfb33 : ♬ Audio - Heart_Monitor_Beep--freesound.org 
╎   └─╼  7a7f9d14d80062884dbefd156818b339 : ♬ Audio - Clair De Lune 
╙──  1071671e7bffa0532e930debee501d2e : 📂 ManualPlaylistsFolder - Playlists 

The initial code is definitely rough, but with a bit of tweaking it should enable robust automated testing of the API.

Erotemic commented 2 weeks ago

I've moved the demo server code into a separate submodule.