Skip to content

Commit 6222017

Browse files
authored
V2.0.0 (#58)
* WIP * Update README * Update README * WIP * WIP * WIP * Update docstrings etc * Update documentation * Fix bugs and typos * Update documentation * Update documentation * Fix bug
1 parent 711741f commit 6222017

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+4141
-14771
lines changed

‎.flake8‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
[flake8]
22
max-line-length = 120
33
exclude = scratch.*, docs/
4-
ignore = W503 # line break before binary operator
5-
per-file-ignores = __init__.py:E402, F401
4+
ignore =
5+
W503, # line break before binary operator
6+
E203, # whitespace before ':'
7+
per-file-ignores =
8+
__init__.py:E402, F401
9+
_cdnlinks.py:E501

‎.travis.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ python:
1010

1111
env:
1212
- EXTRA_INSTALLS=""
13-
- EXTRA_INSTALLS="ipython pandas matplotlib bokeh plotly kaleido weasyprint beautifulsoup4 html5lib"
13+
- EXTRA_INSTALLS="ipython pandas matplotlib bokeh plotly kaleido weasyprint<53 beautifulsoup4 html5lib"
1414

1515
install:
1616
- pip install . pytest coverage $EXTRA_INSTALLS

‎Makefile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ test-all: ## run tests on every Python version with tox
7272
python -m tests.check_package_version
7373

7474
coverage: ## check code coverage quickly with the default Python
75-
coverage run --source esparto -m pytest
75+
-coverage run --source esparto -m pytest
7676
coverage report -m
7777
coverage html
7878
# $(BROWSER) htmlcov/index.html

‎README.md‎

Lines changed: 45 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,43 @@ esparto
1010

1111

1212
## Introduction
13-
`esparto` is a simple HTML and PDF document generator for Python.
14-
The library takes a fully Pythonic approach to defining documents,
15-
allowing iterative building and modification of the page and its contents.
13+
**esparto** is a Python package for building shareable reports with content
14+
from popular data analysis libraries.
15+
With just a few lines of code, **esparto** turns DataFrames, plots, and
16+
Markdown into an interactive webpage or PDF document.
1617

18+
Documents produced by **esparto** are completely portable - no backend server
19+
is required - and entirely customisable using CSS and Jinja templating.
20+
All content dependencies are declared inline or loaded via a CDN, meaning your
21+
reports can be shared by email, hosted on a standard http server, or made
22+
available as static pages as-is.
1723

18-
### Example Use Cases
19-
* Automated MI reporting
20-
* Collating and sharing data visualisations
21-
* ML model performance and evaluation documents
22-
* Designing simple web pages
24+
25+
## Basic Usage
26+
```python
27+
import esparto as es
28+
page = es.Page(title="My Report")
29+
page["Data Analysis"] = (pandas_dataframe, plotly_figure)
30+
page.save_html("my-report.html")
31+
```
2332

2433

2534
## Main Features
26-
* Lightweight API
27-
* Jupyter Notebook support
28-
* Output self-contained HTML and PDF files
29-
* Responsive layout from [Bootstrap](https://getbootstrap.com/)
30-
* No CSS or HTML required
31-
* Implicit conversion for:
35+
* Automatic and adaptive layout
36+
* Customisable with CSS or Jinja
37+
* Jupyter Notebook friendly
38+
* Output as HTML or PDF
39+
* Built-in adaptors for:
3240
* Markdown
3341
* Images
34-
* Pandas DataFrames
35-
* Matplotlib
36-
* Bokeh
37-
* Plotly
42+
* [Pandas DataFrames][Pandas]
43+
* [Matplotlib][Matplotlib]
44+
* [Bokeh][Bokeh]
45+
* [Plotly][Plotly]
3846

3947

4048
## Installation
41-
`esparto` is available from PyPI:
49+
**esparto** is available from PyPI:
4250
```bash
4351
pip install esparto
4452
```
@@ -54,7 +62,8 @@ pip install weasyprint
5462
* [jinja2](https://palletsprojects.com/p/jinja/)
5563
* [markdown](https://python-markdown.github.io/)
5664
* [Pillow](https://python-pillow.org/)
57-
* [weasyprint](https://weasyprint.org/) _(optional - for PDF output)_
65+
* [PyYAML](https://pyyaml.org/)
66+
* [weasyprint](https://weasyprint.org/) _(optional - required for PDF output)_
5867

5968

6069
## License
@@ -64,69 +73,27 @@ pip install weasyprint
6473
## Documentation
6574
Full documentation and examples are available at [domvwt.github.io/esparto/](https://domvwt.github.io/esparto/).
6675

67-
68-
## Basic Usage
69-
```python
70-
import esparto as es
71-
72-
# Instantiating a Page
73-
page = es.Page(title="Research")
74-
75-
# Page layout hierarchy:
76-
# Page -> Section -> Row -> Column -> Content
77-
78-
# Add or update content
79-
# Keys are used as titles
80-
page["Introduction"]["Part One"]["Item A"] = "./text/content.md"
81-
page["Introduction"]["Part One"]["Item B"] = "./pictures/image1.jpg"
82-
83-
# Add content without a title
84-
page["Introduction"]["Part One"][""] = "Hello, Wolrd!"
85-
86-
# Replace child at index - useful if no title given
87-
page["Introduction"]["Part One"][-1] = "Hello, World!"
88-
89-
# Set content and return input object
90-
# Useful in Jupyter Notebook as it will be displayed in cell output
91-
page["Methodology"]["Part One"]["Item A"] << "dolor sit amet"
92-
# >>> "dolor sit amet"
93-
94-
# Set content and return new layout
95-
page["Methodology"]["Part Two"]["Item B"] >> "foobar"
96-
# >>> {'Item B': ['Markdown']}
97-
98-
# Show document structure
99-
page.tree()
100-
# >>> {'Research': [{'Introduction': [{'Part One': [{'Item A': ['Markdown']},
101-
# {'Item B': ['Image']}]}]},
102-
# {'Methodology': [{'Part One': [{'Item A': ['Markdown']}]},
103-
# {'Part Two': [{'Item A': ['Markdown']}]}]}]}
104-
105-
# Remove content
106-
del page["Methodology"]["Part One"]["Item A"]
107-
del page.methodology.part_two.item_b
108-
109-
# Access existing content as an attribute
110-
page.introduction.part_one.item_a = "./pictures/image2.jpg"
111-
page.introduction.part_one.tree()
112-
# >>> {'Part One': [{'Item A': ['Image']},
113-
# {'Item B': ['Image']},
114-
# {'Column 2': ['Markdown']}]}
115-
116-
# Save the document
117-
page.save_html("my-page.html")
118-
page.save_pdf("my-page.pdf")
119-
```
76+
## Contributions, Issues, and Requests
77+
All feedback and contributions are welcome - please raise an issue or pull request on [GitHub][GitHub].
12078

12179

122-
## Example Output
123-
Iris Report - [HTML](https://domvwt.github.io/esparto/examples/iris-report.html) |
80+
## Examples
81+
Iris Report - [Webpage](https://domvwt.github.io/esparto/examples/iris-report.html) |
12482
[PDF](https://domvwt.github.io/esparto/examples/iris-report.pdf)
12583

126-
Bokeh and Plotly - [HTML](https://domvwt.github.io/esparto/examples/interactive-plots.html) |
84+
Bokeh and Plotly - [Webpage](https://domvwt.github.io/esparto/examples/interactive-plots.html) |
12785
[PDF](https://domvwt.github.io/esparto/examples/interactive-plots.pdf)
12886

12987
<br>
13088

131-
<img width=600 src="https://github.com/domvwt/esparto/blob/fdc0e787c0bc013d16667773e82e21c647b71d91/docs/images/iris-report-compressed.png?raw=true"
132-
alt="example page" style="border-radius:0.5%;">
89+
<p width=100%>
90+
<img width=80% src="https://github.com/domvwt/esparto/blob/fdc0e787c0bc013d16667773e82e21c647b71d91/docs/images/iris-report-compressed.png?raw=true" alt="example page" style="border-radius:0.5%;">
91+
</p>
92+
93+
<!-- Links -->
94+
[Bootstrap]: https://getbootstrap.com/docs/4.6/getting-started/introduction/
95+
[Pandas]: https://pandas.pydata.org/
96+
[Matplotlib]: https://matplotlib.org/
97+
[Bokeh]: https://docs.bokeh.org/en/latest/index.html
98+
[Plotly]: https://plotly.com/
99+
[GitHub]: https://github.com/domvwt/esparto

‎docs/01-getting-started/quickstart.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ my_page.save_html("esparto-quick.html")
3737
```
3838
<br>
3939

40-
The rendered HTML document:
40+
The rendered web document:
4141

4242
<img src='../esparto-quickstart-screenshot.png' style='border: 1px dotted lightgrey; width: 60%; height: auto'>
4343

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
### Jinja
2+
3+
### CSS
4+
5+
#### Bootstrap Themes
6+
7+
### Layout Classes
8+
9+
### Content Classes

‎docs/02-user-guide/examples.md‎

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,56 @@
1-
# Examples
1+
# Guides
22

33
These examples demonstrate recommended ways of working with `esparto`.
4-
Note that Jupyter Notebooks do not preserve the formatting of rendered
5-
content between sessions - be sure to re-run the examples in order to
6-
view the output as intended.
4+
5+
6+
## Getting Started
7+
8+
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/domvwt/esparto/blob/main/docs/examples/getting-started.ipynb)
9+
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/domvwt/esparto/main?filepath=docs%2Fexamples%2Fgetting-started.ipynb)
10+
[![GitHub](https://img.shields.io/badge/view%20on-GitHub-lightgrey)](https://github.com/domvwt/esparto/blob/main/docs/examples/getting-started.ipynb)
11+
12+
A guided tour of the `esparto` API. This notebook covers:
13+
14+
* Working with different Content types
15+
* Layout and formatting
16+
* Page options
17+
* Saving your work
18+
19+
---
20+
721

822
## Data Analysis
923

1024
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/domvwt/esparto/blob/main/docs/examples/iris-report.ipynb)
1125
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/domvwt/esparto/main?filepath=docs%2Fexamples%2Firis-report.ipynb)
1226
[![GitHub](https://img.shields.io/badge/view%20on-GitHub-lightgrey)](https://github.com/domvwt/esparto/blob/main/docs/examples/iris-report.ipynb)
1327

14-
The iris dataset is one of the most well known datasets in statistics and
15-
data science. This notebook shows how we can put together a simple
16-
data analysis report in `esparto`.
28+
This notebook shows how we can put together a simple data analysis in `esparto`.
1729

1830
This example covers:
1931

20-
* Text content with markdown formatting
32+
* Text content with Markdown formatting
2133
* Including images from files
2234
* Converting a Pandas DataFrame to a table
2335
* Adding plots from Matplotlib and Seaborn
2436

25-
Output: [HTML](../examples/iris-report.html) | [PDF](../examples/iris-report.pdf)
37+
Output: [Webpage](../examples/iris-report.html) | [PDF](../examples/iris-report.pdf)
2638

2739
----
2840

2941

30-
31-
## Interactive Plotting
42+
## Interactive Plots
3243

3344
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/domvwt/esparto/blob/main/docs/examples/interactive-plots.ipynb)
3445
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/domvwt/esparto/main?filepath=docs%2Fexamples%2Finteractive-plots.ipynb)
3546
[![GitHub](https://img.shields.io/badge/view%20on-GitHub-lightgrey)](https://github.com/domvwt/esparto/blob/main/docs/examples/interactive-plots.ipynb)
3647

37-
The [pandas-bokeh](https://github.com/PatrikHlobil/Pandas-Bokeh) library
38-
offers convenient functions for producing interactive Bokeh plots with
39-
few lines of code.
40-
41-
With the [Plotly backend for Pandas](https://plotly.com/python/pandas-backend/)
42-
we can access the Plotly Express API directly from the `.plot()` method of
43-
any DataFrame or Series.
44-
45-
This notebook shows basic examples from each library:
48+
This notebook shows basic examples from interactive plotting libraries:
4649

47-
* Interactive plotting with Bokeh and Plotly
48-
* Adding interactive content to the page
50+
* Bokeh
51+
* Plotly
4952

50-
Output: [HTML](../examples/interactive-plots.html) | [PDF](../examples/interactive-plots.pdf)
53+
Output: [Webpage](../examples/interactive-plots.html) | [PDF](../examples/interactive-plots.pdf)
5154

5255
!!! note
5356
PDF output is not officially supported for `Bokeh` at this time.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
## Offline Mode
2+
When working in an environment with no internet connection it is necessary to
3+
use inline content dependencies rather than the preferred Content Distribution Network (CDN).
4+
5+
6+
Offline mode can be activated by changing the relevant `esparto.options` attribute:
7+
```python
8+
import esparto as es
9+
10+
es.options.offline_mode = True
11+
```
12+
13+
## Matplotlib Output
14+
To produce sharp and scalable images, esparto defaults to SVG format for
15+
static plots.
16+
This can cause a significant drain on resources when plotting a high number
17+
of data points and so PNG format may be preferred.
18+
19+
PNG format can be selected for all Matplotlib plots:
20+
```python
21+
es.options.matplotlib_output_format = "png"
22+
```
23+
24+
Or configured on a case by case basis:
25+
```python
26+
fig = df.plot()
27+
esparto_fig = es.FigureMpl(fig, output_format="png")
28+
```
29+
30+
Options provided directly to `FigureMpl` will override the global configuration.
31+
32+
## PDF Output
33+
34+
### From the API
35+
Saving a page to PDF is achieved through the API by calling the `.save_pdf()`
36+
method from a `Page` object:
37+
38+
```python
39+
import esparto as es
40+
41+
my_page = es.Page(title="My Page")
42+
my_page += "image.jpg"
43+
my_page.save_pdf("my-page.pdf)
44+
```
45+
46+
In order to render plots for PDF output, they must be rendered to SVG. While
47+
this leads to consistent and attractive results for Matplotlib figures, it is
48+
less predictable and requires additional system configuration for Bokeh and
49+
Plotly objects.
50+
51+
#### Plotly
52+
The preferred approach with Plotly is to use the Kaleido library, which is installable
53+
with pip:
54+
```bash
55+
pip install kaleido
56+
```
57+
Esparto will automatically handle the conversion, provided Kaleido is available.
58+
59+
Make sure to inspect results for unusual cropping and other artifacts.
60+
61+
#### Bokeh
62+
The approach taken by Bokeh is to use a browser and webdriver combination.
63+
I have not been able to make this work during testing but the functionality
64+
has been retained in esparto should you have more luck with it.
65+
66+
See the Bokeh documenation on [additional dependencies for exporting plots.](https://docs.bokeh.org/en/latest/docs/user_guide/export.html#additional-dependencies)
67+
68+
Conversion should be handled by esparto, provided the Bokeh dependencies
69+
are satisfied.
70+
71+
### Saving from a Browser
72+
Alternatively, it is possible to save any HTML page as a PDF through the print
73+
menu in your web browser. This method should work with all content types.
74+
75+
<br>

0 commit comments

Comments
 (0)