Path: blob/main/src/resources/jupyter/lang/python/setup.py
12923 views
1# imports2import os3import sys4import types5import json6import base6478# figure size/format9fig_width = {fig_width}10fig_height = {fig_height}11fig_format = '{fig_format}'12fig_dpi = {fig_dpi}13interactivity = '{interactivity}'14is_shiny = {is_shiny}15is_dashboard = {is_dashboard}16plotly_connected = {plotly_connected}1718# matplotlib defaults / format19try:20import matplotlib.pyplot as plt21plt.rcParams['figure.figsize'] = (fig_width, fig_height)22plt.rcParams['figure.dpi'] = fig_dpi23plt.rcParams['savefig.dpi'] = "figure"2425# IPython 7.14 deprecated set_matplotlib_formats from IPython26try:27from matplotlib_inline.backend_inline import set_matplotlib_formats28except ImportError:29# Fall back to deprecated location for older IPython versions30from IPython.display import set_matplotlib_formats3132set_matplotlib_formats(fig_format)33except Exception:34pass3536# plotly use connected mode37try:38import plotly.io as pio39if plotly_connected:40pio.renderers.default = "notebook_connected"41else:42pio.renderers.default = "notebook"43for template in pio.templates.keys():44pio.templates[template].layout.margin = dict(t=30,r=0,b=0,l=0)45except Exception:46pass4748# disable itables paging for dashboards49if is_dashboard:50try:51from itables import options52options.dom = 'fiBrtlp'53options.maxBytes = 1024 * 102454options.language = dict(info = "Showing _TOTAL_ entries")55options.classes = "display nowrap compact"56options.paging = False57options.searching = True58options.ordering = True59options.info = True60options.lengthChange = False61options.autoWidth = False62options.responsive = True63options.keys = True64options.buttons = []65except Exception:66pass6768try:69import altair as alt70# By default, dashboards will have container sized71# vega visualizations which allows them to flow reasonably72theme_sentinel = '_quarto-dashboard-internal'73def make_theme(name):74nonTheme = alt.themes._plugins[name]75def patch_theme(*args, **kwargs):76existingTheme = nonTheme()77if 'height' not in existingTheme:78existingTheme['height'] = 'container'79if 'width' not in existingTheme:80existingTheme['width'] = 'container'8182if 'config' not in existingTheme:83existingTheme['config'] = dict()8485# Configure the default font sizes86title_font_size = 1587header_font_size = 1388axis_font_size = 1289legend_font_size = 1290mark_font_size = 1291tooltip = False9293config = existingTheme['config']9495# The Axis96if 'axis' not in config:97config['axis'] = dict()98axis = config['axis']99if 'labelFontSize' not in axis:100axis['labelFontSize'] = axis_font_size101if 'titleFontSize' not in axis:102axis['titleFontSize'] = axis_font_size103104# The legend105if 'legend' not in config:106config['legend'] = dict()107legend = config['legend']108if 'labelFontSize' not in legend:109legend['labelFontSize'] = legend_font_size110if 'titleFontSize' not in legend:111legend['titleFontSize'] = legend_font_size112113# The header114if 'header' not in config:115config['header'] = dict()116header = config['header']117if 'labelFontSize' not in header:118header['labelFontSize'] = header_font_size119if 'titleFontSize' not in header:120header['titleFontSize'] = header_font_size121122# Title123if 'title' not in config:124config['title'] = dict()125title = config['title']126if 'fontSize' not in title:127title['fontSize'] = title_font_size128129# Marks130if 'mark' not in config:131config['mark'] = dict()132mark = config['mark']133if 'fontSize' not in mark:134mark['fontSize'] = mark_font_size135136# Mark tooltips137if tooltip and 'tooltip' not in mark:138mark['tooltip'] = dict(content="encoding")139140return existingTheme141142return patch_theme143144# We can only do this once per session145if theme_sentinel not in alt.themes.names():146for name in alt.themes.names():147alt.themes.register(name, make_theme(name))148149# register a sentinel theme so we only do this once150alt.themes.register(theme_sentinel, make_theme('default'))151alt.themes.enable('default')152153except Exception:154pass155156# enable pandas latex repr when targeting pdfs157try:158import pandas as pd159if fig_format == 'pdf':160pd.set_option('display.latex.repr', True)161except Exception:162pass163164# interactivity165if interactivity:166from IPython.core.interactiveshell import InteractiveShell167InteractiveShell.ast_node_interactivity = interactivity168169# NOTE: the kernel_deps code is repeated in the cleanup.py file170# (we can't easily share this code b/c of the way it is run).171# If you edit this code also edit the same code in cleanup.py!172173# output kernel dependencies174kernel_deps = dict()175for module in list(sys.modules.values()):176# Some modules play games with sys.modules (e.g. email/__init__.py177# in the standard library), and occasionally this can cause strange178# failures in getattr. Just ignore anything that's not an ordinary179# module.180if not isinstance(module, types.ModuleType):181continue182path = getattr(module, "__file__", None)183if not path:184continue185if path.endswith(".pyc") or path.endswith(".pyo"):186path = path[:-1]187if not os.path.exists(path):188continue189kernel_deps[path] = os.stat(path).st_mtime190print(json.dumps(kernel_deps))191192# set run_path if requested193run_path = '{run_path}'194if run_path:195# hex-decode the path196run_path = base64.b64decode(run_path.encode("utf-8")).decode("utf-8")197os.chdir(run_path)198199# reset state200%reset201202# shiny203# Checking for shiny by using {is_shiny} directly because we're after the %reset. We don't want204# to set a variable that stays in global scope.205if {is_shiny}:206try:207import htmltools as _htmltools208import ast as _ast209210_htmltools.html_dependency_render_mode = "json"211212# This decorator will be added to all function definitions213def _display_if_has_repr_html(x):214try:215# IPython 7.14 preferred import216from IPython.display import display, HTML217except:218from IPython.core.display import display, HTML219220if hasattr(x, '_repr_html_'):221display(HTML(x._repr_html_()))222return x223224# ideally we would undo the call to ast_transformers.append225# at the end of this block whenver an error occurs, we do226# this for now as it will only be a problem if the user227# switches from shiny to not-shiny mode (and even then likely228# won't matter)229import builtins230builtins._display_if_has_repr_html = _display_if_has_repr_html231232class _FunctionDefReprHtml(_ast.NodeTransformer):233def visit_FunctionDef(self, node):234node.decorator_list.insert(2350,236_ast.Name(id="_display_if_has_repr_html", ctx=_ast.Load())237)238return node239240def visit_AsyncFunctionDef(self, node):241node.decorator_list.insert(2420,243_ast.Name(id="_display_if_has_repr_html", ctx=_ast.Load())244)245return node246247ip = get_ipython()248ip.ast_transformers.append(_FunctionDefReprHtml())249250except:251pass252253def ojs_define(**kwargs):254import json255try:256# IPython 7.14 preferred import257from IPython.display import display, HTML258except:259from IPython.core.display import display, HTML260261# do some minor magic for convenience when handling pandas262# dataframes263def convert(v):264try:265import pandas as pd266except ModuleNotFoundError: # don't do the magic when pandas is not available267return v268if type(v) == pd.Series:269v = pd.DataFrame(v)270if type(v) == pd.DataFrame:271j = json.loads(v.T.to_json(orient='split'))272return dict((k,v) for (k,v) in zip(j["index"], j["data"]))273else:274return v275276v = dict(contents=list(dict(name=key, value=convert(value)) for (key, value) in kwargs.items()))277display(HTML('<script type="ojs-define">' + json.dumps(v) + '</script>'), metadata=dict(ojs_define = True))278globals()["ojs_define"] = ojs_define279globals()["__spec__"] = None280281