Created
July 2, 2024 10:26
-
-
Save billettg/2500fd16c82fd554b0caad3d98668161 to your computer and use it in GitHub Desktop.
Sample code for PIN authentication using Plex API
This file contains hidden or 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
import uuid | |
import random | |
import time | |
import requests | |
import logging | |
# Configure logging | |
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') | |
# Constants | |
APP_NAME = "My App" | |
BASE_URL = "https://plex.tv/api/v2" | |
# In-memory storage for client identifier and access token | |
client_identifier = None | |
access_token = None | |
# Function to generate or retrieve client identifier | |
def get_client_identifier(): | |
global client_identifier | |
if not client_identifier: | |
client_identifier = str(uuid.uuid4()) | |
logging.debug(f"Generated new client identifier: {client_identifier}") | |
else: | |
logging.debug(f"Using existing client identifier: {client_identifier}") | |
return client_identifier | |
# Function to check if access token is valid | |
def is_access_token_valid(client_identifier, access_token): | |
headers = { | |
"accept": "application/json", | |
} | |
data = { | |
"X-Plex-Product": APP_NAME, | |
"X-Plex-Client-Identifier": client_identifier, | |
"X-Plex-Token": access_token, | |
} | |
logging.debug(f"Checking access token validity for client identifier: {client_identifier}") | |
response = requests.get(f"{BASE_URL}/user", headers=headers, data=data) | |
logging.debug(f"Received response: {response.status_code}") | |
return response.status_code == 200 | |
# Function to generate a new 4-digit PIN | |
def generate_pin(client_identifier): | |
headers = { | |
"accept": "application/json", | |
} | |
data = { | |
"strong": "false", | |
"X-Plex-Product": APP_NAME, | |
"X-Plex-Client-Identifier": client_identifier, | |
} | |
logging.debug(f"Generating new PIN for client identifier: {client_identifier}") | |
response = requests.post(f"{BASE_URL}/pins", headers=headers, data=data) | |
pin_data = response.json() | |
print(pin_data) | |
pin_id = pin_data["id"] | |
pin_code = pin_data["code"] | |
logging.debug(f"Generated PIN: {pin_code} with ID: {pin_id}") | |
return pin_id, pin_code | |
# Function to poll for access token | |
def poll_for_access_token(pin_id, pin_code, client_identifier): | |
headers = { | |
"accept": "application/json", | |
} | |
data = { | |
"X-Plex-Client-Identifier": client_identifier, | |
"code": pin_code, | |
} | |
logging.debug(f"Starting to poll for access token with PIN ID: {pin_id} and PIN code: {pin_code}") | |
while True: | |
response = requests.get(f"{BASE_URL}/pins/{pin_id}", headers=headers, data=data) | |
pin_data = response.json() | |
logging.debug(f"Polled PIN data: {pin_data}") | |
if "authToken" in pin_data and pin_data["authToken"]: | |
logging.debug("Access token found.") | |
return pin_data["authToken"] | |
if pin_data.get("expiresIn", 0) <= 0: | |
logging.debug("PIN expired.") | |
break | |
time.sleep(1) | |
return None | |
# Main function | |
def authenticate_with_plex(): | |
global client_identifier, access_token | |
client_identifier = get_client_identifier() | |
if access_token and is_access_token_valid(client_identifier, access_token): | |
logging.debug("Access token is valid.") | |
return access_token | |
logging.debug("Access token is missing or invalid. Generating a new PIN...") | |
pin_id, pin_code = generate_pin(client_identifier) | |
# Inform the user to visit plex.tv/link and enter the pin_code | |
logging.info(f"Please navigate to: https://plex.tv/link and enter the code: {pin_code}") | |
logging.debug("Polling for access token...") | |
access_token = poll_for_access_token(pin_id, pin_code, client_identifier) | |
if access_token: | |
logging.debug("Access token obtained successfully.") | |
else: | |
logging.debug("Failed to obtain access token.") | |
return access_token | |
if __name__ == "__main__": | |
authenticate_with_plex() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment