Python SDK for the Product Hunt API v2
Project description
Product Hunt SDK
A Python SDK for the Product Hunt API. Track trending products, discover new launches, and monitor your own products.
Quick Start
pip install producthunt-sdk
from producthunt_sdk import ProductHuntClient, BearerAuth
client = ProductHuntClient(auth=BearerAuth("your_developer_token"))
# Get today's top products
for post in client.get_posts(featured=True, first=5).nodes:
print(f"{post.name} - {post.votes_count} votes")
Get your token at producthunt.com/v2/oauth/applications
Data Access
Product Hunt's API has privacy restrictions. Here's what you can access:
| Data | Access |
|---|---|
| Featured/trending posts | Full access |
| Post details (votes, comments count) | Full access |
| Topics and collections | Full access |
| Comments on posts | Text only (commenter info redacted) |
| Your own profile, posts, votes, followers | Full access |
| Other users' profiles, posts, votes, followers | Redacted |
For extended access to user data, contact Product Hunt at hello@producthunt.com.
What You Can Do
Track Your Launch Performance
post = client.get_post(slug="your-product")
print(f"Votes: {post.votes_count}")
print(f"Comments: {post.comments_count}")
print(f"Rating: {post.reviews_rating}")
Find Trending Products
from datetime import datetime, timedelta, UTC
from producthunt_sdk import PostsOrder
# Top AI products from the last week
posts = client.get_posts(
topic="artificial-intelligence",
posted_after=datetime.now(UTC) - timedelta(days=7),
order=PostsOrder.VOTES,
first=10
)
for post in posts.nodes:
print(f"{post.name}: {post.tagline}")
Read Product Comments
from producthunt_sdk import CommentsOrder
comments = client.get_post_comments(
post_slug="chatgpt",
first=10,
order=CommentsOrder.VOTES_COUNT
)
for comment in comments.nodes:
print(f"{comment.body[:100]}...")
Monitor Topics and Trends
from producthunt_sdk import TopicsOrder
# Most popular topics
topics = client.get_topics(order=TopicsOrder.FOLLOWERS_COUNT, first=10)
for topic in topics.nodes:
print(f"{topic.name}: {topic.followers_count} followers, {topic.posts_count} products")
Access Your Own Data
# Get your profile (requires your token)
viewer = client.get_viewer()
print(f"Logged in as: @{viewer.user.username}")
# Get your own posts
my_posts = client.get_user_posts(username=viewer.user.username)
for post in my_posts.nodes:
print(f"{post.name} - {post.votes_count} votes")
Async Support
For high-performance applications:
import asyncio
from producthunt_sdk import AsyncProductHuntClient, BearerAuth
async def main():
async with AsyncProductHuntClient(auth=BearerAuth("your_token")) as client:
posts = await client.get_posts(featured=True)
print(f"Found {len(posts.nodes)} products")
asyncio.run(main())
OAuth Authentication
Use OAuth when building apps that authenticate users. This gives you access to the authenticated user's own data.
Note: Product Hunt requires HTTPS redirect URIs. Use ngrok to tunnel to localhost for development.
from producthunt_sdk import ProductHuntClient, OAuth2
# Just create the client - OAuth flow runs automatically on first request
client = ProductHuntClient(auth=OAuth2(
client_id="your_client_id",
client_secret="your_client_secret",
redirect_uri="https://your-app.ngrok.io/callback",
))
# This triggers the OAuth flow: opens browser, waits for callback, exchanges token
viewer = client.get_viewer()
print(f"Logged in as @{viewer.user.username}")
# Token is cached - subsequent requests use the cached token
posts = client.get_user_posts(username=viewer.user.username)
Token Caching
Tokens are cached in memory by default. For persistence across restarts:
from producthunt_sdk import OAuth2, TokenCache
# Use file-based cache
OAuth2.token_cache = TokenCache("~/.producthunt_tokens.json")
See examples/oauth_flow.py for a complete example.
Custom GraphQL Queries
Need something specific? Use raw GraphQL:
data = client.graphql("""
query {
posts(first: 5, featured: true) {
edges {
node {
name
votesCount
}
}
}
}
""")
Installation
# With pip
pip install producthunt-sdk
# With uv
uv add producthunt-sdk
Requirements: Python 3.13+
Configuration
from producthunt_sdk import ProductHuntClient, BearerAuth
client = ProductHuntClient(
auth=BearerAuth("your_token"),
auto_wait_on_rate_limit=True, # Wait instead of failing (default: True)
max_wait_seconds=900, # Max wait time for rate limits (default: 15min)
timeout=30.0, # Request timeout (default: 30s)
max_retries=3, # Retry on network errors (default: 3)
)
Rate Limits
The API allows 6,250 complexity points per 15 minutes. The SDK:
- Tracks your usage automatically
- Waits when you hit the limit (configurable)
- Retries on network errors and server issues
Check your usage:
info = client.rate_limit_info
print(f"Remaining: {info.remaining}/{info.limit}")
print(f"Resets in: {info.seconds_until_reset:.0f}s")
Available Methods
| Method | Description | Access |
|---|---|---|
get_post(id, slug) |
Get a single product | Public |
get_posts(...) |
List products with filters | Public |
get_topic(id, slug) |
Get a topic/category | Public |
get_topics(...) |
List topics | Public |
get_collection(id, slug) |
Get a curated collection | Public |
get_collections(...) |
List collections | Public |
get_collection_posts(...) |
Products in a collection | Public |
get_post_comments(...) |
Comments on a product | Public (user info redacted) |
get_post_votes(...) |
Votes on a product | Public (user info redacted) |
get_comment(id) |
Get a single comment | Public (user info redacted) |
get_viewer() |
Current authenticated user | Your data only |
get_user(id, username) |
Get user profile | Your data only |
get_user_posts(...) |
Products made by user | Your data only |
get_user_voted_posts(...) |
Products user upvoted | Your data only |
get_user_followers(...) |
User's followers | Your data only |
get_user_following(...) |
Who user follows | Your data only |
follow_user(user_id) |
Follow a user | Requires write scope |
unfollow_user(user_id) |
Unfollow a user | Requires write scope |
graphql(query, variables) |
Run custom GraphQL | Varies |
Pagination
All list methods return paginated results:
# First page
page1 = client.get_posts(first=20)
# Next page
if page1.page_info.has_next_page:
page2 = client.get_posts(first=20, after=page1.page_info.end_cursor)
# Iterate all items
for post in page1.nodes:
print(post.name)
Error Handling
from producthunt_sdk import (
ProductHuntError,
AuthenticationError,
RateLimitError,
GraphQLError,
)
try:
posts = client.get_posts()
except AuthenticationError:
print("Check your API token")
except RateLimitError as e:
print(f"Rate limited. Retry in {e.rate_limit_info.seconds_until_reset}s")
except GraphQLError as e:
print(f"API error: {e.message}")
except ProductHuntError as e:
print(f"Something went wrong: {e}")
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file producthunt_sdk-0.1.0.tar.gz.
File metadata
- Download URL: producthunt_sdk-0.1.0.tar.gz
- Upload date:
- Size: 42.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be18900911dd7e9e610b48399cb3acefede9ccce5eefc54e2a33e142e5cce11b
|
|
| MD5 |
7496eba6998386f68115a93bc2865ad4
|
|
| BLAKE2b-256 |
c06509c3c0308af8f3d46fbdee741d64bbf38b56510615d73ab1bba44eec0a29
|
Provenance
The following attestation bundles were made for producthunt_sdk-0.1.0.tar.gz:
Publisher:
publish.yml on Domoryonok/producthunt-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
producthunt_sdk-0.1.0.tar.gz -
Subject digest:
be18900911dd7e9e610b48399cb3acefede9ccce5eefc54e2a33e142e5cce11b - Sigstore transparency entry: 790807556
- Sigstore integration time:
-
Permalink:
Domoryonok/producthunt-sdk@0a397de8309a2266fca2bd3ebb56465bf2fbc892 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Domoryonok
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0a397de8309a2266fca2bd3ebb56465bf2fbc892 -
Trigger Event:
release
-
Statement type:
File details
Details for the file producthunt_sdk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: producthunt_sdk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6973ef8d1eb5f691093a150bcfb7d14463fc78e0e2f1bb55df4322f2825aa3a1
|
|
| MD5 |
94e4e5ef6b59a3973688437cdb45a6da
|
|
| BLAKE2b-256 |
e4f15c87287c176de4eafa210121812c98955760713d1bd743513018d4680ae9
|
Provenance
The following attestation bundles were made for producthunt_sdk-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Domoryonok/producthunt-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
producthunt_sdk-0.1.0-py3-none-any.whl -
Subject digest:
6973ef8d1eb5f691093a150bcfb7d14463fc78e0e2f1bb55df4322f2825aa3a1 - Sigstore transparency entry: 790807562
- Sigstore integration time:
-
Permalink:
Domoryonok/producthunt-sdk@0a397de8309a2266fca2bd3ebb56465bf2fbc892 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Domoryonok
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0a397de8309a2266fca2bd3ebb56465bf2fbc892 -
Trigger Event:
release
-
Statement type: