#python #git #github
#python #git #github
Вопрос:
Используя PyGithub API, я пытаюсь извлечь все содержимое из определенной папки из определенной ветки репозитория, размещенного на Github. Я не могу поделиться фактическим репозиторием или спецификой данных, но код, который я использую, таков:
import github
import json
import requests
import base64
from collections import namedtuple
Package = namedtuple('Package', 'name version')
# Parameters
gh_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
header = {"Authorization": f"token {gh_token}"}
gh_hostname = 'devtopia.xxx.com'
gh = github.Github(base_url=f'https://{gh_hostname}/api/v3', login_or_token = gh_token)
repo_name = "xxxxxxxxx/SupportFiles"
conda_meta = "xxxxxxx/bin/Python/envs/xxxxxx-xx/conda-meta"
repo = gh.get_repo(repo_name)
def parse_conda_meta(branch):
package_list = []
meta_contents = repo.get_contents(conda_meta, ref=branch) #<< Returns less files than expected for
# a specified branch "xxx/release/3.2.0",
# returns expected number of files for
# "master" branch.
for i, pkg in enumerate(meta_contents):
if ".json" in pkg.name: # filter for JSON files
print(i, pkg.name)
# Need to use GitHub Data API (REST) blobs instead of easier
# `github` with `pkg.decoded_content` here because that method
# only works with files <= 1MB whereas Data API allows for
# reading files <= 100MB.
resp = requests.get(f"https://devtopia.xxxx.com/api/v3/repos/xxxxxxxxx/SupportFiles/git/blobs/{pkg.sha}?ref={branch}", headers=header)
pkg_cont = json.loads(base64.b64decode(json.loads(resp.content)["content"]))
package_list.append(Package(pkg_cont['name'], pkg_cont['version']))
else:
print('>>', i, pkg.name)
return package_list
if __name__ == "__main__":
pkgs = parse_conda_meta("xxx/release/3.2.0")
print(pkgs)
print(len(pkgs))
По какой-то причине, в которой я не могу разобраться, я не получаю правильное количество возвращаемых файлов repo.get_contents(conda_meta, ref=branch)
. Для ветки, которую я указываю, когда эта ветка извлекается, я вижу 186 файлов в папке conda-meta. Однако repo.get_contents(conda_meta, ref=branch)
возвращает только 182, мне не хватает четырех файлов JSON.
Есть ли какие-то ограничения repo.get_contents
, о которых я не знаю? Я читал документ, но не могу найти ничего, что намекало бы на проблему, с которой я столкнулся. Есть один момент, когда он обрабатывает только файлы размером до 1 МБ, но я вижу возвращаемые файлы большего размера, чем этот (например, python равен 1.204МБ и возвращается в списке файлов). Я считаю, что это относится только к чтению содержимого файла более 1 МБ, с которым я справляюсь, используя GitHub Data API (REST) дальше по потоку. Я что-то делаю не так?
Спасибо за чтение, любая помощь в этом очень ценится!
Комментарии:
1. Я вижу, вы анонимизировали имя хоста, это для GitHub Enterprise? Если да, то какая версия?
2. Эй, я полагаю, что это нормально, чтобы поделиться, мы используем Devtopia , см. Обновленный исходный пост с именем хоста, не анонимизированным. Спасибо!
Ответ №1:
Обновление с решением!
Проблема:
После еще нескольких поисков я нашел причину проблемы. Это не связано с приведенным выше кодом или repo.get_contents(conda_meta, ref=branch)
конкретно. На самом деле это столкновение unix / windows, которое было ошибочно введено в наш репозиторий для этой конкретной ветки «xxx / release / 3.2.0», но отсутствует в других.
Итак, в чем была проблема? NTFS (и Windows в более широком смысле) по умолчанию не учитывает регистр, но Git из мира Unix и по умолчанию учитывает регистр
Мы непреднамеренно создали две папки для Python в каталоге bin conda_meta
path ( xxxxxx/bin/
), одну папку с именем «Python» и одну с именем «python» (обратите внимание на нижний регистр). При локальном извлечении репозитория отображается только папка «Python», содержащая все 168 файлов. Однако на GitHub путь с «Python» содержит 182 файла, в то время как путь с «python» содержит оставшиеся 4 файла.
Решение:
Решение состоит в том, чтобы добавить conda_meta_folders
параметр, который принимает список путей к parse_conda_meta
каждому каталогу и выполняет поиск в нем. Хотя может быть более простое решение, я изучаю, возможно ли сделать что-то подобное git config core.ignorecase true
с PyGithub API. Кто-нибудь знает, возможно ли, чтобы PyGithub соблюдал это или был настроен для этого?
Комментарии:
1.
core.ignorecase
это не настройка для управления Git, а скорее настройка для информирования Git. Он сообщает Git: Эй, если вы создаете Python/, а затем пишете python/foo.py , это закончится в Python/foo.py вместо этого. Если вы включите или выключите его, вы неправильно информируете Git: он настроен на основе того, как на самом деле ведет себя ваш компьютер (Git пробует несколько вещей при первом создании репозитория, чтобы выяснить, как ведет себя ваш компьютер).