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
Asked By: TheDataGuy

||

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.

Answered By: LeGEC

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.

Answered By: TheDataGuy
    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)
Answered By: ben othman zied
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.