rusterize


Namerusterize JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryHigh performance rasterization tool for Python built in Rust
upload_time2025-02-12 17:48:47
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseNone
keywords fast raster
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # rusterize

High performance rasterization tool for Python built in Rust. This
repository is heavily based on the [fasterize](https://github.com/ecohealthalliance/fasterize.git) package built in C++
for R. This version ports it to Python with a Rust backend, with some useful improvements.

Functionally, it takes an input [geopandas](https://geopandas.org/en/stable/)
dataframes and returns a [xarray](https://docs.xarray.dev/en/stable/). It
tighly mirrors the processing routine of fasterize, so it works only on
(multi)polygon geometries at the moment.

# Installation

Install the current version with pip:

``` shell
pip install rusterize
```

# Contributing

Any contribution is welcome! You can install **rusterize** directly
from this repo using [maturin](https://www.maturin.rs/) as an editable
package. For this to work, you’ll need to have [Rust](https://www.rust-lang.org/tools/install) and
[cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html)
installed.

``` shell
# Clone repo
git clone https://github.com/<username>/rusterize.git
cd rusterize

# Install the Rust nightly toolchain
rustup toolchain install nightly-2025-01-05

 # Install maturin
pip install maturin

# Install editable version with optmized code
maturin develop --profile dist-release
```

# API

This function has a simple API:

``` python
from rusterize.core import rusterize

# gdf = <import datasets as needed>

# rusterize
rusterize(gdf,
          res=(30, 30),
          out_shape=(10, 10)
          extent=(0, 300, 0, 300)
          field="field",
          by="by",
          fun="sum",
          background=0) 
```

- `gdf`: geopandas dataframe to rasterize
- `res`: tuple of (xres, yres) for desired resolution
- `out_shape`: tuple of (nrows, ncols) for desired output shape
- `extent`: tuple of (xmin, ymin, xmax, ymax) for desired output extent
- `field`: field to rasterize. Default is None (a value of `1` is rasterized).
- `by`: column to rasterize. Assigns each group to a band in the
  stack. Values are taken from `field`. Default is None
- `fun`: pixel function to use when multiple values overlap. Default is
  `last`. Available options are `sum`, `first`, `last`, `min`, `max`, `count`, or `any`
- `background`: background value in final raster. Default is None (NaN)

Note that control over the desired extent is not as strict as for resolution and shape. That is,
when resolution, output shape, and extent are specified, priority is given to resolution and shape.
So, extent is not guaranteed, but resolution and shape are. If extent is not given, it is taken
from the polygons and is not modified, unless you specify a resolution value. If you only specify an output
shape, the extent is maintained. This mimics the logics of `gdal_rasterize`.

# Usage

**rusterize** consists of a single function `rusterize()`. The Rust implementation
returns an array that is converted to a xarray on the Python side
for simpliicty.

``` python
from rusterize.core import rusterize
import geopandas as gpd
from shapely import wkt
import matplotlib.pyplot as plt

# example from fasterize
polygons = [
    "POLYGON ((-180 -20, -140 55, 10 0, -140 -60, -180 -20), (-150 -20, -100 -10, -110 20, -150 -20))",
    "POLYGON ((-10 0, 140 60, 160 0, 140 -55, -10 0))",
    "POLYGON ((-125 0, 0 60, 40 5, 15 -45, -125 0))"
]

# Convert WKT strings to Shapely geometries
geometries = [wkt.loads(polygon) for polygon in polygons]

# Create a GeoDataFrame
gdf = gpd.GeoDataFrame({'value': range(1, len(polygons) + 1)}, geometry=geometries, crs='EPSG:32619')

# rusterize
output = rusterize(
    gdf,
    res=(1, 1),
    field="value",
    fun="sum"
).squeeze()

# plot it
fig, ax = plt.subplots(figsize=(12, 6))
output.plot.imshow(ax=ax)
plt.show()
```

![](img/plot.png)

# Benchmarks

**rusterize** is fast! Let’s try it on small and large datasets.

``` python
from rusterize.core import rusterize
import geopandas as gpd
import requests
import zipfile
from io import BytesIO

# large dataset (~380 MB)
url = "https://s3.amazonaws.com/hp3-shapefiles/Mammals_Terrestrial.zip"
response = requests.get(url)

# unzip
with zipfile.ZipFile(BytesIO(response.content), 'r') as zip_ref:
    zip_ref.extractall()
    
# read
gdf_large = gpd.read_file("Mammals_Terrestrial/Mammals_Terrestrial.shp")

# small dataset (first 1000 rows)
gdf_small = gdf_large.iloc[:1000, :]

# rusterize at 1/6 degree resolution
def test_large(benchmark):
  benchmark(rusterize, gdf_large, (1/6, 1/6), fun="sum")
   
def test_small(benchmark):
  benchmark(rusterize, gdf_small, (1/6, 1/6), fun="sum")  
```

Then you can run it with [pytest](https://docs.pytest.org/en/stable/)
and
[pytest-benchmark](https://pytest-benchmark.readthedocs.io/en/stable/):

```
pytest <python file> --benchmark-min-rounds=20 --benchmark-time-unit='s'

--------------------------------------------- benchmark: 1 tests --------------------------------------------
Name (time in s)         Min      Max     Mean  StdDev   Median     IQR  Outliers     OPS  Rounds  Iterations
-------------------------------------------------------------------------------------------------------------
test_large           10.5870  11.2302  10.8633  0.1508  10.8417  0.1594       4;1  0.0921      20           1
test_small            0.5083   0.6416   0.5265  0.0393   0.5120  0.0108       2;2  1.8995      20           1
-------------------------------------------------------------------------------------------------------------
```

And fasterize:

``` r
large <- st_read("Mammals_Terrestrial/Mammals_Terrestrial.shp", quiet = TRUE)
small <- large[1:1000, ]
fn <- function(v) {
  r <- raster(v, res = 1/6)
  return(fasterize(v, r, fun = "sum"))
}
microbenchmark(
  fasterize_large = f <- fn(large),
  fasterize_small = f <- fn(small),
  times=20L,
  unit='s'
)
```

```
Unit: seconds
      expr             min        lq      mean    median        uq       max  neval
 fasterize_large  9.565781  9.815375  10.02838  9.984965  10.18532  10.66656     20
 fasterize_small  0.469389  0.500616  0.571851  0.558818  0.613419  0.795159     20
```

And on even
[larger](https://open.canada.ca/data/en/dataset/fbf12500-bffe-4209-a1ae-fba86f154ebf/resource/cc90d77c-fba3-4f84-b30a-e684cfe0649a)
datasets? This is a benchmark with 350K+ geometries rasterized at 30
meters (20 rounds) with no field value and pixel function `sum`.

```
# rusterize
--------------------------------------------- benchmark: 1 tests --------------------------------------------
Name (time in s)         Min      Max     Mean  StdDev   Median     IQR  Outliers     OPS  Rounds  Iterations
-------------------------------------------------------------------------------------------------------------
test_sbw             46.5711  49.0212  48.4340  0.5504  48.5812  0.5054       3;1  0.0206      20           1
-------------------------------------------------------------------------------------------------------------

# fasterize
Unit: seconds
      expr      min       lq     mean   median       uq      max neval
 fasterize 62.12409 72.13832 74.53424 75.12375 77.72899 84.77415    20
```

# Comparison with other tools

While `rusterize` is fast, there are other very fast solutions out there, including:
- `GDAL`
- `rasterio`
- `geocube`

However, `rusterize` allows for a seamless, Rust-native processing with similar or lower memory footprint that doesn't require you to leave Python, and returns the geoinformation you need for downstream processing.

The following is a time comparison run on a dataset with 340K+ geometries, rasterized at 2m resolution.
```
rusterize:   24 sec
fasterize:   47 sec
GDAL (cli):  40 sec (read from fast drive, write to fast drive)
rasterio:    20 sec (but no spatial information)
geocube:     42 sec (larger memory footprint)
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "rusterize",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "fast, raster",
    "author": null,
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/7a/a3/b6dc12bfd4bc8a8df57a4d9cf0c889b73d93ee1b9e236b60ac7ff1b37f7b/rusterize-0.1.1.tar.gz",
    "platform": null,
    "description": "# rusterize\n\nHigh performance rasterization tool for Python built in Rust. This\nrepository is heavily based on the [fasterize](https://github.com/ecohealthalliance/fasterize.git) package built in C++\nfor R. This version ports it to Python with a Rust backend, with some useful improvements.\n\nFunctionally, it takes an input [geopandas](https://geopandas.org/en/stable/)\ndataframes and returns a [xarray](https://docs.xarray.dev/en/stable/). It\ntighly mirrors the processing routine of fasterize, so it works only on\n(multi)polygon geometries at the moment.\n\n# Installation\n\nInstall the current version with pip:\n\n``` shell\npip install rusterize\n```\n\n# Contributing\n\nAny contribution is welcome! You can install **rusterize** directly\nfrom this repo using [maturin](https://www.maturin.rs/) as an editable\npackage. For this to work, you\u2019ll need to have [Rust](https://www.rust-lang.org/tools/install) and\n[cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html)\ninstalled.\n\n``` shell\n# Clone repo\ngit clone https://github.com/<username>/rusterize.git\ncd rusterize\n\n# Install the Rust nightly toolchain\nrustup toolchain install nightly-2025-01-05\n\n # Install maturin\npip install maturin\n\n# Install editable version with optmized code\nmaturin develop --profile dist-release\n```\n\n# API\n\nThis function has a simple API:\n\n``` python\nfrom rusterize.core import rusterize\n\n# gdf = <import datasets as needed>\n\n# rusterize\nrusterize(gdf,\n          res=(30, 30),\n          out_shape=(10, 10)\n          extent=(0, 300, 0, 300)\n          field=\"field\",\n          by=\"by\",\n          fun=\"sum\",\n          background=0) \n```\n\n- `gdf`: geopandas dataframe to rasterize\n- `res`: tuple of (xres, yres) for desired resolution\n- `out_shape`: tuple of (nrows, ncols) for desired output shape\n- `extent`: tuple of (xmin, ymin, xmax, ymax) for desired output extent\n- `field`: field to rasterize. Default is None (a value of `1` is rasterized).\n- `by`: column to rasterize. Assigns each group to a band in the\n  stack. Values are taken from `field`. Default is None\n- `fun`: pixel function to use when multiple values overlap. Default is\n  `last`. Available options are `sum`, `first`, `last`, `min`, `max`, `count`, or `any`\n- `background`: background value in final raster. Default is None (NaN)\n\nNote that control over the desired extent is not as strict as for resolution and shape. That is,\nwhen resolution, output shape, and extent are specified, priority is given to resolution and shape.\nSo, extent is not guaranteed, but resolution and shape are. If extent is not given, it is taken\nfrom the polygons and is not modified, unless you specify a resolution value. If you only specify an output\nshape, the extent is maintained. This mimics the logics of `gdal_rasterize`.\n\n# Usage\n\n**rusterize** consists of a single function `rusterize()`. The Rust implementation\nreturns an array that is converted to a xarray on the Python side\nfor simpliicty.\n\n``` python\nfrom rusterize.core import rusterize\nimport geopandas as gpd\nfrom shapely import wkt\nimport matplotlib.pyplot as plt\n\n# example from fasterize\npolygons = [\n    \"POLYGON ((-180 -20, -140 55, 10 0, -140 -60, -180 -20), (-150 -20, -100 -10, -110 20, -150 -20))\",\n    \"POLYGON ((-10 0, 140 60, 160 0, 140 -55, -10 0))\",\n    \"POLYGON ((-125 0, 0 60, 40 5, 15 -45, -125 0))\"\n]\n\n# Convert WKT strings to Shapely geometries\ngeometries = [wkt.loads(polygon) for polygon in polygons]\n\n# Create a GeoDataFrame\ngdf = gpd.GeoDataFrame({'value': range(1, len(polygons) + 1)}, geometry=geometries, crs='EPSG:32619')\n\n# rusterize\noutput = rusterize(\n    gdf,\n    res=(1, 1),\n    field=\"value\",\n    fun=\"sum\"\n).squeeze()\n\n# plot it\nfig, ax = plt.subplots(figsize=(12, 6))\noutput.plot.imshow(ax=ax)\nplt.show()\n```\n\n![](img/plot.png)\n\n# Benchmarks\n\n**rusterize** is fast! Let\u2019s try it on small and large datasets.\n\n``` python\nfrom rusterize.core import rusterize\nimport geopandas as gpd\nimport requests\nimport zipfile\nfrom io import BytesIO\n\n# large dataset (~380 MB)\nurl = \"https://s3.amazonaws.com/hp3-shapefiles/Mammals_Terrestrial.zip\"\nresponse = requests.get(url)\n\n# unzip\nwith zipfile.ZipFile(BytesIO(response.content), 'r') as zip_ref:\n    zip_ref.extractall()\n    \n# read\ngdf_large = gpd.read_file(\"Mammals_Terrestrial/Mammals_Terrestrial.shp\")\n\n# small dataset (first 1000 rows)\ngdf_small = gdf_large.iloc[:1000, :]\n\n# rusterize at 1/6 degree resolution\ndef test_large(benchmark):\n  benchmark(rusterize, gdf_large, (1/6, 1/6), fun=\"sum\")\n   \ndef test_small(benchmark):\n  benchmark(rusterize, gdf_small, (1/6, 1/6), fun=\"sum\")  \n```\n\nThen you can run it with [pytest](https://docs.pytest.org/en/stable/)\nand\n[pytest-benchmark](https://pytest-benchmark.readthedocs.io/en/stable/):\n\n```\npytest <python file> --benchmark-min-rounds=20 --benchmark-time-unit='s'\n\n--------------------------------------------- benchmark: 1 tests --------------------------------------------\nName (time in s)         Min      Max     Mean  StdDev   Median     IQR  Outliers     OPS  Rounds  Iterations\n-------------------------------------------------------------------------------------------------------------\ntest_large           10.5870  11.2302  10.8633  0.1508  10.8417  0.1594       4;1  0.0921      20           1\ntest_small            0.5083   0.6416   0.5265  0.0393   0.5120  0.0108       2;2  1.8995      20           1\n-------------------------------------------------------------------------------------------------------------\n```\n\nAnd fasterize:\n\n``` r\nlarge <- st_read(\"Mammals_Terrestrial/Mammals_Terrestrial.shp\", quiet = TRUE)\nsmall <- large[1:1000, ]\nfn <- function(v) {\n  r <- raster(v, res = 1/6)\n  return(fasterize(v, r, fun = \"sum\"))\n}\nmicrobenchmark(\n  fasterize_large = f <- fn(large),\n  fasterize_small = f <- fn(small),\n  times=20L,\n  unit='s'\n)\n```\n\n```\nUnit: seconds\n      expr             min        lq      mean    median        uq       max  neval\n fasterize_large  9.565781  9.815375  10.02838  9.984965  10.18532  10.66656     20\n fasterize_small  0.469389  0.500616  0.571851  0.558818  0.613419  0.795159     20\n```\n\nAnd on even\n[larger](https://open.canada.ca/data/en/dataset/fbf12500-bffe-4209-a1ae-fba86f154ebf/resource/cc90d77c-fba3-4f84-b30a-e684cfe0649a)\ndatasets? This is a benchmark with 350K+ geometries rasterized at 30\nmeters (20 rounds) with no field value and pixel function `sum`.\n\n```\n# rusterize\n--------------------------------------------- benchmark: 1 tests --------------------------------------------\nName (time in s)         Min      Max     Mean  StdDev   Median     IQR  Outliers     OPS  Rounds  Iterations\n-------------------------------------------------------------------------------------------------------------\ntest_sbw             46.5711  49.0212  48.4340  0.5504  48.5812  0.5054       3;1  0.0206      20           1\n-------------------------------------------------------------------------------------------------------------\n\n# fasterize\nUnit: seconds\n      expr      min       lq     mean   median       uq      max neval\n fasterize 62.12409 72.13832 74.53424 75.12375 77.72899 84.77415    20\n```\n\n# Comparison with other tools\n\nWhile `rusterize` is fast, there are other very fast solutions out there, including:\n- `GDAL`\n- `rasterio`\n- `geocube`\n\nHowever, `rusterize` allows for a seamless, Rust-native processing with similar or lower memory footprint that doesn't require you to leave Python, and returns the geoinformation you need for downstream processing.\n\nThe following is a time comparison run on a dataset with 340K+ geometries, rasterized at 2m resolution.\n```\nrusterize:   24 sec\nfasterize:   47 sec\nGDAL (cli):  40 sec (read from fast drive, write to fast drive)\nrasterio:    20 sec (but no spatial information)\ngeocube:     42 sec (larger memory footprint)\n```\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "High performance rasterization tool for Python built in Rust",
    "version": "0.1.1",
    "project_urls": {
        "repository": "https://github.com/ttrotto/rusterize"
    },
    "split_keywords": [
        "fast",
        " raster"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "04e4f606feb4efcd190109d576fbec58276b8553f3f8631c5416be435659ee36",
                "md5": "fbb06b1dc013bc15dab7e30d64a4dfbb",
                "sha256": "52b19631f3241f632f4295b8395aa3379271b8c88c882f421dc30939ededd2a1"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-macosx_10_12_x86_64.whl",
            "has_sig": false,
            "md5_digest": "fbb06b1dc013bc15dab7e30d64a4dfbb",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 11290034,
            "upload_time": "2025-02-12T17:48:15",
            "upload_time_iso_8601": "2025-02-12T17:48:15.942491Z",
            "url": "https://files.pythonhosted.org/packages/04/e4/f606feb4efcd190109d576fbec58276b8553f3f8631c5416be435659ee36/rusterize-0.1.1-cp310-abi3-macosx_10_12_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "31e7bf88ee2294a2dea98120bbf2d9c8316cdd15643b2666c8dd25cb25c61198",
                "md5": "5952dcdd7f5dad0469918c722cfebb08",
                "sha256": "4c694fb70d638eebeaac63540d237b2fcb8686d23917233ecc3a0789f229db41"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "5952dcdd7f5dad0469918c722cfebb08",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 10206710,
            "upload_time": "2025-02-12T17:48:18",
            "upload_time_iso_8601": "2025-02-12T17:48:18.964127Z",
            "url": "https://files.pythonhosted.org/packages/31/e7/bf88ee2294a2dea98120bbf2d9c8316cdd15643b2666c8dd25cb25c61198/rusterize-0.1.1-cp310-abi3-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "869b756f315fb59a13bcc262fb4837dcec855ae68a474350cd34c119cce8485a",
                "md5": "a106243fcde35d4df7124fb14bdc4f94",
                "sha256": "bb3683c8c30af92534499c6c9e247f0066120015335854d6387379c9cdfbdc1f"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "has_sig": false,
            "md5_digest": "a106243fcde35d4df7124fb14bdc4f94",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 10624658,
            "upload_time": "2025-02-12T17:48:22",
            "upload_time_iso_8601": "2025-02-12T17:48:22.466525Z",
            "url": "https://files.pythonhosted.org/packages/86/9b/756f315fb59a13bcc262fb4837dcec855ae68a474350cd34c119cce8485a/rusterize-0.1.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7ebf4e22c488949ba8fe9c291727387e69f07e2a5330c1fa6e0de6920cbba9a5",
                "md5": "cacff9254d4bce890f3b74ab733bacc0",
                "sha256": "f8ab4743da7847f8dd14df334170bc61e23ed1ac461af8de329ddcb8d21c40d5"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",
            "has_sig": false,
            "md5_digest": "cacff9254d4bce890f3b74ab733bacc0",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 11541305,
            "upload_time": "2025-02-12T17:48:25",
            "upload_time_iso_8601": "2025-02-12T17:48:25.751759Z",
            "url": "https://files.pythonhosted.org/packages/7e/bf/4e22c488949ba8fe9c291727387e69f07e2a5330c1fa6e0de6920cbba9a5/rusterize-0.1.1-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1a13112fac0b928e391e1f45ba88830a14da86f4c7897f69ed82942d3726563b",
                "md5": "c29bce214f28c0105bec2d494756642b",
                "sha256": "97f3ce9c5091589389dc4d22904f5958dfe16e1321bd23e77a5c2cffdf2e369c"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
            "has_sig": false,
            "md5_digest": "c29bce214f28c0105bec2d494756642b",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 12180985,
            "upload_time": "2025-02-12T17:48:28",
            "upload_time_iso_8601": "2025-02-12T17:48:28.595868Z",
            "url": "https://files.pythonhosted.org/packages/1a/13/112fac0b928e391e1f45ba88830a14da86f4c7897f69ed82942d3726563b/rusterize-0.1.1-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3f4c95fc5f063e514e23d06706096d0a5424fabd4b3be613b30edf0ddaf62dd6",
                "md5": "9bbe434097bffc8e6ee048332b435260",
                "sha256": "86f7e2d398ac3a27928485d4d626244b27fbf7e3c56d04fa76842f7e3320fbc4"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "9bbe434097bffc8e6ee048332b435260",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 11610107,
            "upload_time": "2025-02-12T17:48:32",
            "upload_time_iso_8601": "2025-02-12T17:48:32.045428Z",
            "url": "https://files.pythonhosted.org/packages/3f/4c/95fc5f063e514e23d06706096d0a5424fabd4b3be613b30edf0ddaf62dd6/rusterize-0.1.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bbad15077eec0fcb3700b40dba1044a3a44b196e8a6cd3ed9722cc6c416e11ab",
                "md5": "f09f0018b391dc26dde11a4c76b75bbf",
                "sha256": "392879a53a6df35b38fea5eed5c9f7b214f50232fd88df66ea8c452ee9bfe7f4"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-musllinux_1_2_aarch64.whl",
            "has_sig": false,
            "md5_digest": "f09f0018b391dc26dde11a4c76b75bbf",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 10725260,
            "upload_time": "2025-02-12T17:48:35",
            "upload_time_iso_8601": "2025-02-12T17:48:35.551568Z",
            "url": "https://files.pythonhosted.org/packages/bb/ad/15077eec0fcb3700b40dba1044a3a44b196e8a6cd3ed9722cc6c416e11ab/rusterize-0.1.1-cp310-abi3-musllinux_1_2_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c2d3c8373e035328313c7491b5d2288bd2cd42386eda504fd5c0f563fbd1e3e8",
                "md5": "5f11d184e4571a5709ded60343c64930",
                "sha256": "987bf04c83e6626b6ba3c821685e480262ec35d39ec6abc197a2b5b20b47d432"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-musllinux_1_2_armv7l.whl",
            "has_sig": false,
            "md5_digest": "5f11d184e4571a5709ded60343c64930",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 11859506,
            "upload_time": "2025-02-12T17:48:38",
            "upload_time_iso_8601": "2025-02-12T17:48:38.165044Z",
            "url": "https://files.pythonhosted.org/packages/c2/d3/c8373e035328313c7491b5d2288bd2cd42386eda504fd5c0f563fbd1e3e8/rusterize-0.1.1-cp310-abi3-musllinux_1_2_armv7l.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1946a65ee491b6a07895c04942278419288fa937024c761d99705b639786b4bc",
                "md5": "c80c6435b945d81312172d2fac7ec814",
                "sha256": "b027e025247bdf4a4a873c8520ac79cd3e58dc49aac9ddbfd12ab31f2ba7bd57"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-musllinux_1_2_x86_64.whl",
            "has_sig": false,
            "md5_digest": "c80c6435b945d81312172d2fac7ec814",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 11689008,
            "upload_time": "2025-02-12T17:48:41",
            "upload_time_iso_8601": "2025-02-12T17:48:41.762664Z",
            "url": "https://files.pythonhosted.org/packages/19/46/a65ee491b6a07895c04942278419288fa937024c761d99705b639786b4bc/rusterize-0.1.1-cp310-abi3-musllinux_1_2_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9f2244b0f90712e3199406d60a6df37026b65fc16631eb877bc81038a6b78f62",
                "md5": "8bdddb9ec738e7e5e10285b7a76fa4f1",
                "sha256": "f7b021b12e5ea255fb0cb3126712110ebe65db5be8537e792061d1361ab839b3"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1-cp310-abi3-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "8bdddb9ec738e7e5e10285b7a76fa4f1",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 11303632,
            "upload_time": "2025-02-12T17:48:45",
            "upload_time_iso_8601": "2025-02-12T17:48:45.261098Z",
            "url": "https://files.pythonhosted.org/packages/9f/22/44b0f90712e3199406d60a6df37026b65fc16631eb877bc81038a6b78f62/rusterize-0.1.1-cp310-abi3-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7aa3b6dc12bfd4bc8a8df57a4d9cf0c889b73d93ee1b9e236b60ac7ff1b37f7b",
                "md5": "30ff9cd6d486a6400a4966b0f0a0e365",
                "sha256": "0574a863214375315a7118d3da1e218454fe54e5241f9bebbb8ef7dfeffffc0b"
            },
            "downloads": -1,
            "filename": "rusterize-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "30ff9cd6d486a6400a4966b0f0a0e365",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 61328,
            "upload_time": "2025-02-12T17:48:47",
            "upload_time_iso_8601": "2025-02-12T17:48:47.609151Z",
            "url": "https://files.pythonhosted.org/packages/7a/a3/b6dc12bfd4bc8a8df57a4d9cf0c889b73d93ee1b9e236b60ac7ff1b37f7b/rusterize-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-12 17:48:47",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ttrotto",
    "github_project": "rusterize",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "rusterize"
}
        
Elapsed time: 1.90466s