Created
December 29, 2021 19:23
-
-
Save BrenekH/83a7896f71ed36812573352645c794f4 to your computer and use it in GitHub Desktop.
Authorize a Third-Party Application with Plex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env python3 | |
"""Authorize a Third-Party Application with Plex | |
Python implementation of the steps described on the plex forum (https://forums.plex.tv/t/authenticating-with-plex/609370). | |
Dependencies: requests | |
Author: Brenek Harrison | |
""" | |
import requests, time | |
from urllib.parse import urlencode | |
app_name = "BrenekH Test 1" # Should be consistent across all instances of the app | |
unique_client_id = "brenekh-test-1" # This should be randomly generated and stored | |
# Request a pin from Plex | |
r = requests.post( | |
"https://plex.tv/api/v2/pins", | |
headers={"Accept": "application/json"}, | |
data={ | |
"strong": "true", | |
"X-Plex-Product": app_name, | |
"X-Plex-Client-Identifier": unique_client_id, | |
}, | |
) | |
r_json = r.json() | |
pin_id, pin_code = (r_json["id"], r_json["code"]) | |
encoded_params = urlencode( | |
{ | |
"clientID": unique_client_id, | |
"code": pin_code, | |
"context[device][product]": app_name, | |
} | |
) | |
auth_url = f"https://app.plex.tv/auth#?{encoded_params}" | |
# Output url for user to visit (alternatively can open the web browser directly) | |
print(f"Please visit {auth_url} to authenticate {app_name}.") | |
for _ in range(1800): # Pins are only valid for 30 minutes. If we pass that limit, there's no point in continuing to request the auth token. | |
headers = {"accept": "application/json"} | |
data = {"code": pin_code, "X-Plex-Client-Identifier": unique_client_id} | |
r = requests.get(f"https://plex.tv/api/v2/pins/{pin_id}", headers=headers, data=data) | |
# Check if a valid authToken has been provided | |
authToken = r.json()["authToken"] | |
if authToken != None: | |
print(authToken) | |
break | |
time.sleep(1) | |
else: | |
# The for-else feature allows us to run code if break is never called in the for loop. | |
print("Pin timed out") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment