Skip to content

Commit

Permalink
Improve docs for 2.0 release (#102)
Browse files Browse the repository at this point in the history
* Improve docs

* Update test for callable change

* Add sphinx-contributors

* Use sbt and theme contributors

* Customise the theme
  • Loading branch information
Cadair authored Jun 29, 2022
1 parent 455002b commit c75353c
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 28 deletions.
28 changes: 15 additions & 13 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"sphinx_autodoc_typehints", # must be loaded after napoleon
"sphinx_automodapi.automodapi",
"sphinx_automodapi.smart_resolver",
"sphinx_contributors",
]

# Add any paths that contain templates here, relative to this directory.
Expand Down Expand Up @@ -82,30 +83,31 @@
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
"https://docs.python.org/": None,
"http://aiohttp.readthedocs.io/en/stable": None,
"https://docs.aiohttp.org/en/stable": None,
"https://aioftp.readthedocs.io/": None,
}

# -- Options for HTML output ---------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.

try:
from sunpy_sphinx_theme.conf import * # NOQA

html_theme_options = {
"logo_url": "https://parfive.readthedocs.io/en/latest/",
"page_toctree_depths": {},
}

except ImportError:
pass
html_theme = "sphinx_book_theme"

html_theme_options = {
"home_page_in_toc": True,
"repository_url": "https://github.com/Cadair/parfive",
"use_repository_button": True,
"use_issues_button": True,
"use_download_button": False,
}

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']
html_static_path = ["static"]
html_css_files = [
"css/contributors.css",
]

# Render inheritance diagrams in SVG
graphviz_output_format = "svg"
Expand Down
42 changes: 39 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.. currentmodule:: parfive

.. _parfive:

=======
Parfive
=======
Expand All @@ -8,7 +10,12 @@ Parfive is a small library for downloading files, its objective is to provide a
It also aims to provide a clear interface for inspecting any failed downloads.

The parfive package was motivated by the needs of `SunPy's <https://sunpy.org>`__ ``net`` submodule, but should be generally applicable to anyone who wants a user friendly way of downloading multiple files in parallel.
Parfive supports downloading files over either HTTP or FTP using `aiohttp <http://aiohttp.readthedocs.io/>`__ and `aioftp <https://aioftp.readthedocs.io/>`__ ``aioftp`` is an optional dependency, which does not need to be installed to download files over HTTP.
Parfive uses asyncio to support downloading multiple files in parallel, and to support downloading a single file in multiple parallel chunks.
Parfive supports downloading files over either HTTP or FTP using `aiohttp <http://aiohttp.readthedocs.io/>`__ and `aioftp <https://aioftp.readthedocs.io/>`__ (``aioftp`` is an optional dependency, which does not need to be installed to download files over HTTP).

Parfive provides both a function and coroutine interface, so that it can be used from both synchronous and asyncronous code.
It also has opt-in support for using `aiofiles <https://github.com/Tinche/aiofiles>`__ to write downloaded data to disk using a separate thread pool, which may be useful if you are using parfive from within an asyncio application.


Installation
------------
Expand All @@ -30,8 +37,7 @@ or from `GitHub <https://github.com/Cadair/parfive>`__.
Usage
-----

parfive works by creating a downloader object, queuing downloads with it and then running the download.
parfive has a synchronous API, but uses `asyncio` to parallelise downloading the files.
Parfive works by creating a downloader object, queuing downloads with it and then running the download.

A simple example is::

Expand Down Expand Up @@ -65,6 +71,28 @@ Parfive also bundles a CLI. The following example will download the two files co
Directory to which downloaded files are saved.
--print-filenames Print successfully downloaded files's names to stdout.


Options and Customisation
-------------------------

Parfive aims to support as many use cases as possible, and therefore has a number of options.

There are two main points where you can customise the behaviour of the downloads, in the initialiser to `parfive.Downloader` or when adding a URL to the download queue with `~parfive.Downloader.enqueue_file`.
The arguments to the ``Downloader()`` constructor affect all files transferred, and the arguments to ``enqueue_file()`` apply to only that file.

By default parfive will transfer 5 files in parallel and, if supported by the remote server, chunk those files and download 5 chunks simultaneously.
This behaviour is controlled by the ``max_conn=`` and ``max_splits=`` keyword arguments.

Further configuration of the ``Downloader`` instance is done by passing in a `parfive.SessionConfig` object as the ``config=`` keyword argument to ``Downloader()``.
See the documentation of that class for more details.

