fix pip binary loading

This commit is contained in:
Nick Sweeting 2024-10-04 23:26:49 -07:00
parent 497d3e9c2d
commit 80e052b166
No known key found for this signature in database
6 changed files with 72 additions and 42 deletions

View file

@ -95,10 +95,15 @@ class BaseBinary(BaseHook, Binary):
return binary return binary
@validate_call @validate_call
def load_or_install(self, **kwargs) -> Self: def load_or_install(self, fresh=False, **kwargs) -> Self:
binary = super().load_or_install(**kwargs) try:
self.symlink_to_lib(binary=binary, bin_dir=CONSTANTS.LIB_BIN_DIR) binary = self.load(fresh=fresh)
return binary if binary and binary.version:
self.symlink_to_lib(binary=binary, bin_dir=CONSTANTS.LIB_BIN_DIR)
return binary
except Exception:
pass
return self.install(**kwargs)
@property @property
def admin_url(self) -> str: def admin_url(self) -> str:

View file

@ -961,7 +961,7 @@ def install(out_dir: Path=DATA_DIR) -> None:
providers = ' [grey53]or[/grey53] '.join(provider.name for provider in binary.binproviders_supported) providers = ' [grey53]or[/grey53] '.join(provider.name for provider in binary.binproviders_supported)
print(f'[+] Locating / Installing [yellow]{binary.name}[/yellow] using [red]{providers}[/red]...') print(f'[+] Locating / Installing [yellow]{binary.name}[/yellow] using [red]{providers}[/red]...')
try: try:
print(binary.load_or_install().model_dump(exclude={'binproviders_supported', 'loaded_binprovider', 'provider_overrides', 'loaded_abspaths', 'bin_dir', 'loaded_respath', 'hook_type'})) print(binary.load_or_install(fresh=True).model_dump(exclude={'provider_overrides', 'bin_dir', 'hook_type'}))
except Exception as e: except Exception as e:
print(f'[X] Failed to install {binary.name}: {e}') print(f'[X] Failed to install {binary.name}: {e}')

View file

@ -1,7 +1,7 @@
__package__ = 'archivebox.plugins_extractor.readability' __package__ = 'archivebox.plugins_extractor.readability'
from pathlib import Path from pathlib import Path
from typing import List, Dict, Optional, ClassVar from typing import List, Dict, Optional
# from typing_extensions import Self # from typing_extensions import Self
# Depends on other PyPI/vendor packages: # Depends on other PyPI/vendor packages:
@ -45,17 +45,17 @@ class ReadabilityBinary(BaseBinary):
} }
@validate_call @validate_call
def install(self, binprovider_name: Optional[BinProviderName]=None) -> ShallowBinary: def install(self, binprovider_name: Optional[BinProviderName]=None, **kwargs) -> ShallowBinary:
# force install to only use lib/npm provider, we never want to modify global NPM packages # force install to only use lib/npm provider, we never want to modify global NPM packages
return BaseBinary.install(self, binprovider_name=binprovider_name or LIB_NPM_BINPROVIDER.name) return BaseBinary.install(self, binprovider_name=binprovider_name or LIB_NPM_BINPROVIDER.name, **kwargs)
@validate_call @validate_call
def load_or_install(self, binprovider_name: Optional[BinProviderName] = None) -> ShallowBinary: def load_or_install(self, binprovider_name: Optional[BinProviderName] = None, fresh=False, **kwargs) -> ShallowBinary:
# force install to only use lib/npm provider, we never want to modify global NPM packages
try: try:
return self.load() return self.load(fresh=fresh)
except Exception: except Exception:
return BaseBinary.install(self, binprovider_name=binprovider_name or LIB_NPM_BINPROVIDER.name) # force install to only use lib/npm provider, we never want to modify global NPM packages
return BaseBinary.install(self, binprovider_name=binprovider_name or LIB_NPM_BINPROVIDER.name, **kwargs)

View file

