Settings

The Pharaoh settings file pharaoh.yaml is used for three main purposes:

  • Configuration of Pharaoh functionality like asset generation, report build, archiving, RDDL upload, notifications…

  • Hold info about all added components

  • User-defined settings (accessible from templates)

The settings file is loaded using the OmegaConf library.

OmegaConf is a YAML based hierarchical configuration system, with support for merging configurations from multiple sources (files, CLI argument, environment variables) providing a consistent API regardless of how the configuration was created. OmegaConf also offers runtime type safety via Structured Configs.

The library offers lots of features like Variable interpolation and Resolvers. So if you want to get the best out of your configuration file, have a look in the OmegaConf documentation on the mentioned topics above.

Default Settings

A Pharaoh project is generated with following default settings, if not specified otherwise:

logging:
  # The logging level for the Pharaoh logger, one of DEBUG, INFO, WARNING, ERROR
  level: "INFO"

report:
  # The report output format. Currently supported are:
  # - html and all other Sphinx default builders; see https://www.sphinx-doc.org/en/master/usage/builders/index.html
  # - confluence, singleconfluence; see https://sphinxcontrib-confluencebuilder.readthedocs.io/en/stable/builders/
  builder: "html"
  # Verbosity of the Sphinx build. 0: INFO, 1: VERBOSE, 2: DEBUG
  # VERBOSE: Will enable debug output of .. pharaoh-asset:: directive
  verbosity: 0
  # The report title displayed on the index page
  title: "Pharaoh Report"
  # The report author
  author: "${user:}"
  # Name of the ZIP archive. For available resolvers consult documentation
  archive_name: "pharaoh_report_${utcnow.strf:%Y%m%d_%H%M%S}.zip"
  # Options for HTML builder
  html:
    # Show Pharaoh logo on HTML report. Kindly let this enabled for branding, unless it's for external customers ;)
    show_pharaoh_logo: true

asset_gen:
  # Create static (png, svg) assets instead of dynamic (html) ones where possible.
  # This only has effect on the patched functions of frameworks like pandas, bokeh, plotly, ... .
  # For more info refer to the documentation: todo
  force_static: false
  # How many worker processes (CPUs) to use for parallel asset generation. "auto" or some integer value.
  # Use 0 to execute all asset scripts sequentially in the current process.
  # Using multiprocessing only outperforms single-process if there are a large amount of asset scripts.
  # The proof is in the pudding ;)
  worker_processes: 0
  # Regular expression (case-insensitive). If matches on file name with extension, the script is not executed during
  # asset generation
  script_ignore_pattern: "_.*"  # ignore scripts that start with underscore
  # The default width of embedded iframes. (html attribute)
  default_iframe_width: "100%"
  # The default height of embedded iframes. (html attribute)
  default_iframe_height: "500px"
  # Show all datatables per default with an interactive search function
  default_datatable_extended_search: false

# Options for toolkit patches
toolkits:
  bokeh:
    export_png:
      width: 720
      height: 480
  matplotlib:
    savefig:
      dpi: 150
      facecolor: "auto"
      edgecolor: "auto"
  plotly:
    write_image:
      width: 1000
      height: 600
      scale: 1
      validate: true
    write_html:
      default_width: "100%"
      default_height: "100%"
  holoviews:
    save:
      dpi: 300
  pandas:
    to_html:
      na_rep: ""

Custom Settings

Since default settings are very likely to not fit everyone’s needs, they can be modified by the user in several ways:

Important

Make sure all keys in your settings are lowercase, otherwise putting/getting settings might not work as expected since settings are all treated lowercase internally!

  • Pass a custom settings file on project creation via the keyword argument custom_settings. The file is merged with the default settings, so it’s enough to overwrite only the divergent settings:

    from pharaoh.api import PharaohProject
    
    proj = PharaohProject(project_root="some-path", custom_settings="mysettings.yaml")
    

    Note

    If custom_settings is a relative path, then the current working directory is used as anchor

  • Put settings via the settings API put_setting(key: str, value: Any):

    from pharaoh.api import PharaohProject
    
    proj = PharaohProject(project_root="some-path")
    proj.put_setting("report.title", "My own title")
    proj.put_setting("toolkits.bokeh.export_png", dict(width=720, height=480))
    proj.save_settings()  # Optional
    

    Important

    Defining settings like this only changes the settings for the project instance in memory but does not persist them to pharaoh.yaml.

    To do so call save_settings() manually if you don’t plan to modify components/resources right after (those functions do an auto-safe).

  • Put settings via environment variables

    Same example as with settings API, but with environment variables:

    import os
    from pharaoh.api import PharaohProject
    
    # Env variables have to be prefixed with "pharaoh." and are always treated lowercase
    os.environ["pharaoh.report.title"] = "My own title"
    os.environ["pharaoh.toolkits.bokeh.export_png"] = "{'width': 720, 'height': 480}"
    
    proj = PharaohProject(project_root="some-path")
    proj.save_settings(include_env=True)
    

    Note

    Double-underscore __ also acts as a valid separator for keys, since some shell environments don’t allow dots inside variable names. E.g. PHARAOH__a.B__c___d will resolve to pharaoh.a.b.c___d.

    Important

    Environment variables are only persisted to pharaoh.yaml when saving like this: save_settings(include_env=True)

    Important

    If Pharaoh environment variables are changed while the project is already instantiated, you can reload settings using load_settings(namespace="env"):

    import os
    from pharaoh.api import PharaohProject
    
    proj = PharaohProject(project_root="some-path")
    os.environ["pharaoh.report.title"] = "My Title"
    proj.load_settings(namespace="env")
    proj.save_settings(include_env=True)
    

Accessing Settings

Setting values can be accessed in various places throughout the Pharaoh project using PharaohProject.get_setting():

  • in Python scripts, e.g. asset- or local context-scripts:

    from pharaoh.api import get_project
    pharaoh_project = get_project(__file__)  # Get a project instance location of this file in project directory
    title = project.get_setting("report.title")
    
  • in templates:

    {{ heading(get_setting("report.title"), 1) }}
    {% set static_export = get_setting("asset_gen.force_static", False) -%}
    

Custom Resolvers

OmegaConf offers already some builtin resolvers like oc.env: author: "${oc.env:USERNAME,unknown}" but Pharaoh adds additional ones for your convenience:

  • utcnow.strf: Formats UTC time.

    Usage: archive_name: "pharaoh_report_${utcnow.strf:%Y%m%d_%H%M%S}.zip"

  • now.strf: Same as above, but with timestamp of local timezone.

  • pharaoh.project_dir: Returns the Pharaoh project directory with / as path separator.

    Usage: key: "${pharaoh.project_dir:}/somepath" (note the trailing :, without, it would be a reference).

If you need additional resolvers just register them like this.

If you think others might benefit too, please add them to pharaoh.util.oc_resolvers and raise a PR.