Python – Upload files directly to github using PyGithub
Question:
I have a public repo and want to upload files to that repo using python (PyGithub library).
I referred the below code from SO:
import base64
from github import Github
from github import InputGitTreeElement
user = "GithubUsername"
password = "*********"
g = Github(user,password)
repo = g.get_user().get_repo('git-test')
file_list = [
'C:\UsersjesseDropboxSwell-Forecastgit-testindex.html',
'C:\UsersjesseDropboxSwell-Forecastgit-testmargin_table.html'
]
file_names = [
'index.html',
'margin_table.html'
]
commit_message = 'python update 2'
master_ref = repo.get_git_ref('heads/master')
master_sha = master_ref.object.sha
base_tree = repo.get_git_tree(master_sha)
element_list = list()
for i, entry in enumerate(file_list):
with open(entry) as input_file:
data = input_file.read()
if entry.endswith('.png'):
data = base64.b64encode(data)
element = InputGitTreeElement(file_names[i], '100644', 'blob', data)
element_list.append(element)
tree = repo.create_git_tree(element_list, base_tree)
parent = repo.get_git_commit(master_sha)
commit = repo.create_git_commit(commit_message, tree, [parent])
master_ref.edit(commit.sha)
But I don’t want to clone the repo, add files then commit. Instead, just directly upload the files.
Is there any method/sample code that I can use for direct upload?
EG:
Current Repo:
file1.txt
file2.txt
Upload new files:
file1.txt
file2.txt
myfolder/
|_ file3.txt
|_ file4.txt
Answers:
(note : not tested)
I think the code you linked does what you want.
This gist, written in ruby, shows a very similar scenario, but has the additional benefit of explicitly naming the API routes queried for each action (create_tree
, create_commit
, …)
Check the docs for the PyGithub library : the methods are most probably wrappers around the same API calls.
I have created a small set of code for this. And it worked. Sharing it here, so others can get benefit from it.
Sample code:
This code will upload a file/replace the existing file.
Local file path: /tmp/file.txt
Github folder name: folder1/
from github import Github
g = Github("username", "password")
repo = g.get_user().get_repo(GITHUB_REPO)
all_files = []
contents = repo.get_contents("")
while contents:
file_content = contents.pop(0)
if file_content.type == "dir":
contents.extend(repo.get_contents(file_content.path))
else:
file = file_content
all_files.append(str(file).replace('ContentFile(path="','').replace('")',''))
with open('/tmp/file.txt', 'r') as file:
content = file.read()
# Upload to github
git_prefix = 'folder1/'
git_file = git_prefix + 'file.txt'
if git_file in all_files:
contents = repo.get_contents(git_file)
repo.update_file(contents.path, "committing files", content, contents.sha, branch="master")
print(git_file + ' UPDATED')
else:
repo.create_file(git_file, "committing files", content, branch="master")
print(git_file + ' CREATED')
This question is also related to this.
from github import Github
ACCESS_TOKEN = ""
GITHUB_REPO = "data_store"
GIT_BRANCH = "main"
INTERNAL_FILE = "local/data/folder/file1.csv"
FOLDER_EMPL_IN_GIT = "serialized/file.txt"
def add_or_update_in_git(access_tocken, github_repo, git_branch, initial_file, folder_empl_in_git):
g = Github(access_tocken)
repo = g.get_user().get_repo(github_repo)
all_files = []
contents = repo.get_contents("")
while contents:
file_content = contents.pop(0)
if file_content.type == "dir":
contents.extend(repo.get_contents(file_content.path))
else:
file = file_content
all_files.append(str(file).replace('ContentFile(path="', '').replace('")', ''))
with open(initial_file, 'r') as file:
content = file.read()
# Upload to github
if folder_empl_in_git in all_files:
contents = repo.get_contents(folder_empl_in_git)
repo.update_file(contents.path, "committing files", content, contents.sha, branch=git_branch)
return folder_empl_in_git + ' UPDATED'
else:
repo.create_file(folder_empl_in_git, "committing files", content, branch=git_branch)
return folder_empl_in_git + ' CREATED'
add_or_update_in_git(ACCESS_TOKEN, GITHUB_REPO, GIT_BRANCH, INTERNAL_FILE, FOLDER_EMPL_IN_GIT)
I have a public repo and want to upload files to that repo using python (PyGithub library).
I referred the below code from SO:
import base64
from github import Github
from github import InputGitTreeElement
user = "GithubUsername"
password = "*********"
g = Github(user,password)
repo = g.get_user().get_repo('git-test')
file_list = [
'C:\UsersjesseDropboxSwell-Forecastgit-testindex.html',
'C:\UsersjesseDropboxSwell-Forecastgit-testmargin_table.html'
]
file_names = [
'index.html',
'margin_table.html'
]
commit_message = 'python update 2'
master_ref = repo.get_git_ref('heads/master')
master_sha = master_ref.object.sha
base_tree = repo.get_git_tree(master_sha)
element_list = list()
for i, entry in enumerate(file_list):
with open(entry) as input_file:
data = input_file.read()
if entry.endswith('.png'):
data = base64.b64encode(data)
element = InputGitTreeElement(file_names[i], '100644', 'blob', data)
element_list.append(element)
tree = repo.create_git_tree(element_list, base_tree)
parent = repo.get_git_commit(master_sha)
commit = repo.create_git_commit(commit_message, tree, [parent])
master_ref.edit(commit.sha)
But I don’t want to clone the repo, add files then commit. Instead, just directly upload the files.
Is there any method/sample code that I can use for direct upload?
EG:
Current Repo:
file1.txt
file2.txt
Upload new files:
file1.txt
file2.txt
myfolder/
|_ file3.txt
|_ file4.txt
(note : not tested)
I think the code you linked does what you want.
This gist, written in ruby, shows a very similar scenario, but has the additional benefit of explicitly naming the API routes queried for each action (create_tree
, create_commit
, …)
Check the docs for the PyGithub library : the methods are most probably wrappers around the same API calls.
I have created a small set of code for this. And it worked. Sharing it here, so others can get benefit from it.
Sample code:
This code will upload a file/replace the existing file.
Local file path: /tmp/file.txt
Github folder name: folder1/
from github import Github
g = Github("username", "password")
repo = g.get_user().get_repo(GITHUB_REPO)
all_files = []
contents = repo.get_contents("")
while contents:
file_content = contents.pop(0)
if file_content.type == "dir":
contents.extend(repo.get_contents(file_content.path))
else:
file = file_content
all_files.append(str(file).replace('ContentFile(path="','').replace('")',''))
with open('/tmp/file.txt', 'r') as file:
content = file.read()
# Upload to github
git_prefix = 'folder1/'
git_file = git_prefix + 'file.txt'
if git_file in all_files:
contents = repo.get_contents(git_file)
repo.update_file(contents.path, "committing files", content, contents.sha, branch="master")
print(git_file + ' UPDATED')
else:
repo.create_file(git_file, "committing files", content, branch="master")
print(git_file + ' CREATED')
This question is also related to this.
from github import Github
ACCESS_TOKEN = ""
GITHUB_REPO = "data_store"
GIT_BRANCH = "main"
INTERNAL_FILE = "local/data/folder/file1.csv"
FOLDER_EMPL_IN_GIT = "serialized/file.txt"
def add_or_update_in_git(access_tocken, github_repo, git_branch, initial_file, folder_empl_in_git):
g = Github(access_tocken)
repo = g.get_user().get_repo(github_repo)
all_files = []
contents = repo.get_contents("")
while contents:
file_content = contents.pop(0)
if file_content.type == "dir":
contents.extend(repo.get_contents(file_content.path))
else:
file = file_content
all_files.append(str(file).replace('ContentFile(path="', '').replace('")', ''))
with open(initial_file, 'r') as file:
content = file.read()
# Upload to github
if folder_empl_in_git in all_files:
contents = repo.get_contents(folder_empl_in_git)
repo.update_file(contents.path, "committing files", content, contents.sha, branch=git_branch)
return folder_empl_in_git + ' UPDATED'
else:
repo.create_file(folder_empl_in_git, "committing files", content, branch=git_branch)
return folder_empl_in_git + ' CREATED'
add_or_update_in_git(ACCESS_TOKEN, GITHUB_REPO, GIT_BRANCH, INTERNAL_FILE, FOLDER_EMPL_IN_GIT)