initial commit
This commit is contained in:
53
pythonapp/Libs/ConfigDataClass.py
Normal file
53
pythonapp/Libs/ConfigDataClass.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import json
|
||||
import atexit
|
||||
from dataclasses import dataclass, asdict, fields
|
||||
from typing import Any, Dict
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@dataclass
|
||||
class Config:
|
||||
filename: str
|
||||
autosave: bool = False
|
||||
|
||||
def __post_init__(self):
|
||||
# Загружаем значения из файла при создании экземпляра
|
||||
self.load()
|
||||
|
||||
# Регистрируем автоматическое сохранение при завершении программы
|
||||
if self.autosave:
|
||||
atexit.register(self.save)
|
||||
|
||||
def load(self) -> None:
|
||||
"""Загружает значения полей из файла"""
|
||||
try:
|
||||
if Path(self.filename).exists():
|
||||
with open(self.filename, 'r') as f:
|
||||
data = json.load(f)
|
||||
for field in fields(self):
|
||||
if field.name in data and field.name != 'filename':
|
||||
setattr(self, field.name, data[field.name])
|
||||
except Exception as e:
|
||||
print(f"Error loading config: {e}")
|
||||
|
||||
def save(self) -> None:
|
||||
"""Сохраняет текущие значения полей в файл"""
|
||||
try:
|
||||
# Преобразуем объект в словарь, исключая поле filename
|
||||
data = asdict(self)
|
||||
data.pop('filename', None)
|
||||
|
||||
# Создаем директорию, если она не существует
|
||||
Path(self.filename).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Сохраняем в файл с кастомным сериализатором для Path объектов
|
||||
with open(self.filename, 'w') as f:
|
||||
json.dump(data, f, indent=4, default=self._json_serializer)
|
||||
except Exception as e:
|
||||
print(f"Error saving config: {e}")
|
||||
|
||||
def _json_serializer(self, obj: Any) -> Any:
|
||||
"""Кастомный сериализатор для объектов, которые не могут быть сериализованы по умолчанию"""
|
||||
if isinstance(obj, Path):
|
||||
return str(obj)
|
||||
raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")
|
||||
0
pythonapp/Libs/__init__.py
Normal file
0
pythonapp/Libs/__init__.py
Normal file
BIN
pythonapp/Libs/__pycache__/ConfigDataClass.cpython-313.pyc
Normal file
BIN
pythonapp/Libs/__pycache__/ConfigDataClass.cpython-313.pyc
Normal file
Binary file not shown.
BIN
pythonapp/Libs/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
pythonapp/Libs/__pycache__/__init__.cpython-313.pyc
Normal file
Binary file not shown.
BIN
pythonapp/Libs/__pycache__/git.cpython-313.pyc
Normal file
BIN
pythonapp/Libs/__pycache__/git.cpython-313.pyc
Normal file
Binary file not shown.
BIN
pythonapp/Libs/__pycache__/pip_api.cpython-313.pyc
Normal file
BIN
pythonapp/Libs/__pycache__/pip_api.cpython-313.pyc
Normal file
Binary file not shown.
54
pythonapp/Libs/getpytorch.py
Normal file
54
pythonapp/Libs/getpytorch.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from typing import List
|
||||
from dataclasses import dataclass
|
||||
from .pip_api import pip_api
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class PyTorchInfo:
|
||||
"""Датакласс для хранения информации о версиях PyTorch компонентов"""
|
||||
torch: List[str]
|
||||
torchvision: List[str]
|
||||
torchaudio: List[str]
|
||||
|
||||
|
||||
class getpytorch:
|
||||
"""Класс для получения версий компонентов PyTorch"""
|
||||
BASE_URL = "https://download.pytorch.org/whl/"
|
||||
|
||||
def __init__(self, base_url: str = None):
|
||||
self.base_url = base_url or self.BASE_URL
|
||||
|
||||
def get_versions(self, api: str) -> PyTorchInfo:
|
||||
"""Получает версии всех компонентов PyTorch для указанного API"""
|
||||
base_url = f"{self.base_url.rstrip('/')}/{api}"
|
||||
|
||||
return PyTorchInfo(
|
||||
torch=self.get_torch_versions(api),
|
||||
torchvision=self.get_torchvision_versions(api),
|
||||
torchaudio=self.get_torchaudio_versions(api),
|
||||
)
|
||||
|
||||
def get_torch_versions(self, api: str) -> List[str]:
|
||||
"""Получает версии torch"""
|
||||
return pip_api.get_pkg_versions('torch', f"{self.base_url.rstrip('/')}/{api}")
|
||||
|
||||
def get_torchvision_versions(self, api: str) -> List[str]:
|
||||
"""Получает версии torchvision"""
|
||||
return pip_api.get_pkg_versions('torchvision', f"{self.base_url.rstrip('/')}/{api}")
|
||||
|
||||
def get_torchaudio_versions(self, api: str) -> List[str]:
|
||||
"""Получает версии torchaudio"""
|
||||
return pip_api.get_pkg_versions('torchaudio', f"{self.base_url.rstrip('/')}/{api}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Пример использования
|
||||
pytorch = getpytorch()
|
||||
|
||||
api = input("API version (cu121): ") or "cu121"
|
||||
versions = pytorch.get_versions(api)
|
||||
|
||||
print(f"Все версии PyTorch: {versions.torch}")
|
||||
print(f"Все версии torchvision: {versions.torchvision}")
|
||||
print(f"Все версии torchaudio: {versions.torchaudio}")
|
||||
10
pythonapp/Libs/git.py
Normal file
10
pythonapp/Libs/git.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import subprocess
|
||||
|
||||
|
||||
class git:
|
||||
@staticmethod
|
||||
def clone(url, output_path = None, git = 'git'):
|
||||
command = [git, 'clone', url]
|
||||
if output_path: command.append(output_path)
|
||||
result = subprocess.run(command)
|
||||
return result
|
||||
138
pythonapp/Libs/pip_api.py
Normal file
138
pythonapp/Libs/pip_api.py
Normal file
@@ -0,0 +1,138 @@
|
||||
import subprocess
|
||||
from typing import List, Optional
|
||||
import re
|
||||
import subprocess
|
||||
import shlex
|
||||
from typing import List, Optional, Dict, Any, Union
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class PipResult:
|
||||
"""Результат выполнения команды pip."""
|
||||
exit_code: int
|
||||
stdout: str
|
||||
stderr: str
|
||||
command: str
|
||||
success: bool
|
||||
|
||||
|
||||
class pip_api:
|
||||
@staticmethod
|
||||
def get_pkg_versions(package: str, index_url: Optional[str] = None) -> List[str]:
|
||||
# Формируем базовую команду
|
||||
command = [
|
||||
'python3', '-m', 'pip',
|
||||
'install',
|
||||
'--use-deprecated=legacy-resolver', # Для совместимости со старыми репозиториями
|
||||
'--dry-run',
|
||||
'--no-deps',
|
||||
f'{package}==0.0.0.0' # Специально несуществующая версия
|
||||
]
|
||||
|
||||
if index_url:
|
||||
command.extend(['--index-url', index_url])
|
||||
|
||||
# Запускаем процесс
|
||||
result = subprocess.run(
|
||||
command,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30 # Таймаут для избежания зависаний
|
||||
)
|
||||
|
||||
#print(result.stdout)
|
||||
#print(result.stderr)
|
||||
# Парсим вывод для получения версий
|
||||
if result.stderr:
|
||||
match = re.search(r'from versions: (.+?)\)', result.stderr)
|
||||
if match:
|
||||
versions = match.group(1).split(', ')
|
||||
return [v.strip() for v in versions if v.strip()]
|
||||
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def run_pip_install(
|
||||
pip_path: str,
|
||||
packages: List[str],
|
||||
index_url: Optional[str] = None,
|
||||
extra_index_urls: Optional[List[str]] = None,
|
||||
dry_run: bool = False
|
||||
) -> PipResult:
|
||||
"""
|
||||
Выполняет установку пакетов через pip с указанными параметрами.
|
||||
|
||||
Args:
|
||||
pip_path: Путь к исполняемому файлу pip
|
||||
packages: Список пакетов для установки
|
||||
index_url: Основной URL репозитория пакетов
|
||||
extra_index_urls: Дополнительные URLs репозиториев пакетов
|
||||
dry_run: Если True, команда только выводится, но не выполняется
|
||||
|
||||
Returns:
|
||||
PipResult: Объект с результатами выполнения команды
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: Если pip_path не существует
|
||||
ValueError: Если packages пуст
|
||||
"""
|
||||
# Проверка входных параметров
|
||||
if not packages:
|
||||
raise ValueError("Список пакетов не может быть пустым")
|
||||
|
||||
# Формирование команды
|
||||
command = [pip_path, "install"]
|
||||
|
||||
if dry_run:
|
||||
command.append('--dry-run')
|
||||
|
||||
# Добавление основного index-url
|
||||
if index_url:
|
||||
command.extend(["--index-url", index_url])
|
||||
|
||||
# Добавление дополнительных index-urls
|
||||
if extra_index_urls:
|
||||
for url in extra_index_urls:
|
||||
command.extend(["--extra-index-url", url])
|
||||
|
||||
# Добавление пакетов
|
||||
command.extend(packages)
|
||||
|
||||
# Преобразование команды в строку для вывода
|
||||
command_str = " ".join(shlex.quote(arg) for arg in command)
|
||||
|
||||
# Выполнение команды
|
||||
try:
|
||||
result = subprocess.run(
|
||||
command,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False # Не вызываем исключение при ненулевом коде возврата
|
||||
)
|
||||
|
||||
return PipResult(
|
||||
exit_code=result.returncode,
|
||||
stdout=result.stdout,
|
||||
stderr=result.stderr,
|
||||
command=command_str,
|
||||
success=result.returncode == 0
|
||||
)
|
||||
|
||||
except FileNotFoundError:
|
||||
raise FileNotFoundError(f"Файл pip не найден по пути: {pip_path}")
|
||||
except Exception as e:
|
||||
return PipResult(
|
||||
exit_code=-1,
|
||||
stdout="",
|
||||
stderr=str(e),
|
||||
command=command_str,
|
||||
success=False
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
versions = pip_api.get_pkg_versions("torch", "https://download.pytorch.org/whl/cu121")
|
||||
print(versions)
|
||||
Reference in New Issue
Block a user