@ -66,18 +66,16 @@ class SinglefileBinary(BaseBinary):
}, },
} }
@validate_call def install(self, binprovider_name: Optional[BinProviderName]=None, **kwargs) -> ShallowBinary:
def install(self, binprovider_name: Optional[BinProviderName]=None) -> ShallowBinary:
# force install to only use lib/npm provider, we never want to modify global NPM packages # force install to only use lib/npm provider, we never want to modify global NPM packages
return BaseBinary.install(self, binprovider_name=binprovider_name or LIB_NPM_BINPROVIDER.name) return BaseBinary.install(self, binprovider_name=binprovider_name or LIB_NPM_BINPROVIDER.name, **kwargs)
@validate_call def load_or_install(self, binprovider_name: Optional[BinProviderName]=None, fresh=False, **kwargs) -> ShallowBinary:
def load_or_install(self, binprovider_name: Optional[BinProviderName] = None) -> ShallowBinary:
# force install to only use lib/npm provider, we never want to modify global NPM packages
try: try:
return self.load() return self.load(fresh=fresh)
except Exception: except Exception:
return BaseBinary.install(self, binprovider_name=binprovider_name or LIB_NPM_BINPROVIDER.name) # force install to only use lib/npm provider, we never want to modify global NPM packages
return BaseBinary.install(self, binprovider_name=binprovider_name or LIB_NPM_BINPROVIDER.name, **kwargs)

View file

