코드
import yaml
import subprocess
import sys
import os
import requests
def load_config(config_file):
with open(config_file, 'r') as file:
return yaml.safe_load(file)
def load_requirements(requirements_file):
with open(requirements_file, 'r') as file:
return [line.strip() for line in file.readlines() if line.strip()]
def get_platform_string(os_name, architecture):
platform_mapping = {
'windows': {
'amd64': 'win_amd64',
'arm': 'win_arm64',
},
'linux': {
'amd64': 'manylinux2014_x86_64',
'arm': 'manylinux2014_aarch64',
},
'macosx': {
'amd64': 'macosx_10_9_x86_64',
'arm': 'macosx_11_0_arm64',
}
}
return platform_mapping.get(os_name.lower(), {}).get(architecture.lower(), None)
def get_all_versions(package_name):
url = f"https://pypi.org/pypi/{package_name}/json"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return list(data['releases'].keys())
else:
print(f"Failed to fetch versions for package {package_name}")
return []
def create_pip_download_cmd(package, version, config):
cmd = [sys.executable, '-m', 'pip', 'download', '--prefer-binary', '--no-deps', '--no-build-isolation']
if 'repository' in config:
cmd += ['-i', config['repository']]
if 'python_version' in config:
cmd += ['--python-version', str(config['python_version'])]
platform_string = get_platform_string(config.get('os', ''), config.get('architecture', ''))
if platform_string:
cmd += ['--platform', platform_string]
else:
print(f"Unsupported OS or architecture: {config.get('os')}, {config.get('architecture')}")
return None
if 'download_path' in config:
cmd += ['-d', config['download_path']]
if version:
package_with_version = f"{package}=={version}"
else:
package_with_version = package
cmd.append(package_with_version)
return cmd
def download_package(package_line, config):
try:
ignore_versions = config.get('ignore_versions', False)
if '==' in package_line:
package_name, specified_version = package_line.split('==', 1)
else:
package_name = package_line
specified_version = None
if ignore_versions:
all_versions = get_all_versions(package_name)
if not all_versions:
print(f"No versions found for {package_name}")
return
for version in all_versions:
print(f"Downloading {package_name}=={version}")
cmd = create_pip_download_cmd(package_name, version, config)
if cmd:
result = subprocess.run(cmd)
if result.returncode == 0:
print(f"Downloaded {package_name}=={version}")
else:
print(f"Failed to download {package_name}=={version}. Skipping...")
else:
package_with_version = package_line
cmd = create_pip_download_cmd(package_with_version, None, config)
if cmd:
subprocess.run(cmd, check=True)
print(f"Downloaded {package_with_version}")
except subprocess.CalledProcessError:
print(f"Failed to download {package_line}. Skipping...")
def ensure_download_path(config):
download_path = config.get('download_path', './downloads')
if not os.path.exists(download_path):
os.makedirs(download_path)
print(f"Created download path: {download_path}")
def main():
config_file = 'config.yaml'
requirements_file = 'requirements.txt'
config = load_config(config_file)
ensure_download_path(config)
packages = load_requirements(requirements_file)
for package_line in packages:
download_package(package_line, config)
if __name__ == "__main__":
main()
설정파일 예시(config.yaml)
repository: https://pypi.org/simple
python_version: 3.8
os: windows # windows or linux
architecture: amd64 # amd64 or arm
download_path: ./downloads # 패키지 다운로드 경로
ignore_versions: true # true시 모든 버전 설치, false시 지정 버전 설치(지정 버전 없으면 최신 버전)
패키지 리스트 예시(requirements.txt)
tqdm==버전
pyyaml
Deprecated
import yaml
import subprocess
import sys
import os
def load_config(config_file):
with open(config_file, 'r') as file:
return yaml.safe_load(file)
def load_requirements(requirements_file):
with open(requirements_file, 'r') as file:
return [line.strip() for line in file.readlines() if line.strip()]
def get_platform_string(os_name, architecture):
platform_mapping = {
'windows': {
'amd64': 'win_amd64',
'arm': 'win_arm64',
},
'linux': {
'amd64': 'manylinux2014_x86_64',
'arm': 'manylinux2014_aarch64',
},
'macosx': {
'amd64': 'macosx_10_9_x86_64',
'arm': 'macosx_11_0_arm64',
}
}
return platform_mapping.get(os_name.lower(), {}).get(architecture.lower(), None)
def create_pip_download_cmd(package, config):
cmd = [sys.executable, '-m', 'pip', 'download', '--prefer-binary', '--no-deps']
if 'repository' in config:
cmd += ['-i', config['repository']]
if 'python_version' in config:
cmd += ['--python-version', str(config['python_version'])]
platform_string = get_platform_string(config.get('os', ''), config.get('architecture', ''))
if platform_string:
cmd += ['--platform', platform_string]
else:
print(f"Unsupported OS or architecture: {config.get('os')}, {config.get('architecture')}")
return None
if 'download_path' in config:
cmd += ['-d', config['download_path']]
cmd.append(package)
return cmd
def download_package(package, config):
try:
cmd = create_pip_download_cmd(package, config)
if cmd is None:
print(f"Skipping {package} due to unsupported platform or architecture.")
return
print(f"Downloading {package} with command: {' '.join(cmd)}")
subprocess.run(cmd, check=True)
print(f"{package} downloaded successfully.")
except subprocess.CalledProcessError:
print(f"Failed to download {package}. Skipping...")
def ensure_download_path(config):
download_path = config.get('download_path', './downloads')
if not os.path.exists(download_path):
os.makedirs(download_path)
print(f"Created download path: {download_path}")
def main():
config_file = 'config.yaml'
requirements_file = 'requirements.txt'
config = load_config(config_file)
ensure_download_path(config)
packages = load_requirements(requirements_file)
for package in packages:
download_package(package, config)
if __name__ == "__main__":
main()