package-guardian 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package_guardian-1.0.0/PKG-INFO +14 -0
- package_guardian-1.0.0/autopublish/__init__.py +0 -0
- package_guardian-1.0.0/autopublish/publishe1r.py +58 -0
- package_guardian-1.0.0/fasthardware/__init__.py +0 -0
- package_guardian-1.0.0/fasthardware/fasthardware.py +99 -0
- package_guardian-1.0.0/package_guardian/__init__.py +0 -0
- package_guardian-1.0.0/package_guardian/guardian.py +69 -0
- package_guardian-1.0.0/package_guardian.egg-info/PKG-INFO +14 -0
- package_guardian-1.0.0/package_guardian.egg-info/SOURCES.txt +11 -0
- package_guardian-1.0.0/package_guardian.egg-info/dependency_links.txt +1 -0
- package_guardian-1.0.0/package_guardian.egg-info/top_level.txt +3 -0
- package_guardian-1.0.0/setup.cfg +4 -0
- package_guardian-1.0.0/setup.py +15 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: package-guardian
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Intelligent missing package resolver with size detection
|
|
5
|
+
Author: WoongYo Choi
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
9
|
+
Requires-Python: >=3.8
|
|
10
|
+
Dynamic: author
|
|
11
|
+
Dynamic: classifier
|
|
12
|
+
Dynamic: license
|
|
13
|
+
Dynamic: requires-python
|
|
14
|
+
Dynamic: summary
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import subprocess
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def deploy():
|
|
7
|
+
"""
|
|
8
|
+
Automatically builds setup.py and deploys the package to PyPI using token authentication.
|
|
9
|
+
"""
|
|
10
|
+
print("\nπ [PyPI Auto-Publisher] Starting global deployment pipeline...")
|
|
11
|
+
|
|
12
|
+
# 1. Check for setup.py
|
|
13
|
+
if not os.path.exists("setup.py"):
|
|
14
|
+
print("β ERROR: 'setup.py' not found in the current directory.")
|
|
15
|
+
print("π‘ Action: Please navigate to the root directory of your project.")
|
|
16
|
+
return
|
|
17
|
+
|
|
18
|
+
# 2. Retrieve PyPI Token from Environment Variables
|
|
19
|
+
pypi_token = os.environ.get("PYPI_TOKEN")
|
|
20
|
+
if not pypi_token:
|
|
21
|
+
print("β ERROR: Environment variable 'PYPI_TOKEN' is missing.")
|
|
22
|
+
print("π‘ Action: Set your token in the terminal first:")
|
|
23
|
+
print(" Windows (PowerShell): $env:PYPI_TOKEN='pypi-your-token-here'")
|
|
24
|
+
print(" Linux/Mac (Bash) : export PYPI_TOKEN='pypi-your-token-here'")
|
|
25
|
+
return
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
# 3. Clean up previous build artifacts
|
|
29
|
+
print("\nπ§Ή [1/3] Cleaning up old build artifacts (dist/build)...")
|
|
30
|
+
if os.path.exists("dist"):
|
|
31
|
+
subprocess.run("rmdir /s /q dist" if os.name == "nt" else "rm -rf dist", shell=True)
|
|
32
|
+
if os.path.exists("build"):
|
|
33
|
+
subprocess.run("rmdir /s /q build" if os.name == "nt" else "rm -rf build", shell=True)
|
|
34
|
+
|
|
35
|
+
# 4. Build source distribution and wheel
|
|
36
|
+
print("\nπ¦ [2/3] Building source distribution and wheel archives...")
|
|
37
|
+
subprocess.run([sys.executable, "setup.py", "sdist", "bdist_wheel"], check=True)
|
|
38
|
+
|
|
39
|
+
# 5. Inject credentials and trigger Twine upload
|
|
40
|
+
print("\nπ₯ [3/3] Uploading packages to PyPI warehouse via Twine...")
|
|
41
|
+
|
|
42
|
+
# Inject API token into environment for secure non-interactive authentication
|
|
43
|
+
env_copy = os.environ.copy()
|
|
44
|
+
env_copy["TWINE_USERNAME"] = "__token__"
|
|
45
|
+
env_copy["TWINE_PASSWORD"] = pypi_token
|
|
46
|
+
|
|
47
|
+
# Execute twine upload bypass-mode
|
|
48
|
+
subprocess.run(["twine", "upload", "dist/*"], check=True, env=env_copy, shell=True)
|
|
49
|
+
|
|
50
|
+
print("\nπ [SUCCESS] Deployment completed successfully!")
|
|
51
|
+
print("π Your library has been published to the global Python ecosystem.")
|
|
52
|
+
|
|
53
|
+
except subprocess.CalledProcessError as e:
|
|
54
|
+
print(f"\nβ ERROR: Command execution failed during build/upload process.")
|
|
55
|
+
print(f"Details: {e}")
|
|
56
|
+
except Exception as e:
|
|
57
|
+
print(f"\nβ ERROR: Unexpected system error occurred.")
|
|
58
|
+
print(f"Details: {e}")
|
|
File without changes
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import gc
|
|
4
|
+
import ctypes
|
|
5
|
+
import multiprocessing
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class HardwareAccelerator:
|
|
9
|
+
def __init__(self):
|
|
10
|
+
self.device_status = "UNKNOWN"
|
|
11
|
+
self.cpu_cores = multiprocessing.cpu_count()
|
|
12
|
+
|
|
13
|
+
def speedup(self, enable_gc_tuning=True, force_device=None):
|
|
14
|
+
print("\n" + "=" * 60)
|
|
15
|
+
print("[HARDWARE SPEEDUP ENGAGED] engine activated...")
|
|
16
|
+
print("=" * 60)
|
|
17
|
+
|
|
18
|
+
# 1. νμ΄μ¬ λ΄μ₯ λ©λͺ¨λ¦¬ κ΄λ¦¬(GC) κ°μ νλ
|
|
19
|
+
if enable_gc_tuning:
|
|
20
|
+
gc.disable()
|
|
21
|
+
print(f"[GC TUNING] python's built-in garbage collector disabled.")
|
|
22
|
+
|
|
23
|
+
# 2. νλμ¨μ΄ νκ²½ μλ νμ λ° κ°μ λ°±μλ λ§€ν
|
|
24
|
+
detected_gpu = self._detect_gpu_hardware()
|
|
25
|
+
|
|
26
|
+
if force_device:
|
|
27
|
+
self.device_status = force_device
|
|
28
|
+
print(f"{force_device} mode activated.")
|
|
29
|
+
else:
|
|
30
|
+
self.device_status = detected_gpu
|
|
31
|
+
|
|
32
|
+
# 3. κ°μ§λ νλμ¨μ΄λ³ νΉν μ΅μ ν νκ²½ μ£Όμ
|
|
33
|
+
if self.device_status == "NVIDIA_CUDA":
|
|
34
|
+
self._engage_cuda_acceleration()
|
|
35
|
+
elif self.device_status == "INTEL_IGPU" or self.device_status == "OPENVINO":
|
|
36
|
+
self._engage_intel_acceleration()
|
|
37
|
+
else:
|
|
38
|
+
self._engage_cpu_vector_acceleration()
|
|
39
|
+
|
|
40
|
+
print(f"'{self.device_status}' acceleration mode is now active. Ready to unleash the full potential of your hardware!")
|
|
41
|
+
print("=" * 60 + "\n")
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
def _detect_gpu_hardware(self):
|
|
45
|
+
""" μμ€ν
νλμ¨μ΄λ₯Ό λ€μ΄λ νΈλ‘ μ€μΊνλ λ΄λΆ 맀컀λμ¦ """
|
|
46
|
+
# 1. NVIDIA CUDA κ°λ₯ μ¬λΆ 체ν¬
|
|
47
|
+
try:
|
|
48
|
+
import torch
|
|
49
|
+
if torch.cuda.is_available():
|
|
50
|
+
return "NVIDIA_CUDA"
|
|
51
|
+
except ImportError:
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
# 2. Intel OpenVINO κ°μ μ₯μΉ μ²΄ν¬
|
|
55
|
+
try:
|
|
56
|
+
import openvino as ov
|
|
57
|
+
core = ov.Core()
|
|
58
|
+
if "GPU" in core.available_devices:
|
|
59
|
+
return "INTEL_IGPU"
|
|
60
|
+
except ImportError:
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
return "PURE_CPU"
|
|
64
|
+
|
|
65
|
+
def _engage_cuda_acceleration(self):
|
|
66
|
+
""" NVIDIA μΈμ₯ κ·Έλν½ μΉ΄λκ° μμ λ VRAM μ μ‘ μλ λ° μ€λ λ μ΅μ ν """
|
|
67
|
+
print("NVIDIA CUDA acceleration activated.")
|
|
68
|
+
# λ΄λΆ νλ μμν¬ νλ νλκ·Έ μ€μ
|
|
69
|
+
os.environ["CUDA_MODULE_LOADING"] = "LAZY"
|
|
70
|
+
# OpenCVκ° λͺ
μμ μΌλ‘ CUDAλ₯Ό μΈ μ μλλ‘ νκ²½ λ§€ν (λΉλ νκ²½μ λ°λΌ μλ)
|
|
71
|
+
os.environ["OPENCV_CUDA_USE_NVTX"] = "1"
|
|
72
|
+
|
|
73
|
+
def _engage_intel_acceleration(self):
|
|
74
|
+
""" μΈν
λ΄μ₯ GPU λλ OpenVINO νμ΄νλΌμΈ μ΅μ ν λ μ΄ν΄μ μ£Όμ
"""
|
|
75
|
+
print("Intel iGPU / OpenVINO acceleration activated.")
|
|
76
|
+
# μΈν
νλμ¨μ΄ μ°λ£¨ν μ΅μ ν νλκ·Έ κ³ μ
|
|
77
|
+
os.environ["OV_FRONTEND_CACHE_ENABLE"] = "1"
|
|
78
|
+
|
|
79
|
+
def _engage_cpu_vector_acceleration(self):
|
|
80
|
+
""" GPUκ° μμ λ, CPUμ λͺ¨λ λ©ν°μ½μ΄λ₯Ό 100% μ₯μ΄μ§λ AVX2/OpenMP κ°μ λ°μΈλ© """
|
|
81
|
+
print(f"CPU vector acceleration activated. Utilizing all {self.cpu_cores} cores with AVX2/OpenMP optimizations.")
|
|
82
|
+
|
|
83
|
+
# MKL, OpenBLAS λ± νμ΄μ¬ λ΄λΆ νλ ¬ μ°μ° λΌμ΄λΈλ¬λ¦¬κ° CPU λ©ν°μ½μ΄λ₯Ό νλ‘ μ°λλ‘ κ°μ μΈν
|
|
84
|
+
threads_str = str(self.cpu_cores)
|
|
85
|
+
os.environ["OMP_NUM_THREADS"] = threads_str
|
|
86
|
+
os.environ["MKL_NUM_THREADS"] = threads_str
|
|
87
|
+
os.environ["OPENBLAS_NUM_THREADS"] = threads_str
|
|
88
|
+
os.environ["VECLIB_MAXIMUM_THREADS"] = threads_str
|
|
89
|
+
os.environ["NUMEXPR_NUM_THREADS"] = threads_str
|
|
90
|
+
|
|
91
|
+
def manual_sweep(self):
|
|
92
|
+
""" νλ‘κ·Έλ¨ λ£¨ν μμμ ν
κΉμ λ°©μ§νκΈ° μν΄ λ³΄μ€κ° μν λ μλμΌλ‘ λ©λͺ¨λ¦¬λ₯Ό μ΄κ³ μ μ²μνλ λ©μλ """
|
|
93
|
+
gc.collect()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# μΈλΆμμ κ·Έλ₯ "import hardware" ν λ°λ‘ μΈ μ μλλ‘ μ±κΈν€ μΈμ€ν΄μ€ 미리 μμ±
|
|
97
|
+
_accelerator = HardwareAccelerator()
|
|
98
|
+
speedup = _accelerator.speedup
|
|
99
|
+
manual_sweep = _accelerator.manual_sweep
|
|
File without changes
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import importlib.util
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
import urllib.request
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_package_size(package_name):
|
|
10
|
+
"""
|
|
11
|
+
Fetches the approximate download size of the package from the PyPI JSON API.
|
|
12
|
+
Returns size in MB as a string, or 'Unknown' if failed.
|
|
13
|
+
"""
|
|
14
|
+
try:
|
|
15
|
+
# Querying PyPI official JSON API
|
|
16
|
+
url = f"https://pypi.org/pypi/{package_name}/json"
|
|
17
|
+
with urllib.request.urlopen(url, timeout=3) as response:
|
|
18
|
+
data = json.loads(response.read().decode())
|
|
19
|
+
|
|
20
|
+
# Look at the latest release files to calculate size
|
|
21
|
+
latest_version = data["info"]["version"]
|
|
22
|
+
releases = data["releases"].get(latest_version, [])
|
|
23
|
+
|
|
24
|
+
if not releases:
|
|
25
|
+
return "Unknown"
|
|
26
|
+
|
|
27
|
+
# Sum up sizes of available wheels/tarballs
|
|
28
|
+
total_bytes = sum(file_info["size"] for file_info in releases if "size" in file_info)
|
|
29
|
+
size_mb = total_bytes / (1024 * 1024)
|
|
30
|
+
return f"{size_mb:.2f} MB"
|
|
31
|
+
except Exception:
|
|
32
|
+
return "Unknown"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def auto_require(package_name, pip_name=None):
|
|
36
|
+
"""
|
|
37
|
+
Checks if a package is installed. If not, prompts the user with size info and installs it.
|
|
38
|
+
"""
|
|
39
|
+
if pip_name is None:
|
|
40
|
+
pip_name = package_name
|
|
41
|
+
|
|
42
|
+
# Check if package is already installed
|
|
43
|
+
spec = importlib.util.find_spec(package_name)
|
|
44
|
+
if spec is not None:
|
|
45
|
+
return # Already installed, pass smoothly
|
|
46
|
+
|
|
47
|
+
print(f"\nπ [Package Guardian] Missing required package: '{pip_name}'")
|
|
48
|
+
print("β³ Fetching package metadata from PyPI...")
|
|
49
|
+
|
|
50
|
+
# Get download size
|
|
51
|
+
size = get_package_size(pip_name)
|
|
52
|
+
print(f"π¦ Package: {pip_name} | Estimated Download Size: {size}")
|
|
53
|
+
|
|
54
|
+
# Prompt user for installation
|
|
55
|
+
response = input(f"β Would you like to install '{pip_name}' now? (y/n): ").strip().lower()
|
|
56
|
+
|
|
57
|
+
if response in ['y', 'yes']:
|
|
58
|
+
print(f"β‘ Installing '{pip_name}' via pip... Please wait.")
|
|
59
|
+
try:
|
|
60
|
+
# Execute pip install programmatically
|
|
61
|
+
subprocess.check_call([sys.executable, "-m", "pip", "install", pip_name])
|
|
62
|
+
print(f"π [SUCCESS] '{pip_name}' has been successfully installed!\n")
|
|
63
|
+
except subprocess.CalledProcessError as e:
|
|
64
|
+
print(f"β [ERROR] Failed to install '{pip_name}'.")
|
|
65
|
+
print(f"Details: {e}")
|
|
66
|
+
sys.exit(1)
|
|
67
|
+
else:
|
|
68
|
+
print(f"π [CANCELLED] Installation aborted by user. Execution cannot continue without '{pip_name}'.")
|
|
69
|
+
sys.exit(1)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: package-guardian
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Intelligent missing package resolver with size detection
|
|
5
|
+
Author: WoongYo Choi
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
9
|
+
Requires-Python: >=3.8
|
|
10
|
+
Dynamic: author
|
|
11
|
+
Dynamic: classifier
|
|
12
|
+
Dynamic: license
|
|
13
|
+
Dynamic: requires-python
|
|
14
|
+
Dynamic: summary
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
setup.py
|
|
2
|
+
autopublish/__init__.py
|
|
3
|
+
autopublish/publishe1r.py
|
|
4
|
+
fasthardware/__init__.py
|
|
5
|
+
fasthardware/fasthardware.py
|
|
6
|
+
package_guardian/__init__.py
|
|
7
|
+
package_guardian/guardian.py
|
|
8
|
+
package_guardian.egg-info/PKG-INFO
|
|
9
|
+
package_guardian.egg-info/SOURCES.txt
|
|
10
|
+
package_guardian.egg-info/dependency_links.txt
|
|
11
|
+
package_guardian.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="package-guardian",
|
|
5
|
+
version="1.0.0",
|
|
6
|
+
author="WoongYo Choi",
|
|
7
|
+
description="Intelligent missing package resolver with size detection",
|
|
8
|
+
packages=find_packages(),
|
|
9
|
+
license="MIT",
|
|
10
|
+
classifiers=[
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"Operating System :: Microsoft :: Windows",
|
|
13
|
+
],
|
|
14
|
+
python_requires='>=3.8',
|
|
15
|
+
)
|