
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
dbbasic-rss
Advanced tools
Simple, composable RSS feed generation for Python. Framework-agnostic, works with TSV/CSV/JSON, follows Unix philosophy.
Simple, composable RSS feed generation for Python. Framework-agnostic, works with TSV/CSV/JSON, follows Unix philosophy.
dbbasic-tsv and other modulespip install dbbasic-rss
Optional dependencies:
# For TSV support with dbbasic-tsv
pip install dbbasic-rss[tsv]
# For YAML frontmatter in from_directory()
pip install dbbasic-rss[yaml]
# For development
pip install dbbasic-rss[dev]
import dbbasic_rss as rss
# Auto-detects format and generates feed
rss.generate('articles.tsv', 'feed.xml',
title='My Blog',
url_pattern='https://example.com/{slug}/')
import dbbasic_rss as rss
feed = rss.from_tsv(
'articles.tsv',
title='My Blog',
link='https://example.com',
description='Articles about Python and web development',
url_pattern='https://example.com/{slug}/'
)
# Save to file
feed.write('feed.xml')
# Or get as string
xml = feed.to_xml()
print(xml)
import dbbasic_rss as rss
posts = [
{
'title': 'Getting Started with Python',
'date': '2025-10-19',
'content': 'Learn the basics...',
'slug': 'getting-started-python',
'author': 'Dan Quellhorst'
},
{
'title': 'Advanced Python Tips',
'date': '2025-10-18',
'content': 'Expert techniques...',
'slug': 'advanced-python-tips'
}
]
feed = rss.from_posts(
posts,
title='Python Blog',
link='https://example.com',
description='Learn Python programming',
url_pattern='https://example.com/posts/{slug}/'
)
feed.write('feed.xml')
import dbbasic_rss as rss
# Create feed
feed = rss.Feed(
title='My Tech Blog',
link='https://example.com',
description='Articles about software engineering',
language='en',
author='Dan Quellhorst',
author_email='dan@example.com'
)
# Add posts
feed.add_post(
title='Understanding RSS Feeds',
link='https://example.com/understanding-rss/',
description='A comprehensive guide to RSS',
content='<p>Full HTML content here...</p>',
pub_date='2025-10-19',
author='Dan Quellhorst',
categories=['rss', 'web', 'tutorial']
)
feed.add_post(
title='Python Web Frameworks',
link='https://example.com/python-frameworks/',
description='Comparing Flask, Django, and FastAPI',
pub_date='2025-10-18',
categories=['python', 'web']
)
# Generate XML
xml = feed.to_xml()
# Or write to file
feed.write('feed.xml')
from flask import Flask, Response
import dbbasic_rss as rss
app = Flask(__name__)
@app.route('/rss')
def rss_feed():
# Load your posts data
posts = load_posts() # Your data loading logic
feed = rss.from_posts(
posts,
title='My Blog',
link='https://example.com',
description='Latest blog posts',
url_pattern='https://example.com/{slug}/'
)
return Response(feed.to_xml(), mimetype='application/rss+xml')
from django.http import HttpResponse
import dbbasic_rss as rss
def rss_feed(request):
# Query your models
articles = Article.objects.all().order_by('-published_date')[:20]
# Convert to list of dicts
posts = list(articles.values('title', 'slug', 'content', 'published_date', 'author__name'))
feed = rss.from_posts(
posts,
title='My Django Blog',
link='https://example.com',
description='Latest articles',
url_pattern='https://example.com/articles/{slug}/',
date_field='published_date',
author_field='author__name'
)
return HttpResponse(feed.to_xml(), content_type='application/rss+xml')
from fastapi import FastAPI
from fastapi.responses import Response
import dbbasic_rss as rss
app = FastAPI()
@app.get('/rss', response_class=Response)
async def rss_feed():
posts = await get_posts() # Your async data loading
feed = rss.from_posts(
posts,
title='FastAPI Blog',
link='https://example.com',
description='Latest posts',
url_pattern='https://example.com/posts/{id}/'
)
return Response(content=feed.to_xml(), media_type='application/rss+xml')
import dbbasic_rss as rss
# Generate from markdown files
feed = rss.from_directory(
'content/posts/',
pattern='*.md',
extract_metadata=True, # Reads YAML frontmatter
title='My Static Blog',
link='https://example.com',
description='Static blog posts',
url_pattern='https://example.com/posts/{stem}/'
)
# Write static file
feed.write('public/rss.xml')
# articles.tsv:
# title slug date description author
# Post 1 post-1 2025-10-19 Description... Dan
feed = rss.from_tsv(
'articles.tsv',
title='Blog',
url_pattern='https://example.com/{slug}/'
)
feed = rss.from_csv(
'posts.csv',
title='Blog',
url_pattern='https://example.com/{id}/'
)
# posts.json:
# [
# {"title": "Post 1", "url": "https://...", "date": "2025-10-19"},
# ...
# ]
feed = rss.from_json(
'posts.json',
title='Blog',
link='https://example.com'
)
# Reads markdown files with YAML frontmatter:
# ---
# title: My Post
# date: 2025-10-19
# author: Dan
# ---
# Content here...
feed = rss.from_directory(
'posts/',
pattern='*.md',
extract_metadata=True,
title='Blog',
url_pattern='https://example.com/{stem}/'
)
posts = [
{
'headline': 'My Article',
'published': '2025-10-19',
'body': 'Article content...',
'permalink': 'https://example.com/articles/my-article'
}
]
feed = rss.from_posts(
posts,
title_field='headline',
date_field='published',
content_field='body',
url_field='permalink'
)
posts = [
{
'title': 'Python Tutorial',
'url': 'https://example.com/tutorial',
'tags': 'python,tutorial,beginner' # Comma-separated
}
]
feed = rss.from_posts(
posts,
categories_field='tags'
)
feed.add_post(
title='Article Title',
link='https://example.com/article',
description='Short plain-text description for RSS readers',
content='<p>Full <strong>HTML</strong> content for readers that support it</p>',
pub_date='2025-10-19'
)
feed = rss.Feed(
title='My Blog',
link='https://example.com',
description='Blog description',
image_url='https://example.com/logo.png',
image_title='My Blog Logo',
image_link='https://example.com'
)
feed.add_post(
title='Episode 1: Introduction',
link='https://example.com/podcast/ep1',
description='In this episode...',
pub_date='2025-10-19',
enclosure={
'url': 'https://example.com/audio/ep1.mp3',
'type': 'audio/mpeg',
'length': '12345678' # Size in bytes
}
)
feed = rss.Feed(title='', link='https://example.com')
warnings = feed.validate()
for warning in warnings:
print(f"Warning: {warning}")
# Output: Warning: Feed title is missing
print(f"Total posts: {feed.count()}")
print(f"Oldest post: {feed.oldest()}")
print(f"Newest post: {feed.newest()}")
from dbbasic_tsv import TSV
import dbbasic_rss as rss
# Read and query with dbbasic-tsv
db = TSV('articles.tsv')
posts = db.query(category='python', limit=10)
# Generate RSS feed
feed = rss.from_posts(
posts,
title='Python Articles',
url_pattern='https://example.com/{slug}/'
)
feed.write('python-feed.xml')
Feed(title, link, description, ...)Main feed class.
Parameters:
title (str): Feed titlelink (str): Feed URLdescription (str): Feed descriptionlanguage (str): Language code (default: 'en')author (str): Author nameauthor_email (str): Author emailimage_url (str): Feed image/logo URLttl (int): Cache time-to-live in minutescategory (str): Feed categoryMethods:
add_post(**kwargs): Add a post to the feedto_xml(): Generate RSS XML stringwrite(filepath): Write feed to filevalidate(): Return list of validation warningscount(): Return number of itemsoldest(): Return oldest publication datenewest(): Return newest publication datefrom_posts(posts, ...)Generate feed from list of dictionaries.
Parameters:
posts (list): List of post dictionariestitle (str): Feed titlelink (str): Feed URLdescription (str): Feed descriptionurl_pattern (str): URL pattern with {field} placeholderstitle_field (str): Field name for title (default: 'title')date_field (str): Field name for date (default: 'date')content_field (str): Field name for content (default: 'content')author_field (str): Field name for author (default: 'author')url_field (str): Field name for URL (default: 'url')categories_field (str): Field name for categories**kwargs: Additional Feed() argumentsfrom_tsv(filepath, ...), from_csv(filepath, ...), from_json(filepath, ...)Generate feed from file. Same parameters as from_posts().
from_directory(directory, pattern='*.md', ...)Generate feed from directory of files.
Additional Parameters:
directory (str): Directory pathpattern (str): Glob pattern (default: '*.md')extract_metadata (bool): Extract YAML frontmatter (default: True)generate(source, output, ...)One-liner to generate feed from file to file.
Parameters:
source (str): Input file path (.tsv, .csv, .json)output (str): Output XML file path**kwargs: Same as from_posts()feedgen (most popular):
dbbasic-rss:
RSS is just XML! dbbasic-rss helps you understand RSS by providing:
Contributions welcome! Please:
pytestMIT License - see LICENSE file for details.
Created by Ask Robots as part of the DBBasic framework.
Inspired by the Unix philosophy and built for simplicity, composability, and ease of learning.
FAQs
Simple, composable RSS feed generation for Python. Framework-agnostic, works with TSV/CSV/JSON, follows Unix philosophy.
We found that dbbasic-rss demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.