lsm
===
Fast Python bindings for [SQLite's LSM key/value store](http://www.sqlite.org/src4/doc/trunk/www/lsmusr.wiki>).
The LSM storage engine was initially written as part of the experimental
SQLite4 rewrite (now abandoned). More recently, the LSM source code was moved
into the SQLite3 [source tree](https://www.sqlite.org/cgi/src/dir?ci=e148cdad35520e66&name=ext/lsm1)
and has seen some improvements and fixes. This project uses the LSM code from
the SQLite3 source tree.
Features:
* Embedded zero-conf database.
* Keys support in-order traversal using cursors.
* Transactional (including nested transactions).
* Single writer/multiple reader MVCC based transactional concurrency model.
* On-disk database stored in a single file.
* Data is durable in the face of application or power failure.
* Thread-safe.
* Releases GIL for read and write operations
(each connection has own mutex)
* Page compression (lz4 or zstd)
* Zero dependency static library
* Python 3.x.
Limitations:
The source for Python lsm is
[hosted on GitHub](https://github.com/mosquito/python-lsm).
If you encounter any bugs in the library, please
[open an issue](https://github.com/mosquito/python-lsm/issues/new),
including a description of the bug and any related traceback.
## Quick-start
Below is a sample interactive console session designed to show some of the
basic features and functionality of the ``lsm`` Python library.
To begin, instantiate a `LSM` object, specifying a path to a database file.
<!-- name: test_example_db -->
```python
from lsm import LSM
db = LSM('test.ldb')
assert db.open()
```
More pythonic variant is using context manager:
<!-- name: test_example_db_context_manager -->
```python
from lsm import LSM
with LSM("test.ldb") as db:
assert db.info()
```
Not opened database will raise a RuntimeError:
<!-- name: test_example_db -->
```python
import pytest
from lsm import LSM
db = LSM('test.ldb')
with pytest.raises(RuntimeError):
db.info()
```
### Binary/string mode
You should select mode for opening the database with ``binary: bool = True``
argument.
For example when you want to store strings just pass ``binary=False``:
<!-- name: test_binary_mode -->
```python
from lsm import LSM
with LSM("test_0.ldb", binary=False) as db:
# must be str for keys and values
db['foo'] = 'bar'
assert db['foo'] == "bar"
```
Otherwise, you must pass keys and values ad ``bytes`` (default behaviour):
<!-- name: test_string_mode -->
```python
from lsm import LSM
with LSM("test.ldb") as db:
db[b'foo'] = b'bar'
assert db[b'foo'] == b'bar'
```
### Key/Value Features
``lsm`` is a key/value store, and has a dictionary-like API:
<!-- name: test_getitem -->
```python
from lsm import LSM
with LSM("test.ldb", binary=False) as db:
db['foo'] = 'bar'
assert db['foo'] == 'bar'
```
Database apply changes as soon as possible:
<!-- name: test_get_del_item -->
```python
import pytest
from lsm import LSM
with LSM("test.ldb", binary=False) as db:
for i in range(4):
db[f'k{i}'] = str(i)
assert 'k3' in db
assert 'k4' not in db
del db['k3']
with pytest.raises(KeyError):
print(db['k3'])
```
By default, when you attempt to look up a key, ``lsm`` will search for an
exact match. You can also search for the closest key, if the specific key you
are searching for does not exist:
<!-- name: test_get_del_item_seek_mode -->
```python
import pytest
from lsm import LSM, SEEK_LE, SEEK_GE, SEEK_LEFAST
with LSM("test.ldb", binary=False) as db:
for i in range(4):
db[f'k{i}'] = str(i)
# Here we will match "k1".
assert db['k1xx', SEEK_LE] == '1'
# Here we will match "k1" but do not fetch a value
# In this case the value will always be ``True`` or there will
# be an exception if the key is not found
assert db['k1xx', SEEK_LEFAST] is True
with pytest.raises(KeyError):
print(db['000', SEEK_LEFAST])
# Here we will match "k2".
assert db['k1xx', SEEK_GE] == "2"
```
`LSM` supports other common dictionary methods such as:
* `keys()`
* `values()`
* `items()`
* `update()`
### Slices and Iteration
The database can be iterated through directly, or sliced. When you are slicing
the database the start and end keys need not exist -- ``lsm`` will find the
closest key (details can be found in the [LSM.fetch_range()](https://lsm-db.readthedocs.io/en/latest/api.html#lsm.LSM.fetch_range)
documentation).
<!--
name: test_slices;
-->
```python
from lsm import LSM
with LSM("test_slices.ldb", binary=False) as db:
# clean database
for key in db.keys():
del db[key]
db['foo'] = 'bar'
for i in range(3):
db[f'k{i}'] = str(i)
# Can easily iterate over the database items
assert (
sorted(item for item in db.items()) == [
('foo', 'bar'), ('k0', '0'), ('k1', '1'), ('k2', '2')
]
)
# However, you will not read the entire database into memory, as special
# iterator objects are used.
assert str(db['k0':'k99']).startswith("<lsm_slice object at")
# But you can cast it to the list for example
assert list(db['k0':'k99']) == [('k0', '0'), ('k1', '1'), ('k2', '2')]
```
You can use open-ended slices. If the lower- or upper-bound is outside the
range of keys an empty list is returned.
<!--
name: test_slices;
case: open_ended_slices
-->
```python
with LSM("test_slices.ldb", binary=False, readonly=True) as db:
assert list(db['k0':]) == [('k0', '0'), ('k1', '1'), ('k2', '2')]
assert list(db[:'k1']) == [('foo', 'bar'), ('k0', '0'), ('k1', '1')]
assert list(db[:'aaa']) == []
```
To retrieve keys in reverse order or stepping over more than one item,
simply use a third slice argument as usual.
Negative step value means reverse order, but first and second arguments
must be ordinarily ordered.
<!--
name: test_slices;
case: reverse_slices
-->
```python
with LSM("test_slices.ldb", binary=False, readonly=True) as db:
assert list(db['k0':'k99':2]) == [('k0', '0'), ('k2', '2')]
assert list(db['k0'::-1]) == [('k2', '2'), ('k1', '1'), ('k0', '0')]
assert list(db['k0'::-2]) == [('k2', '2'), ('k0', '0')]
assert list(db['k0'::3]) == [('k0', '0')]
```
You can also **delete** slices of keys, but note that delete **will not**
include the keys themselves:
<!--
name: test_slices;
case: del_slice
-->
```python
with LSM("test_slices.ldb", binary=False) as db:
del db['k0':'k99']
# Note that 'k0' still exists.
assert list(db.items()) == [('foo', 'bar'), ('k0', '0')]
```
### Cursors
While slicing may cover most use-cases, for finer-grained control you can use
cursors for traversing records.
<!--
name: test_cursors;
case: iterate_over_one_item
-->
```python
from lsm import LSM, SEEK_GE, SEEK_LE
with LSM("test_cursors.ldb", binary=False) as db:
del db["a":"z"]
db["spam"] = "spam"
with db.cursor() as cursor:
cursor.seek('spam')
key, value = cursor.retrieve()
assert key == 'spam'
assert value == 'spam'
```
Seeking over cursors:
<!--
name: test_cursors;
case: iterate_over_multiple_items
-->
```python
with LSM("test_cursors.ldb", binary=False) as db:
db.update({'k0': '0', 'k1': '1', 'k2': '2', 'k3': '3', 'foo': 'bar'})
with db.cursor() as cursor:
cursor.first()
key, value = cursor.retrieve()
assert key == "foo"
assert value == "bar"
cursor.last()
key, value = cursor.retrieve()
assert key == "spam"
assert value == "spam"
cursor.previous()
key, value = cursor.retrieve()
assert key == "k3"
assert value == "3"
```
Finding the first match that is greater than or equal to `'k0'` and move
forward until the key is less than `'k99'`
<!--
name: test_cursors;
case: iterate_ge_until_k99
-->
```python
with LSM("test_cursors.ldb", binary=False) as db:
with db.cursor() as cursor:
cursor.seek("k0", SEEK_GE)
results = []
while cursor.compare("k99") > 0:
key, value = cursor.retrieve()
results.append((key, value))
cursor.next()
assert results == [('k0', '0'), ('k1', '1'), ('k2', '2'), ('k3', '3')]
```
Finding the last match that is lower than or equal to `'k99'` and move
backward until the key is less than `'k0'`
<!--
name: test_cursors;
case: iterate_le_until_k0
-->
```python
with LSM("test_cursors.ldb", binary=False) as db:
with db.cursor() as cursor:
cursor.seek("k99", SEEK_LE)
results = []
while cursor.compare("k0") >= 0:
key, value = cursor.retrieve()
results.append((key, value))
cursor.previous()
assert results == [('k3', '3'), ('k2', '2'), ('k1', '1'), ('k0', '0')]
```
It is very important to close a cursor when you are through using it. For this
reason, it is recommended you use the `LSM.cursor()` context-manager, which
ensures the cursor is closed properly.
### Transactions
``lsm`` supports nested transactions. The simplest way to use transactions
is with the `LSM.transaction()` method, which returns a context-manager:
<!-- name: test_transactions -->
```python
from lsm import LSM
with LSM("test_tx.ldb", binary=False) as db:
del db["a":"z"]
for i in range(10):
db[f"k{i}"] = f"{i}"
with LSM("test_tx.ldb", binary=False) as db:
with db.transaction() as tx1:
db['k1'] = '1-mod'
with db.transaction() as tx2:
db['k2'] = '2-mod'
tx2.rollback()
assert db['k1'] == '1-mod'
assert db['k2'] == '2'
```
You can commit or roll-back transactions part-way through a wrapped block:
<!-- name: test_transactions_2 -->
```python
from lsm import LSM
with LSM("test_tx_2.ldb", binary=False) as db:
del db["a":"z"]
for i in range(10):
db[f"k{i}"] = f"{i}"
with LSM("test_tx_2.ldb", binary=False) as db:
with db.transaction() as txn:
db['k1'] = 'outer txn'
# The write operation is preserved.
txn.commit()
db['k1'] = 'outer txn-2'
with db.transaction() as txn2:
# This is committed after the block ends.
db['k1'] = 'inner-txn'
assert db['k1'] == "inner-txn"
# Rolls back both the changes from txn2 and the preceding write.
txn.rollback()
assert db['k1'] == 'outer txn', db['k1']
```
If you like, you can also explicitly call `LSM.begin()`, `LSM.commit()`, and
`LSM.rollback()`.
<!-- name: test_transactions_db -->
```python
from lsm import LSM
# fill db
with LSM("test_db_tx.ldb", binary=False) as db:
del db["k":"z"]
for i in range(10):
db[f"k{i}"] = f"{i}"
with LSM("test_db_tx.ldb", binary=False) as db:
# start transaction
db.begin()
db['k1'] = '1-mod'
# nested transaction
db.begin()
db['k2'] = '2-mod'
# rolling back nested transaction
db.rollback()
# comitting top-level transaction
db.commit()
assert db['k1'] == '1-mod'
assert db['k2'] == '2'
```
### Thanks to
* [@coleifer](https://github.com/coleifer) - this project was inspired by
[coleifer/python-lsm-db](https://github.com/coleifer/python-lsm-db).
Raw data
{
"_id": null,
"home_page": "https://github.com/mosquito/python-lsm/",
"name": "lsm",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6,<4",
"maintainer_email": "",
"keywords": "",
"author": "Dmitry Orlov",
"author_email": "me@mosquito.su",
"download_url": "https://files.pythonhosted.org/packages/06/6b/0ffe3ccab39dc87807aa52ddde66c7947324bbf1827604df571a44c5a64e/lsm-0.5.4.tar.gz",
"platform": null,
"description": "lsm\n===\n\nFast Python bindings for [SQLite's LSM key/value store](http://www.sqlite.org/src4/doc/trunk/www/lsmusr.wiki>).\nThe LSM storage engine was initially written as part of the experimental\nSQLite4 rewrite (now abandoned). More recently, the LSM source code was moved\ninto the SQLite3 [source tree](https://www.sqlite.org/cgi/src/dir?ci=e148cdad35520e66&name=ext/lsm1)\nand has seen some improvements and fixes. This project uses the LSM code from\nthe SQLite3 source tree.\n\nFeatures:\n\n* Embedded zero-conf database.\n* Keys support in-order traversal using cursors.\n* Transactional (including nested transactions).\n* Single writer/multiple reader MVCC based transactional concurrency model.\n* On-disk database stored in a single file.\n* Data is durable in the face of application or power failure.\n* Thread-safe.\n* Releases GIL for read and write operations\n (each connection has own mutex)\n* Page compression (lz4 or zstd)\n* Zero dependency static library\n* Python 3.x.\n\nLimitations:\n\nThe source for Python lsm is\n[hosted on GitHub](https://github.com/mosquito/python-lsm).\n\nIf you encounter any bugs in the library, please\n[open an issue](https://github.com/mosquito/python-lsm/issues/new),\nincluding a description of the bug and any related traceback.\n\n## Quick-start\n\nBelow is a sample interactive console session designed to show some of the\nbasic features and functionality of the ``lsm`` Python library.\n\nTo begin, instantiate a `LSM` object, specifying a path to a database file.\n\n<!-- name: test_example_db -->\n```python\nfrom lsm import LSM\ndb = LSM('test.ldb')\nassert db.open()\n```\n\nMore pythonic variant is using context manager:\n\n<!-- name: test_example_db_context_manager -->\n```python\nfrom lsm import LSM\nwith LSM(\"test.ldb\") as db:\n assert db.info()\n```\n\nNot opened database will raise a RuntimeError:\n\n<!-- name: test_example_db -->\n```python\nimport pytest\nfrom lsm import LSM\n\ndb = LSM('test.ldb')\n\nwith pytest.raises(RuntimeError):\n db.info()\n```\n\n### Binary/string mode\n\nYou should select mode for opening the database with ``binary: bool = True``\nargument.\n\nFor example when you want to store strings just pass ``binary=False``:\n\n<!-- name: test_binary_mode -->\n```python\nfrom lsm import LSM\nwith LSM(\"test_0.ldb\", binary=False) as db:\n # must be str for keys and values\n db['foo'] = 'bar'\n assert db['foo'] == \"bar\"\n```\n\nOtherwise, you must pass keys and values ad ``bytes`` (default behaviour):\n\n<!-- name: test_string_mode -->\n```python\nfrom lsm import LSM\n\nwith LSM(\"test.ldb\") as db:\n db[b'foo'] = b'bar'\n assert db[b'foo'] == b'bar'\n```\n\n### Key/Value Features\n\n``lsm`` is a key/value store, and has a dictionary-like API:\n\n<!-- name: test_getitem -->\n```python\nfrom lsm import LSM\nwith LSM(\"test.ldb\", binary=False) as db:\n db['foo'] = 'bar'\n assert db['foo'] == 'bar'\n```\n\nDatabase apply changes as soon as possible:\n\n<!-- name: test_get_del_item -->\n```python\nimport pytest\nfrom lsm import LSM\n\nwith LSM(\"test.ldb\", binary=False) as db:\n for i in range(4):\n db[f'k{i}'] = str(i)\n\n assert 'k3' in db\n assert 'k4' not in db\n del db['k3']\n\n with pytest.raises(KeyError):\n print(db['k3'])\n```\n\nBy default, when you attempt to look up a key, ``lsm`` will search for an\nexact match. You can also search for the closest key, if the specific key you\nare searching for does not exist:\n\n<!-- name: test_get_del_item_seek_mode -->\n```python\nimport pytest\nfrom lsm import LSM, SEEK_LE, SEEK_GE, SEEK_LEFAST\n\n\nwith LSM(\"test.ldb\", binary=False) as db:\n for i in range(4):\n db[f'k{i}'] = str(i)\n\n # Here we will match \"k1\".\n assert db['k1xx', SEEK_LE] == '1'\n\n # Here we will match \"k1\" but do not fetch a value\n # In this case the value will always be ``True`` or there will\n # be an exception if the key is not found\n assert db['k1xx', SEEK_LEFAST] is True\n\n with pytest.raises(KeyError):\n print(db['000', SEEK_LEFAST])\n\n # Here we will match \"k2\".\n assert db['k1xx', SEEK_GE] == \"2\"\n```\n\n`LSM` supports other common dictionary methods such as:\n\n* `keys()`\n* `values()`\n* `items()`\n* `update()`\n\n\n### Slices and Iteration\n\nThe database can be iterated through directly, or sliced. When you are slicing\nthe database the start and end keys need not exist -- ``lsm`` will find the\nclosest key (details can be found in the [LSM.fetch_range()](https://lsm-db.readthedocs.io/en/latest/api.html#lsm.LSM.fetch_range)\ndocumentation).\n\n<!--\n name: test_slices;\n-->\n```python\nfrom lsm import LSM\n\nwith LSM(\"test_slices.ldb\", binary=False) as db:\n\n # clean database\n for key in db.keys():\n del db[key]\n\n db['foo'] = 'bar'\n\n for i in range(3):\n db[f'k{i}'] = str(i)\n\n # Can easily iterate over the database items\n assert (\n sorted(item for item in db.items()) == [\n ('foo', 'bar'), ('k0', '0'), ('k1', '1'), ('k2', '2')\n ]\n )\n\n # However, you will not read the entire database into memory, as special\n # iterator objects are used.\n assert str(db['k0':'k99']).startswith(\"<lsm_slice object at\")\n\n # But you can cast it to the list for example\n assert list(db['k0':'k99']) == [('k0', '0'), ('k1', '1'), ('k2', '2')]\n```\n\nYou can use open-ended slices. If the lower- or upper-bound is outside the\nrange of keys an empty list is returned.\n\n\n<!--\n name: test_slices;\n case: open_ended_slices\n-->\n```python\nwith LSM(\"test_slices.ldb\", binary=False, readonly=True) as db:\n assert list(db['k0':]) == [('k0', '0'), ('k1', '1'), ('k2', '2')]\n assert list(db[:'k1']) == [('foo', 'bar'), ('k0', '0'), ('k1', '1')]\n assert list(db[:'aaa']) == []\n```\n\nTo retrieve keys in reverse order or stepping over more than one item,\nsimply use a third slice argument as usual.\nNegative step value means reverse order, but first and second arguments\nmust be ordinarily ordered.\n\n<!--\n name: test_slices;\n case: reverse_slices\n-->\n```python\nwith LSM(\"test_slices.ldb\", binary=False, readonly=True) as db:\n assert list(db['k0':'k99':2]) == [('k0', '0'), ('k2', '2')]\n assert list(db['k0'::-1]) == [('k2', '2'), ('k1', '1'), ('k0', '0')]\n assert list(db['k0'::-2]) == [('k2', '2'), ('k0', '0')]\n assert list(db['k0'::3]) == [('k0', '0')]\n```\n\nYou can also **delete** slices of keys, but note that delete **will not**\ninclude the keys themselves:\n\n<!--\n name: test_slices;\n case: del_slice\n-->\n```python\nwith LSM(\"test_slices.ldb\", binary=False) as db:\n del db['k0':'k99']\n\n # Note that 'k0' still exists.\n assert list(db.items()) == [('foo', 'bar'), ('k0', '0')]\n```\n\n### Cursors\n\nWhile slicing may cover most use-cases, for finer-grained control you can use\ncursors for traversing records.\n\n<!--\n name: test_cursors;\n case: iterate_over_one_item\n-->\n```python\nfrom lsm import LSM, SEEK_GE, SEEK_LE\n\nwith LSM(\"test_cursors.ldb\", binary=False) as db:\n del db[\"a\":\"z\"]\n\n db[\"spam\"] = \"spam\"\n\n with db.cursor() as cursor:\n cursor.seek('spam')\n key, value = cursor.retrieve()\n assert key == 'spam'\n assert value == 'spam'\n```\n\nSeeking over cursors:\n\n<!--\n name: test_cursors;\n case: iterate_over_multiple_items\n-->\n```python\nwith LSM(\"test_cursors.ldb\", binary=False) as db:\n db.update({'k0': '0', 'k1': '1', 'k2': '2', 'k3': '3', 'foo': 'bar'})\n\n with db.cursor() as cursor:\n\n cursor.first()\n key, value = cursor.retrieve()\n assert key == \"foo\"\n assert value == \"bar\"\n\n cursor.last()\n key, value = cursor.retrieve()\n assert key == \"spam\"\n assert value == \"spam\"\n\n cursor.previous()\n key, value = cursor.retrieve()\n assert key == \"k3\"\n assert value == \"3\"\n\n```\n\nFinding the first match that is greater than or equal to `'k0'` and move\nforward until the key is less than `'k99'`\n\n<!--\n name: test_cursors;\n case: iterate_ge_until_k99\n-->\n```python\nwith LSM(\"test_cursors.ldb\", binary=False) as db:\n with db.cursor() as cursor:\n cursor.seek(\"k0\", SEEK_GE)\n results = []\n\n while cursor.compare(\"k99\") > 0:\n key, value = cursor.retrieve()\n results.append((key, value))\n cursor.next()\n\n assert results == [('k0', '0'), ('k1', '1'), ('k2', '2'), ('k3', '3')]\n\n```\n\nFinding the last match that is lower than or equal to `'k99'` and move\nbackward until the key is less than `'k0'`\n\n<!--\n name: test_cursors;\n case: iterate_le_until_k0\n-->\n```python\nwith LSM(\"test_cursors.ldb\", binary=False) as db:\n with db.cursor() as cursor:\n cursor.seek(\"k99\", SEEK_LE)\n results = []\n\n while cursor.compare(\"k0\") >= 0:\n key, value = cursor.retrieve()\n results.append((key, value))\n cursor.previous()\n\n assert results == [('k3', '3'), ('k2', '2'), ('k1', '1'), ('k0', '0')]\n```\n\nIt is very important to close a cursor when you are through using it. For this\nreason, it is recommended you use the `LSM.cursor()` context-manager, which\nensures the cursor is closed properly.\n\n### Transactions\n\n``lsm`` supports nested transactions. The simplest way to use transactions\nis with the `LSM.transaction()` method, which returns a context-manager:\n\n<!-- name: test_transactions -->\n```python\nfrom lsm import LSM\n\nwith LSM(\"test_tx.ldb\", binary=False) as db:\n del db[\"a\":\"z\"]\n for i in range(10):\n db[f\"k{i}\"] = f\"{i}\"\n\n\nwith LSM(\"test_tx.ldb\", binary=False) as db:\n with db.transaction() as tx1:\n db['k1'] = '1-mod'\n\n with db.transaction() as tx2:\n db['k2'] = '2-mod'\n tx2.rollback()\n\n assert db['k1'] == '1-mod'\n assert db['k2'] == '2'\n```\n\nYou can commit or roll-back transactions part-way through a wrapped block:\n\n<!-- name: test_transactions_2 -->\n```python\nfrom lsm import LSM\n\nwith LSM(\"test_tx_2.ldb\", binary=False) as db:\n del db[\"a\":\"z\"]\n for i in range(10):\n db[f\"k{i}\"] = f\"{i}\"\n\nwith LSM(\"test_tx_2.ldb\", binary=False) as db:\n with db.transaction() as txn:\n db['k1'] = 'outer txn'\n\n # The write operation is preserved.\n txn.commit()\n\n db['k1'] = 'outer txn-2'\n\n with db.transaction() as txn2:\n # This is committed after the block ends.\n db['k1'] = 'inner-txn'\n\n assert db['k1'] == \"inner-txn\"\n\n # Rolls back both the changes from txn2 and the preceding write.\n txn.rollback()\n\n assert db['k1'] == 'outer txn', db['k1']\n```\n\n\nIf you like, you can also explicitly call `LSM.begin()`, `LSM.commit()`, and\n`LSM.rollback()`.\n\n<!-- name: test_transactions_db -->\n```python\nfrom lsm import LSM\n\n# fill db\nwith LSM(\"test_db_tx.ldb\", binary=False) as db:\n del db[\"k\":\"z\"]\n for i in range(10):\n db[f\"k{i}\"] = f\"{i}\"\n\n\nwith LSM(\"test_db_tx.ldb\", binary=False) as db:\n # start transaction\n db.begin()\n db['k1'] = '1-mod'\n\n # nested transaction\n db.begin()\n db['k2'] = '2-mod'\n # rolling back nested transaction\n db.rollback()\n\n # comitting top-level transaction\n db.commit()\n\n assert db['k1'] == '1-mod'\n assert db['k2'] == '2'\n```\n\n### Thanks to\n\n* [@coleifer](https://github.com/coleifer) - this project was inspired by\n[coleifer/python-lsm-db](https://github.com/coleifer/python-lsm-db).\n\n\n",
"bugtrack_url": null,
"license": "Apache Software License",
"summary": "Python bindings for SQLite's LSM key/value engine",
"version": "0.5.4",
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "2e2c0dc11291fa4abd99e4366e33e9b18116cc93715dcc7406980b69f74fe622",
"md5": "081775682466f06b35c9de985081c110",
"sha256": "acc953e61e75b1efa36d909b604f1237762dedef955b065f77080bb5ccc06b6f"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp310-cp310-macosx_10_9_universal2.whl",
"has_sig": false,
"md5_digest": "081775682466f06b35c9de985081c110",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.6,<4",
"size": 2187466,
"upload_time": "2023-04-05T19:23:52",
"upload_time_iso_8601": "2023-04-05T19:23:52.019971Z",
"url": "https://files.pythonhosted.org/packages/2e/2c/0dc11291fa4abd99e4366e33e9b18116cc93715dcc7406980b69f74fe622/lsm-0.5.4-cp310-cp310-macosx_10_9_universal2.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c669b9ae85ff4c9ce982e104e6a7e27ad8feba2ed59f3897f2e63cc1730afdd5",
"md5": "13ef6c52ab966b74a309a52a3dff83d9",
"sha256": "b265d3237b27019cc490c43f681646a6eb3b8d6c499f6f69e339dd9b430f3604"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp310-cp310-macosx_11_0_x86_64.whl",
"has_sig": false,
"md5_digest": "13ef6c52ab966b74a309a52a3dff83d9",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.6,<4",
"size": 1579558,
"upload_time": "2023-04-05T19:23:10",
"upload_time_iso_8601": "2023-04-05T19:23:10.447331Z",
"url": "https://files.pythonhosted.org/packages/c6/69/b9ae85ff4c9ce982e104e6a7e27ad8feba2ed59f3897f2e63cc1730afdd5/lsm-0.5.4-cp310-cp310-macosx_11_0_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "bcc2b5e7cb91dd837cce3a24186343b679aa6cb428b557570b61da8e333f2215",
"md5": "0a169a345662dd55985e2d56381348bc",
"sha256": "9f78ea0ee5324f543c89d28d43abd28e8582450bdc259a85d54b41e6448f66ec"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "0a169a345662dd55985e2d56381348bc",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.6,<4",
"size": 1992722,
"upload_time": "2023-04-05T19:28:38",
"upload_time_iso_8601": "2023-04-05T19:28:38.975444Z",
"url": "https://files.pythonhosted.org/packages/bc/c2/b5e7cb91dd837cce3a24186343b679aa6cb428b557570b61da8e333f2215/lsm-0.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "95296504dc500ba90f279b69052f1a07b1e288eb8627bfe1127b5bbeafb3099d",
"md5": "0b284d101923f9beb70be212acea7ba4",
"sha256": "16373c7d6f2d7bcf3cf164d87fa331d33feb561ac2c6a4053d3c2187ae70314a"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "0b284d101923f9beb70be212acea7ba4",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.6,<4",
"size": 2023228,
"upload_time": "2023-04-05T19:23:51",
"upload_time_iso_8601": "2023-04-05T19:23:51.160758Z",
"url": "https://files.pythonhosted.org/packages/95/29/6504dc500ba90f279b69052f1a07b1e288eb8627bfe1127b5bbeafb3099d/lsm-0.5.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ecd424221f9520260b8f812450f1055ad430e00557c1b77d15f623086a99c93a",
"md5": "1e5dca192616d40560dfac103815b0dd",
"sha256": "bb498840c471c36d1a5a798323ab02e8dd0c748d9bfe8388e799e037a5bc46e3"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp310-cp310-win_amd64.whl",
"has_sig": false,
"md5_digest": "1e5dca192616d40560dfac103815b0dd",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.6,<4",
"size": 1237633,
"upload_time": "2023-04-05T19:26:55",
"upload_time_iso_8601": "2023-04-05T19:26:55.415502Z",
"url": "https://files.pythonhosted.org/packages/ec/d4/24221f9520260b8f812450f1055ad430e00557c1b77d15f623086a99c93a/lsm-0.5.4-cp310-cp310-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8fbbe02a85da9e1da3ad7c150a4e52fb3427110d48daf23ff0d9442d4037b3bc",
"md5": "477eec57e324d14613658a227d8e6636",
"sha256": "672b1c37b9c42de0d1090a30b5dc2b0a25b76e6882f4912869be54dda5c8a597"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp311-cp311-macosx_10_9_universal2.whl",
"has_sig": false,
"md5_digest": "477eec57e324d14613658a227d8e6636",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.6,<4",
"size": 2188576,
"upload_time": "2023-04-05T19:23:54",
"upload_time_iso_8601": "2023-04-05T19:23:54.371227Z",
"url": "https://files.pythonhosted.org/packages/8f/bb/e02a85da9e1da3ad7c150a4e52fb3427110d48daf23ff0d9442d4037b3bc/lsm-0.5.4-cp311-cp311-macosx_10_9_universal2.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1ffe88e2198b84f34b0583354cda3e35965e1b7be181bf6167c230104bbe9ad6",
"md5": "a0526b9f3b94ea934b6eb6a8c0cf8d10",
"sha256": "e89ec0cee4a86a86373f61bfacdff9c4e8a1527d46e8abbe579766c804af01a9"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "a0526b9f3b94ea934b6eb6a8c0cf8d10",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.6,<4",
"size": 1994463,
"upload_time": "2023-04-05T19:28:40",
"upload_time_iso_8601": "2023-04-05T19:28:40.536856Z",
"url": "https://files.pythonhosted.org/packages/1f/fe/88e2198b84f34b0583354cda3e35965e1b7be181bf6167c230104bbe9ad6/lsm-0.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "17e08873804a2e76338ee47a5d99e1f652c294a552d31e0e57c8fc194481e31e",
"md5": "bf940dd02893cee6578d067e3b2c12de",
"sha256": "f20b82b82faf3b88022fcbf2605fd22f21c641a58d849ae870e183cbfc1ffbe2"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "bf940dd02893cee6578d067e3b2c12de",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.6,<4",
"size": 2024542,
"upload_time": "2023-04-05T19:23:53",
"upload_time_iso_8601": "2023-04-05T19:23:53.074235Z",
"url": "https://files.pythonhosted.org/packages/17/e0/8873804a2e76338ee47a5d99e1f652c294a552d31e0e57c8fc194481e31e/lsm-0.5.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1fb77e63a1f8925aff680b39e4d71a035fc14621d22d6d5db29d8674ab136e39",
"md5": "3a3dd66daf539455cc43da69856951b4",
"sha256": "812654eeb02b4441445369b8ce2c8fc5a865e1e092e31e80b63f16fd2e3d2b6d"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp311-cp311-win_amd64.whl",
"has_sig": false,
"md5_digest": "3a3dd66daf539455cc43da69856951b4",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.6,<4",
"size": 1237729,
"upload_time": "2023-04-05T19:25:43",
"upload_time_iso_8601": "2023-04-05T19:25:43.171593Z",
"url": "https://files.pythonhosted.org/packages/1f/b7/7e63a1f8925aff680b39e4d71a035fc14621d22d6d5db29d8674ab136e39/lsm-0.5.4-cp311-cp311-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8996aa39a1dad7d3f6e48351c5b3fcca1063be1c9e60736d8b085377b024fdd6",
"md5": "3bde1d44616a4d79ba04608aaf2c22a6",
"sha256": "f6b233641c9f40ba30aff20f7a7916c04e3bc6d8e3efeda29397d5d81b60c37e"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp37-cp37m-macosx_10_15_x86_64.whl",
"has_sig": false,
"md5_digest": "3bde1d44616a4d79ba04608aaf2c22a6",
"packagetype": "bdist_wheel",
"python_version": "cp37",
"requires_python": ">=3.6,<4",
"size": 1574872,
"upload_time": "2023-04-05T19:24:07",
"upload_time_iso_8601": "2023-04-05T19:24:07.532961Z",
"url": "https://files.pythonhosted.org/packages/89/96/aa39a1dad7d3f6e48351c5b3fcca1063be1c9e60736d8b085377b024fdd6/lsm-0.5.4-cp37-cp37m-macosx_10_15_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "940eae9c9c64ef4f2cf93e12cf9fdc2e0e14a58cfa1203e5b5a141f71f502589",
"md5": "6ab45d2a890b745451356c674237ffc4",
"sha256": "fd620afa8068699a877702a1003d542f8135e6f14b66bc49d581a6f4b19d9fbb"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp37-cp37m-macosx_10_9_x86_64.whl",
"has_sig": false,
"md5_digest": "6ab45d2a890b745451356c674237ffc4",
"packagetype": "bdist_wheel",
"python_version": "cp37",
"requires_python": ">=3.6,<4",
"size": 1584931,
"upload_time": "2023-04-05T19:23:56",
"upload_time_iso_8601": "2023-04-05T19:23:56.774482Z",
"url": "https://files.pythonhosted.org/packages/94/0e/ae9c9c64ef4f2cf93e12cf9fdc2e0e14a58cfa1203e5b5a141f71f502589/lsm-0.5.4-cp37-cp37m-macosx_10_9_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a49dac73c416c539ec7acee73de47a35293cb3eae70815e4b58f3d29ce78da33",
"md5": "8e2b39fd81387c708023210f1b750f97",
"sha256": "8ccf2ba35e6814868592fa01be379ca2c33b25c558456d6f2b65f3ae6b5cb914"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "8e2b39fd81387c708023210f1b750f97",
"packagetype": "bdist_wheel",
"python_version": "cp37",
"requires_python": ">=3.6,<4",
"size": 1994726,
"upload_time": "2023-04-05T19:28:42",
"upload_time_iso_8601": "2023-04-05T19:28:42.246059Z",
"url": "https://files.pythonhosted.org/packages/a4/9d/ac73c416c539ec7acee73de47a35293cb3eae70815e4b58f3d29ce78da33/lsm-0.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2fba150aa501e7ad631738adedaa32350d06523c8d747f7f1c7e769bf7a25ae2",
"md5": "0631b74c515fc5536c7599f11ea6ab66",
"sha256": "ebe692d83456fd57bd24c5c057326f15dd517107aee56bdd1a063507234a9ebd"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "0631b74c515fc5536c7599f11ea6ab66",
"packagetype": "bdist_wheel",
"python_version": "cp37",
"requires_python": ">=3.6,<4",
"size": 2024778,
"upload_time": "2023-04-05T19:23:54",
"upload_time_iso_8601": "2023-04-05T19:23:54.972862Z",
"url": "https://files.pythonhosted.org/packages/2f/ba/150aa501e7ad631738adedaa32350d06523c8d747f7f1c7e769bf7a25ae2/lsm-0.5.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1d59ae5308dd7b61b320181bddb2cf5cb21f1601937389f3bf806f18458d58ad",
"md5": "e046cccc7f261c47b2ff9dff56825ee8",
"sha256": "15809f186e2d5f44e31bce57792a6b1a0e6c945ad2cdf750386fdd8efe452b38"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp37-cp37m-win_amd64.whl",
"has_sig": false,
"md5_digest": "e046cccc7f261c47b2ff9dff56825ee8",
"packagetype": "bdist_wheel",
"python_version": "cp37",
"requires_python": ">=3.6,<4",
"size": 1321406,
"upload_time": "2023-04-05T19:25:38",
"upload_time_iso_8601": "2023-04-05T19:25:38.946836Z",
"url": "https://files.pythonhosted.org/packages/1d/59/ae5308dd7b61b320181bddb2cf5cb21f1601937389f3bf806f18458d58ad/lsm-0.5.4-cp37-cp37m-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ca4b620604464daffb6c96c764209d86927206e03bed2bd69b9fd7b276e987be",
"md5": "abae8f4230240263c005e0fe20e2a6c4",
"sha256": "97c4bc88284a0ef59f1a4726fef9bed575b5154f358b9bda171c057abe9568fe"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp38-cp38-macosx_10_15_x86_64.whl",
"has_sig": false,
"md5_digest": "abae8f4230240263c005e0fe20e2a6c4",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.6,<4",
"size": 1578414,
"upload_time": "2023-04-05T19:25:04",
"upload_time_iso_8601": "2023-04-05T19:25:04.142288Z",
"url": "https://files.pythonhosted.org/packages/ca/4b/620604464daffb6c96c764209d86927206e03bed2bd69b9fd7b276e987be/lsm-0.5.4-cp38-cp38-macosx_10_15_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "f52be7ea2e0b33e2f1dbda75f1e247d0271d0f3c06077dfa113a80e164a17bec",
"md5": "70abe5f2ed895fcaa6b68c5cbd165140",
"sha256": "57c4eab9fe6500c8b73333aa5c0fd23b23120ab9bffa512277903238480706ff"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp38-cp38-macosx_11_0_universal2.whl",
"has_sig": false,
"md5_digest": "70abe5f2ed895fcaa6b68c5cbd165140",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.6,<4",
"size": 2187662,
"upload_time": "2023-04-05T19:24:00",
"upload_time_iso_8601": "2023-04-05T19:24:00.129183Z",
"url": "https://files.pythonhosted.org/packages/f5/2b/e7ea2e0b33e2f1dbda75f1e247d0271d0f3c06077dfa113a80e164a17bec/lsm-0.5.4-cp38-cp38-macosx_11_0_universal2.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "84ce97aa7f86b59d6c276e50340773c35b285ad4215d7fdc8e863bce0946faa6",
"md5": "e69366014a5d578b87ac2fab6ad14e70",
"sha256": "e8ab1e76acc867b5e72d0974623e3830d25d60e5cf48025b509ee3a0e27b33b8"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "e69366014a5d578b87ac2fab6ad14e70",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.6,<4",
"size": 1993463,
"upload_time": "2023-04-05T19:28:43",
"upload_time_iso_8601": "2023-04-05T19:28:43.948426Z",
"url": "https://files.pythonhosted.org/packages/84/ce/97aa7f86b59d6c276e50340773c35b285ad4215d7fdc8e863bce0946faa6/lsm-0.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "da740b193cd2cf4aa0b770834cdc75bb487f85dbe62095d1ad60d88d6c3a5e38",
"md5": "a52a03262f185b3e60aa25a197b79b29",
"sha256": "1f6315cfb014abd49d4570708d97d8894406b3bca8a7b23865935059d156ca08"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "a52a03262f185b3e60aa25a197b79b29",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.6,<4",
"size": 2024169,
"upload_time": "2023-04-05T19:23:57",
"upload_time_iso_8601": "2023-04-05T19:23:57.310647Z",
"url": "https://files.pythonhosted.org/packages/da/74/0b193cd2cf4aa0b770834cdc75bb487f85dbe62095d1ad60d88d6c3a5e38/lsm-0.5.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "627d6f5e8e77e737e2c68d25d3450007626eb1a9a8c88b1bf90563133fa74ac6",
"md5": "34853068ae229c18047bc015a9592292",
"sha256": "8589723021a4091e07fddfbf15ead6c4f99133502c00ca6ef9c118acb95d5163"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp38-cp38-win_amd64.whl",
"has_sig": false,
"md5_digest": "34853068ae229c18047bc015a9592292",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.6,<4",
"size": 1325546,
"upload_time": "2023-04-05T19:24:55",
"upload_time_iso_8601": "2023-04-05T19:24:55.995980Z",
"url": "https://files.pythonhosted.org/packages/62/7d/6f5e8e77e737e2c68d25d3450007626eb1a9a8c88b1bf90563133fa74ac6/lsm-0.5.4-cp38-cp38-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "02bbddbdd88b68b5379b26c0029d6c4c3dee369f35c5fd8e8e5ae830e20d369d",
"md5": "bcc8f8a468ed8961da17cdfdce03c720",
"sha256": "43dd488443eb0347f3ece19f77040888581190bd3f28c76dd217c90674b6f55d"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp39-cp39-macosx_10_9_universal2.whl",
"has_sig": false,
"md5_digest": "bcc8f8a468ed8961da17cdfdce03c720",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.6,<4",
"size": 2187629,
"upload_time": "2023-04-05T19:24:02",
"upload_time_iso_8601": "2023-04-05T19:24:02.707109Z",
"url": "https://files.pythonhosted.org/packages/02/bb/ddbdd88b68b5379b26c0029d6c4c3dee369f35c5fd8e8e5ae830e20d369d/lsm-0.5.4-cp39-cp39-macosx_10_9_universal2.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "eaef5e65e774a7811a46a8c2bc810713d154e5b1419c5b1cb95401830e5c8d3d",
"md5": "8a7ed707c56daa1c97adf37475faeb78",
"sha256": "cf9c95851fa41f8dbd590056f271fc5a9afab311a865a9f77cbd920e4f3f48c5"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp39-cp39-macosx_11_0_x86_64.whl",
"has_sig": false,
"md5_digest": "8a7ed707c56daa1c97adf37475faeb78",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.6,<4",
"size": 1579692,
"upload_time": "2023-04-05T19:25:10",
"upload_time_iso_8601": "2023-04-05T19:25:10.363113Z",
"url": "https://files.pythonhosted.org/packages/ea/ef/5e65e774a7811a46a8c2bc810713d154e5b1419c5b1cb95401830e5c8d3d/lsm-0.5.4-cp39-cp39-macosx_11_0_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "4c15c342a05fc632eafcc7dacd6f87262257d03def0a48e3226f974326dea52b",
"md5": "53142c214b3f658e5473822aac147053",
"sha256": "9bc285ebd1cc038bdbd15e00abc71a22c15d381a358744bd7816f9fb29955a44"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "53142c214b3f658e5473822aac147053",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.6,<4",
"size": 1992512,
"upload_time": "2023-04-05T19:28:45",
"upload_time_iso_8601": "2023-04-05T19:28:45.440411Z",
"url": "https://files.pythonhosted.org/packages/4c/15/c342a05fc632eafcc7dacd6f87262257d03def0a48e3226f974326dea52b/lsm-0.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "432d0e8548df768694fbe28974d65882ce11cac1c754ba6df08ba5918cf3203d",
"md5": "b3df6687e16ac9f52d7ae43bb2766034",
"sha256": "72e48572e75db24a3ef98aeafcb4e3c8c4b2546025e57bca859aa6e97574dfcd"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "b3df6687e16ac9f52d7ae43bb2766034",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.6,<4",
"size": 2023214,
"upload_time": "2023-04-05T19:23:59",
"upload_time_iso_8601": "2023-04-05T19:23:59.487024Z",
"url": "https://files.pythonhosted.org/packages/43/2d/0e8548df768694fbe28974d65882ce11cac1c754ba6df08ba5918cf3203d/lsm-0.5.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b5653dce69bc0103b3d0cb441ab1aee1238a415343bf9bd9dc5442cd8d8680c5",
"md5": "1378e5a6b28a7cca6fc63d7b2069385e",
"sha256": "54c848fea5cd8771bc62276c73fee69bdd84823d49a0a1d2efa6168494956e75"
},
"downloads": -1,
"filename": "lsm-0.5.4-cp39-cp39-win_amd64.whl",
"has_sig": false,
"md5_digest": "1378e5a6b28a7cca6fc63d7b2069385e",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.6,<4",
"size": 1325491,
"upload_time": "2023-04-05T19:24:58",
"upload_time_iso_8601": "2023-04-05T19:24:58.690029Z",
"url": "https://files.pythonhosted.org/packages/b5/65/3dce69bc0103b3d0cb441ab1aee1238a415343bf9bd9dc5442cd8d8680c5/lsm-0.5.4-cp39-cp39-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "066b0ffe3ccab39dc87807aa52ddde66c7947324bbf1827604df571a44c5a64e",
"md5": "c0255f353109131a4e675c4126c9c3df",
"sha256": "2048586ce2202de895270e557500e86dc2127d44f5943b99091b9deb19380e55"
},
"downloads": -1,
"filename": "lsm-0.5.4.tar.gz",
"has_sig": false,
"md5_digest": "c0255f353109131a4e675c4126c9c3df",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6,<4",
"size": 891263,
"upload_time": "2023-04-05T19:22:39",
"upload_time_iso_8601": "2023-04-05T19:22:39.355371Z",
"url": "https://files.pythonhosted.org/packages/06/6b/0ffe3ccab39dc87807aa52ddde66c7947324bbf1827604df571a44c5a64e/lsm-0.5.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-04-05 19:22:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "mosquito",
"github_project": "python-lsm",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "lsm"
}