Skip to content

PackageRecord#

PackageRecord #

A single record in the Conda repodata. A single record refers to a single binary distribution of a package on a Conda channel.

arch: Optional[str] property writable #

Optionally the architecture the package supports.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.arch
'x86_64'
>>> record.arch = "arm64"
>>> record.arch
'arm64'
>>> record.arch = None
>>> record.arch is None
True
>>>

build: str property writable #

The build string of the package.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.build
'hcfcfb64_0'
>>> record.build = "new_build_1"
>>> record.build
'new_build_1'
>>>

build_number: int property writable #

The build number of the package.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.build_number
0
>>> record.build_number = 42
>>> record.build_number
42
>>>

constrains: List[str] property writable #

Additional constraints on packages. Constrains are different from depends in that packages specified in depends must be installed next to this package, whereas packages specified in constrains are not required to be installed, but if they are installed they must follow these constraints.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.constrains
[]
>>> record.constrains = ["python >=3.6"]
>>> record.constrains
['python >=3.6']
>>>

depends: List[str] property writable #

Specification of packages this package depends on.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.depends
['ucrt >=10.0.20348.0', 'vc >=14.2,<15', 'vs2015_runtime >=14.29.30139']
>>> record.depends = ["python >=3.6"]
>>> record.depends
['python >=3.6']
>>>

features: Optional[str] property writable #

Features are a deprecated way to specify different feature sets for the conda solver. This is not supported anymore and should not be used. Instead, mutex packages should be used to specify mutually exclusive features.

Examples#
>>> record = PackageRecord.from_index_json(
...     "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> record.features is None
True
>>> record.features = "feature1"
>>> record.features
'feature1'
>>> record.features = None
>>> record.features is None
True
>>>

legacy_bz2_md5: Optional[bytes] property writable #

A deprecated md5 hash.

Examples#
>>> record = PackageRecord.from_index_json(
...     "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> record.legacy_bz2_md5 is None
True
>>> record.legacy_bz2_md5 = bytes.fromhex("2ddbbaf3a82b46ac7214681262e3d746")
>>> record.legacy_bz2_md5.hex()
'2ddbbaf3a82b46ac7214681262e3d746'
>>> record.legacy_bz2_md5 = None
>>> record.legacy_bz2_md5 is None
True
>>>

legacy_bz2_size: Optional[int] property writable #

A deprecated package archive size.

Examples#
>>> record = PackageRecord.from_index_json(
...     "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> record.legacy_bz2_size is None
True
>>> record.legacy_bz2_size = 42
>>> record.legacy_bz2_size
42
>>> record.legacy_bz2_size = None
>>> record.legacy_bz2_size is None
True
>>>

license: Optional[str] property writable #

The specific license of the package.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.license
'Unlicense'
>>> record.license = "MIT"
>>> record.license
'MIT'
>>> record.license = None
>>> record.license is None
True
>>>

license_family: Optional[str] property writable #

The license family.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/pip-23.0-pyhd8ed1ab_0.json"
... )
>>> record.license_family
'MIT'
>>> record.license_family = "BSD"
>>> record.license_family
'BSD'
>>> record.license_family = None
>>> record.license_family is None
True
>>>

md5: Optional[bytes] property writable #

Optionally a MD5 hash of the package archive.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.md5.hex()
'5e5a97795de72f8cc3baf3d9ea6327a2'
>>> record.md5 = bytes.fromhex("2ddbbaf3a82b46ac7214681262e3d746")
>>> record.md5.hex()
'2ddbbaf3a82b46ac7214681262e3d746'
>>> record.md5 = None
>>> record.md5 is None
True
>>>

name: PackageName property writable #

The name of the package.

Examples#
>>> from rattler import PrefixRecord, PackageName
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.name
PackageName("libsqlite")
>>> record.name = PackageName("newname")
>>> record.name
PackageName("newname")
>>>

noarch: NoArchType property writable #

The noarch type of the package.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.noarch
NoArchType(None)
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/pip-23.0-pyhd8ed1ab_0.json"
... )
>>> record.noarch
NoArchType("python")
>>> record.noarch = NoArchType("generic")
>>> record.noarch
NoArchType("generic")
>>> record.noarch = NoArchType(None)
>>> record.noarch.none
True
>>>

platform: Optional[str] property writable #

Optionally the platform the package supports.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.platform
'win32'
>>> record.platform = "linux"
>>> record.platform
'linux'
>>> record.platform = None
>>> record.platform is None
True
>>>

python_site_packages_path: Optional[str] property writable #

Optionally a path within the environment of the site-packages directory. This field is only present for python interpreter packages. This field was introduced with https://github.com/conda/ceps/blob/main/cep-17.md.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/python-3.11.9-h932a869_0_cpython.json"
... )
>>> record.python_site_packages_path
'lib/python3.11/site-packages'
>>>

sha256: Optional[bytes] property writable #

Optionally a SHA256 hash of the package archive.

Examples#

