if len(champ_matches_preds) > 0: cols = list(champ_matches_preds[0].keys()) df = pd.DataFrame(champ_matches_preds, columns=cols) df.index = df.index + 1 today_predictions.append({ 'champ_full_name': map_champ_fullname[key], 'df': df.copy() }) doc = HTMLDocument() doc.set_title('Zepto Game | Sports forecasting research') doc.add_header('Zepto Game | Sports forecasting research', level='h1', align='center') local = pytz.timezone('Europe/Moscow') time_now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') naive_time = datetime.datetime.strptime(f"{time_now}", "%Y-%m-%d %H:%M:%S") local_dt_now = local.localize(naive_time, is_dst=None) utc_dt_now = local_dt_now.astimezone(pytz.utc) if len(today_champs) > 0: doc.add_text(f'Generated {str(utc_dt_now)}', size='14px') doc.add_line_break() doc.add_header('FOOTBALL', level='h3', align='center') for champ_ in today_champs: doc.add_header(f'{champ_}', level='h3') for pred_ in today_predictions:
import numpy as np import pandas as pd from htmlcreator import HTMLDocument np.random.seed(123) # Create new document with default CSS style document = HTMLDocument() # Set document title document.set_title('my first document title') # Add main header document.add_header('my first document header level 1', level='h1', align='center') # Add section header document.add_header( 'section header level 2') # defaults: level='h2' align='left' # Add text paragraphs document.add_text(', '.join(['this is text'] * 50), size='14px', indent='15px', align='justify') document.add_text( 'another text') # defaults: size='16px', indent='0' alight='left' # Embed images
def test_HTMLDocument(): document = HTMLDocument() assert document.style != '' document.set_title(title='title') document.add_header(header='header', level='h2', align='left') document.add_text(text='text', size='15px', indent='0', align='left') document.add_line_break() document.add_page_break() document.add_table(df=_get_df()) try: document.add_table(df=[_get_df()]) except Exception as e: assert isinstance(e, TypeError) assert str( e ) == "df is of type <class 'list'>, but it should be of type <class 'pandas.core.frame.DataFrame'>." document.add_image(image=_get_image_array(), title='title', height=320, width=480, pixelated=False) document.add_image(image=_get_PIL_Image()) _create_test_image() document.add_image(image=_TEST_IMAGE_PATH) document.add_image_link(image_link=_TEST_IMAGE_PATH, title='title', width='100%') document.add_image(image=pathlib.Path(_TEST_IMAGE_PATH)) document.add_image_link(image_link=pathlib.Path(_TEST_IMAGE_PATH)) _remove_test_image() try: document.add_image(image=_get_image_array().astype(np.float32)) except Exception as e: assert isinstance(e, RuntimeError) assert str(e) == 'image.dtype is float32, but it should be uint8.' try: document.add_image( image=np.random.randint(0, 256, size=(1, 200, 200, 3)).astype(np.uint8)) except Exception as e: assert isinstance(e, RuntimeError) assert str(e) == 'image.ndim is 4, but it should be 2 or 3.' try: document.add_image(image=[_get_image_array()]) except Exception as e: assert isinstance(e, TypeError) assert str( e ) == "image is of type <class 'list'>, but it should be one of: <class 'numpy.ndarray'>, <class 'PIL.Image.Image'>, <class 'pathlib.Path'> or <class 'str'>." try: document.add_image_link(image_link=_get_image_array()) except Exception as e: assert isinstance(e, TypeError) assert str( e ) == "image_link is of type <class 'numpy.ndarray'>, but it should be <class 'pathlib.Path'> or <class 'str'>." document.write(_TEST_DOCUMENT_PATH) assert os.path.exists(_TEST_DOCUMENT_PATH) _remove_test_document()
class HTML_Report: def __init__(self, name, title=None): self.name = name self.document = HTMLDocument() self.document.set_title(title if title is not None else name) self.footer = '' self.document.style = ( \ """ body { max-width: 1060px; margin: auto; padding-bottom: 20px; font-family: "Lato", sans-serif; } p{ font-family: sans-serif; overflow-x: hidden; color: var(--gray90); font-family: "Lato", sans-serif; font-size: 1.5rem; line-height: 1.5rem; font-size:16px; text-indent: 0; text-align: left } div.pandas-dataframe { overflow: auto; } table.dataframe { border-collapse: collapse; border: none; } table.dataframe td { background-color: #fffef4; font-size: 14px; text-align: center; white-space: nowrap; margin: 0; padding-top: 0.4em; padding-bottom: 0.4em; padding-left: 0.5em; padding-right: 0.5em; border: 1px solid #d7d7d7; } table.dataframe th { background-color: #f9f9f9; font-size: 12px; text-align: center; white-space: nowrap; padding-left: 1em; padding-right: 1em; padding-top: 0.5em; padding-bottom: 0.5em; border: 1px solid #e0e0e0; } table.dataframe tr:nth-child(even) td { background: #fff2e4; } table.dataframe tr:nth-child(odd) td { background: #ffffe8; } table.dataframe tr:hover td { background-color: #ddeeff; } table.dataframe tbody th { font-weight: normal; } h4{ background-color: #F8F7F7 } h3{ background-color: #FDF2E9 } h2{ background-color: #FAE5D3 } h1{ background-color: #FDF2E9 } """) def add_header(self, header, level: int = 1): self.document.add_header(header, level=f'h{level}', align='center') print('##' + '>>' * (5 - level) + ' ' + header + ' ' + (5 - level) * '<<' + '##') def add_text(self, text): self.document.add_text( text) # defaults: size='16px', indent='0' alight='left' def add_html(self, text): self.document.body += text def add_line_break(self): self.document.add_line_break() def add_fig(self, fig, close=True): self.document.body += mpld3.fig_to_html(fig) if close: plt.close(fig) def add_df(self, df): self.document.add_table(df) def add_dict(self, dic): self.add_df(pd.Series(dic).to_frame().T) def add_img(self, image_url, title='', width_percent=100): self.document.add_image_link(image_url, title=title, width=f'{width_percent}%') def save(self, open=True): htmlfile = ProjectPaths.html_dir / f'{self.name} {uuid.uuid1()}.html' self.document.add_text(self.footer) self.document.write(htmlfile) print(f'{htmlfile} has been saved successfully!') if open: webbrowser.open_new_tab(htmlfile) def __exit__(self, exc_type, exc_val, exc_tb): try: self.save() except Exception as e: print(f'Can\'t save html. {e})') def __enter__(self): return self @staticmethod def __test__(): with HTML_Report('test') as doc: doc.add_header("Test report") doc.add_text('this is text ' * 20) doc.add_line_break() import numpy as np, datetime ts = pd.Series(np.random.randn(1000)) ts = ts.cumsum() plot = ts.plot() fig = plot.get_figure() doc.add_fig(fig) arrays = [ np.array( ['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']), np.array( ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']) ] df = pd.DataFrame(np.random.randn(8, 4), index=arrays) doc.add_df(df) timestr = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") doc.add_text(f'Created at {timestr}') def add_footer(self, text): self.footer += text
import plotly.express as px from htmlcreator import HTMLDocument # Create new document with default CSS style document = HTMLDocument() # Set document title document.set_title('my document with plotly figures') # Embed plotly figure document.add_header('plotly figure #1') df = px.data.iris() fig = px.scatter(df, x=df.sepal_length, y=df.sepal_width, color=df.species, size=df.petal_length) fig.update_layout(title={'text': 'Iris Data Set', 'x': 0.5, 'xanchor': 'center'}) document.add_plotly_figure(fig) # The first `add_plotly_figure` call includes `plotly.js` library in the document # Including `plotly.js` makes HTML document self-contained but also heavier (+3 MB) # Embed another plotly figure document.add_header('plotly figure #2') df = px.data.gapminder().query('continent=="Oceania"') fig = px.line(df, x='year', y='lifeExp', color='country', color_discrete_sequence=px.colors.qualitative.Plotly[3:]) fig.update_layout(title={'text': 'Life expectancy: Oceania', 'x': 0.5, 'xanchor': 'center'}) document.add_plotly_figure(fig) # Embed third plotly figure document.add_header('plotly figure #3') df = px.data.tips() df['dayIndex'] = df['day'].map({'Thur': 4, 'Fri': 5, 'Sat': 6, 'Sun': 7}) df = df.sort_values('dayIndex')