🚀 Executive Summary
TL;DR: This guide addresses the problem of losing Pocket Casts subscriptions due to app glitches by providing a robust, automated backup solution. It details a Python script that authenticates with the Pocket Casts API, fetches user subscriptions, and exports them to a standard OPML file for peace of mind and data integrity.
🎯 Key Takeaways
- The solution leverages Python with `requests` for API interaction, `python-dotenv` for secure credential management, and `lxml` for OPML file generation.
- Authentication with the unofficial Pocket Casts API requires an email and password to obtain a bearer token, which is then used to fetch the user’s podcast subscription list.
- Podcast subscription data, including titles and RSS URLs, is programmatically converted into an OPML 2.0 XML file, ensuring a standardized and portable backup format.
- Automation via a cron job is recommended to ensure consistent, scheduled backups, making the solution a ‘set-it-and-forget-it’ system for data resilience.
Syncing Pocket Casts subscriptions to OPML for backup
Alright, let’s talk about a small but crucial piece of automation. I listen to a ton of podcasts—everything from SRE deep dives to cybersecurity news. A while back, an app update glitched and wiped out a custom folder with about 20 subscriptions I was vetting for the team. Re-finding all of them was a massive pain. It was one of those “never again” moments. That’s why I built this simple Python script to automatically back up my Pocket Casts subscriptions to a standard OPML file. It’s a set-it-and-forget-it solution that gives me peace of mind.
This isn’t about fancy dashboards; it’s about robust, simple data integrity. Let’s get it done.
Prerequisites
Before we dive in, make sure you have the following ready:
- Python 3.x installed on your system.
- Your Pocket Casts login credentials (email and password).
- Basic comfort with running Python scripts and managing dependencies.
The Guide: Step-by-Step
Step 1: Project Setup
First, you’ll need a directory for our project. I’ll skip the standard virtualenv setup commands since you likely have your own workflow for that. Just make sure you’re working in an isolated environment.
Inside your project directory, you’ll need three things:
- A Python script file we’ll call
pocketcasts_sync.py. - A configuration file named
config.envto securely store our credentials. - The script will generate our backup,
subscriptions.opml, in this same directory.
Step 2: Installing Dependencies
We need a few Python libraries to make this work. You’ll want to install requests for making HTTP calls, python-dotenv for managing our credentials from the `config.env` file, and lxml for building the OPML file. You can install these using your standard package manager, for instance, with `pip`.
Step 3: Storing Your Credentials
Let’s get that config.env file set up. This is much safer than hardcoding your credentials directly in the script.
Create the `config.env` file and add your Pocket Casts email and password:
POCKETCASTS_EMAIL="your_email@example.com"
POCKETCASTS_PASSWORD="your_super_secret_password"
Pro Tip: In my production setups, I’d pull these from a proper secrets manager like HashiCorp Vault or AWS Secrets Manager. For a personal script like this, a `config.env` file excluded from version control (via `.gitignore`) is a perfectly reasonable approach.
Step 4: The Python Script
Now for the core logic. Open up pocketcasts_sync.py and let’s build this out. The script will perform four key actions:
- Load credentials from our `config.env` file.
- Authenticate with the Pocket Casts API to get a token.
- Fetch the list of your current podcast subscriptions.
- Generate an OPML file from that list.
Here is the complete script. I’ve added comments to explain what each part does.
import os
import requests
from dotenv import load_dotenv
from lxml import etree
def authenticate(email, password):
"""Authenticates with Pocket Casts and returns an auth token."""
auth_url = 'https://api.pocketcasts.com/user/login'
payload = {'email': email, 'password': password, 'scope': 'web'}
try:
response = requests.post(auth_url, json=payload)
response.raise_for_status() # This will raise an HTTPError for bad responses (4xx or 5xx)
token = response.json().get('token')
if not token:
print("Authentication failed. Token not found in response.")
return None
print("Successfully authenticated with Pocket Casts.")
return token
except requests.exceptions.RequestException as e:
print(f"Error during authentication: {e}")
return None
def fetch_subscriptions(token):
"""Fetches the user's podcast subscriptions."""
subs_url = 'https://api.pocketcasts.com/user/podcast/list'
headers = {'Authorization': f'Bearer {token}'}
try:
response = requests.post(subs_url, headers=headers)
response.raise_for_status()
podcasts = response.json().get('podcasts')
if podcasts is None:
print("Could not find 'podcasts' key in the subscription response.")
return []
print(f"Found {len(podcasts)} podcast subscriptions.")
return podcasts
except requests.exceptions.RequestException as e:
print(f"Error fetching subscriptions: {e}")
return []
def generate_opml(podcasts, output_file):
"""Generates an OPML file from a list of podcasts."""
opml = etree.Element('opml', version='2.0')
head = etree.SubElement(opml, 'head')
title = etree.SubElement(head, 'title')
title.text = "Pocket Casts Subscriptions"
body = etree.SubElement(opml, 'body')
for podcast in podcasts:
etree.SubElement(body, 'outline',
type='rss',
text=podcast.get('title', 'No Title'),
xmlUrl=podcast.get('url', ''))
# Use lxml's tostring method to get a nicely formatted XML string
opml_string = etree.tostring(opml, pretty_print=True, xml_declaration=True, encoding='UTF-8')
try:
with open(output_file, 'wb') as f: # Write in binary mode
f.write(opml_string)
print(f"Successfully saved subscriptions to {output_file}")
except IOError as e:
print(f"Error writing to file {output_file}: {e}")
def main():
"""Main function to run the sync process."""
load_dotenv('config.env')
email = os.getenv('POCKETCASTS_EMAIL')
password = os.getenv('POCKETCASTS_PASSWORD')
output_filename = 'subscriptions.opml'
if not email or not password:
print("Error: POCKETCASTS_EMAIL or POCKETCASTS_PASSWORD not set in config.env")
return
auth_token = authenticate(email, password)
if auth_token:
podcast_list = fetch_subscriptions(auth_token)
if podcast_list:
generate_opml(podcast_list, output_filename)
else:
print("No podcasts to process. OPML file not generated.")
else:
print("Could not proceed without authentication token.")
if __name__ == "__main__":
main()
Step 5: Automation
A backup script is only useful if it runs consistently. I use a simple cron job for this. Set it to run weekly, and you’ll always have a recent backup.
Here’s an example cron entry that runs the script every Monday at 2:00 AM.
`0 2 * * 1 python3 script.py`
Pro Tip: Make sure your cron job runs in the context of your project directory or use absolute paths for the script and the output file in your Python code. I prefer the former to keep the script portable. Also, direct the output of your cron job to a log file (`>> /path/to/your/logs/pocketcasts.log 2>&1`) to capture any errors.
Common Pitfalls
Here is where I usually mess up on the first try:
- API Changes: The Pocket Casts API is not officially public, so it can change without notice. If the script suddenly stops working, the first thing I check is if the API endpoints or the authentication payload have been updated.
- Credential Errors: A simple typo in the
config.envfile can lead to authentication failures. Double-check that your email and password are correct and that the script has permission to read the file. - File Permissions: The most classic problem. The script needs write permissions in the directory where it’s running to create the
subscriptions.opmlfile. If you see an `IOError`, this is the likely culprit.
Conclusion
And that’s it. With a simple Python script and a cron job, you’ve built a resilient, automated backup system for your podcast library. This is a small investment of time that saves you from a massive headache down the road. It embodies a core DevOps principle: automate the boring stuff so you can focus on what matters. Now you can be sure your carefully curated list of subscriptions is safe and sound.
🤖 Frequently Asked Questions
âť“ How can I automatically back up my Pocket Casts subscriptions to an OPML file?
You can use a Python script that authenticates with the Pocket Casts API using your credentials, fetches your list of subscribed podcasts, and then generates an OPML 2.0 formatted XML file containing the podcast details.
âť“ Are there official Pocket Casts features for exporting subscriptions, or how does this script compare to alternatives?
The article implies the Pocket Casts API is not officially public, suggesting this script is a custom, community-driven solution for a missing official export feature. It prioritizes robust, simple data integrity over fancy dashboards, providing a direct OPML backup.
âť“ What are common pitfalls when implementing this Pocket Casts subscription backup script?
Common pitfalls include unannounced Pocket Casts API changes that can break the script, credential errors in the `config.env` file leading to authentication failures, and file permission issues preventing the script from writing the `subscriptions.opml` file.
Leave a Reply