def list_grid( source: list, expand_full: bool = False, column_count: int = 2, row_spacing: float = 1 ): """ :param source: :param expand_full: :param column_count: :param row_spacing: :return: """ environ.abort_thread() max_width = 1400 if expand_full else 900 column_width = '{}px'.format( max(50, int(math.floor(max_width / column_count))) ) return templating.render_template( 'list_grid.html', items=['{}'.format(x) for x in source], css_modifier='full' if expand_full else 'limited', column_width=column_width, row_spacing=row_spacing )
def __getattr__(self, item): environ.abort_thread() if item.startswith('_'): return None return self._shared_cache_data.get(item)
def __setattr__(self, key, value): environ.abort_thread() if key.startswith('_'): super(SharedCache, self).__setattr__(key, value) else: self._shared_cache_data[key] = value
def inspect_data(source_key: str = None, source=None) -> dict: """ :param source_key: :param source: :return: """ environ.abort_thread() if isinstance(source, dict): out = {'type': 'dict', 'key': source_key, 'structure': []} for key, value in source.items(): out['structure'].append(inspect_data(key, value)) return out if isinstance(source, (list, tuple)): return { 'type': 'list', 'length': len(source), 'key': source_key, 'structure': inspect_data(None, source[0]) } if isinstance(source, str): return {'type': 'str', 'key': source_key, 'structure': None} if isinstance(source, (float, int)): return {'type': 'number', 'key': source_key, 'structure': None} if isinstance(source, bool): return {'type': 'bool', 'key': source_key, 'structure': None} return {'type': 'None', 'key': source_key, 'structure': None}
def code_block( block: str = None, path: str = None, language: str = None, title: str = None, caption: str = None ) -> str: """ :param block: :param path: :param language: :param title: :param caption: :return: """ environ.abort_thread() code_dom = ( code_file(path, language=language, is_code_block=True) if path else code(block, language=language, is_code_block=True) ) return templating.render_template( 'code-block.html', code=code_dom, title=title, caption=caption )
def code( source: str, language: str = None, filename: str = None, mime_type: str = None, is_code_block: bool = False ) -> str: """ :param source: :param language: :param filename: :param mime_type: :param is_code_block: :return: """ environ.abort_thread() if not source: return '' cleaned = textwrap.dedent(source.strip('\n')) return syntax_highlighting.as_html( source=cleaned, language=language, filename=filename, mime_type=mime_type, is_code_block=is_code_block )
def __setattr__(self, key, value): environ.abort_thread() if key.startswith('_'): super(SharedCache, self).__setattr__(key, value) else: self._shared_cache_data[key] = value
def code_block(code: str = None, path: str = None, language_id: str = None, title: str = None, caption: str = None): """ Adds a block of syntax highlighted code to the display from either the supplied code argument, or from the code file specified by the path argument. :param code: A string containing the code to be added to the display :param path: A path to a file containing code to be added to the display :param language_id: The language identifier that indicates what language should be used by the syntax highlighter. Valid values are any of the languages supported by the Pygments highlighter. :param title: If specified, the code block will include a title bar with the value of this argument :param caption: If specified, the code block will include a caption box below the code that contains the value of this argument """ environ.abort_thread() r = _get_report() r.append_body( render.code_block(block=code, path=path, language=language_id, title=title, caption=caption)) r.stdout_interceptor.write_source('{}\n'.format(code))
def code(source: str, language: str = None, filename: str = None, mime_type: str = None, is_code_block: bool = False) -> str: """ :param source: :param language: :param filename: :param mime_type: :param is_code_block: :return: """ environ.abort_thread() if not source: return '' cleaned = textwrap.dedent(source.strip('\n')) return syntax_highlighting.as_html(source=cleaned, language=language, filename=filename, mime_type=mime_type, is_code_block=is_code_block)
def as_html(source: str, language: str = None, filename: str = None, mime_type: str = None, is_code_block: bool = False): """ :param source: :param language: :param filename: :param mime_type: :param is_code_block: :return: """ environ.abort_thread() lexer = fetch_lexer(source, language, filename, mime_type) Formatter = CodeBlockHtmlFormatter if is_code_block else HtmlFormatter dom = highlight(code=source, lexer=lexer if lexer else DjangoLexer(), formatter=Formatter(linenos=True)) if not is_code_block: return dom return (dom.replace('<pre>', '').replace('</pre>', '').replace( '<table', '<div').replace('</table>', '</div>').replace('<tr>', '').replace( '</tr>', '').replace('<td', '<div').replace('</td>', '</div>'))
def __getattr__(self, item): environ.abort_thread() if item.startswith('_'): return None return self._shared_cache_data.get(item)
def bokeh_plot(model, scale: float = 0.7, responsive: bool = True) -> str: """ :param model: :param scale: :param responsive: :return: """ environ.abort_thread() try: from bokeh import embed except Exception: embed = None if responsive: model.sizing_mode = "scale_width" # model.responsive = True model.plot_width = 800 model.plot_height = round((scale * 9 / 16) * 800) results = embed.components(model) script = results[0] \ .split('>', 1)[1] \ .rsplit('</', 1)[0] return templating.render_template( 'bokeh_component.html', script=script, dom=results[1], scale=round(100 * scale) if scale is not None else 1000)
def table(data_frame, scale: float = 0.7, include_index: bool = False, max_rows: int = 500) -> str: """ :param data_frame: :param scale: :param include_index: :param max_rows: :return: """ environ.abort_thread() table_id = 'table-{}-{}'.format(datetime.utcnow().strftime('%H-%M-%S-%f'), random.randint(0, 1e8)) df_source = (data_frame.head(max_rows) if len(data_frame) > max_rows else data_frame) if include_index: df_source = df_source.reset_index() column_headers = ['"{}"'.format(x) for x in df_source.columns.tolist()] data = df_source.values.tolist() json_data = json_internal.dumps(data, cls=encoding.ComplexJsonEncoder) return templating.render_template('table.html', id=table_id, scale=min(0.95, max(0.05, scale)), data=json_data, column_headers=', '.join(column_headers))
def clear(self) -> 'SharedCache': """ Clears all of the variables currently stored in this cache """ environ.abort_thread() self._shared_cache_data = dict() return self
def clear(self) -> 'SharedCache': """ Clears all of the variables currently stored in this cache """ environ.abort_thread() self._shared_cache_data = dict() return self
def whitespace(lines: float = 1.0) -> str: """ :param lines: :return: """ environ.abort_thread() pixels = round(12 * lines) return '<div style="height:{}px"> </div>'.format(pixels)
def jinja(path: str, **kwargs) -> str: """ :param path: :param kwargs: :return: """ environ.abort_thread() return templating.render_file(path, **kwargs)
def whitespace(lines: float = 1.0) -> str: """ :param lines: :return: """ environ.abort_thread() pixels = round(12 * lines) return '<div style="height:{}px"> </div>'.format(pixels)
def jinja(path: str, **kwargs) -> str: """ :param path: :param kwargs: :return: """ environ.abort_thread() return templating.render_file(path, **kwargs)
def inspect(source: dict) -> str: """ :param source: :return: """ environ.abort_thread() out = inspection.inspect_data(source=source) return inspection.render_tree(out)
def svg(svg_data: str) -> str: """ :param svg_data: :return: """ environ.abort_thread() return templating.render('<div class="svg-box">{{ svg }}</div>', svg=svg_data)
def inspect(source: dict) -> str: """ :param source: :return: """ environ.abort_thread() out = inspection.inspect_data(source=source) return inspection.render_tree(out)
def html(content) -> str: """ :param content: :return: """ environ.abort_thread() return templating.render('<div class="box">{{content}}</div>', content=content)
def pyplot(figure=None, scale: float = 0.8, clear: bool = True, aspect_ratio: typing.Union[list, tuple] = None) -> str: """ :param figure: :param scale: :param clear: :param aspect_ratio: :return: """ environ.abort_thread() from bs4 import BeautifulSoup try: from matplotlib import pyplot as mpl_pyplot except Exception: mpl_pyplot = None if not figure: figure = mpl_pyplot.gcf() if aspect_ratio: figure.set_size_inches(aspect_ratio[0], aspect_ratio[1]) else: figure.set_size_inches(12, 8) buffer = io.StringIO() figure.savefig(buffer, format='svg', dpi=300) buffer.seek(0) svg_data = buffer.read() if clear: figure.clear() soup = BeautifulSoup(svg_data, 'html.parser') svg_tag = soup.find_all('svg')[0] svg_tag['width'] = '100%' svg_tag['height'] = '100%' classes = svg_tag.get('class', '').strip().split(' ') classes.append('cd-pylab-svg') svg_tag['class'] = '\n'.join(classes) styles = [ s for s in svg_tag.get('style', '').split(';') if len(s.strip()) > 1 ] styles.append('max-height:{}vh;'.format(int(100.0 * scale))) svg_tag['style'] = ';'.join(styles) return '<div class="cd-pylab-plot">{}</div>'.format(soup.prettify())
def elapsed(): """ Displays the elapsed time since the step started running. """ environ.abort_thread() step = _cd.project.get_internal_project().current_step r = _get_report() r.append_body(render.elapsed_time(step.elapsed_time)) result = '[ELAPSED]: {}\n'.format(timedelta(seconds=step.elapsed_time)) r.stdout_interceptor.write_source(result)
def preformatted_text(source: str) -> str: """Renders preformatted text box""" environ.abort_thread() if not source: return '' source = render_utils.html_escape(source) return '<pre class="preformatted-textbox">{text}</pre>'.format( text=str(textwrap.dedent(source)))
def elapsed_time(seconds: float) -> str: """Displays the elapsed time since the current step started running.""" environ.abort_thread() parts = ('{}'.format(timedelta(seconds=seconds)).rsplit('.', 1)) hours, minutes, seconds = parts[0].split(':') return templating.render_template( 'elapsed_time.html', hours=hours.zfill(2), minutes=minutes.zfill(2), seconds=seconds.zfill(2), microseconds=parts[-1] if len(parts) > 1 else '')
def elapsed(): """ Displays the elapsed time since the step started running. """ environ.abort_thread() step = _cd.project.get_internal_project().current_step r = _get_report() r.append_body(render.elapsed_time(step.elapsed_time)) result = '[ELAPSED]: {}\n'.format(timedelta(seconds=step.elapsed_time)) r.stdout_interceptor.write_source(result)
def plotly( data: list = None, layout: dict = None, scale: float = 0.5, figure: dict = None, static: bool = False ) -> str: """ :param data: :param layout: :param scale: :param figure: :param static: :return: """ environ.abort_thread() try: import plotly as plotly_lib except ImportError: plotly_lib = None if plotly_lib is None: return templating.render_template( template_name='import-error.html', library_name='Plotly' ) source = figure if figure else {'data': data, 'layout': layout} dom = plotly_lib.offline.plot( figure_or_data=source, output_type='div', include_plotlyjs=False ) found = re.search(r'id="(?P<id>[^"]+)"', dom) dom_id = found.group('id') insert_index = dom.index('"showLink":') dom = ''.join([ dom[:insert_index], '"staticPlot": {}, '.format('true' if static else 'false'), dom[insert_index:] ]) return templating.render_template( 'plotly-component.html', dom=dom, scale=scale, min_height=round(100.0 * scale), id=dom_id )
def status( data: dict, values: bool = True, types: bool = True ) -> str: """ :param data: :param values: :param types: :return: """ environ.abort_thread() out = [] keys = list(data.keys()) keys.sort() for key in keys: value = data[key] value_type = getattr( value, '__class__', {'__name__': 'Unknown'} ).__name__ if hasattr(value, 'head'): try: value = value.head(5) except Exception: pass elif isinstance(value, dict): temp_value = [] for k, v in value.items(): temp_value.append('{}: {}'.format(k, v)) value = '\n'.join(temp_value) elif isinstance(value, (list, tuple)): value = '\n'.join(['{}'.format(v) for v in value]) value = '<pre>{}</pre>'.format( render_utils.html_escape('{}'.format(value))[:600] ) out.append(templating.render_template( 'status-variable.template.html', name=key, values=values, types=types, type=value_type, value=value )) return ''.join(out)
def json(**kwargs) -> str: """ :param kwargs: :return: """ environ.abort_thread() return templating.render_template('json_include.html', data=json_internal.dumps( kwargs, cls=encoding.ComplexJsonEncoder))
def svg(svg_data: str) -> str: """ :param svg_data: :return: """ environ.abort_thread() return templating.render( '<div class="svg-box">{{ svg }}</div>', svg=svg_data )
def json(**kwargs) -> str: """ :param kwargs: :return: """ environ.abort_thread() return templating.render_template( 'json_include.html', data=json_internal.dumps(kwargs, cls=encoding.ComplexJsonEncoder) )
def html(content) -> str: """ :param content: :return: """ environ.abort_thread() return templating.render( '<div class="box">{{content}}</div>', content=content )
def preformatted_text(source: str) -> str: """Renders preformatted text box""" environ.abort_thread() if not source: return '' source = render_utils.html_escape(source) return '<pre class="preformatted-textbox">{text}</pre>'.format( text=str(textwrap.dedent(source)) )
def latex(source: str, inline: bool = False) -> str: """ :param source: :param inline: :return: """ environ.abort_thread() return templating.render_template('katex.html', source=render_utils.format_latex(source), inline=inline)
def head(value, count: int = 5) -> str: """ :param value: :param count: :return: """ environ.abort_thread() if count < 1: return '' try: if hasattr(value, 'head'): return preformatted_text( '\n'.join(['{}'.format(v) for v in value.head(count)]) ) except Exception: pass if isinstance(value, str): return preformatted_text( '\n'.join(value.split('\n')[:count]) ) if isinstance(value, (list, tuple)): out = ['{}'.format(v) for v in value[:count]] return preformatted_text('\n'.join(out)) if isinstance(value, dict): out = [] for k, v in value.items(): if len(out) >= count: break out.append('{}: {}'.format(k, v)) return preformatted_text('\n'.join(out)) try: out = [] for v in value: if len(out) >= count: break out.append('{}'.format(v)) return preformatted_text('\n'.join(out)) except Exception: pass out = '{}'.format(value) out = out.split('\n') return '\n'.join(out[:count])
def latex(source: str, inline: bool = False) -> str: """ :param source: :param inline: :return: """ environ.abort_thread() return templating.render_template( 'katex.html', source=render_utils.format_latex(source), inline=inline )
def elapsed_time(seconds: float) -> str: """Displays the elapsed time since the current step started running.""" environ.abort_thread() parts = ( '{}'.format(timedelta(seconds=seconds)) .rsplit('.', 1) ) hours, minutes, seconds = parts[0].split(':') return templating.render_template( 'elapsed_time.html', hours=hours.zfill(2), minutes=minutes.zfill(2), seconds=seconds.zfill(2), microseconds=parts[-1] if len(parts) > 1 else '' )
def image( rendered_path: str, width: int = None, height: int = None, justify: str = None ) -> str: """Renders an image block""" environ.abort_thread() return templating.render_template( 'image.html', path=rendered_path, width=width, height=height, justification=(justify or 'left').lower() )
def table( data_frame, scale: float = 0.7, include_index: bool = False, max_rows: int = 500 ) -> str: """ :param data_frame: :param scale: :param include_index: :param max_rows: :return: """ environ.abort_thread() table_id = 'table-{}-{}'.format( datetime.utcnow().strftime('%H-%M-%S-%f'), random.randint(0, 1e8) ) df_source = ( data_frame.head(max_rows) if len(data_frame) > max_rows else data_frame ) if include_index: df_source = df_source.reset_index() try: column_headers = ['"{}"'.format(x) for x in df_source.columns.tolist()] data = df_source.values.tolist() except AttributeError: # If no columns are found assume that it is a Series instead of a # DataFrame and reformat the data to match the expected structure. column_headers = ['"{}"'.format(df_source.name)] data = df_source.values.reshape([len(df_source), 1]).tolist() json_data = json_internal.dumps(data, cls=encoding.ComplexJsonEncoder) return templating.render_template( 'table.html', id=table_id, scale=min(0.95, max(0.05, scale)), data=json_data, column_headers=', '.join(column_headers) )
def status( message: str = None, progress: float = None, section_message: str = None, section_progress: float = None, ): """ Updates the status display, which is only visible while a step is running. This is useful for providing feedback and information during long-running steps. A section progress is also available for cases where long running tasks consist of multiple tasks and you want to display sub-progress messages within the context of the larger status. Note: this is only supported when running in the Cauldron desktop application. :param message: The status message you want to display. If left blank the previously set status message will be retained. Should you desire to remove an existing message, specify a blank string for this argument. :param progress: A number between zero and one that indicates the overall progress for the current status. If no value is specified, the previously assigned progress will be retained. :param section_message: The status message you want to display for a particular task within a long-running step. If left blank the previously set section message will be retained. Should you desire to remove an existing message, specify a blank string for this argument. :param section_progress: A number between zero and one that indicates the progress for the current section status. If no value is specified, the previously assigned section progress value will be retained. """ environ.abort_thread() step = _cd.project.internal_project.current_step if message is not None: step.progress_message = message if progress is not None: step.progress = max(0, min(1.0, progress)) if section_message is not None: step.sub_progress_message = section_message if section_progress is not None: step.sub_progress = section_progress
def status( message: str = None, progress: float = None, section_message: str = None, section_progress: float = None, ): """ Updates the status display, which is only visible while a step is running. This is useful for providing feedback and information during long-running steps. A section progress is also available for cases where long running tasks consist of multiple tasks and you want to display sub-progress messages within the context of the larger status. Note: this is only supported when running in the Cauldron desktop application. :param message: The status message you want to display. If left blank the previously set status message will be retained. Should you desire to remove an existing message, specify a blank string for this argument. :param progress: A number between zero and one that indicates the overall progress for the current status. If no value is specified, the previously assigned progress will be retained. :param section_message: The status message you want to display for a particular task within a long-running step. If left blank the previously set section message will be retained. Should you desire to remove an existing message, specify a blank string for this argument. :param section_progress: A number between zero and one that indicates the progress for the current section status. If no value is specified, the previously assigned section progress value will be retained. """ environ.abort_thread() step = _cd.project.get_internal_project().current_step if message is not None: step.progress_message = message if progress is not None: step.progress = max(0.0, min(1.0, progress)) if section_message is not None: step.sub_progress_message = section_message if section_progress is not None: step.sub_progress = section_progress
def text(value: str) -> str: """ :param value: :return: """ environ.abort_thread() value = render_utils.html_escape(value) lines = str(value).strip().split('\n') paragraph_separator = '</p><p class="plaintextbox">' # Convert empty lines into paragraph separators for index, line in enumerate(lines): lines[index] = line.strip() or paragraph_separator return '<p class="plaintextbox">{text}</p>'.format(text=' '.join(lines))
def listing(source: list, ordered: bool = False, expand_full: bool = False) -> str: """ :param source: :param ordered: :param expand_full: :return: """ environ.abort_thread() return templating.render_template( 'listing.html', type='ol' if ordered else 'ul', items=['{}'.format(x) for x in source], css_modifier='full' if expand_full else 'limited')
def plotly(data: list = None, layout: dict = None, scale: float = 0.5, figure: dict = None, static: bool = False) -> str: """ :param data: :param layout: :param scale: :param figure: :param static: :return: """ environ.abort_thread() try: import plotly as plotly_lib except ImportError: plotly_lib = None if plotly_lib is None: return templating.render_template(template_name='import-error.html', library_name='Plotly') source = figure if figure else {'data': data, 'layout': layout} dom = plotly_lib.offline.plot(figure_or_data=source, output_type='div', include_plotlyjs=False) found = re.search(r'id="(?P<id>[^"]+)"', dom) dom_id = found.group('id') insert_index = dom.index('"showLink":') dom = ''.join([ dom[:insert_index], '"staticPlot": {}, '.format('true' if static else 'false'), dom[insert_index:] ]) return templating.render_template('plotly-component.html', dom=dom, scale=scale, min_height=round(100.0 * scale), id=dom_id)
def text(value: str) -> str: """ :param value: :return: """ environ.abort_thread() value = render_utils.html_escape(value) lines = str(value).strip().split('\n') paragraph_separator = '</p><p class="plaintextbox">' # Convert empty lines into paragraph separators for index, line in enumerate(lines): lines[index] = line.strip() or paragraph_separator return '<p class="plaintextbox">{text}</p>'.format(text=' '.join(lines))
def status(data: dict, values: bool = True, types: bool = True) -> str: """ :param data: :param values: :param types: :return: """ environ.abort_thread() out = [] keys = list(data.keys()) keys.sort() for key in keys: value = data[key] value_type = getattr(value, '__class__', { '__name__': 'Unknown' }).__name__ if hasattr(value, 'head'): try: value = value.head(5) except Exception: pass elif isinstance(value, dict): temp_value = [] for k, v in value.items(): temp_value.append('{}: {}'.format(k, v)) value = '\n'.join(temp_value) elif isinstance(value, (list, tuple)): value = '\n'.join(['{}'.format(v) for v in value]) value = '<pre>{}</pre>'.format( render_utils.html_escape('{}'.format(value))[:600]) out.append( templating.render_template('status-variable.template.html', name=key, values=values, types=types, type=value_type, value=value)) return ''.join(out)
def tail(value, count: int = 5) -> str: """ :param value: :param count: :return: """ environ.abort_thread() if count < 1: return '' try: if hasattr(value, 'tail'): return preformatted_text( '\n'.join(['{}'.format(v) for v in value.tail(count)]) ) except Exception: pass if isinstance(value, str): return preformatted_text( '\n'.join(value.split('\n')[-count:]) ) if isinstance(value, (list, tuple)): out = ['{}'.format(v) for v in value[-count:]] return preformatted_text('\n'.join(out)) if isinstance(value, dict): out = [] keys = sorted(list(value.keys()), reverse=True) for key in keys[:count]: out.append('{}: {}'.format(key, value[key])) return preformatted_text('\n'.join(out)) try: value = list(value) out = ['{}'.format(v) for v in value[-count:]] return preformatted_text('\n'.join(out)) except Exception: pass out = '{}'.format(value).split('\n') return '\n'.join(out[-count:])
def fetch_lexer( source: str, language: str = None, filename: str = None, mime_type: str = None ) -> Lexer: """ :param source: :param language: :param filename: :param mime_type: :return: """ environ.abort_thread() try: if language: return get_lexer_by_name(language, stripall=True) except ClassNotFound: pass if filename: try: return get_lexer_for_filename(filename, stripall=True) except ClassNotFound: pass try: return guess_lexer_for_filename(filename, source, stripall=True) except ClassNotFound: pass try: if mime_type: return get_lexer_for_mimetype(mime_type, stripall=True) except ClassNotFound: pass try: return guess_lexer(source, stripall=True) except ClassNotFound: return TextLexer()
def head(value, count: int = 5) -> str: """ :param value: :param count: :return: """ environ.abort_thread() if count < 1: return '' try: if hasattr(value, 'head'): return preformatted_text('\n'.join( ['{}'.format(v) for v in value.head(count)])) except Exception: pass if isinstance(value, str): return preformatted_text('\n'.join(value.split('\n')[:count])) if isinstance(value, (list, tuple)): out = ['{}'.format(v) for v in value[:count]] return preformatted_text('\n'.join(out)) if isinstance(value, dict): out = [] keys = sorted(list(value.keys())) for key in keys[:count]: out.append('{}: {}'.format(key, value[key])) return preformatted_text('\n'.join(out)) try: value = list(value) out = ['{}'.format(v) for v in value[:count]] return preformatted_text('\n'.join(out)) except Exception: pass out = '{}'.format(value) out = out.split('\n') return '\n'.join(out[:count])
def text(value: str) -> str: """ :param value: :return: """ environ.abort_thread() value = render_utils.html_escape(value) lines = str(value).strip().split('\n') for index, line in enumerate(lines): l = line.strip() if len(l) < 1: l = '</p><p class="plaintextbox">' lines[index] = l return '<p class="plaintextbox">{text}</p>'.format(text=' '.join(lines))
def fetch(self, key: typing.Union[str, None], default_value=None): """ Retrieves the value of the specified variable from the cache :param key: The name of the variable for which the value should be returned :param default_value: The value to return if the variable does not exist in the cache :return: The value of the specified key if it exists in the cache or the default_Value if it does not """ environ.abort_thread() if key is None: return self._shared_cache_data return self._shared_cache_data.get(key, default_value)
def put(self, *args, **kwargs) -> 'SharedCache': """ Adds one or more variables to the cache. :param args: Variables can be specified by two consecutive arguments where the first argument is a key and the second one the corresponding value. For example: ``` put('a', 1, 'b', False) ``` would add two variables to the cache where the value of _a_ would be 1 and the value of _b_ would be False. :param kwargs: Keyword arguments to be added to the cache, which are name value pairs like standard keyword named arguments in Python. For example: ``` put(a=1, b=False) ``` would add two variables to the cache where the value of _a_ would be 1 and the value of _b_ would be False. """ environ.abort_thread() index = 0 while index < (len(args) - 1): key = args[index] value = args[index + 1] self._shared_cache_data[key] = value index += 2 for key, value in kwargs.items(): if value is None and key in self._shared_cache_data: del self._shared_cache_data[key] else: self._shared_cache_data[key] = value return self
def put(self, *args, **kwargs) -> 'SharedCache': """ Adds one or more variables to the cache. :param args: Variables can be specified by two consecutive arguments where the first argument is a key and the second one the corresponding value. For example: ``` put('a', 1, 'b', False) ``` would add two variables to the cache where the value of _a_ would be 1 and the value of _b_ would be False. :param kwargs: Keyword arguments to be added to the cache, which are name value pairs like standard keyword named arguments in Python. For example: ``` put(a=1, b=False) ``` would add two variables to the cache where the value of _a_ would be 1 and the value of _b_ would be False. """ environ.abort_thread() index = 0 while index < (len(args) - 1): key = args[index] value = args[index + 1] self._shared_cache_data[key] = value index += 2 for key, value in kwargs.items(): if value is None and key in self._shared_cache_data: del self._shared_cache_data[key] else: self._shared_cache_data[key] = value return self
def fetch(self, key: typing.Union[str, None], default_value=None): """ Retrieves the value of the specified variable from the cache :param key: The name of the variable for which the value should be returned :param default_value: The value to return if the variable does not exist in the cache :return: The value of the specified key if it exists in the cache or the default_Value if it does not """ environ.abort_thread() if key is None: return self._shared_cache_data return self._shared_cache_data.get(key, default_value)
def as_html( source: str, language: str = None, filename: str = None, mime_type: str = None, is_code_block: bool = False ): """ :param source: :param language: :param filename: :param mime_type: :param is_code_block: :return: """ environ.abort_thread() lexer = fetch_lexer(source, language, filename, mime_type) Formatter = CodeBlockHtmlFormatter if is_code_block else HtmlFormatter dom = highlight( code=source, lexer=lexer if lexer else DjangoLexer(), formatter=Formatter(linenos=True) ) if not is_code_block: return dom return ( dom .replace('<pre>', '') .replace('</pre>', '') .replace('<table', '<div') .replace('</table>', '</div>') .replace('<tr>', '') .replace('</tr>', '') .replace('<td', '<div') .replace('</td>', '</div>') )
def listing( source: list, ordered: bool = False, expand_full: bool = False ) -> str: """ :param source: :param ordered: :param expand_full: :return: """ environ.abort_thread() return templating.render_template( 'listing.html', type='ol' if ordered else 'ul', items=['{}'.format(x) for x in source], css_modifier='full' if expand_full else 'limited' )
def code_file( path: str, language: str = None, mime_type: str = None, is_code_block: bool = False ) -> str: """ :param path: :param language: :param mime_type: :param is_code_block: :return: """ environ.abort_thread() path = environ.paths.clean(path) if not os.path.exists(path): return 'File does not exist: {}'.format(path) source = None for encoding in ['utf-8', 'mac_roman', 'cp1250']: try: with open(path, 'r', encoding=encoding) as f: source = f.read() break except Exception: pass if source is None: return '' return code( source=source, language=language, filename=path, mime_type=mime_type, is_code_block=is_code_block )
def inspect_data(source_key: str = None, source=None) -> dict: """ :param source_key: :param source: :return: """ environ.abort_thread() if isinstance(source, dict): out = { 'type': 'dict', 'key': source_key, 'structure': [] } for key, value in source.items(): out['structure'].append(inspect_data(key, value)) return out if isinstance(source, (list, tuple)): return { 'type': 'list', 'length': len(source), 'key': source_key, 'structure': inspect_data(None, source[0]) } if isinstance(source, str): return {'type': 'str', 'key': source_key, 'structure': None} if isinstance(source, (float, int)): return {'type': 'number', 'key': source_key, 'structure': None} if isinstance(source, bool): return {'type': 'bool', 'key': source_key, 'structure': None} return {'type': 'None', 'key': source_key, 'structure': None}