@ -5,17 +5,16 @@ import sys
import inspect import inspect
from pathlib import Path from pathlib import Path
from typing import List, Dict, Optional from typing import List, Dict, Optional
from pydantic import InstanceOf, Field, model_validator from pydantic import InstanceOf, Field, model_validator, validate_call
import django import django
from django.db.backends.sqlite3.base import Database as django_sqlite3 # type: ignore[import-type] from django.db.backends.sqlite3.base import Database as django_sqlite3 # type: ignore[import-type]
from django.core.checks import Error, Tags from django.core.checks import Error, Tags
from pydantic_pkgr import BinProvider, PipProvider, BinName, BinProviderName, ProviderLookupDict, SemVer from pydantic_pkgr import BinProvider, PipProvider, BinName, BinProviderName, ProviderLookupDict, SemVer, bin_abspath
from archivebox.config import CONSTANTS, VERSION from archivebox.config import CONSTANTS, VERSION
import abx
from abx.archivebox.base_plugin import BasePlugin from abx.archivebox.base_plugin import BasePlugin
from abx.archivebox.base_configset import BaseConfigSet from abx.archivebox.base_configset import BaseConfigSet
from abx.archivebox.base_check import BaseCheck from abx.archivebox.base_check import BaseCheck
@ -35,12 +34,9 @@ class PipDependencyConfigs(BaseConfigSet):
PIP_EXTRA_ARGS: List[str] = [] PIP_EXTRA_ARGS: List[str] = []
PIP_DEFAULT_ARGS: List[str] = [] PIP_DEFAULT_ARGS: List[str] = []
PIP_CONFIG = PipDependencyConfigs()
DEFAULT_GLOBAL_CONFIG = {
}
PIP_CONFIG = PipDependencyConfigs(**DEFAULT_GLOBAL_CONFIG)
class SystemPipBinProvider(PipProvider, BaseBinProvider): class SystemPipBinProvider(PipProvider, BaseBinProvider):
name: BinProviderName = "sys_pip" name: BinProviderName = "sys_pip"
INSTALLER_BIN: BinName = "pip" INSTALLER_BIN: BinName = "pip"
@ -83,11 +79,19 @@ class ArchiveboxBinary(BaseBinary):
binproviders_supported: List[InstanceOf[BinProvider]] = [VENV_PIP_BINPROVIDER, SYS_PIP_BINPROVIDER, apt, brew, env] binproviders_supported: List[InstanceOf[BinProvider]] = [VENV_PIP_BINPROVIDER, SYS_PIP_BINPROVIDER, apt, brew, env]
provider_overrides: Dict[BinProviderName, ProviderLookupDict] = { provider_overrides: Dict[BinProviderName, ProviderLookupDict] = {
VENV_PIP_BINPROVIDER.name: {'packages': lambda: [], 'version': lambda: VERSION}, VENV_PIP_BINPROVIDER.name: {'packages': lambda: [], 'version': lambda: VERSION, 'abspath': lambda: bin_abspath('archivebox')},
SYS_PIP_BINPROVIDER.name: {'packages': lambda: [], 'version': lambda: VERSION}, SYS_PIP_BINPROVIDER.name: {'packages': lambda: [], 'version': lambda: VERSION, 'abspath': lambda: bin_abspath('archivebox')},
apt.name: {'packages': lambda: [], 'version': lambda: VERSION}, apt.name: {'packages': lambda: [], 'version': lambda: VERSION, 'abspath': lambda: bin_abspath('archivebox')},
brew.name: {'packages': lambda: [], 'version': lambda: VERSION}, brew.name: {'packages': lambda: [], 'version': lambda: VERSION, 'abspath': lambda: bin_abspath('archivebox')},
} }
@validate_call
def install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
@validate_call
def load_or_install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
ARCHIVEBOX_BINARY = ArchiveboxBinary() ARCHIVEBOX_BINARY = ArchiveboxBinary()
@ -98,12 +102,18 @@ class PythonBinary(BaseBinary):
binproviders_supported: List[InstanceOf[BinProvider]] = [VENV_PIP_BINPROVIDER, SYS_PIP_BINPROVIDER, apt, brew, env] binproviders_supported: List[InstanceOf[BinProvider]] = [VENV_PIP_BINPROVIDER, SYS_PIP_BINPROVIDER, apt, brew, env]
provider_overrides: Dict[BinProviderName, ProviderLookupDict] = { provider_overrides: Dict[BinProviderName, ProviderLookupDict] = {
SYS_PIP_BINPROVIDER.name: { SYS_PIP_BINPROVIDER.name: {
'abspath': lambda: 'abspath': lambda: sys.executable,
sys.executable, 'version': lambda: '{}.{}.{}'.format(*sys.version_info[:3]),
'version': lambda:
'{}.{}.{}'.format(*sys.version_info[:3]),
}, },
} }
@validate_call
def install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
@validate_call
def load_or_install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
PYTHON_BINARY = PythonBinary() PYTHON_BINARY = PythonBinary()
@ -134,6 +144,14 @@ class SqliteBinary(BaseBinary):
'https://code.djangoproject.com/wiki/JSON1Extension' 'https://code.djangoproject.com/wiki/JSON1Extension'
]) ])
return self return self
@validate_call
def install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
@validate_call
def load_or_install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
SQLITE_BINARY = SqliteBinary() SQLITE_BINARY = SqliteBinary()
@ -152,6 +170,14 @@ class DjangoBinary(BaseBinary):
"version": lambda: django.VERSION[:3], "version": lambda: django.VERSION[:3],
}, },
} }
@validate_call
def install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
@validate_call
def load_or_install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
DJANGO_BINARY = DjangoBinary() DJANGO_BINARY = DjangoBinary()
@ -159,6 +185,13 @@ class PipBinary(BaseBinary):
name: BinName = "pip" name: BinName = "pip"
binproviders_supported: List[InstanceOf[BinProvider]] = [LIB_PIP_BINPROVIDER, VENV_PIP_BINPROVIDER, SYS_PIP_BINPROVIDER, apt, brew, env] binproviders_supported: List[InstanceOf[BinProvider]] = [LIB_PIP_BINPROVIDER, VENV_PIP_BINPROVIDER, SYS_PIP_BINPROVIDER, apt, brew, env]
@validate_call
def install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
@validate_call
def load_or_install(self, **kwargs):
return self.load() # obviously it's already installed if we are running this ;)
PIP_BINARY = PipBinary() PIP_BINARY = PipBinary()
@ -242,9 +275,3 @@ class PipPlugin(BasePlugin):
PLUGIN = PipPlugin() PLUGIN = PipPlugin()
# PLUGIN.register(settings) # PLUGIN.register(settings)
DJANGO_APP = PLUGIN.AppConfig DJANGO_APP = PLUGIN.AppConfig
@abx.hookimpl
def register_django_checks(settings):
USER_IS_NOT_ROOT_CHECK.register_with_django_check_system(settings)
PIP_ENVIRONMENT_CHECK.register_with_django_check_system(settings)

@ -1 +1 @@
Subproject commit 5bb42056bda9269e600885d83369b89f8dd916a5 Subproject commit 7647d3757ef0655bd8ba106c4c5b27ae16909e03