```python

from rattler import PrefixRecord record = PrefixRecord.from_path( ... "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json" ... ) record.sha256.hex() '4e50b3d90a351c9d47d239d3f90fce4870df2526e4f7fef35203ab3276a6dfc9' record.sha256 = bytes.fromhex("edd7dd24fc070fad8ca690a920d94b6312a376faa96b47c657f9ef5fe5a97dd1") record.sha256.hex() 'edd7dd24fc070fad8ca690a920d94b6312a376faa96b47c657f9ef5fe5a97dd1' record.sha256 = None record.sha256 is None True

size: Optional[int] property writable #

Optionally the size of the package archive in bytes.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.size
669941
>>> record.size = 42
>>> record.size
42
>>> record.size = None
>>> record.size is None
True
>>>

subdir: str property writable #

The subdirectory where the package can be found.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.subdir
'win-64'
>>> record.subdir = "linux-64"
>>> record.subdir
'linux-64'
>>>

timestamp: Optional[datetime.datetime] property writable #

The date this entry was created.

Examples#
>>> from rattler import PrefixRecord
>>> import datetime
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.timestamp
datetime.datetime(2022, 11, 17, 15, 7, 19, 781000, tzinfo=datetime.timezone.utc)
>>> new_time = datetime.datetime(2023, 1, 1, tzinfo=datetime.timezone.utc)
>>> record.timestamp = new_time
>>> record.timestamp
datetime.datetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)
>>> record.timestamp = None
>>> record.timestamp is None
True
>>>

track_features: List[str] property writable #

Track features are nowadays only used to downweight packages (ie. give them less priority). To that effect, the number of track features is counted (number of commas) and the package is downweighted by the number of track_features.

Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.track_features
[]
>>> record.track_features = ["feature1", "feature2"]
>>> record.track_features
['feature1', 'feature2']
>>>

version: VersionWithSource property writable #

The version of the package.

Examples#
>>> from rattler import PrefixRecord, VersionWithSource
>>> record = PrefixRecord.from_path(
...     "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.version
VersionWithSource(version="3.40.0", source="3.40.0")
>>> record.version = VersionWithSource("1.0.0")
>>> record.version
VersionWithSource(version="1.0.0", source="1.0.0")
>>>

__repr__() #

Returns a representation of the PackageRecord.

Examples#
>>> record = PackageRecord.from_index_json(
...     "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> record
PackageRecord("pysocks=1.7.1=pyh0701188_6")
>>>

__str__() #

Returns the string representation of the PackageRecord.

Examples#
>>> record = PackageRecord.from_index_json(
...     "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> str(record)
'pysocks=1.7.1=pyh0701188_6'
>>>

from_index_json(path, size=None, sha256=None, md5=None) staticmethod #

Builds a PackageRecord from an index.json. These can be found in info directory inside an extracted package archive.

Examples#
>>> record = PackageRecord.from_index_json(
...     "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> assert isinstance(record, PackageRecord)
>>> record.name
PackageName("pysocks")
>>> record.version
VersionWithSource(version="1.7.1", source="1.7.1")
>>> record.build
'pyh0701188_6'
>>>

matches(spec) #

Match a [PackageRecord] against a [MatchSpec].

Examples#
>>> from rattler import MatchSpec
>>> record = PackageRecord.from_index_json(
...     "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> spec = MatchSpec("pysocks")
>>> record.matches(spec)
True
>>> spec = MatchSpec("pysocks>=1.7")
>>> record.matches(spec)
True
>>> spec = MatchSpec("pysocks<1.7")
>>> record.matches(spec)
False
>>>

sort_topologically(records) staticmethod #

Sorts the records topologically. This function is deterministic, meaning that it will return the same result regardless of the order of records and of the depends vector inside the records. Note that this function only works for packages with unique names.

Examples#
>>> from os import listdir
>>> from os.path import isfile, join
>>> from rattler import PrefixRecord
>>> records = [
...     PrefixRecord.from_path(join("../test-data/conda-meta/", f))
...     for f in listdir("../test-data/conda-meta")
...     if isfile(join("../test-data/conda-meta", f))
... ]
>>> sorted = PackageRecord.sort_topologically(records)
>>> sorted[0].name
PackageName("python_abi")
>>> # Verify it's deterministic by sorting again
>>> sorted2 = PackageRecord.sort_topologically(records)
>>> [str(r) for r in sorted] == [str(r) for r in sorted2]
True
>>>

to_graph(records) staticmethod #

Converts a list of PackageRecords to a DAG (networkx.DiGraph). The nodes in the graph are the PackageRecords and the edges are the dependencies.

Note: Virtual packages (starting with __) are skipped.

to_json() #

Convert the PackageRecord to a JSON string.

Examples#
>>> import json
>>> record = PackageRecord.from_index_json(
...     "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> json_data = record.to_json()
>>> isinstance(json_data, str)
True
>>> as_dict = json.loads(json_data)
>>> as_dict["name"]
'pysocks'
>>> as_dict["version"]
'1.7.1'
>>>

validate(records) staticmethod #

Validate that the given package records are valid w.r.t. 'depends' and 'constrains'.

This function will return nothing if all records form a valid environment, i.e., all dependencies of each package are satisfied by the other packages in the list. If there is a dependency that is not satisfied, this function will raise an exception.

Examples#
>>> from os import listdir
>>> from os.path import isfile, join
>>> from rattler import PrefixRecord
>>> from rattler.exceptions import ValidatePackageRecordsException
>>> records = [
...     PrefixRecord.from_path(join("../test-data/conda-meta/", f))
...     for f in sorted(listdir("../test-data/conda-meta"))
...     if isfile(join("../test-data/conda-meta", f))
... ]
>>> try:
...     PackageRecord.validate(records)
... except ValidatePackageRecordsException as e:
...     print(e)
package 'libsqlite=3.40.0=hcfcfb64_0' has dependency 'ucrt >=10.0.20348.0', which is not in the environment
>>>