{"library":"resolvelib","title":"resolvelib","description":"Resolvelib is a Python library that provides a generic dependency resolution algorithm. It allows you to resolve abstract dependencies into concrete ones by implementing a custom 'Provider' interface that defines how packages, requirements, and candidates interact. The current version is 1.2.1, and it maintains an active release cadence with several updates per year, indicating ongoing development and support.","language":"python","status":"active","last_verified":"Wed May 20","install":{"commands":["pip install resolvelib"],"cli":null},"imports":["from resolvelib import Resolver","from resolvelib.reporters import BaseReporter","import resolvelib.providers"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import resolvelib\nfrom resolvelib.reporters import BaseReporter\nimport os\n\n# Define simple data structures for our 'packages' and 'requirements'\n# In a real scenario, these would be richer objects (e.g., Package(name, version), Requirement(package_name, specifier))\nclass MyPackage:\n    def __init__(self, name, version):\n        self.name = name\n        self.version = version\n\n    def __repr__(self):\n        return f'{self.name}=={self.version}'\n\n    def __hash__(self):\n        return hash((self.name, self.version))\n\n    def __eq__(self, other):\n        return isinstance(other, MyPackage) and self.name == other.name and self.version == other.version\n\nclass MyRequirement:\n    def __init__(self, name, specifier):\n        self.name = name\n        self.specifier = specifier # e.g., '>=1.0', '<2.0'\n\n    def __repr__(self):\n        return f'{self.name}{self.specifier}'\n\n    def __hash__(self):\n        return hash((self.name, self.specifier))\n\n    def __eq__(self, other):\n        return isinstance(other, MyRequirement) and self.name == other.name and self.specifier == other.specifier\n\n# Implement the Provider interface\nclass MyProvider:\n    def get_base_requirement(self, identifier):\n        # For this simple example, we assume identifier is the package name\n        # and we don't have a 'base' requirement beyond the initial ones.\n        return None\n\n    def identify(self, requirement_or_candidate):\n        return requirement_or_candidate.name\n\n    def get_preference(self, identifier, resolutions, candidates, information):\n        # Prefer higher versions\n        return len(candidates) + 1 # Dummy preference, real logic would sort candidates\n\n    def get_dependencies(self, candidate):\n        # Define dependencies for candidates\n        if candidate.name == 'A' and candidate.version == '1.0':\n            return [MyRequirement('B', '>=1.0')]\n        if candidate.name == 'B' and candidate.version == '1.0':\n            return [MyRequirement('C', '>=1.0')]\n        return []\n\n    def get_candidates(self, requirement):\n        # Return available candidates for a given requirement\n        if requirement.name == 'A':\n            yield MyPackage('A', '1.0')\n            yield MyPackage('A', '2.0')\n        elif requirement.name == 'B':\n            yield MyPackage('B', '1.0')\n            yield MyPackage('B', '1.1')\n        elif requirement.name == 'C':\n            yield MyPackage('C', '1.0')\n            yield MyPackage('C', '1.2')\n        else:\n            return []\n\n    def is_satisfied_by(self, requirement, candidate):\n        # In a real scenario, this would check if candidate.version satisfies requirement.specifier\n        # For simplicity, we assume any candidate with the correct name satisfies a basic requirement\n        return requirement.name == candidate.name\n\n# Create an instance of the provider and reporter\nprovider = MyProvider()\nreporter = BaseReporter()\n\n# Create the resolver\nresolver = resolvelib.Resolver(provider, reporter)\n\n# Define the initial requirements\nrequirements = [MyRequirement('A', '>=1.0')]\n\n# Kick off the resolution process\ntry:\n    result = resolver.resolve(requirements)\n    print(\"Resolution successful:\")\n    for candidate in result.graph.iter_network_linear():\n        if isinstance(candidate, MyPackage):\n            print(f\"  - {candidate}\")\nexcept resolvelib.ResolutionImpossible as e:\n    print(f\"Resolution failed: {e}\")\n\n# Example of getting an auth key, though not directly used by resolvelib\napi_key = os.environ.get('RESOLVELIB_API_KEY', 'your_default_or_mock_key')\nif api_key == 'your_default_or_mock_key':\n    print(\"\\nNote: For real-world use with external registries, an API key might be passed via Provider.\")\nelse:\n    print(f\"\\nUsing API Key (first 5 chars): {api_key[:5]}...\")\n","lang":"python","description":"This quickstart demonstrates the core usage of `resolvelib`. It involves defining custom `Package` and `Requirement` objects, then implementing a `Provider` class to teach the resolver how to find candidates, handle dependencies, and determine preferences. Finally, a `Resolver` instance is created and used to find a consistent set of packages based on the initial requirements.","tag":null,"tag_description":null,"last_tested":"2026-04-24","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]},"compatibility":{"tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","last_tested":"2026-05-20","installed_version":"1.2.1","pypi_latest":"1.2.1","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":1.5,"avg_import_s":0.02,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"17.9M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"17.9M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.5,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"18M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.03,"mem_mb":0.8,"disk_size":"19.8M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":0.8,"disk_size":"19.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.02,"mem_mb":1,"disk_size":"20M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.02,"mem_mb":0.8,"disk_size":"11.6M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.8,"disk_size":"11.6M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.02,"mem_mb":0.8,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.8,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.02,"mem_mb":0.8,"disk_size":"11.4M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.8,"disk_size":"11.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.6,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"17.4M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"17.4M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.7,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"resolvelib","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"18M"}]}}