In pod2gen, the term podcast refers to the show which listeners can subscribe to, which consists of individual episodes. Therefore, the Podcast class will be the first thing you start with.

Creating a new instance

You can start with a blank podcast by invoking the Podcast constructor with no arguments, like this:

from pod2gen import Podcast
p = Podcast()

Mandatory attributes

There are four attributes which must be set before you can generate your podcast. They are mandatory because Apple’s podcast directory will not accept podcasts without this information. If you try to generate the podcast without setting all of the mandatory attributes, you will get an error.

The mandatory attributes are:

p.name = "My Example Podcast"
p.description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
p.website = "https://example.org"
p.explicit = False

They’re mostly self explanatory, but you can read more about them if you’d like:


A podcast’s image is worth special attention:

p.image = "https://example.com/static/example_podcast.png"

The URL of the artwork for this podcast. iTunes prefers square images that are at least 1400x1400 pixels. Podcasts with an image smaller than this are not eligible to be featured on the iTunes Store.

iTunes supports images in JPEG and PNG formats with an RGB color space (CMYK is not supported). The URL must end in “.jpg” or “.png”; if they don’t, a NotSupportedByItunesWarning will be issued.






If you change your podcast’s image, you must also change the file’s name; iTunes doesn’t check the image to see if it has changed.

Additionally, the server hosting your cover art image must allow HTTP HEAD requests (most servers support this).

Even though the image technically is optional, you won’t reach people without it.

The two types of podcasts

There are two types of podcasts in the world (according to Apple Podcasts, anyway):

  • Episodic podcasts are podcasts whose episodes are meant to be consumed in any order. New listeners will likely start with the newest episode. This is the traditional type of podcast, with examples like “The Daily” and “The Joe Rogan Experience”. Each episode of an episodic podcast is largely self-contained, although there may be recurring jokes and references to older episodes.

  • Serial podcasts are podcasts whose episodes must be consumed from beginning to end. New listeners will likely start with the first episode of the current season. This is a newer phenomenon, made popular by the appropriately titled podcast “Serial”. Each episode of a serial podcast starts off where the last episode ended, though the seasons are independent from one another.

If you don’t do anything, pod2gen will assume that your podcast is episodic.

If your podcast is serial, you can set the is_serial attribute to True, like this:

p.is_serial = True


When is_serial is set to True, all full episodes must be given an episode_number. Additionally, it is recommended that you associate each episode with a season. This is covered on the Episode page.

Optional attributes

There are plenty of other attributes that can be used with Podcast:

Commonly used

p.copyright = "2016 Example Radio"
p.language = "en-US"
p.authors = [Person("John Doe", "editor@example.org")]
p.feed_url = "https://example.com/feeds/podcast.rss"  # URL of this feed
p.category = Category("Music", "Music History")
p.owner = p.authors[0]
p.xslt = "https://example.com/feed/stylesheet.xsl"  # URL of XSLT stylesheet

Read more:

Less commonly used

Some of those are obscure while some of them are often times not needed. Others again have very reasonable defaults.

# RSS Cloud enables podcatchers to subscribe to notifications when there's
# a new episode ready, however it's not used much.
p.cloud = ("server.example.com", 80, "/rpc", "cloud.notify", "xml-rpc")

import datetime
from dateutil import tz
# last_updated is datetime when the feed was last refreshed. If you don't
# set it, the current date and time will be used instead when the feed is
# generated, which is generally what you want. Nevertheless, you can
# set your own date:
p.last_updated = datetime.datetime(2016, 5, 18, 0, 0, tzinfo=tz.UTC))

# publication_date is when the contents of this feed last were published.
# If you don't set it, the date of the most recent Episode is used. Again,
# this is generally what you want, but you can override it:
p.publication_date = datetime.datetime(2016, 5, 17, 15, 32,tzinfo=tz.UTC))

# Set of days on which podcatchers won't need to refresh the feed.
# Not implemented widely.
p.skip_days = {"Friday", "Saturday", "Sunday"}

# Set of hours on which podcatchers won't need to refresh the feed.
# Not implemented widely.
p.skip_hours = set(range(8))
p.skip_hours |= set(range(16, 24))

# Person to contact regarding technical aspects of the feed.
p.web_master = Person(None, "helpdesk@dallas.example.com")

# Identify the software which generates the feed (defaults to pod2gen)
p.set_generator("ExamplePodcastProgram", (1,0,0))
# (you can also set the generator string directly)
p.generator = "ExamplePodcastProgram v1.0.0 (with help from python-feedgen)"

# !!! Be very careful about using the following attributes !!!

# Tell iTunes that this feed has moved somewhere else.
p.new_feed_url = "https://podcast.example.com/example"

# Tell iTunes that this feed will never be updated again.
p.complete = True

# Tell iTunes that you'd rather not have this feed appear on iTunes.
p.withhold_from_itunes = True

Read more:

Shortcut for filling in data

Instead of creating a new Podcast object in one statement, and populating it with data one statement at a time afterwards, you can create a new Podcast object and fill it with data in one statement. Simply use the attribute name as keyword arguments to the constructor:

import pod2gen
p = pod2gen.Podcast(
    <attribute name>=<attribute value>,
    <attribute name>=<attribute value>,

Using this technique, you can define the Podcast as part of a list comprehension, dictionaries and so on. Take a look at the API Documentation for Podcast for a practical example.