initial commit

This commit is contained in:
Bacruru Sakaguchi
2025-09-12 17:10:13 +07:00
commit 9e5e214944
57 changed files with 1538 additions and 0 deletions

12
pythonapp/Env/Env.py Normal file
View File

@@ -0,0 +1,12 @@
class Env:
def __init__(self):
self.pip_path = ""
pass
def create(self):
raise NotImplemented
def install_pkgs(self, pkgs: list, repo: str = None, extra: str = None):
raise NotImplemented

View File

@@ -0,0 +1,120 @@
import os
import platform
import subprocess
import urllib.request
import zipfile
import tarfile
import re
from typing import List
try:
from .Env import Env
except ImportError:
from Env import Env
class StandalonePythonEnv(Env):
def __init__(self, path: str, version: str):
super().__init__()
self.version = version
self.path = path
self.python_path = self._get_python_executable_path()
self.pip_path = self._get_pip_executable_path()
def _get_platform_info(self):
system = platform.system().lower()
arch = platform.machine().lower()
if arch in ['x86_64', 'amd64']:
arch = 'amd64'
elif arch in ['i386', 'i686', 'x86']:
arch = 'win32' if system == 'windows' else 'x86'
return system, arch
def _get_python_executable_path(self):
system, _ = self._get_platform_info()
if system == 'windows':
return os.path.join(self.path, 'python.exe')
return os.path.join(self.path, 'bin', 'python3')
def _get_pip_executable_path(self):
system, _ = self._get_platform_info()
if system == 'windows':
return os.path.join(self.path, 'Scripts', 'pip.exe')
return os.path.join(self.path, 'bin', 'pip')
def _download_and_extract(self):
system, arch = self._get_platform_info()
base_url = 'https://www.python.org/ftp/python'
if system == 'windows':
url = f'{base_url}/{self.version}/python-{self.version}-embed-{arch}.zip'
extract_path = self.path
zip_path = os.path.join(self.path, 'python.zip')
os.makedirs(self.path, exist_ok=True)
urllib.request.urlretrieve(url, zip_path)
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(extract_path)
os.remove(zip_path)
elif system == 'linux':
url = f'{base_url}/{self.version}/Python-{self.version}.tgz'
tar_path = os.path.join(self.path, 'python.tgz')
os.makedirs(self.path, exist_ok=True)
urllib.request.urlretrieve(url, tar_path)
with tarfile.open(tar_path, 'r:gz') as tar_ref:
if hasattr(tarfile, 'data_filter'):
tar_ref.extractall(self.path, filter='data')
else:
tar_ref.extractall(self.path)
os.remove(tar_path)
# Компиляция Python из исходников
source_dir = os.path.join(self.path, f'Python-{self.version}')
subprocess.run([
'./configure', f'--prefix={self.path}',
'--enable-optimizations',
'--with-ensurepip=install'
], cwd=source_dir, check=True)
subprocess.run(['make', '-j8'], cwd=source_dir, check=True)
subprocess.run(['make', 'install'], cwd=source_dir, check=True)
import shutil
shutil.copy2(os.path.join(self.path, 'bin', 'pip3'), os.path.join(self.path, 'bin', 'pip'))
pass
else:
raise NotImplementedError(f"Unsupported platform: {system}")
def create(self):
self._download_and_extract()
def install_pkgs(self, pkgs: List[str], repo: str = None, extra :str = None):
command = [self.pip_path, 'install'] + pkgs
if repo: command.extend(["--index-url", repo])
if extra: command.extend(["--extra-index-url", extra])
subprocess.run(command, check=True)
@staticmethod
def get_available_versions():
import requests
from bs4 import BeautifulSoup
url = 'https://www.python.org/downloads/'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
versions = []
for release in soup.select('.release-list .release-number'):
version_text = release.text.strip().split()[-1]
if re.match(r'^\d+\.\d+\.\d+$', version_text):
versions.append(version_text)
return sorted(versions, key=lambda x: tuple(map(int, x.split('.'))), reverse=True)
if __name__ == '__main__':
env = StandalonePythonEnv(os.path.join('/tmp', 'build/test_standalone'), '3.12.9')
env.create()
env.install_pkgs(['requests', 'numpy'])

45
pythonapp/Env/Venv.py Normal file
View File

@@ -0,0 +1,45 @@
import subprocess
import os
from warnings import deprecated
try:
from .Env import Env
except ImportError:
from Env import Env
class Venv(Env):
def __init__(self, path: str, python='python3'):
super().__init__()
self.path = path
self.pip_path = os.path.join(self.path, "bin", "pip")
self.python = python
self._check_pip()
def _check_pip(self):
if not os.path.exists(self.pip_path): self.pip_path = os.path.join(self.path, "Scripts", "pip")
def create(self):
command = [self.python, '-m', 'venv', self.path]
subprocess.run(command)
def install_pkgs(self, pkgs: list, repo: str = None, extra :str = None):
self._check_pip()
command: list = [self.pip_path, "install"]
command.extend(pkgs)
if repo: command.extend(["--index-url", repo])
if extra: command.extend(["--extra-index-url", extra])
subprocess.run(command, check=True)
#@deprecated
def install_req(self, req_file: str, extra_index_url=None):
self._check_pip()
command = [self.pip_path, "install", "-r", req_file]
if extra_index_url: command.extend(["--extra-index-url", extra_index_url])
subprocess.run(command)
if __name__ == '__main__':
env = Venv(os.path.join('/tmp', 'build/test_venv'))
env.create()
env.install_pkgs(['requests', 'numpy'])

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.