A Python wrapper for the Product Hunt Beta API
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
ph_py
.gitignore
LICENSE.txt
README.md
setup.cfg
setup.py

README.md

ph_py

A Python wrapper for Product Hunt's REST API

Built by Anat and Jasdev!

Installation

pip install ph_py

Dependencies:

  • requests
  • simplejson

Beta API Note

The Product Hunt API is in an early beta phase. As such, the official docs are super minimal. So, we implemented this library to the best of our knowledge. Also, since write access to the API is currently restricted, we had to build functions with write functionality solely off the public documentation (there may be bugs). If you find any issues, please submit a GitHub issue or a pull request!

Authentication

Product Hunt's API uses the OAuth2 protocol for authentication.

Obtaining app credentials

  • Create your app via the app dashboard
  • Obtain an API Key and API Secret by entering your application name and redirect URI

Using the ProductHuntClient class

Once you have your app credentials, you can pass them to the ProductHuntClient initializer. If your code is open source, make sure to remove the credentials to prevent others from using them. Environment variables can help with this.

The library will automatically obtain a client token upon initialization.

from ph_py import ProductHuntClient

client_id = YOUR_CLIENT_ID
client_secret = YOUR_CLIENT_SECRET
redirect_uri = "http://localhost:5000"

phc = ProductHuntClient(client_id, client_secret, redirect_uri)

# Example request
for post in phc.get_todays_posts():
    print(post.tagline)

User Authorization

In order to authenticate using OAuth2, the user must authorize your app. To accomplish this flow, we've built some nice wrappers!

import webbrowser
from ph_py import ProductHuntClient

client_id = YOUR_CLIENT_ID
client_secret = YOUR_CLIENT_SECRET
redirect_uri = "http://localhost:5000"
phc = ProductHuntClient(client_id, client_secret, redirect_uri)

webbrowser.open(phc.build_authorize_url())
code = Input("What is the code? ") # Python 3x
#code = raw_Input("What is the code? ") # Python 2x

# Sets user auth
phc.oauth_user_token(code)

user_details = phc.get_current_user_details()
print(user_details.email)

Note: if you have a developer token, you can optionally initialize with it as well (skipping authorization step).

from ph_py import ProductHuntClient

client_id = YOUR_CLIENT_ID
client_secret = YOUR_CLIENT_SECRET
redirect_uri = "http://localhost:5000"
dev_token = YOUR_DEV_TOKEN

phc = ProductHuntClient(client_id, client_secret, redirect_uri, dev_token)

user_details = phc.get_current_user_details()
print(user_details.email)

Context

context is passed around in many of the ProductHuntClient functions as an optional parameter. The context may be either a "client" or "user". This specifies from which context the request should be made. The default is "client", except for endpoints take actions on or about a specific user.

Error Handling

ProductHuntError is the general error handler with access to the error message and status code:

try
    ...
except ProductHuntError as e
    print(e.error_message)
    print(e.status_code)

Posts

  • Today's posts

    Note: comments, votes, and related links only available when requesting a specific post)

    • Input:
      • Optional: context
    get_todays_posts(context="client")
    • Output:
  • Previous day's posts

    • Input:
      • Required: days_ago (specify how many days ago, e.g. yesterday => 1)
      • Optional: context
    get_previous_days_posts(days_ago, context="client")
    • Output:
  • Specific day's posts

    • Input:
      • Required: day (date in format of "YYYY-MM-DD")
      • Optional: context
    get_specific_days_posts(day, context="client")
  • Details of a post

    • Input:
      • Required: post_id
      • Optional: context
    get_details_of_post(post_id, context="client")
  • Create a post

    • Input:
      • Required: url
      • Required: name (name of the product)
      • Required: tagline (tagline of the product)
    create_a_post(url, name, tagline)

Notifications

  • Show Notifications
    • Input:
      • Optional: older (get only records older than the provided id)
      • Optional: newer (get only records newer than the provided id)
      • Optional: per_page (define the amount of records sent per call, max 100)
      • Optional: order (define the order you want to receive the records, does not affect older/newer behavior)
    show_notifications(older=None, newer=None, per_page=100, order=None)
  • Clear Notifications
    clear_notifications():

User

  • Get Users
    • Input:
      • Optional: older (get only records older than the provided id)
      • Optional: newer (get only records newer than the provided id)
      • Optional: per_page (define the amount of records sent per call, max 100)
      • Optional: order (define the order you want to receive the records, does not affect older/newer behavior)
      • Optional: context
    get_users(older=None, newer=None, per_page=100, order=None, context="client")
    • Output:
  • Get User
    • Input:
      • Required: username
      • Optional: context
    get_user(username, context="client"):

Post Votes

  • Vote for a Post
    • Input:
      • Required: post_id
    create_vote(post_id)
  • Delete a Vote
    • Input:
      • Required: post_id
    delete_vote(post_id)
  • Delete a Vote
    • Input:
      • Required: post_id
    delete_vote(post_id)
  • See all votes for a Post
    • Input:
      • Required: post_id
      • Optional: older (get only records older than the provided id)
      • Optional: newer (get only records newer than the provided id)
      • Optional: per_page (define the amount of records sent per call, max 100)
      • Optional: order (define the order you want to receive the records, does not affect older/newer behavior)
      • Optional: context
    get_post_votes(post_id, older=None, newer=None, per_page=100, order=None, context="client"):
    • Output:
  • See all of a user's Votes
    • Input:
      • Required: user_id
      • Optional: older (get only records older than the provided id)
      • Optional: newer (get only records newer than the provided id)
      • Optional: per_page (define the amount of records sent per call, max 100)
      • Optional: order (define the order you want to receive the records, does not affect older/newer behavior)
      • Optional: context
    get_user_votes(user_id, older=None, newer=None, per_page=100, order=None, context="client"):
    • Output:

Comments

  • Fetch a Post's Comments
    • Input:
      • Required: post_id
      • Optional: older (get only records older than the provided id)
      • Optional: newer (get only records newer than the provided id)
      • Optional: per_page (define the amount of records sent per call, max 100)
      • Optional: order (define the order you want to receive the records, does not affect older/newer behavior)
      • Optional: context
    get_comments(post_id, older=None, newer=None, per_page=100, order=None, context="client"):
  • Create a Comment (or comment reply)
    • Input:
      • Required: body
      • Required: post_id
      • Optional: parent_comment_id
    create_comment(body, post_id, parent_comment_id=None):
  • Update Comment
    • Input:
      • Required: body
      • Required: comment_id
    update_comment(body, comment_id):

Related-Links

  • Create a Related-Link
    • Input:
      • Required: post_id
      • Required: url
      • Optional: title
    create_related_link(post_id, url, title=None):
  • Update a Related-Link
    • Input:
      • Required: post_id
      • Required: related_link_id
      • Required: title
    update_related_link(post_id, related_link_id, title):
  • Delete Related-Link
    • Input:
      • Required: body
      • Required: related_link_id
    delete_related_link(post_id, related_link_id):