Python上传GitHub文件函数首次成功后报422错误的问题
问题:上传GitHub文件首次成功,更新时报错"sha wasn't supplied"
我编写了如下Python函数,用于通过PyGithub库将文件上传至GitHub仓库:
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)
该文件首次上传可成功,但再次上传同一文件时,会报错:
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"}
为何仅首次上传有效,无法更新已上传的文件?
原因分析
GitHub的REST API要求更新已存在的文件时必须提供该文件当前的SHA值,这个机制是为了防止并发修改冲突——确保你是基于文件的最新版本进行更新。首次创建文件时,因为文件不存在,所以不需要SHA参数;但当文件已经存在时,必须传入该文件当前的SHA才能完成更新操作。你的代码只调用了create_file方法,没有处理文件已存在的情况,自然缺少SHA参数,导致报错。
修复后的代码
修改函数,先检查目标路径下的文件是否存在:如果存在,获取其SHA值,再调用create_file时传入该参数;如果不存在,直接创建即可。
def upload_to_github(github_token: str, source_file: str, destination_folder: str, github_repo: str, git_branch: str) -> None: """ Uploads or updates 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 from github.GithubException import UnknownObjectException # Initialize GitHub instance g = Github(github_token) repo = g.get_user().get_repo(github_repo) branch = repo.get_branch(git_branch) # Read local file content with open(source_file, "rb") as f: content = f.read() # Build target file path in repo file_name = source_file.split("/")[-1] path = f"{destination_folder}/{file_name}" # Check if file exists in repo to get SHA sha = None try: # Try to get the existing file existing_file = repo.get_contents(path, ref=branch.name) sha = existing_file.sha except UnknownObjectException: # File doesn't exist, no SHA needed pass # Create or update the file repo.create_file( path, "Upload/Update file", content, branch=branch.name, sha=sha # Pass SHA only if file exists )
说明
- 新增了
UnknownObjectException捕获:当文件不存在时,PyGithub会抛出这个异常,此时我们不需要设置SHA。 - 获取到已存在文件的SHA后,将其传入
create_file方法,GitHub会识别这是一个更新操作,而非创建操作。 - 修改了提交信息,更准确地反映操作类型。
内容的提问来源于stack exchange,提问作者user3848207
相关产品推荐
相关产品推荐

