# Polars IPTools
Polars IPTools is a Rust-based extension to accelerates IP address manipulation and enrichment in Polars dataframes. This library includes various utility functions for working with IPv4 and IPv6 addresses and geoip and anonymization/proxy enrichment using MaxMind databases.
## Install
```shell
pip install polars-iptools
```
## Examples
### Simple enrichments
IPTools' Rust implementation gives you speedy answers to basic IP questions like "is this a private IP?"
```python
>>> import polars as pl
>>> import polars_iptools as ip
>>> df = pl.DataFrame({'ip': ['8.8.8.8', '2606:4700::1111', '192.168.100.100', '172.21.1.1', '172.34.5.5', 'a.b.c.d']})
>>> df.with_columns(ip.is_private(pl.col('ip')).alias('is_private'))
shape: (6, 2)
┌─────────────────┬────────────┐
│ ip ┆ is_private │
│ --- ┆ --- │
│ str ┆ bool │
╞═════════════════╪════════════╡
│ 8.8.8.8 ┆ false │
│ 2606:4700::1111 ┆ false │
│ 192.168.100.100 ┆ true │
│ 172.21.1.1 ┆ true │
│ 172.34.5.5 ┆ false │
│ a.b.c.d ┆ false │
└─────────────────┴────────────┘
```
### `is_in` but for network ranges
Pandas and Polars have `is_in` functions to perform membership lookups. IPTools extends this to enable IP address membership in IP _networks_. This function works seamlessly with both IPv4 and IPv6 addresses and converts the specified networks into a [Level-Compressed trie (LC-Trie)](https://github.com/Orange-OpenSource/iptrie) for fast, efficient lookups.
```python
>>> import polars as pl
>>> import polars_iptools as ip
>>> df = pl.DataFrame({'ip': ['8.8.8.8', '1.1.1.1', '2606:4700::1111']})
>>> networks = ['8.8.8.0/24', '2606:4700::/32']
>>> df.with_columns(ip.is_in(pl.col('ip'), networks).alias('is_in'))
shape: (3, 2)
┌─────────────────┬───────┐
│ ip ┆ is_in │
│ --- ┆ --- │
│ str ┆ bool │
╞═════════════════╪═══════╡
│ 8.8.8.8 ┆ true │
│ 1.1.1.1 ┆ false │
│ 2606:4700::1111 ┆ true │
└─────────────────┴───────┘
```
### GeoIP enrichment
Using [MaxMind's](https://www.maxmind.com/en/geoip-databases) _GeoLite2-ASN.mmdb_ and _GeoLite2-City.mmdb_ databases, IPTools provides offline enrichment of network ownership and geolocation.
`ip.geoip.full` returns a Polars struct containing all available metadata parameters. If you just want the ASN and AS organization, you can use `ip.geoip.asn`.
```python
>>> import polars as pl
>>> import polars_iptools as ip
>>> df = pl.DataFrame({"ip":["8.8.8.8", "192.168.1.1", "2606:4700::1111", "999.abc.def.123"]})
>>> df.with_columns([ip.geoip.full(pl.col("ip")).alias("geoip")])
shape: (4, 2)
┌─────────────────┬─────────────────────────────────┐
│ ip ┆ geoip │
│ --- ┆ --- │
│ str ┆ struct[11] │
╞═════════════════╪═════════════════════════════════╡
│ 8.8.8.8 ┆ {15169,"GOOGLE","","NA","","",… │
│ 192.168.1.1 ┆ {0,"","","","","","","",0.0,0.… │
│ 2606:4700::1111 ┆ {13335,"CLOUDFLARENET","","","… │
│ 999.abc.def.123 ┆ {null,null,null,null,null,null… │
└─────────────────┴─────────────────────────────────┘
>>> df.with_columns([ip.geoip.asn(pl.col("ip")).alias("asn")])
shape: (4, 2)
┌─────────────────┬───────────────────────┐
│ ip ┆ asn │
│ --- ┆ --- │
│ str ┆ str │
╞═════════════════╪═══════════════════════╡
│ 8.8.8.8 ┆ AS15169 GOOGLE │
│ 192.168.1.1 ┆ │
│ 2606:4700::1111 ┆ AS13335 CLOUDFLARENET │
│ 999.abc.def.123 ┆ │
└─────────────────┴───────────────────────┘
```
### Spur enrichment
[Spur](https://spur.us/) is a commercial service that provides "data to detect VPNs, residential proxies, and bots". One of its offerings is a [Maxmind mmdb format](https://docs.spur.us/feeds?id=feed-export-utility) of at most 2,000,000 "busiest" Anonymous or Anonymous+Residential ips.
`ip.spur.full` returns a Polars struct containing all available metadata parameters.
```python
>>> import polars as pl
>>> import polars_iptools as ip
>>> df = pl.DataFrame({"ip":["8.8.8.8", "192.168.1.1", "999.abc.def.123"]})
>>> df.with_columns([ip.spur.full(pl.col("ip")).alias("spur")])
shape: (3, 2)
┌─────────────────┬─────────────────────────────────┐
│ ip ┆ geoip │
│ --- ┆ --- │
│ str ┆ struct[7] │
╞═════════════════╪═════════════════════════════════╡
│ 8.8.8.8 ┆ {0.0,"","","","","",null} │
│ 192.168.1.1 ┆ {0.0,"","","","","",null} │
│ 999.abc.def.123 ┆ {null,null,null,null,null,null… │
└─────────────────┴─────────────────────────────────┘
```
## Environment Configuration
IPTools uses two MaxMind databases: _GeoLite2-ASN.mmdb_ and _GeoLite2-City.mmdb_. You only need these files if you call the geoip functions.
Set the `MAXMIND_MMDB_DIR` environment variable to tell the extension where these files are located.
```shell
export MAXMIND_MMDB_DIR=/path/to/your/mmdb/files
# or Windows users
set MAXMIND_MMDB_DIR=c:\path\to\your\mmdb\files
````
If the environment is not set, polars_iptools will check two other common locations (on Mac/Linux):
```
/usr/local/share/GeoIP
/opt/homebrew/var/GeoIP
```
### Spur Environment
If you're a Spur customer, export the feed as `spur.mmdb` and specify its location using `SPUR_MMDB_DIR` environment variable.
```shell
export SPUR_MMDB_DIR=/path/to/spur/mmdb
# or Windows users
set SPUR_MMDB_DIR=c:\path\to\spur\mmdb
````
## Credit
Developing this extension was super easy by following Marco Gorelli's [tutorial](https://marcogorelli.github.io/polars-plugins-tutorial/) and [cookiecutter template](https://github.com/MarcoGorelli/cookiecutter-polars-plugins).
Raw data
{
"_id": null,
"home_page": null,
"name": "polars-iptools",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "polars, dfir, geoip",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/a0/95/8681705050a97fd249d5b8a422d0e6d670372037f1009ea7b0780b37f29f/polars_iptools-0.1.8.tar.gz",
"platform": null,
"description": "# Polars IPTools\n\nPolars IPTools is a Rust-based extension to accelerates IP address manipulation and enrichment in Polars dataframes. This library includes various utility functions for working with IPv4 and IPv6 addresses and geoip and anonymization/proxy enrichment using MaxMind databases.\n\n## Install\n\n```shell\npip install polars-iptools\n```\n\n## Examples\n\n### Simple enrichments\n\nIPTools' Rust implementation gives you speedy answers to basic IP questions like \"is this a private IP?\"\n\n```python\n>>> import polars as pl\n>>> import polars_iptools as ip\n>>> df = pl.DataFrame({'ip': ['8.8.8.8', '2606:4700::1111', '192.168.100.100', '172.21.1.1', '172.34.5.5', 'a.b.c.d']})\n>>> df.with_columns(ip.is_private(pl.col('ip')).alias('is_private'))\nshape: (6, 2)\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 ip \u2506 is_private \u2502\n\u2502 --- \u2506 --- \u2502\n\u2502 str \u2506 bool \u2502\n\u255e\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n\u2502 8.8.8.8 \u2506 false \u2502\n\u2502 2606:4700::1111 \u2506 false \u2502\n\u2502 192.168.100.100 \u2506 true \u2502\n\u2502 172.21.1.1 \u2506 true \u2502\n\u2502 172.34.5.5 \u2506 false \u2502\n\u2502 a.b.c.d \u2506 false \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n### `is_in` but for network ranges\n\nPandas and Polars have `is_in` functions to perform membership lookups. IPTools extends this to enable IP address membership in IP _networks_. This function works seamlessly with both IPv4 and IPv6 addresses and converts the specified networks into a [Level-Compressed trie (LC-Trie)](https://github.com/Orange-OpenSource/iptrie) for fast, efficient lookups.\n\n```python\n>>> import polars as pl\n>>> import polars_iptools as ip\n>>> df = pl.DataFrame({'ip': ['8.8.8.8', '1.1.1.1', '2606:4700::1111']})\n>>> networks = ['8.8.8.0/24', '2606:4700::/32']\n>>> df.with_columns(ip.is_in(pl.col('ip'), networks).alias('is_in'))\nshape: (3, 2)\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 ip \u2506 is_in \u2502\n\u2502 --- \u2506 --- \u2502\n\u2502 str \u2506 bool \u2502\n\u255e\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n\u2502 8.8.8.8 \u2506 true \u2502\n\u2502 1.1.1.1 \u2506 false \u2502\n\u2502 2606:4700::1111 \u2506 true \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n### GeoIP enrichment\n\nUsing [MaxMind's](https://www.maxmind.com/en/geoip-databases) _GeoLite2-ASN.mmdb_ and _GeoLite2-City.mmdb_ databases, IPTools provides offline enrichment of network ownership and geolocation.\n\n`ip.geoip.full` returns a Polars struct containing all available metadata parameters. If you just want the ASN and AS organization, you can use `ip.geoip.asn`.\n\n```python\n>>> import polars as pl\n>>> import polars_iptools as ip\n\n>>> df = pl.DataFrame({\"ip\":[\"8.8.8.8\", \"192.168.1.1\", \"2606:4700::1111\", \"999.abc.def.123\"]})\n>>> df.with_columns([ip.geoip.full(pl.col(\"ip\")).alias(\"geoip\")])\n\nshape: (4, 2)\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 ip \u2506 geoip \u2502\n\u2502 --- \u2506 --- \u2502\n\u2502 str \u2506 struct[11] \u2502\n\u255e\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n\u2502 8.8.8.8 \u2506 {15169,\"GOOGLE\",\"\",\"NA\",\"\",\"\",\u2026 \u2502\n\u2502 192.168.1.1 \u2506 {0,\"\",\"\",\"\",\"\",\"\",\"\",\"\",0.0,0.\u2026 \u2502\n\u2502 2606:4700::1111 \u2506 {13335,\"CLOUDFLARENET\",\"\",\"\",\"\u2026 \u2502\n\u2502 999.abc.def.123 \u2506 {null,null,null,null,null,null\u2026 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n>>> df.with_columns([ip.geoip.asn(pl.col(\"ip\")).alias(\"asn\")])\nshape: (4, 2)\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 ip \u2506 asn \u2502\n\u2502 --- \u2506 --- \u2502\n\u2502 str \u2506 str \u2502\n\u255e\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n\u2502 8.8.8.8 \u2506 AS15169 GOOGLE \u2502\n\u2502 192.168.1.1 \u2506 \u2502\n\u2502 2606:4700::1111 \u2506 AS13335 CLOUDFLARENET \u2502\n\u2502 999.abc.def.123 \u2506 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n### Spur enrichment\n\n[Spur](https://spur.us/) is a commercial service that provides \"data to detect VPNs, residential proxies, and bots\". One of its offerings is a [Maxmind mmdb format](https://docs.spur.us/feeds?id=feed-export-utility) of at most 2,000,000 \"busiest\" Anonymous or Anonymous+Residential ips.\n\n`ip.spur.full` returns a Polars struct containing all available metadata parameters.\n\n```python\n>>> import polars as pl\n>>> import polars_iptools as ip\n\n>>> df = pl.DataFrame({\"ip\":[\"8.8.8.8\", \"192.168.1.1\", \"999.abc.def.123\"]})\n>>> df.with_columns([ip.spur.full(pl.col(\"ip\")).alias(\"spur\")])\n\nshape: (3, 2)\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 ip \u2506 geoip \u2502\n\u2502 --- \u2506 --- \u2502\n\u2502 str \u2506 struct[7] \u2502\n\u255e\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n\u2502 8.8.8.8 \u2506 {0.0,\"\",\"\",\"\",\"\",\"\",null} \u2502\n\u2502 192.168.1.1 \u2506 {0.0,\"\",\"\",\"\",\"\",\"\",null} \u2502\n\u2502 999.abc.def.123 \u2506 {null,null,null,null,null,null\u2026 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n## Environment Configuration\n\nIPTools uses two MaxMind databases: _GeoLite2-ASN.mmdb_ and _GeoLite2-City.mmdb_. You only need these files if you call the geoip functions.\n\nSet the `MAXMIND_MMDB_DIR` environment variable to tell the extension where these files are located.\n\n```shell\nexport MAXMIND_MMDB_DIR=/path/to/your/mmdb/files\n# or Windows users\nset MAXMIND_MMDB_DIR=c:\\path\\to\\your\\mmdb\\files\n````\n\nIf the environment is not set, polars_iptools will check two other common locations (on Mac/Linux):\n\n```\n/usr/local/share/GeoIP\n/opt/homebrew/var/GeoIP\n```\n\n### Spur Environment\n\nIf you're a Spur customer, export the feed as `spur.mmdb` and specify its location using `SPUR_MMDB_DIR` environment variable.\n\n```shell\nexport SPUR_MMDB_DIR=/path/to/spur/mmdb\n# or Windows users\nset SPUR_MMDB_DIR=c:\\path\\to\\spur\\mmdb\n````\n\n## Credit\n\nDeveloping this extension was super easy by following Marco Gorelli's [tutorial](https://marcogorelli.github.io/polars-plugins-tutorial/) and [cookiecutter template](https://github.com/MarcoGorelli/cookiecutter-polars-plugins).\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Polars extension for IP address parsing and enrichment including geolocation",
"version": "0.1.8",
"project_urls": {
"Source Code": "https://github.com/erichutchins/polars_iptools"
},
"split_keywords": [
"polars",
" dfir",
" geoip"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "2448f2bc882b941f2a15e136fc21ff489c355ab1ad5f59294dad949b858a2ed5",
"md5": "4523f458a704cbf51d391d5f22bd6762",
"sha256": "55a31af3cc6edc4bfbaaca3ac90f41db0bca8d76eecc0541c73720cfe90e9f1f"
},
"downloads": -1,
"filename": "polars_iptools-0.1.8-cp38-abi3-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "4523f458a704cbf51d391d5f22bd6762",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 3202026,
"upload_time": "2024-09-10T11:48:07",
"upload_time_iso_8601": "2024-09-10T11:48:07.436986Z",
"url": "https://files.pythonhosted.org/packages/24/48/f2bc882b941f2a15e136fc21ff489c355ab1ad5f59294dad949b858a2ed5/polars_iptools-0.1.8-cp38-abi3-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "61e346b3a69dd9f00d31340e4fb96c8ccd478741ef6d137a3840c01a331c0617",
"md5": "74f4503a3e78868751b61f454d576c50",
"sha256": "cd0a9c0d7ade0bad8e1f281ab8bbbd150d4bc8310130fb9e17c70eca019c5b7c"
},
"downloads": -1,
"filename": "polars_iptools-0.1.8-cp38-abi3-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "74f4503a3e78868751b61f454d576c50",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 2836001,
"upload_time": "2024-09-10T11:48:09",
"upload_time_iso_8601": "2024-09-10T11:48:09.462372Z",
"url": "https://files.pythonhosted.org/packages/61/e3/46b3a69dd9f00d31340e4fb96c8ccd478741ef6d137a3840c01a331c0617/polars_iptools-0.1.8-cp38-abi3-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a6a2f043db553a2933c54f6dbc746d0e137ca2bbfbc9ad225ee2d599c703ae2c",
"md5": "c6dcd87a2f4c4a33d72ee95b142764f4",
"sha256": "dde32d75efc9be1a1cce42aeb736a6f255d143f56eeadf6d81ec00e6fd3b55cd"
},
"downloads": -1,
"filename": "polars_iptools-0.1.8-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.whl",
"has_sig": false,
"md5_digest": "c6dcd87a2f4c4a33d72ee95b142764f4",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 3896882,
"upload_time": "2024-09-10T11:48:11",
"upload_time_iso_8601": "2024-09-10T11:48:11.417791Z",
"url": "https://files.pythonhosted.org/packages/a6/a2/f043db553a2933c54f6dbc746d0e137ca2bbfbc9ad225ee2d599c703ae2c/polars_iptools-0.1.8-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d58360e23beb6ac391d42f4b16c55a17b110017a622109fbd933ccf1b2eac42a",
"md5": "88258edb421c87f3094a83f0501e9cf5",
"sha256": "4f6d0be5794d476c48eb729a3949939369cf65270fba92e117cada7ce32acd33"
},
"downloads": -1,
"filename": "polars_iptools-0.1.8-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "88258edb421c87f3094a83f0501e9cf5",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 3796361,
"upload_time": "2024-09-10T11:48:13",
"upload_time_iso_8601": "2024-09-10T11:48:13.522271Z",
"url": "https://files.pythonhosted.org/packages/d5/83/60e23beb6ac391d42f4b16c55a17b110017a622109fbd933ccf1b2eac42a/polars_iptools-0.1.8-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "7e08285109382c52266129d19f3ac258ba8cc1f9f26d4e45ba125fc091fc8ea2",
"md5": "2a88f60bc24d4797e21f89a79b424c6c",
"sha256": "87dbaf08c58deba708df46ae370381ab71748d39cf508ef108e7eb59a8058d8d"
},
"downloads": -1,
"filename": "polars_iptools-0.1.8-cp38-abi3-win_amd64.whl",
"has_sig": false,
"md5_digest": "2a88f60bc24d4797e21f89a79b424c6c",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 3512046,
"upload_time": "2024-09-10T11:48:15",
"upload_time_iso_8601": "2024-09-10T11:48:15.445402Z",
"url": "https://files.pythonhosted.org/packages/7e/08/285109382c52266129d19f3ac258ba8cc1f9f26d4e45ba125fc091fc8ea2/polars_iptools-0.1.8-cp38-abi3-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a0958681705050a97fd249d5b8a422d0e6d670372037f1009ea7b0780b37f29f",
"md5": "5107a56787682168e169e06b52ed6d4b",
"sha256": "4210a58b89b279a74335ff28be3602f325cef3c18a825e0a8f0d969c44d8e77e"
},
"downloads": -1,
"filename": "polars_iptools-0.1.8.tar.gz",
"has_sig": false,
"md5_digest": "5107a56787682168e169e06b52ed6d4b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 48163,
"upload_time": "2024-09-10T11:48:17",
"upload_time_iso_8601": "2024-09-10T11:48:17.014689Z",
"url": "https://files.pythonhosted.org/packages/a0/95/8681705050a97fd249d5b8a422d0e6d670372037f1009ea7b0780b37f29f/polars_iptools-0.1.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-10 11:48:17",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "erichutchins",
"github_project": "polars_iptools",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "polars",
"specs": []
},
{
"name": "maturin",
"specs": []
},
{
"name": "ruff",
"specs": []
},
{
"name": "pytest",
"specs": []
},
{
"name": "mypy",
"specs": []
}
],
"lcname": "polars-iptools"
}