Skip to content

Instantly share code, notes, and snippets.

@ruanbekker
Created March 10, 2024 15:54
Show Gist options
  • Save ruanbekker/946dac18fca09c25a5c09bcc63c70c92 to your computer and use it in GitHub Desktop.
Save ruanbekker/946dac18fca09c25a5c09bcc63c70c92 to your computer and use it in GitHub Desktop.
How to Create Github Discussions via GraphQL API using Python Requests
"""
This script uses the GraphQL API to create discussions programatically using Python and Requests.
"""
import os
import time
import json
import requests
def url_builder(path):
response = f'https://{domain_name}/{path}'
return response
def list_mdx_files(repo, path):
mdx_files = []
contents = repo.get_contents(path)
for content_item in contents:
if content_item.type == "dir":
mdx_files += list_mdx_files(repo, content_item.path)
elif content_item.path.endswith('.mdx'):
mdx_files.append(content_item.path)
return mdx_files
def create_github_discussion(token, repo_owner, repo_name, category_id, title, body):
"""
Create a discussion in a GitHub repository using the GraphQL API.
Parameters:
- token (str): Personal Access Token (PAT) with permissions to access the repository.
- repo_owner (str): Owner of the repository (username or organization).
- repo_name (str): Name of the repository.
- category_id (str): The ID of the discussion category.
- title (str): Title of the discussion.
- body (str): Body content of the discussion.
"""
# GraphQL endpoint
url = "https://api.github.com/graphql"
# GraphQL query. Note: This is a mutation, not a query.
query = """
mutation($input: CreateDiscussionInput!) {
createDiscussion(input: $input) {
discussion {
url
}
}
}
"""
# Variables for the mutation
variables = {
"input": {
"repositoryId": get_repository_id(token, repo_owner, repo_name),
"categoryId": category_id,
"title": title,
"body": body
}
}
# Request headers
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
# Make the POST request
response = requests.post(url, headers=headers, data=json.dumps({"query": query, "variables": variables}))
if response.status_code == 200:
response_data = response.json()
if 'errors' in response_data:
print("Failed to create discussion:", response_data['errors'])
else:
print("Discussion created successfully. URL:", response_data['data']['createDiscussion']['discussion']['url'])
else:
print(f"Failed to create discussion. Status code: {response.status_code}, Response: {response.text}")
def get_repository_id(token, owner, name):
"""
Get the GitHub repository ID using the GraphQL API.
Parameters:
- token (str): Personal Access Token (PAT).
- owner (str): Owner of the repository.
- name (str): Name of the repository.
"""
url = "https://api.github.com/graphql"
query = """
query($name: String!, $owner: String!) {
repository(name: $name, owner: $owner) {
id
}
}
"""
variables = {"name": name, "owner": owner}
headers = {"Authorization": f"Bearer {token}"}
response = requests.post(url, json={'query': query, 'variables': variables}, headers=headers)
if response.status_code == 200:
return response.json()['data']['repository']['id']
else:
print(f"Error fetching repository ID. Status code: {response.status_code}, Response: {response.text}")
return None
def fetch_discussion_categories(token, repo_owner, repo_name):
"""
Fetch discussion categories for a repository using the GraphQL API.
Parameters:
- token (str): Personal Access Token (PAT) with permissions to access the repository.
- repo_owner (str): Owner of the repository (username or organization).
- repo_name (str): Name of the repository.
"""
url = "https://api.github.com/graphql"
query = """
query RepositoryDiscussionCategories($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
discussionCategories(first: 10) {
nodes {
id
name
}
}
}
}
"""
variables = {"owner": repo_owner, "name": repo_name}
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
response = requests.post(url, headers=headers, data=json.dumps({"query": query, "variables": variables}))
if response.status_code == 200:
categories = response.json()['data']['repository']['discussionCategories']['nodes']
for category in categories:
print(f"Category ID: {category['id']}, Name: {category['name']}")
else:
print(f"Failed to fetch discussion categories. Status code: {response.status_code}, Response: {response.text}")
# pat that can write to discussions
token = os.getenv('GITHUB_TOKEN')
repo_owner = os.getenv('GITHUB_REPO_OWNER') # "ruanbekker"
repo_name = os.getenv('GITHUB_REPO_NAME') # "blog-giscus"
category_id = os.getenv('GITHUB_DISCUSSIONS_CATEGORY_ID')
team_slug = None
# use this to scan the category ids
# fetch_discussion_categories(token, repo_owner, repo_name)
discussion_topics_to_be_created = [
{
'title': 'blog/2024/01/01/my-discussion-topic',
'body': 'Discussion for https://my.domain/blog/2024/01/01/my-discussion-topic'
}
]
for each_topic in discussion_topics_to_be_created:
discussion_title = each_topic['title']
discussion_body = each_topic['body']
print(f"Title: {discussion_title}, Body: {discussion_body}")
create_github_discussion(token, repo_owner, repo_name, category_id, discussion_title, discussion_body)
time.sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment