6

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:\\Users\jesse\Dropbox\Swell-Forecast\git-test\index.html',
    'C:\\Users\jesse\Dropbox\Swell-Forecast\git-test\margin_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
2
  • GitPython seems simpler to use: stackoverflow.com/a/39620098/3936044 Commented Aug 15, 2020 at 15:24
  • @Mandera GitPython is a Python wrapper for git while PyGithub is a wrapper for Github API. To create a commit and push with GitPython one has to clone first and the OP wants to avoid this. Commented Aug 15, 2020 at 15:56

3 Answers 3

10

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.

Sign up to request clarification or add additional context in comments.

Comments

0

(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.

Comments

0
    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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.