Keyword arguments to `~parfive.Downloader.enqueue_file` are passed through to either `aiohttp.ClientSession.get` for HTTP downloads or `aioftp.Client` for FTP downloads.
This gives you many per-file options such as headers, authentication, ssl options etc.


Parfive API
-----------

.. automodapi:: parfive
:no-heading:
:no-main-docstr:
Expand All @@ -82,6 +110,14 @@ Parfive reads the following environment variables, note that as of version 2.0 a
* ``PARFIVE_TOTAL_TIMEOUT`` - Overrides the default aiohttp ``total`` timeout value (unless set in Python).
* ``PARFIVE_SOCK_READ_TIMEOUT`` - Overrides the default aiohttp ``sock_read`` timeout value (unless set in Python).

Contributors
------------

.. contributors:: Cadair/parfive
:avatars:
:exclude: pre-commit-ci[bot]
:order: ASC

Changelog
---------

Expand Down
24 changes: 24 additions & 0 deletions docs/static/css/contributors.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.sphinx-contributors img {
border-radius: 50%;
}

.sphinx-contributors_list {
padding-left: 0;
}

.sphinx-contributors_list__item {
padding-right: 0.75em;
padding-left: 0.75em;
}

.sphinx-contributors--avatars .sphinx-contributors_contributor__image {
max-width: 100px;
}

.sphinx-contributors_contributor {
width: initial;
}

.sphinx-contributors {
width: initial;
}
27 changes: 16 additions & 11 deletions parfive/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,15 @@ class SessionConfig:
"""
file_progress: bool = True
"""
If `True` (the default) a progress bar will be shown for every file if any
progress bars are shown.
If `True` (the default) a progress bar will be shown (if any progress bars
are shown) for every file, in addition for one showing progress of
downloading all file.
"""
notebook: Union[bool, None] = None
"""
If `None` `tqdm` will automatically detect if it can draw rich IPython
Notebook progress bars. If `False` or `True` notebook mode will be forced
Override automatic detection of Jupyter notebook for drawing progress bars.
If `None` `tqdm` will automatically detect if it can draw rich notebook
progress bars. If `False` or `True` notebook mode will be forced
off or on.
"""
log_level: Optional[str] = None
Expand All @@ -129,14 +131,15 @@ class SessionConfig:
overridden by the ``PARFIVE_TOTAL_TIMEOUT`` and
``PARFIVE_SOCK_READ_TIMEOUT`` environment variables.
"""
aiohttp_session_generator: Callable[
["SessionConfig"], aiohttp.ClientSession
] = _default_aiohttp_session
aiohttp_session_generator: Optional[Callable[["SessionConfig"], aiohttp.ClientSession]] = None
"""
An optional function to generate the `aiohttp.ClientSession` class.
Due to the fact that this session needs to be executed inside the asyncio context it is a callable.
It takes one argument which is the instance of this ``SessionConfig`` class.
It is expected that you pass ``.headers`` through to this session or the headers will not be sent.
A function to override the generation of the `aiohttp.ClientSession` object.
Due to the fact that this session needs to be instantiated inside the
asyncio context this option is a function. This function takes one argument
which is the instance of this ``SessionConfig`` class. It is expected that
you pass the ``.headers`` attribute of the config instance through to the
``headers=`` keyword argument of the session you instantiate.
"""
env: EnvConfig = field(default_factory=EnvConfig)

Expand Down Expand Up @@ -205,4 +208,6 @@ def __getattr__(self, __name: str):
return getattr(self.config, __name)

def aiohttp_client_session(self):
if self.config.aiohttp_session_generator is None:
return _default_aiohttp_session(self.config)
return self.config.aiohttp_session_generator(self.config)
2 changes: 1 addition & 1 deletion parfive/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

def test_session_config_defaults():
c = SessionConfig()
assert callable(c.aiohttp_session_generator)
assert c.aiohttp_session_generator is None
assert isinstance(c.timeouts, aiohttp.ClientTimeout)
assert c.timeouts.total == 0
assert c.timeouts.sock_read == 90
Expand Down
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ docs =
sphinx-automodapi
sunpy-sphinx-theme
sphinx-autodoc-typehints
sphinx-contributors
sphinx-book-theme

[flake8]
max-line-length = 100
Expand Down

0 comments on commit c75353c

Please # to comment.