Search code examples
pythongithubpygithub

What's wrong with this Python function to upload file to github?


I have the following Python function to upload a file to github repository.

def upload_to_github(github_token: str,
                     source_file: str, destination_folder: str,
                     github_repo: str, git_branch: str) -> None:
    """
    Uploads a file to a GitHub Pages repository using the PyGithub library.
    Parameters:
        github_token: Github token for authentication
        source_file: The path of the local file to be uploaded
        destination_folder: The path of the folder in the GitHub repository where the file will be uploaded
        github_repo: The name of the GitHub repository
        git_branch: The name of the branch in the GitHub repository
    """
    from github import Github

    # Create a Github instance using the username and password
    g = Github(github_token)
    # Get the repository object
    repo = g.get_user().get_repo(github_repo)
    # Get the branch object
    branch = repo.get_branch(git_branch)
    # Read the source file as binary data
    with open(source_file, "rb") as f:
        content = f.read()
    # Create the path of the file in the GitHub repository
    path = destination_folder + "/" + source_file.split("/")[-1]
    # Create or update the file in the GitHub repository
    repo.create_file(path, "Upload file", content, branch=branch.name)

The file can be successfully uploaded the first time. If I upload the same file again, I get the error message github.GithubException.GithubException: 422 {"message": "Invalid request.\n\n\"sha\" wasn't supplied.", "documentation_url": "https://docs.github.com/rest/repos/contents#create-or-update-file-contents"}

Why does it work only the first time? It seems a new file can be uploaded but once uploaded, it cannot be updated.


Solution

  • I will answer my own question. It has been tested to work. The difference is in providing sha for file updates

    def upload_to_github(github_token: str,
                         source_file: str, destination_folder: str,
                         github_repo: str, git_branch: str) -> None:
        """
        Uploads a file to a GitHub Pages repository using the PyGithub library.
        Parameters:
            github_token: Github token for authentication
            source_file: The path of the local file to be uploaded
            destination_folder: The path of the folder in the GitHub repository where the file will be uploaded
            github_repo: The name of the GitHub repository
            git_branch: The name of the branch in the GitHub repository
        """
        from github import Github
    
        # Create a Github instance using token
        g = Github(github_token)
        # Get the repository object
        repo = g.get_user().get_repo(github_repo)
        # Get the branch object
        branch = repo.get_branch(git_branch)
        # Create the path of the file in the GitHub repository
        path = destination_folder + "/" + source_file.split("/")[-1]
        # Create or update the file in the GitHub repository
        try:
            # Get the existing file details if it exists
            existing_file = repo.get_contents(path, ref=branch.name)
            # Update the file
            repo.update_file(path, "Update file", open(source_file, 'rb').read(), existing_file.sha,
                             branch=branch.name)
            print(f"File '{path}' updated successfully.")
        except Exception as e:
            # If the file does not exist, create it
            repo.create_file(path, "Upload file", open(source_file, 'rb').read(), branch=branch.name)
            print(f"File '{path}' created successfully.")