cthoyt / pystow

๐Ÿ‘œ Easily pick a place to store data for your Python code.
https://pystow.readthedocs.io
MIT License
36 stars 6 forks source link

Add progress bars for downloading #61

Closed cthoyt closed 1 year ago

cthoyt commented 1 year ago

Closes #60

Example usage:

import pystow

if __name__ == '__main__':
    url = "https://zenodo.org/record/7633479/files/emojis.zip?download=1"
    path = pystow.ensure(
        "test",
        force=True,
        url=url,
        name="emojis.zip",
        download_kwargs=dict(progress_bar=True, backend="requests", tqdm_kwargs=dict(leave=True)),
    )
    print("download succeeded to ", path)
codecov-commenter commented 1 year ago

Codecov Report

Merging #61 (b18bec0) into main (d7fa850) will decrease coverage by 0.19%. The diff coverage is 56.25%.

@@            Coverage Diff             @@
##             main      #61      +/-   ##
==========================================
- Coverage   66.98%   66.80%   -0.19%     
==========================================
  Files          10       10              
  Lines         933      946      +13     
  Branches      194      198       +4     
==========================================
+ Hits          625      632       +7     
- Misses        287      291       +4     
- Partials       21       23       +2     
Impacted Files Coverage ฮ”
src/pystow/utils.py 61.91% <56.25%> (-0.34%) :arrow_down:

:mega: Weโ€™re building smart automated test selection to slash your CI/CD build times. Learn more

cthoyt commented 1 year ago

Hi @sgbaird @glass-ships, could you please test this out and let me know what you think?

glass-ships commented 1 year ago

will do, thanks @cthoyt !!

glass-ships commented 1 year ago

Hmm, I don't notice any change in behavior.
Is it because I'm using methods like ensure_open_sqlite_gz()? (Does download() get called by these other ensure methods / could it be implemented?)

For reference, the code is just ensuring a zipped SQL db and Solr db

cthoyt commented 1 year ago

This behavior isn't enabled by default, you'll have to do something like:

import pystow

if __name__ == '__main__':
    url = "https://zenodo.org/record/7633479/files/emojis.zip?download=1"
    path = pystow.ensure(
        "test",
        force=True,
        url=url,
        name="emojis.zip",
        download_kwargs=dict(progress_bar=True, backend="requests", tqdm_kwargs=dict(leave=True)),
    )
    print("download succeeded to ", path)
glass-ships commented 1 year ago

This behavior isn't enabled by default, you'll have to do something like:

import pystow

if __name__ == '__main__':
    url = "https://zenodo.org/record/7633479/files/emojis.zip?download=1"
    path = pystow.ensure(
        "test",
        force=True,
        url=url,
        name="emojis.zip",
        download_kwargs=dict(progress_bar=True, backend="requests", tqdm_kwargs=dict(leave=True)),
    )
    print("download succeeded to ", path)

Hmmm, still no luck. Sorry I think I'm missing something here. Updated the call to:

with monarchstow.ensure_open_sqlite_gz(
    "sql", 
    url=SQL_DATA_URL, 
    force=update, 
    download_kwargs=dict(progress_bar=True, backend="requests", tqdm_kwargs=dict(leave=True))
  ) as db:

But I'm getting TypeError: urlretrieve() got an unexpected keyword argument 'progress_bar' or TypeError: Session.request() got an unexpected keyword argument 'progress_bar'

