Bases: BaseService
A service class for Python-related operations.
This class provides methods for managing Python virtual environments and dependencies.
The constructor for the PythonService class.
It initializes package managers for dependency management.
Source code in dev_tool/services/python/service.py
| def __init__(self) -> None:
"""
The constructor for the PythonService class.
It initializes package managers for dependency management.
"""
super().__init__()
self.resolver = DependencyResolver()
self.manager, self.fallback = PackageManagerFactory.create_package_manager()
if sys.platform == OperatingSystem.WINDOWS:
EnvironmentVariables.refresh_environment()
|
A method that removes an existing virtual environment.
Source code in dev_tool/services/python/service.py
| def clean_virtual_environment(self) -> None:
"""A method that removes an existing virtual environment."""
message = 'Cleaning virtual environment...'
self.notification.normal_text(message)
if VENV.exists():
self._remove_directory(VENV)
message = f'Removed virtual environment at {VENV}'
self.notification.normal_text(message)
else:
message = f'No virtual environment found at {VENV}'
self.notification.warning_banner(message)
log.debug(message)
|
A method that creates a Python virtual environment.
Source code in dev_tool/services/python/service.py
| def create_virtual_environment(self) -> None:
"""A method that creates a Python virtual environment."""
message = 'Setting up virtual environment...'
self.notification.normal_text(message)
self.install_package_manager()
if not self.manager.create_virtual_environment():
message = 'Failed to create virtual environment with preferred manager, falling back...'
self.notification.warning_text(message)
log.debug(message)
if not self.fallback.create_virtual_environment():
message = 'Failed to create virtual environment with any package manager'
log.debug(message)
raise VirtualEnvironmentError(message)
|
A method that lists all available dependency sources.
This method discovers and returns information about all available
dependency sources including requirements files and pyproject.toml extras.
Returns:
-
dict[str, list[str]]
–
A dictionary mapping source types to available sources.
Source code in dev_tool/services/python/service.py
| def get_available_dependencies(self) -> dict[str, list[str]]:
"""
A method that lists all available dependency sources.
This method discovers and returns information about all available
dependency sources including requirements files and pyproject.toml extras.
:return: A dictionary mapping source types to available sources.
"""
return self.resolver.get_available_sources()
|
A method that installs Python dependencies.
It requires a virtual environment to be active.
Parameters:
-
requirements_file
(Path | None, default:
None
)
–
Optional path to a specific requirements file. If provided, installs from this file only.
-
types
(list[str] | None, default:
None
)
–
Optional list of dependency types to install (e.g., ['development', 'production']). If None, auto-detects.
Source code in dev_tool/services/python/service.py
| @is_virtual_environment
def install_dependencies(self, requirements_file: Path | None = None, types: list[str] | None = None) -> None:
"""
A method that installs Python dependencies.
It requires a virtual environment to be active.
:param requirements_file: Optional path to a specific requirements file.
If provided, installs from this file only.
:param types: Optional list of dependency types to install
(e.g., ['development', 'production']). If None, auto-detects.
"""
self.install_package_manager()
if requirements_file is not None:
if not requirements_file.exists():
message = f'Requirements file not found: {requirements_file}'
log.debug(message)
raise DependencyInstallationError(message)
log.debug(f'Installing from specified requirements file: {requirements_file.name}')
success = self._install_requirements_file(requirements_file)
if not success:
message = f'Failed to install from {requirements_file}'
log.debug(message)
raise DependencyInstallationError(message)
return
sources = self.resolver.get_strategy(types)
if not sources:
message = 'No dependency files found (requirements.txt or pyproject.toml)'
self.notification.warning_text(message)
log.debug(message)
return
message = f'Found {len(sources)} dependency sources to install'
self.notification.normal_text(message)
primary_failed = [
source.name
for source in sources
if not self._install_from_source(source)
]
all_failed = primary_failed.copy()
if primary_failed and types is None:
message = 'Primary installation sources failed, trying fallback strategy...'
self.notification.warning_text(message)
log.debug(message)
fallback_sources = self.resolver.get_fallback_strategy(sources)
if fallback_sources:
fallback_failed = [
source.name
for source in fallback_sources
if not self._install_from_source(source)
]
all_failed.extend(fallback_failed)
if all_failed:
message = f'Failed to install from sources: {", ".join(all_failed)}'
log.debug(message)
|
A method that installs a single Python package.
It requires a virtual environment to be active.
Source code in dev_tool/services/python/service.py
| @is_virtual_environment
def install_dependency(self) -> None:
"""
A method that installs a single Python package.
It requires a virtual environment to be active.
"""
self.install_package_manager()
package = get_user_input('Which package do you want to install?')
if not package:
message = 'No package specified. Aborting...'
self.notification.warning_text(message)
log.debug(message)
return
if not self.manager.install_package(package):
message = 'Failed to install package with preferred manager, falling back...'
self.notification.warning_text(message)
log.debug(message)
if not self.fallback.install_package(package):
message = f'Failed to install package "{package}" with any package manager'
log.debug(message)
raise DependencyInstallationError(message)
message = f'The {package} package installed successfully.'
self.notification.normal_text(message)
log.debug(message)
|
A method that installs the preferred package manager.
It falls back to an alternative if the preferred manager cannot be installed.
Source code in dev_tool/services/python/service.py
| def install_package_manager(self) -> bool:
"""
A method that installs the preferred package manager.
It falls back to an alternative if the preferred manager cannot be installed.
"""
if self.manager is None or self.fallback is None:
message = 'Package managers not initialized'
self.notification.error_banner(message)
log.debug(message)
return False
if self.manager.is_available():
message = 'uv is already installed.'
self.notification.normal_text(message)
log.debug(message)
return True
if not self.manager.install_package_manager():
message = 'Failed to install preferred package manager, falling back...'
self.notification.warning_text(message)
log.debug(message)
if not self.fallback.install_package_manager():
message = 'Failed to install any package manager'
log.debug(message)
raise PackageManagerError(message)
return False
|
A method that sets up a complete virtual environment.
Creates a virtual environment if needed, upgrades the package manager,
and installs all dependencies.
Parameters:
-
types
(list[str] | None, default:
None
)
–
Optional list of dependency types to install.
Source code in dev_tool/services/python/service.py
| def setup_venv(self, types: list[str] | None = None) -> None:
"""
A method that sets up a complete virtual environment.
Creates a virtual environment if needed, upgrades the package manager,
and installs all dependencies.
:param types: Optional list of dependency types to install.
"""
if not VENV.exists():
self.create_virtual_environment()
self.upgrade_package_manager()
self.install_dependencies(types=types)
|
A method that uninstalls a Python package.
It requires a virtual environment to be active.
Source code in dev_tool/services/python/service.py
| @is_virtual_environment
def uninstall_dependencies(self) -> None:
"""
A method that uninstalls a Python package.
It requires a virtual environment to be active.
"""
self.install_package_manager()
package = get_user_input('Which package do you want to uninstall?')
if not package:
message = 'No package specified. Aborting...'
self.notification.warning_text(message)
log.debug(message)
return
installed = self.manager.list_installed_packages()
if not installed:
installed = self.fallback.list_installed_packages()
if package not in installed:
message = f'The "{package}" package is not installed.'
self.notification.warning_text(message)
log.debug(message)
return
if not self.manager.uninstall_package(package):
message = 'Failed to uninstall package with preferred manager, falling back...'
self.notification.warning_text(message)
log.debug(message)
if not self.fallback.uninstall_package(package):
message = f'Failed to uninstall package "{package}" with any package manager'
log.debug(message)
raise PackageUninstallationError(message)
message = f'The {package} package uninstalled successfully.'
self.notification.normal_text(message)
log.debug(message)
|
A method that upgrades the package manager to the latest version.
It requires a virtual environment to be active.
Source code in dev_tool/services/python/service.py
| @is_virtual_environment
def upgrade_package_manager(self) -> None:
"""
A method that upgrades the package manager to the latest version.
It requires a virtual environment to be active.
"""
if not self.manager.upgrade_package_manager():
message = 'Failed to upgrade preferred package manager, falling back...'
self.notification.warning_text(message)
log.debug(message)
if not self.fallback.upgrade_package_manager():
message = 'Failed to upgrade any package manager'
log.debug(message)
raise PackageManagerError(message)
|