Full traceback ```python โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Traceback (most recent call last) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ D:\dev\tislab\monarch-py\src\monarch_py\sql_cli.py:20 in entity โ”‚ โ”‚ โ”‚ โ”‚ 17 โ”‚ โ”‚ update (bool): = Whether to re-download the Monarch KG. Default False โ”‚ โ”‚ 18 โ”‚ """ โ”‚ โ”‚ 19 โ”‚ data = SQLImplementation() โ”‚ โ”‚ โฑ 20 โ”‚ entity = data.get_entity(id, update) โ”‚ โ”‚ 21 โ”‚ if not entity: โ”‚ โ”‚ 22 โ”‚ โ”‚ print(f"\nEntity '{id}' not found.\n") โ”‚ โ”‚ 23 โ”‚ โ”‚ typer.Abort() โ”‚ โ”‚ โ”‚ โ”‚ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ locals โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ โ”‚ โ”‚ data = โ”‚ โ”‚ โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ”‚ โ”‚ โ”‚ โ”‚ D:\dev\tislab\monarch-py\.venv\lib\site-packages\pystow\impl.py:1485 in ensure_open_sqlite_gz โ”‚ โ”‚ โ”‚ โ”‚ 1482 โ”‚ โ”‚ """ โ”‚ โ”‚ 1483 โ”‚ โ”‚ import sqlite3 โ”‚ โ”‚ 1484 โ”‚ โ”‚ โ”‚ โ”‚ โฑ 1485 โ”‚ โ”‚ path = self.ensure_gunzip( โ”‚ โ”‚ 1486 โ”‚ โ”‚ โ”‚ *subkeys, url=url, name=name, force=force, download_kwargs=download_kwargs โ”‚ โ”‚ 1487 โ”‚ โ”‚ ) โ”‚ โ”‚ 1488 โ”‚ โ”‚ with closing(sqlite3.connect(path.as_posix())) as conn: โ”‚ โ”‚ โ”‚ โ”‚ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ locals โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ โ”‚ โ”‚ download_kwargs = { โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'progress_bar': True, โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'backend': 'requests', โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'tqdm_kwargs': {'leave': True} โ”‚ โ”‚ โ”‚ โ”‚ } โ”‚ โ”‚ โ”‚ โ”‚ force = False โ”‚ โ”‚ โ”‚ โ”‚ name = None โ”‚ โ”‚ โ”‚ โ”‚ self = โ”‚ โ”‚ โ”‚ โ”‚ sqlite3 = โ”‚ โ”‚ โ”‚ โ”‚ subkeys = ('sql',) โ”‚ โ”‚ โ”‚ โ”‚ url = 'https://data.monarchinitiative.org/monarch-kg-dev/latest/monarch-kg.db.gโ€ฆ โ”‚ โ”‚ โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ”‚ โ”‚ โ”‚ โ”‚ D:\dev\tislab\monarch-py\.venv\lib\site-packages\pystow\impl.py:297 in ensure_gunzip โ”‚ โ”‚ โ”‚ โ”‚ 294 โ”‚ โ”‚ gunzipped_path = self.join(*subkeys, name=gunzipped_name, ensure_exists=True) โ”‚ โ”‚ 295 โ”‚ โ”‚ if gunzipped_path.is_file() and not force: โ”‚ โ”‚ 296 โ”‚ โ”‚ โ”‚ return gunzipped_path โ”‚ โ”‚ โฑ 297 โ”‚ โ”‚ path = self.ensure( โ”‚ โ”‚ 298 โ”‚ โ”‚ โ”‚ *subkeys, โ”‚ โ”‚ 299 โ”‚ โ”‚ โ”‚ url=url, โ”‚ โ”‚ 300 โ”‚ โ”‚ โ”‚ name=name, โ”‚ โ”‚ โ”‚ โ”‚ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ locals โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ โ”‚ โ”‚ autoclean = True โ”‚ โ”‚ โ”‚ โ”‚ download_kwargs = { โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'progress_bar': True, โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'backend': 'requests', โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'tqdm_kwargs': {'leave': True} โ”‚ โ”‚ โ”‚ โ”‚ } โ”‚ โ”‚ โ”‚ โ”‚ force = False โ”‚ โ”‚ โ”‚ โ”‚ gunzipped_name = 'monarch-kg.db' โ”‚ โ”‚ โ”‚ โ”‚ gunzipped_path = WindowsPath('C:/Users/glass/.data/monarch/sql/monarch-kg.db') โ”‚ โ”‚ โ”‚ โ”‚ name = 'monarch-kg.db.gz' โ”‚ โ”‚ โ”‚ โ”‚ self = โ”‚ โ”‚ โ”‚ โ”‚ subkeys = ('sql',) โ”‚ โ”‚ โ”‚ โ”‚ url = 'https://data.monarchinitiative.org/monarch-kg-dev/latest/monarch-kg.db.gโ€ฆ โ”‚ โ”‚ โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ”‚ โ”‚ โ”‚ โ”‚ D:\dev\tislab\monarch-py\.venv\lib\site-packages\pystow\impl.py:171 in ensure โ”‚ โ”‚ โ”‚ โ”‚ 168 โ”‚ โ”‚ if name is None: โ”‚ โ”‚ 169 โ”‚ โ”‚ โ”‚ name = name_from_url(url) โ”‚ โ”‚ 170 โ”‚ โ”‚ path = self.join(*subkeys, name=name, ensure_exists=True) โ”‚ โ”‚ โฑ 171 โ”‚ โ”‚ utils.download( โ”‚ โ”‚ 172 โ”‚ โ”‚ โ”‚ url=url, โ”‚ โ”‚ 173 โ”‚ โ”‚ โ”‚ path=path, โ”‚ โ”‚ 174 โ”‚ โ”‚ โ”‚ force=force, โ”‚ โ”‚ โ”‚ params = None โ”‚ โ”‚ โ”‚ โ”‚ url = 'https://data.monarchinitiative.org/monarch-kg-dev/latest/monarch-kg.db.gz' โ”‚ โ”‚ โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ”‚ โ”‚ โ”‚ โ”‚ D:\dev\tislab\monarch-py\.venv\lib\site-packages\requests\api.py:59 in request โ”‚ โ”‚ โ”‚ โ”‚ 56 โ”‚ # avoid leaving sockets open which can trigger a ResourceWarning in some โ”‚ โ”‚ 57 โ”‚ # cases, and look like a memory leak in others. โ”‚ โ”‚ 58 โ”‚ with sessions.Session() as session: โ”‚ โ”‚ โฑ 59 โ”‚ โ”‚ return session.request(method=method, url=url, **kwargs) โ”‚ โ”‚ 60 โ”‚ โ”‚ 61 โ”‚ โ”‚ 62 def get(url, params=None, **kwargs): โ”‚ โ”‚ โ”‚ โ”‚ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ locals โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ โ”‚ โ”‚ kwargs = { โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'params': None, โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'progress_bar': True, โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'tqdm_kwargs': {'leave': True}, โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'stream': True โ”‚ โ”‚ โ”‚ โ”‚ } โ”‚ โ”‚ โ”‚ โ”‚ method = 'get' โ”‚ โ”‚ โ”‚ โ”‚ session = โ”‚ โ”‚ โ”‚ โ”‚ url = 'https://data.monarchinitiative.org/monarch-kg-dev/latest/monarch-kg.db.gz' โ”‚ โ”‚ โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ```
cthoyt commented 1 year ago

@glass-ships you'll have to install your code from the branch where I implemented this, since it's neither merged nor released

glass-ships commented 1 year ago

@glass-ships you'll have to install your code from the branch where I implemented this, since it's neither merged nor released

I thought I had done exactly that by issuing the following:

$ poetry run pip uninstall pystow 
$ cd </pystow/path> 
$ poetry -C </my/library/path> run pip install . 

A pip freeze | grep 'pystow' returns pystow @ file:///D:/dev/pystow though, which I guess I expected to be the version num..

Apologies for my stumbling around, I'm still getting used to manually managing dependencies with Poetry.

glass-ships commented 1 year ago

Ok, sorry again, looks like I've sorted my issue - my system appeared to be caching an older version and claiming it was up to date!

I nuked my environment and started again, and everything appears kosher!

(monarch-py-py3.10) PS D:\dev\pystow> monarch sql entity --id MONDO:0012933
Downloading monarch-kg.db.gz: 100%|โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 475M/475M [00:04<00:00, 110MB/s]

# Rest of output
}
cthoyt commented 1 year ago

FYI @glass-ships I have made a release 0.5.0 that includes this feature