Tropofy API

App

App

class tropofy.app.App(config=None, tropofy_config=None)[source]

Provides an interface for writing a Tropofy App.

Note

Most Tropofy apps are created using the tropofy.app.AppWithDataSets interface. This inherits from tropofy.app.App and is thus able to implement all methods of tropofy.app.App. It is recomended that new developers use tropofy.app.AppWithDataSets.

classmethod app_running_in_debug()[source]

Checks if this app is being run in debug mode.

By default, checks for PyCharm’s default debugger ‘pydevd’. Override this to check some other way to see if running in debug mode.

Returns:bool
export_empty_sheets(app_session)[source]

Whether or not to export empty sheets when a data_set is exported. Can be useful to hide some inner workings of an app.

Parameters:app_session
Returns:True or False
force_use_auto_load_data_set_id()[source]

Forces users to only use the data set specified by get_auto_load_data_set_id :return

Allows additional links to be added to the “burger menu” in the navbar. Return a dictionary of Link Text to URL

This won’t work if using a custom_user_menu

get_app_specific_css(app_session)[source]

(Optional) Path to app-specific CSS either relative to app static path or absolute across internet

get_app_version(app_session=None)[source]

Get a unique identifier for the app’s version :return: string app version

get_auto_load_data_set_id(app_session)[source]

Skips the Getting Started page and loads the returned data_set id automatically. You can use this functionality if your app does not manage data sets (i.e. derives from App not AppWithDataSets) but instead is a view onto another apps data sets

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:None, to not auto load data set, or id (int) of an AppDataSet to auto load it.
get_custom_homepage_template_kwargs(app_session)[source]

Custom keyword args to send to homepage template.

Use to dynamically create homepage with tropofy.app.App.get_app_home_page_renderer_name().

(Dev note - overlaps a little with tropofy.app.App.get_home_page_content(). Could merge and make generic.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:dict
get_default_example_data_set_name()[source]

(Optional) Set the name of the example data set that is created by default on first use of the app.

Returns:String that matches a key in the dictionary returned by tropofy.app.AppWithDataSets.get_examples().
Return type:str

If this function is not implemented or the string returned does not match an example, the first key alphabetically in the dictionary returned by tropofy.app.AppWithDataSets.get_examples() will be used.

get_default_nav_title()[source]

Title to display on nav bar. Defaults to app name.

Return type:str
get_examples()[source]

Define example data sets that a user can load to demonstrate the Apps functionality.

Returns:Dictionary of {example name:function} pairs, where each function populates an empty tropofy.app.data_set.AppDataSet.
Return type:dict

Example usage:

    def get_examples(self):
        return {"Demo data for Brisbane North": load_example_data}

An example of a function that populates a tropofy.app.data_set.AppDataSet is given below,

def load_example_data(app_session):
    stores = []
    stores.append(Store(name="CLAYFIELD", latitude=-27.417536, longitude=153.056677))
    stores.append(Store(name="SANDGATE", latitude=-27.321538, longitude=153.069267))
    app_session.data_set.add_all(stores)

    performances = []
    performances.append(Performance(store_name="CLAYFIELD", year=2011, sales=1000, expenses=400))
    performances.append(Performance(store_name="CLAYFIELD", year=2012, sales=1170, expenses=460))
    performances.append(Performance(store_name="SANDGATE", year=2011, sales=660, expenses=1120))
    performances.append(Performance(store_name="SANDGATE", year=2012, sales=1030, expenses=540))
    app_session.data_set.add_all(performances)

Note

tropofy.app.AppWithDataSets.get_examples() returns a dictionary of strings mapped to functions, each function has the following signature:

example_data_function(app_session)
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
get_gui()[source]

This function defines the user interface for an App.

An App consists of a list of Step Groups, where each Step Group is made up of Steps. A Step Group is represented by the class tropofy.app.StepGroup, and a Step is represented by the class tropofy.app.Step. An example user interface is provided below,

    def get_gui(self):
        step_group_1 = StepGroup(name='Input')
        step_group_1.add_step(Step(name='Stores', widgets=[SimpleGrid(Store)]))
        step_group_1.add_step(Step(name='Performances', widgets=[SimpleGrid(Performance)]))

        step_group_2 = StepGroup(name='Output')
        step_group_2.add_step(Step(name='Map', widgets=[MyKMLMap()]))
        step_group_2.add_step(Step(name='Chart', widgets=[PerformanceBarChart()]))

        return [step_group_1, step_group_2]
Returns:list of step groups of type tropofy.app.StepGroup, each consisting of steps of type tropofy.app.Step.
Return type:list
get_kpis()[source]

Define KPIs to be used in the app.

get_max_data_set_file_size()[source]

Return the number of bytes for the file size limit of importing data sets :rtype: int

get_name()[source]

This function returns the name of the App as a string.

    def get_name(self):
        return "My First App"
Returns:the name of the App.
Return type:str
get_navbar_style(app_session)[source]

Determine the style of the navbar at the top of the page.

Default: App.NAVBARSTYLE_DEFAULT

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.

Options are:

  • App.NAVBARSTYLE_DEFAULT: Light colour scheme
  • App.NAVBARSTYLE_INVERSE: Dark colour scheme
get_navigation_style(app_session)[source]

Determine the navigation style used in the app.

Default: App.NAVSTYLE_ACCORDION.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.

Options are:

  • App.NAVSTYLE_ACCORDION: An accordion style displayed on the LHS of the GUI. Good for apps with many steps and step groups.
  • App.NAVSTYLE_NAVBAR_BUTTONS: Buttons in the navbar that link to each step. Good for apps with very few steps.
get_offline_options(app_session)[source]

Options for Offline.js http://github.hubspot.com/offline/.

Tropofy sets custom defaults of:

  • ‘requests’: False (this stop requests that fail while offline from retrying automatically)
Returns:dict of options for Offline.js.
get_page_title()[source]

(Optional) Set the title for the webpage. In most browsers, used as text in the tab title. Default is ‘Tropofy’.

Return type:str
get_parameters()[source]

Define parameters to be used in the app.

Returns:list of tropofy.app.Parameter mixins
Return type:list

Example from Plotting in 3D Example App:

    def get_parameters(self):
        return PlotParameterGroup.get_params()

The additional helper validating function used above is:

def validate_value_g_zero(value):
    return True if value > 0 else "Value must be > 0."
get_sentry_javascript_dsn(app_session)[source]

Track client side errors using Sentry. To not use Sentry, return None

Parameters:app_session
Returns:
get_show_active_data_set_name_in_navbar(app_session)[source]

Enable showing the name of the current data set in the navbar.

Returns:bool (default True)
get_splash_additional_data()[source]

Gets any additional data which should be passed to the splash page Should be used in conjunction with get_splash_file_path

get_splash_file_path()[source]

Gets the file which should be used to render the app’s splash page

By default, it will look for a splash.mako in the static folder in the same directory as the app def If that doesn’t exist it will default to the provided Tropofy splash

Returns:String path to file
get_static_content_path(app_session)[source]

Defines a path for Tropofy to look at in order to serve any static content referenced by your application. Required in order to make use of any tropoy.widgets.CustomWidget objects.

It is recommended to use os.path, along with __file__ to define the static content path.

By default it will look for a folder in the root of your app called ‘static’ and use that if it exists

Returns:The filesystem path of the directory containing any static content for the application.
get_tic(client_data, app_session)[source]

Used to send custom data to update your app.

Automatically sends server time and the get_tic result of all tropofy.Widget instances

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
get_tic_frequency(app_session)[source]

App tic frequency in seconds

Returns:Period between app tics
Return type:int
get_tropofy_unavailable_message()[source]

If the GUI server is unavailable the compute node will show this message while waiting for a GUI server

Return type:str
logger

Returns the App-specific logger

Loggers are configured in the app’s configuration file via tropofy_extensions.tropofy_logging. The assumption is that a logger with the app’s name has been customised in this configuration. Otherwise an uncustomised logger is returned.

Return type:logging.Logger
notifier

Returns the App-specific slack notification logger

Loggers are configured in the app’s configuration file via tropofy_extensions.tropofy_logging. The assumption is that a logger with the name ‘slack’ has been customised in this configuration. Otherwise an uncustomised logger is returned.

Return type:logging.Logger
skip_to_step_index_on_data_set_load()[source]

When a data set loaded, skip to a specific step.

Defaults to None, which means on first load for a user in an app, the first step in the workflow will be selected. For future loads of the same data_set, the index of the last accessed step will be the first loaded.

This is particularly useful for dashboard style apps which auto-load a data set, and have a primary view which should always be loaded first.

Returns:step index
Return type:(str, str)

AppWithDataSets

class tropofy.app.AppWithDataSets(config=None, tropofy_config=None)[source]

Provides an interface for writing a Tropofy App with data sets. Data sets allow an app to work with separate sets of data, depending on the user.

An app created with tropofy.app.AppWithDataSets will automatically include data set management functionality.

Note

As tropofy.app.AppWithDataSets inherits from tropofy.app.App, all methods that can be overwritten for tropofy.app.App, can also be overidden in tropofy.app.AppWithDataSets

Note

When writing app code, access the open tropofy.app.data_set.AppDataSet through tropofy.app.meta.AppSession.data_set

To create an App with data sets, a developer must implement the tropofy.app.AppWithDataSets interface. This interface defines:

  • App Name
  • User Interface
  • Example Data

The class below, MyFirstApp, provides an example implementation of the tropofy.app.AppWithDataSets interface,

class MyFirstApp(AppWithDataSets):
    def get_name(self):
        return "My First App"

    def get_gui(self):
        step_group_1 = StepGroup(name='Input')
        step_group_1.add_step(Step(name='Stores', widgets=[SimpleGrid(Store)]))
        step_group_1.add_step(Step(name='Performances', widgets=[SimpleGrid(Performance)]))

        step_group_2 = StepGroup(name='Output')
        step_group_2.add_step(Step(name='Map', widgets=[MyKMLMap()]))
        step_group_2.add_step(Step(name='Chart', widgets=[PerformanceBarChart()]))

        return [step_group_1, step_group_2]

Refer to the documentation below for full details of the tropofy.app.AppWithDataSets interface.

get_data_sets_widget(app_session)[source]

Return a DataSets widget Can be overridden to return your own custom data sets widget


AppSession

class tropofy.app.meta.AppSession(webapp, request, db_session=None)[source]

Contains all information about the current users session with the app.

An instance of tropofy.app.meta.AppSession is passed to most functions within the Tropofy framework as the app_session parameter.

app

The tropofy.app.App that created this tropofy.app.meta.AppSession.

Return type:tropofy.app.App
app_module_path

The file path on disk of the app module. Use this to work with file upload/downloads to disk.

Return type:str
app_url_name

The url name of the app that created this tropofy.app.meta.AppSession.

client_addr

Address of the client accessing the app. This will usually be an IP address.

Return type:str
data_set

The open tropofy.app.data_set.AppDataSet within the app that created this tropofy.app.meta.AppSession.

Note

Will be none if app defined with tropofy.app.App and not tropofy.app.AppWithDataSets.

Return type:tropofy.app.data_set.AppDataSet
get_file_path_in_local_data_set_dir(file_name)[source]

Path of file saved into dir generated by tropofy.app.meta.AppSession.local_data_set_dir().

Return type:str
get_queue_name(default='celery')[source]

Name of the celery queue to use if specified via the config key ‘custom.celery_queue_name’. Defaults to ‘celery’

Return type:str
local_app_dir

Unique path on disk to store app files. Not specific to a data set.

Uses server_setting custom.overridden_local_app_dir if it exists. Otherwise defaults to using https://pypi.python.org/pypi/appdirs to get x-platform locations.

Use this to store files locally. For example, as an interface to external code, or to work with file upload/downloads.

Note

Usually tropofy.app.meta.AppSession.local_data_set_dir() should be used, to get data_set specific location within local_app_dir.

local_data_set_dir

Path on disk to store local data for the AppDataSet.

Creates a folder within tropofy.app.meta.AppSession.local_app_dir() of format ‘tropofy-<url-of-running-app>/data_set_data/data_set_<id>’. See tropofy.app.meta.AppSession.local_app_dir() for docs on where local_app_dir is defined.

Use this to store files locally. For example, as an interface to external code, or to work with file upload/downloads.

post_data
Returns:A dictionary of data submitted from the server in the POST of the web request.
Return type:dict
query_string_data
Returns:A dictionary of data submitted from the server in the query string parameters of the web request.
Return type:dict
serialise_for_celery_chain(*args, **kwargs)[source]

Converts app session into a JSON and engine url to be used in sequential celery chains

Return type:dict
server_settings

Settings set in the .ini file used to configure this web server.

Return type:dict
user_app_progress

Details of the users progress through the app. :rtype: tropofy.app.meta.UserAppProgress

user_email
Returns:The email of user logged into the app.
Return type:str

AppDataSet

class tropofy.app.data_set.AppDataSet(app_created_from, created_by_user_email, a_uuid, name='', db_session=None)[source]

An tropofy.app.data_set.AppDataSet represents a collection of data, created by an App and a User. A User can create many tropofy.app.data_set.AppDataSet all relating to one App.

Note

When writing app code, access the open tropofy.app.data_set.AppDataSet through tropofy.app.meta.AppSession.data_set

The AppDataSet provides an interface for interacting with the Data Set. The example below shows how a AppDataSet is used,

def load_example_data(app_session):
    stores = []
    stores.append(Store(name="CLAYFIELD", latitude=-27.417536, longitude=153.056677))
    stores.append(Store(name="SANDGATE", latitude=-27.321538, longitude=153.069267))
    app_session.data_set.add_all(stores)

    performances = []
    performances.append(Performance(store_name="CLAYFIELD", year=2011, sales=1000, expenses=400))
    performances.append(Performance(store_name="CLAYFIELD", year=2012, sales=1170, expenses=460))
    performances.append(Performance(store_name="SANDGATE", year=2011, sales=660, expenses=1120))
    performances.append(Performance(store_name="SANDGATE", year=2012, sales=1030, expenses=540))
    app_session.data_set.add_all(performances)

In addition, tropofy.app.data_set.AppDataSet exposes the SQLAlchemy Query class. This provides a mechanism for easily searching a Data Set. The example below shows how a Data Set can be queried,

    def get_kml(self, app_session):
        kml = Kml()
        for store in app_session.data_set.query(Store).all():
            kml.newpoint(name=store.name, coords=[(store.longitude, store.latitude)])
        return kml.kml()
add(*args, **kwargs)[source]

Adds a TropofyBase object to the Data Set.

Parameters:obj (tropofy.app.TropofyBase()) – Adds obj to the Data Set.
add_all(*args, **kwargs)[source]

Adds a list of TropofyBase mixins to the Data Set.

The example below shows how add_all() is used,

def load_example_data(app_session):
    stores = []
    stores.append(Store(name="CLAYFIELD", latitude=-27.417536, longitude=153.056677))
    stores.append(Store(name="SANDGATE", latitude=-27.321538, longitude=153.069267))
    app_session.data_set.add_all(stores)

    performances = []
    performances.append(Performance(store_name="CLAYFIELD", year=2011, sales=1000, expenses=400))
    performances.append(Performance(store_name="CLAYFIELD", year=2012, sales=1170, expenses=460))
    performances.append(Performance(store_name="SANDGATE", year=2011, sales=660, expenses=1120))
    performances.append(Performance(store_name="SANDGATE", year=2012, sales=1030, expenses=540))
    app_session.data_set.add_all(performances)
Parameters:objects (list) – Adds obj to the Data Set.
alternate_session(*args, **kwds)[source]

Alternate session context. Usage:

with data_set.alternate_session():
    ... do selects/inserts to database with data_set.query and data_set.db_session.bulk_insert_mappings etc

Note that following the tasks executed within the context, the session will commit to the db. After this, it may be unsafe to use the old data_set session (it may not have knowledge of the inserts)

delete(*args, **kwargs)[source]

Remove the provided object from the data set and its attached db_session.

The database delete operation occurs upon flush().

Parameters:obj – Thye object instance to be deleted
Returns:
get_param(name, default=None)[source]

Return the value of a tropofy.app.Parameter

Parameters:
  • name (str) – Name of parameter. Must match a parameter name defined in tropofy.app.AppWithDataSets.get_parameters()
  • default – default value to return if value has not been set elsewhere.
Returns:

Parameter value

get_var(name, default=None)[source]

Get a variable that was set with tropofy.app.AppDataSet.set_var()

Parameters:default – default value to return if value has not been set elsewhere.
static qry_and(*boolean_clauses)[source]

Wraps up sqlalchemy and_() to add data_set_id to boolean clauses.

Assumes that the first boolean clause passed in has a DataSetMixin class on both sides of the clause. e.g. (FirstClass.column_name == SecondClass.column_name)

Parameters:boolean_clauses
Returns:
query(*args, **kwargs)[source]

Returns an SQLAlchemy Query object for the Data Set. The example below shows how query() is used,

    def get_kml(self, app_session):
        kml = Kml()
        for store in app_session.data_set.query(Store).all():
            kml.newpoint(name=store.name, coords=[(store.longitude, store.latitude)])
        return kml.kml()
Parameters:args (Variable number of arguments. Each should be of type tropofy.app.TropofyBase() or a Column on such a class. See the SQLA query docs for help.) – Classes to query, replicates SQLA functionality.
Returns:Returns a Query object populated by with all mixins of type source_class
set_param(name, value, app)[source]

Set the value of a tropofy.app.Parameter

Parameters:
  • name (str) – Name of parameter. Must match a parameter name defined in tropofy.app.AppWithDataSets.get_parameters()
  • value – Value of parameter. Must satisfy any value restrictions specified on the parameter.
set_var(name, value)[source]

Set a variable that can be accessed with tropofy.app.AppDataSet.get_var()

upsert(*args, **kwargs)[source]
Parameters:obj – sqlalchemy mapping object
upsert_all(*args, **kwargs)[source]
Parameters:objects – sqlalchemy orm objects

Step

class tropofy.app.Step(name='Step', widgets=None, help_text=None, hide_navigation=False, key=None)[source]

A list of Steps forms the basis of a Step Group.

A Step consists of a list of Widgets, where a Widget is represented by a tropofy.app.Widget object. Adding a Widget to a Step will append the Widget to the end of the Step. The example below shows how a Step is created,

    def get_gui(self):
        step_group_1 = StepGroup(name='Input')
        step_group_1.add_step(Step(name='Stores', widgets=[SimpleGrid(Store)]))
        step_group_1.add_step(Step(name='Performances', widgets=[SimpleGrid(Performance)]))

        step_group_2 = StepGroup(name='Output')
        step_group_2.add_step(Step(name='Map', widgets=[MyKMLMap()]))
        step_group_2.add_step(Step(name='Chart', widgets=[PerformanceBarChart()]))

        return [step_group_1, step_group_2]

Using this technique, Widgets in the same Step will appear on different rows of the Step. For a more fluid approach, i.e. where Widgets appear next to each other, a column span can be specified for each Widget. The example below shows how this alternative approach can be used when a Step is created,

    def get_gui(self):
        step_group_1 = StepGroup(name='Input')
        step_group_1.add_step(Step(name='Stores', widgets=[SimpleGrid(Store)]))
        step_group_1.add_step(Step(name='Performances', widgets=[SimpleGrid(Performance)]))

        step_group_2 = StepGroup(name='Output')
        step_group_2.add_step(Step(
            name='Visualisations',
            widgets=[
                {"widget": PerformanceBarChart(), "cols": 6},
                {"widget": StoreExpensesPieChart(), "cols": 6},
                {"widget": MyKMLMap(), "cols": 12},
            ],
        ))

        return [step_group_1, step_group_2]

Note

The total number of columns for each Step is fixed at 12. When a row reaches capacity, additional Widgets will be forced onto a new row.

Using this technique, Widgets can appear next to each other. This is useful when creating dashboard like Apps.

Parameters:
  • name (str) – Name of the step
  • widgets – list of widgets, with possible layout dict as explained above.
  • help_text (str) – (Optional) Text that will be displayed at the top of the step.
  • hide_navigation (bool) – (Optional) Hide the navigation accordion, next button, and back button when this step is visible. Default is False. Warning - you must implement another method of changing step if you set this to True, as otherwise users will become stuck.

StepGroup

class tropofy.app.StepGroup(name='Step Group', steps=None, key=None)[source]

A list of Step Groups forms the basis of an App.

A Step Group consists of a list of Steps, where a Step is represented by a tropofy.app.Step object. Adding a Step to a Step Group will append the Step to the end of the Step Group. The example below shows how a StepGroup is created,

    def get_gui(self):
        step_group_1 = StepGroup(name='Input')
        step_group_1.add_step(Step(name='Stores', widgets=[SimpleGrid(Store)]))
        step_group_1.add_step(Step(name='Performances', widgets=[SimpleGrid(Performance)]))

        step_group_2 = StepGroup(name='Output')
        step_group_2.add_step(Step(name='Map', widgets=[MyKMLMap()]))
        step_group_2.add_step(Step(name='Chart', widgets=[PerformanceBarChart()]))

        return [step_group_1, step_group_2]

Parameter

class tropofy.app.Parameter(name, default=None, options=None, allowed_type=None, validator=None, label=None, option_getter=None)[source]

A wrapper for a data_set_var that adds constraints, default values, validation, etc).

  • Expose simply in a tropofy app with tropofy.widgets.ParameterForm.
  • Get and set programatically with tropofy.app.AppDataSet.get_param() and tropofy.app.AppDataSet.set_param() respectively.
Parameters:
  • name (str) – Name of the parameter. Must be unique across all parameters and variables set with tropofy.app.AppDataSet.set_var().
  • default (Must comply with any restrictions imposed by the options, validator, and type parameters.) – (optional) The default parameter value.
  • options (list) – (optional value restriction) An explicit list of values this parameter may take.
  • allowed_type (A Python Type. eg int, str, bool, dict, list) – (optional value restriction) Force the value to be this type. Otherwise raise an exception.
  • validator (function) – (optional value restriction) A function that provides custom validation of this parameter. Accepts a single param value and returns True for successful validation and a string explaining the error if not.
  • label (str) – (optional) Label to use on the parameter input form. name will be used if this is not supplied.
  • option_getter (function) – (optional function) a function which takes in one parameter, data_set, and returns a list of options
get_default(data_set)[source]

Gets the default for this parameter Overload this to provide a dynamic default based on the current data set

Returns:a valid parameter value.

UserAppProgress

class tropofy.app.meta.UserAppProgress(data_set_id, user_email, app)[source]

Track metadata about interaction of a user with a data set through a particular app.


TaskManager

class tropofy.app.task.TaskManager(db_session)[source]

Utility methods for managing interaction with tasks.

Access through app_session.task_manager to manage an active task in the app_session.

communicate_with_subprocess(subprocess, fail_task_if_piped_error_message=True, subprocess_error_msg=None, send_progress_messages_from_subprocess=True, send_progress_messages_from_errors=True, progress_messages_batch_size=50)[source]

Sends progress messages from subprocess. Also terminates the task and subprocess if user has terminated through GUI (Celery only).

To communicate with the subprocess, subprocess must have been initialised with param stdout=subprocess.PIPE.

Furthermore, to report errors in the subprocess, pass the additional parameter to subprocess initialiser stderr=subprocess.PIPE.

By default, it is assumed that if a subprocess pipes any text to stderr, that the task has failed. Set parameter fail_task_if_piped_error_message to False to change this.

Note some sub-processes use stderr for additional logging. In this circumstance, it may be useful to redirect stderr output to stdout. To do this, use stderr=subprocess.STDOUT when initialising subprocess. This will treat output to stderr as if it were stdout (i.e. cannot stop the app even if param fail_task_if_piped_error_message is True).

Example: Calling a subprocess and communicating with it. It is assumed that subprocess has been imported and that this code is within tropofy.widgets.ExecuteFunctionWidget.execute_function(), which defines data_set as an instance of tropofy.app.data_set.AppDataSet.

p = subprocess.Popen(["process_details"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
data_set.communicate_with_subprocess(p)
Parameters:
  • fail_task_if_piped_error_message (bool) – (Default True) Determines if task should be marked as failed (won’t commit db changes) if there are piped error messages with stderr.
  • subprocess_error_msg (str) – (Default “Error during subprocess execution:”) Message to display before writing error messages.
  • send_progress_messages_from_subprocess (bool) – (Default True) Determine if task should send progress messages to the DB
  • send_progress_messages_from_errors (bool) – (Default True) Determine if task should send progress messages from std error to the DB
  • progress_messages_batch_size (int) – (Default 50) Number of progress messages to be read from the stdout queue at once
non_blocking_communicate_with_subprocess(subprocess, fail_task_if_piped_error_message=True, subprocess_error_msg=None)[source]

Sends progress messages from subprocess on a non blocking fashion. Also terminates the task and subprocess if user has terminated through GUI (Celery only).

Warning

To communicate with the subprocess, subprocess must have been initialised with param stdout=subprocess.PIPE. Furthermore, to report errors in the subprocess, pass the additional parameter to subprocess initialiser stderr=subprocess.PIPE. By default, it is assumed that if a subprocess pipes any text to stderr, that the task has failed. Set parameter fail_task_if_piped_error_message to False to change this.

Note

Some subprocesses use stderr for additional logging. In this circumstance, it may be useful to redirect stderr output to stdout. To do this, use stderr=subprocess.STDOUT when initialising subprocess. This will treat output to stderr as if it were stdout (i.e. cannot stop the app even if param fail_task_if_piped_error_message is True).

Example: Calling a subprocess and communicating with it. It is assumed that subprocess has been imported and that this code is within tropofy.widgets.ExecuteFunctionWidget.execute_function(), which defines data_set as an instance of tropofy.app.data_set.AppDataSet.

p = subprocess.Popen(["process_details"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
data_set.non_blocking_communicate_with_subprocess(p)
Parameters:
  • fail_task_if_piped_error_message (bool) – (Default True) Determines if task should be marked as failed (won’t commit db changes) if there are piped error messages with stderr.
  • subprocess_error_msg (str) – (Default “Error during subprocess execution:”) Message to display before writing error messages.
send_progress_message(message, status=None, logger=<celery.utils.log.ProcessAwareLogger object>)[source]

Sends message(s) to the user about the progress of some operation.

Parameters:
  • status (str) – Status of message(s) - use available statuses in tropofy.app.task.TaskManager.message_status(). Colours the message.
  • message (string, or list of strings. If list, each element is a separate message written on a new line.) – Adds message to the current progress message for the data set.

Widgets

Widget

class tropofy.widgets.Widget(widget_subscriptions=None, cols=12, key=None)[source]

A widget is a HTML interface to the database via a developer defined query or framework specified query

Parameters:
  • widget_subscriptions (list of tuples of (tropofy.widget, str of trigger_event_name, str of subscribed_action)) – (Deprecated) Use add_subscription() instead. (Optional) Widget to subscribe to a triggered event of.
  • cols (int or tropofy.widgets.ColMeta) – (Optional) Define width of widget on screen. Pass either int <= 12 (where 12 is 100% width, 6 is 50% width, etc), or tropofy.widgets.ColMeta.
class Action(widget)[source]

An action is a client-side action this widget can take after being triggered by a tropofy.widgets.Widget.Subscription Widgets can extend on this class and add triggers as constants

HIDE = 'hide'

Hide the widget on the page

REFRESH = 'refresh'

Refresh the widget’s data from the server

SHOW = 'show'

Show the widget on the page if it’s hidden

UPDATE = 'update'

Redraw the widget from spec

class Subscription(trigger=None, action=None, mappings=None)[source]

A link between a tropofy.widgets.Widget.Trigger and a tropofy.widgets.Widget.Action which causes triggers to call events on the clientside

Parameters:
  • trigger (str) – The client-side trigger on the current widget
  • action (str) – The action to occur on the client
  • mappings (dict) – The mappings the data should be processed with before going from the Trigger to the Action. Dictionary of {TriggerKey: ActionKey} (Optional)

Below is an example of a subscription between a filter and a grid, using a mapping. If the filter’s Element names are the same as the Grid’s column names, the mapping is unnecessary.

def add_my_subscription(self, my_filter, my_simple_grid):
    """ my_filter is a Filter containing an element named 'textFilterEmployeeName'
        my_simple_grid is a SimpleGrid with a column named 'employee_name'
        This Subscription will cause typing in the Filter Element 'textFilterEmployeeName' to
            filter my_simple_grid's 'employee_name' column on the clientside
    """
    my_filter.add_subscription(
        my_filter.Subscription(
            trigger=my_filter.Trigger.UPDATED,
            action=my_simple_grid.Action.FILTER,
            mapping={
                'textFilterEmployeeName': 'employee_name'
            }
        )
    )
class Trigger[source]

A trigger is a representation of a client-side event which can be fired and used in a tropofy.widgets.Widget.Subscription Widgets can extend on this class and add triggers as constants

HIDDEN = 'hidden'

Triggered when the widget goes from shown to hidden. Not triggered if the widget is created hidden

LOADED = 'loaded'

Triggered after the widget is loaded

SHOWN = 'shown'

Triggered when the widget goes from hidden to shown. Not triggered if the widget is created shown

actions(name)[source]

Return an action object to pass to add_event_subscription .. deprecated:: Use add_subscription() instead

add_event_subscription(trigger_event_name, subscribed_actions)[source]

Add subscription(s) to a trigger event on this widget.

Deprecated since version Use: add_subscription() instead

Parameters:
  • trigger_event_name
  • subscribed_actions (Widget.Action or list of Widget.Action's.) –
add_subscription(subscriptions)[source]

Add client-side subscription(s) to a trigger event on this widget

Parameters:subscription (Widget.Subscription or a list of Widget.Subscription) –
enable_print(app_session)[source]

Shows a button on the widget to print it.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
get_unique_name(app_session)[source]

Return a name for the widget that is unique in this app.

This name can be used to uniquely reference the widget in database tables. This is used by tropofy.widgets.ExecuteFunction to store task history relative to a widget.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
is_hidden(app_session)[source]

Hides a widget. Can be shown through events. Default: False.

Warning: this is evaluated once on step load. After this, visibility must be managed by events. :returns: bool

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.

Layout

class tropofy.widgets.BlockLayoutWidget(widgets=None, *args, **kwargs)[source]

A widget to assist with layouts on complex steps by wrapping widgets inside a Bootstrap row where they can collapse and stack as a group

Parameters:
  • widgets – A list of widgets to go within the row
  • cols (tropofy.widget.ColMeta or int) – The ColMeta to describe this Row object or a number of columns <= 12 where 12 = 100% of parent
class tropofy.widgets.ColMeta(xs=None, sm=None, md=None, lg=None, offset_xs=None, offset_sm=None, offset_md=None, offset_lg=None, push_xs=None, push_sm=None, push_md=None, push_lg=None, pull_xs=None, pull_sm=None, pull_md=None, pull_lg=None)[source]
ColMeta defines metadata about widgets’ layout.
xs, sm, md, lg define the number of columns to take up on their respective device sizes.
offset_xs, offset_sm, offset_md, offset_lg defines the number of columns to leave blank to the left of the object.
push_xs, push_sm, push_md, push_lg and pull_xs, pull_sm, pull_md, pull_lg can be used to push and pull at different sizes.
See http://getbootstrap.com/css/#grid for info about the grid system and how to use it to build layouts.

Chart

class tropofy.widgets.Chart(widget_subscriptions=None, cols=12, key=None)[source]

Displays a chart on the GUI. This widget is an interface to Google Charts. All Google Charts are supported.

To create a chart, you must define the chart type, source data, and optionally provide additional formatting options for the chart. A charts source data is specified in table format. For each Chart, this table must take a specific format. For example, a pie chart expects a two-column table with a string column and a number column, where each row describes a slice, and the first column is the slice label and the second column is the slice value. A scatter chart, however, expects a table consisting of two numeric columns, where each row is a point, and the two columns are the X and Y values of the point.

These formats are specified on the Google Charts documentation for each chart under Data Format (Pie Chart example).

Below is an example of configuring a Bar Chart:

class ExampleBarChart(Chart):
    def get_chart_type(self, app_session):
        return Chart.BARCHART

    def get_table_schema(self, app_session):
        return {
            "year": ("string", "Year"),
            "sales": ("number", "Sales"),
            "expenses": ("number", "Expenses")
        }

    def get_table_data(self, app_session):
        return [
            {"year": 2004, "sales": 1000, "expenses": 400},
            {"year": 2005, "sales": 1170, "expenses": 460},
            {"year": 2006, "sales": 660, "expenses": 1120},
            {"year": 2007, "sales": 1030, "expenses": 540}
        ]

    def get_column_ordering(self, app_session):
        return ["year", "sales", "expenses"]

    def get_order_by_column(self, app_session):
        return "year"

    def get_chart_options(self, app_session):
        return {
            'title': 'Company Performance',
            'vAxis': {
                'title': 'Year',
                'titleTextStyle': {'color': 'red'}
            }
        }

The following is a reference of the functions required to define a chart.

get_chart_colours(app_session, attribute_colour_dict, attribute_name, default_colour='#808080')[source]

uses chart get_table_data and dict of colours and returns ordered list of colours for Google Charts

Pass in a dictionary of attribute_value: colour and this will go through the entire data list in order looking for that attribute value on the appropriate attribute and build the ordered list of colours

Parameters:
  • app_session – app_session
  • attribute_colour_dict – dict of attribute_value: colour.
  • attribute_name – attribute name in data that we are colouring on
  • default_colour – default colour to use - defaults to grey
Returns:

ordered list of colours for Google Charts

get_chart_height(app_session)[source]

Specify the height in px of the charts.

Defaults to 600.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:Height of the chart in px
Return type:int
get_chart_options(app_session)[source]

(Optional) Each Chart has a range of configuration options. These are specified in the documentation for each chart under Configuration Options.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:dictionary of options

For example, a possible set of options for a BarChart:

    def get_chart_options(self, app_session):
        return {
            'title': 'Company Performance',
            'vAxis': {
                'title': 'Year',
                'titleTextStyle': {'color': 'red'}
            }
        }

This will set the charts title to ‘Company Performance’, and draw a red title on the vertical axis labelled ‘Year’.

get_chart_title(app_session)[source]

Specify a title for the chart.

Note

This title is independent of any title set in tropofy.widgets.Chart.get_chart_options(). It is recommended that this method only be used for charts where no title can be set through tropofy.widgets.Chart.get_chart_options(). For example, a TIMELINE chart. Furthermore, the height of this title is not included in the chart height specified in tropofy.widgets.Chart.get_chart_height().

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:Title for a chart
Return type:str
get_chart_type(app_session)[source]

Specifies the type of chart to draw. All Google Charts are possible:

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:Chart.CHARTTYPE

For example, for a bar chart:

    def get_chart_type(self, app_session):
        return Chart.BARCHART
get_column_ordering(app_session)[source]

(Optional - though strongly recommended, see note below) The order of the columns in the table used as a data source for the chart.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:list of strings, where the strings are all column IDs in the order in which you want the table created.

For example, to define the order of columns for some table with columns IDs ‘year’, ‘sales’ and ‘expenses’:

    def get_column_ordering(self, app_session):
        return ["year", "sales", "expenses"]

Note

You must list all column IDs in this parameter, if you use it. Furthermore, although optional, it is strongly recommended that you implement this function. Column order is very important for many charts, and there is no default order. The order in which you define the columns in tropofy.widgets.Chart.get_table_schema() is not a default ordering.

get_order_by_column(app_session)[source]

(Optional) The column to order the source table by. This ordering will often affect the way data is displayed on a chart.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:str of column ID

For example, to order a table by one of its columns ‘year’:

    def get_order_by_column(self, app_session):
        return "year"
get_sankey_colours(app_session, node_colour_dict, from_node_name, to_node_name, default_colour='#808080')[source]

uses chart get_table_data and dict of colours and returns ordered list of colours for Google Charts

Parameters:
  • app_session – app_session
  • node_colour_dict – dict of node_name: colour
  • from_node_name – from node name to look up in both data and node_colour_dict
  • to_node_name – to node name to look up in both data and node_colour dict
  • default_colour – default colour to use - defaults to grey
Returns:

ordered list of colours for Google Charts

get_table_data(app_session)[source]

The rows of data of the charts data source table.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:List of dictionaries, where each dictionary represents a row of data. Each key must match a column ID specified in tropofy.widgets.Chart.get_table_schema().

The simplest (though least useful) way to use this function is to return static data. The following is an example of returning static data. Each dictionary corresponds to a row in the table, with key value pairs where the keys correspond to the columns IDs (this table has the columns ‘year’, ‘sales’, and ‘expenses’):

    def get_table_data(self, app_session):
        return [
            {"year": 2004, "sales": 1000, "expenses": 400},
            {"year": 2005, "sales": 1170, "expenses": 460},
            {"year": 2006, "sales": 660, "expenses": 1120},
            {"year": 2007, "sales": 1030, "expenses": 540}
        ]

The following example shows the data_set being queried to return a list of dictionaries of data. A user defined python class representing a store’s financial ‘Performance’ is being queried, with data being summaried over each year for sales and expenses.

    def get_table_data(self, app_session):
        results = []
        years = [y for r in app_session.data_set.query(Performance.year).distinct() for y in r]
        for year in years:
            performances = app_session.data_set.query(Performance).filter_by(year=year).all()
            results.append({
                "year": year,
                "sales": sum(p.sales for p in performances),
                "expenses": sum(p.expenses for p in performances),
            })
        return results
get_table_schema(app_session)[source]

The table schema describes all the columns in the table.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:dict. Key represents a column ID, and value a tuple describing the column. The tuple has the form (data_type [,label [,custom_properties]]]).

The following example uses a dictionary to define a static table schema of three columns with IDs: ‘year’, ‘sales’, and ‘expenses’. The key: value pairs are in the format ID: (data_type, label).

    def get_table_schema(self, app_session):
        return {
            "year": ("string", "Year"),
            "sales": ("number", "Sales"),
            "expenses": ("number", "Expenses")
        }

Extensions to GoogleCharts:

  • Custom tooltips for Timeline charts. Add a column with role ‘tooltip’. eg: “tooltip”: (“string”, “HoverOver”, {‘role’: ‘tooltip’})
refresh(app_session)[source]

Return dict of chart args.

Override if any of the other standard functions are dependent on each other.

Dict keys:
table_data table_schema chart_options chart_type chart_title chart_height_px column_ordering order_by_column
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:dict of chart args

FilteredChart

class tropofy.widgets.FilteredChart(data_filter, *args, **kwargs)[source]

A FilteredChart is a tropofy.widgets.Chart, linked to a tropofy.widgets.Filter.

FilteredChart inherits from tropofy.widgets.Chart, and is implemented identically except for the addition of a data_filter parameter and the helper function tropofy.widgets.FilteredChart.get_filter_values().

Parameters:data_filter (tropofy.widgets.Filter) – A filter widget that filters this chart.

PlotlyWidget

class tropofy.widgets.PlotlyWidget(widget_subscriptions=None, cols=12, key=None)[source]

A Plot.ly chart. Minimal complete definition is: get_figure || (get_layout && get_data)

Below is an example implementation:

class ExamplePlotlyChart(PlotlyWidget):
    def get_data(self, app_session):
        return [
            go.Scatter(
                x=[2001, 2002, 2003, 2004],
                y=[11.2, 11.3, 11.5, 12],
                name='Revenue'
            )
        ]

    def get_layout(self, app_session):
        return go.Layout(
            title='Example Chart',
            xaxis=dict(
                title='Year'
            ),
            yaxis=dict(
                title='Revenue ($ millions)'
            )
        )
get_chart_static(app_session)[source]

Get if the chart should be static (no interactivity)

Example: https://plot.ly/javascript/configuration-options/#making-a-static-chart-with-plotlyjs

get_colour_palette(app_session)[source]

Return a list of colours that you want to use instead of Plot.ly’s. If it needs more colours, it will just repeat from the start again.

get_configuration_options(app_session)[source]

Get the plotly options for your chart.

Docs: https://plot.ly/javascript/configuration-options

WARNING: “modeBarButtonsToRemove” is overriden for privacy reasons

get_data(app_session)[source]

Get the plotly data object for your chart

get_display_modebar(app_session)[source]

None means display on hover, True is always show, False is always hide.

get_double_click_mode(app_session)[source]

Get double click mode.

Get the bottom right link text

Example: https://plot.ly/javascript/configuration-options/#edit-the-link-text-of-your-chart-with-plotlyjs

get_enable_scroll_to_zoom(app_session)[source]

Get if scroll should zoom the chart in/out.

get_figure(app_session)[source]

Get a plotly figure object for your chart

get_layout(app_session)[source]

Get the plotly layout object for your chart

Get if the logo should be visible

Example: https://plot.ly/javascript/configuration-options/#hide-the-plotly-logo-on-the-modebar-with-plotlyjs

get_warning(app_session, figure)[source]

If this returns a string, it will be displayed above the chart in a red box.


TimelineWidget

class tropofy.widgets.TimelineWidget(widget_subscriptions=None, cols=12, key=None)[source]

Displays a timeline on the GUI. This widget is an interface to VisJS.

To create a timeline, you only need to provide the data, but there are a range of options that can be set aswell.

Below is an example of creating a Timeline Widget:

class ExampleTimelineWidget(wg.TimelineWidget):
    def get_title(self, app_session):
        return 'Work shifts'

    def get_options(self, app_session):
        return {
            'hiddenDates': [
                {
                    'start': datetime.datetime(2017, 1, 2, 18),
                    'end': datetime.datetime(2017, 1, 3, 6)
                }
            ]
        }

    def get_data(self, app_session):
        return [
            {'id': 1, 'group': 'John', 'content': 'Monday Shift 1', 'start': datetime.datetime(2017, 1, 2, 7),
             'end': datetime.datetime(2017, 1, 2, 12)},
            {'id': 2, 'group': 'John', 'content': 'Tuesday Shift 2', 'start': datetime.datetime(2017, 1, 3, 12),
             'end': datetime.datetime(2017, 1, 3, 17)},
            {'id': 3, 'group': 'Sarah', 'content': 'Monday Shift 2', 'start': datetime.datetime(2017, 1, 2, 11),
             'end': datetime.datetime(2017, 1, 2, 17)},
            {'id': 4, 'group': 'Sarah', 'content': 'Tuesday Shift 1', 'start': datetime.datetime(2017, 1, 3, 7),
             'end': datetime.datetime(2017, 1, 3, 12)},
        ]

The following is a reference of the functions that can be used to define a timeline.

add_items(app_session, items)[source]

Called when an item was added and saved.

Parameters:items – List of the items (each item is in VisJS form, see get_data for information on VisJS form)
get_auto_color(app_session)[source]

Get whether TimelineWidget should automatically colour items for you.

Makes it more like Google Timelines.

To customize more, you can return a dictionary instead with the key: ‘colorByGroup’ or ‘singleColor’ (which act like their Google Timeline alternatives)

get_auto_group(app_session)[source]

Get whether TimelineWidget should automatically create the groups for you. If you want manual groups, look at TimelineWidget.get_groups.

Automatic groups will allow you to use this widget more like Google Timelines as you just put the group name as the value for the ‘group’ key in TimelineWidget.get_data. It is also nicer if your groups come from the same query that gets your data.

get_auto_id(app_session)[source]

Get whether TimelineWidget should automatically create ids for you.

This means that if you aren’t make an editable timeline you don’t need to give an id.

get_auto_tooltip(app_session)[source]

Get whether TimelineWidget should automatically create tooltips for you. If you want manual tooltips, look at TimelineWidget.get_data.

Automatic tooltips will make the Timeline feel more like Google Timelines.

Note: If a manual tooltip is set, it won’t be overridden.

get_data(app_session)[source]

Get the data for the timeline.

Format should be:

[
    {"start": datetime.datetime(..), "end": datetime.datetime(..), ...},
    ...
]

Specification: http://visjs.org/docs/timeline/#items

get_groups(app_session)[source]

Get the manual groups for the timeline. This will only be used if TimelineWidget.get_auto_group returns False.

Format should be:

[
    {id: <group_id>, content: <group_name>},
    ...
]

Where <group_id> is the value put in the TimelineWidget.get_data entries with the key ‘group’; and <group_name> is the value that will appear on the chart next to the group.

Specification: http://visjs.org/docs/timeline/#groups

get_options(app_session)[source]

Get the options for the timeline.

Format should be:

{
    "width": "100%",
    "margin": {
        "item": {
            "horizontal": -1
        }
    },
    ...
}

Specification: http://visjs.org/docs/timeline/#Configuration_Options

Note that not all of these options are available (primarily the ones where you supply a function)

There is also a custom option ‘customTimes’, this allows you to have static vertical lines in your timeline. The reason this is custom is because it is meant to be supplied by the JS function ‘addCustomTime’, (http://visjs.org/docs/timeline/#Methods). ‘customTimes’ accepts a list of objects, each with an id and a time. e.g.

'customTimes': [
    {'id': 'start', 'time': datetime(1970, 1, 1)}
]
get_refresh_time(app_session)[source]

Get the amount of time before the Timeline refreshes (repeated) in milliseconds.

Return None to never refresh.

get_title(app_session)[source]

Get the title that will appear above the timeline.

remove_items(app_session, items)[source]

Called when an item was removed and saved.

Parameters:items – List of the IDs of the removed items.
update_items(app_session, items)[source]

Called when an item was updated and saved.

Parameters:items – List of the updated items (each item is in VisJS form, see get_data for information on VisJS form)

CustomExport

class tropofy.widgets.CustomExport(filter=None, widget_subscriptions=None, button_text='Export', button_context='info', file_name=None, *args, **kwargs)[source]

Displays a download button in the GUI to download custom content.

For a simple, out of the box solution that processes a single DataSetMixin class to a downloadable file string, use tropofy.widgets.custom_export_widget.FileFrameExport which implements this class.

Parameters:
  • filter (tropofy.widgets.form_widget.Filter) – Display a filter before exporting. Use self.get_filter_values to get values in filter from methods of CustomExport.
  • button_text (str) – The text on the button in the GUI.
  • button_context (str) – button context (as seen in http://getbootstrap.com/css/#buttons-options) are default, primary, success, danger, warning, info: Defaults to success.
  • file_name (str) – the file name to export the data to, including extension
get_button_context(app_session)[source]

Set a ‘context’ for the button, defining the colour and style.

Contexts (as seen in http://getbootstrap.com/css/#buttons-options) are default, primary, success, danger, warning, info: Defaults to success.

Note: this can be set on construction of the widget by passing the text to init. No need to override this.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:str
get_custom_export_data(app_session)[source]

The data to be downloadable. It is intended that developers override get_data_frames rather than this method.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:valid data string
get_custom_export_file_name_with_extension(app_session)[source]

The name of the file to be downloaded.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:file name with extension
Return type:str
get_data_frames(app_session)[source]

Gets the data frames for processing.

Override this function to get the data frames (and a name for each) for processing. Changed to take app-session to work with filter-widgets in orb. KW 06/02/2107

Parameters:app_session (tropofy.app.meta.AppSession) – the Tropofy AppSession with the data to retrieve data frames from
Returns:dict of {name: data_frame}
Return type:dict of {str: pandas.DataFrame}
get_export_button_text(app_session)[source]

The text on the button in the GUI. Note: this can be set on construction of the widget by passing the text to init. No need to override this

Return type:str
get_filter_values(app_session)[source]

Helper method that returns the values of the filter.

Use this method within tropofy.widgets.CustomExport.get_custom_export_data() with self.get_filter_values(data_set).

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:dict representation of the filtered values

ExecuteFunction

class tropofy.widgets.ExecuteFunction(widget_subscriptions=None, cols=12, key=None)[source]

A button which executes a Python function when clicked.

If your app solves a specific problem then this is where your custom code is executed.

Below is an example of creating an ExecuteFunction widget:

class ExecuteSolverFunction(ExecuteFunction):

    def get_button_text(self, app_session):
        return "Solve Facility Location Problem"

    def execute_function(self, app_session):
        if len(app_session.data_set.query(Shop).all()) > 200:
            app_session.task_manager.send_progress_message("You can only solve problems with 200 shops of fewer using the free version of this app")
        else:
            formulate_and_solve_facility_location_problem(app_session)

The following is a reference of the functions required to define an ExecuteFunction widget.

class Action(widget)[source]

Extended Actions for execute_function_widget. Also inherits Actions from tropofy.widgets.Widget.Action

EXECUTE_FUNCTION_ON_SERVER = 'executeFunctionOnServer'

Submit a request to start executing the class’s function on the server

class Trigger[source]

Extended Triggeres for execute_function_widget. Also inherits Triggers from tropofy.widgets.Widget.Trigger

FUNCTION_EXECUTION_COMPLETE = 'functionExecutionComplete'

Triggers when the function execution has completed

execute_function(app_session)[source]

Any Python code to be executed.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:None

Use tropofy.app.AppDataSet.send_progress_message() to post messages to the GUI.

Example: The following example demonstrates implementing code to be executed. This code assumes a SQLA ORM class Location exists.

def execute_function(self, app_session):
    app_session.task_manager.send_progress_message("Deleting locations...")
    app_session.data_set.query(Location).delete()
    app_session.task_manager.send_progress_message("Locations deleted.")
execute_tasks_with_celery(app_session)[source]

Execute tasks asynchronously and receive messages during task execution. Additional configuration is required beyond returning True here - see ‘Working With Celery’ Tropofy docs.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:bool
get_button_text(app_session)[source]

The text on the button in the GUI.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:str
    def get_button_text(self, app_session):
        return "Solve Facility Location Problem"
max_poll_failures(app_session)[source]

How many successive polls before the client deems itself disconnected and fails

Default is 5

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:int
max_simultaneous_tasks_running(app_session)[source]

It is possible to run multiple tasks simultaneously. Defaults to 1.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:int
max_tasks_displayed(app_session)[source]

The n most recently started tasks will have their details displayed. Defaults to 1.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:int
play_sound_on_complete(app_session)[source]

Whether or not the client should play a little jingle on task completion

Default is False

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:bool
progress_message_console_height_px(app_session)[source]

Height in px for the task progress message console.

Default is 300. Example below sets height to 600.

def progress_message_console_height_px(self, app_session):
    return 600
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:int

FileUpload

class tropofy.widgets.FileUpload(widget_subscriptions=None, cols=12, max_file_size=10000000, button_text='Select Files...', button_context='success', popover=False, allowed_file_types=None, *args, **kwargs)[source]

A button through which files can be uploaded to an app.

A progress bar is displayed, as well as results for all files uploaded. Files are processed on a compute node with tropofy.widgets.FileUpload.process_file(). Multiple file selected is not supported by some older browsers (ie8).

class Action(widget)[source]

Extended Actions for file_upload_widget. Also inherits Actions from tropofy.widgets.Widget.Action

CLEAR_OLD_RESULTS = 'clearOldResults'

Clear old upload results from the screen and set the progress to 0

UPDATE = 'update'

Update the widget from its spec (redraw)

class Status[source]

Status levels

STATUS_ERROR = 'danger'

When the upload fails

STATUS_SUCCESS = 'success'

When the upload was successful

STATUS_WARNING = 'warning'

When the upload had a warning

class Trigger[source]

Extended Triggers for file_upload_widget. Also inherits Triggers from tropofy.widgets.Widget.Trigger

FILE_UPLOAD_FAILURE = 'fileUploadFailure'

Triggered when a file upload fails. Passes a dict of {‘fileName’: fileName}.

FILE_UPLOAD_START = 'fileUploadStart'

Triggered when the user starts uploading a file

FILE_UPLOAD_SUCCESS = 'fileUploadSuccess'

Triggered when a file upload is successful. Passes a fileResultViewModel. DO NOT APPLY MAPPINGS.

get_allowed_file_types(app_session)[source]

List of allowable file types to be uploaded.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:list of allowable file types. Each type is a MIME type.
get_button_context(app_session)[source]

Set a ‘context’ for the button, defining the colour and style.

Contexts (as seen in http://getbootstrap.com/css/#buttons-options) are default, primary, success, danger, warning, info: Defaults to success.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:str
get_max_file_size(app_session)[source]

Max uploadable file size (bytes). Default 10mb.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:int (number of bytes)
get_select_files_button_text(app_session)[source]

Text displayed on button when prompting to select files.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:str
process_file(app_session, in_memory_file, result)[source]

Processes the file Called by framework. It’s not intended that devs would override this, override process_file_stores instead

Parameters:
  • app_session (tropofy.app.meta.AppSession) – the current AppSession
  • in_memory_file (FieldStorage) – the in-memory file as sent through from the browser A dictionary to store result information. Report a message by setting result[‘message’]. A single string can be added or a list of strings giving more detailed information.
Return type:

None

process_file_stores(app_session, stores, result)[source]

Process the file stores retrieved from the in-memory file

Parameters:
  • app_session (tropofy.app.meta.AppSession) – the current AppSession
  • stores (list of tropofy.fileframe.store.FileStore) – The set of FileStore objects generated from the in-memory file
Returns:

message to respond to send back to the user through browser

Return type:

str

show_progress_and_results_as_popover(app_session)[source]

Progress and results are usually shown under the file upload button. Returning true here makes them show as a dismissable popover.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:bool (default False)

Form

class tropofy.widgets.Form(widget_subscriptions=None, cols=12, key=None)[source]

A form through which data can be added and edited.

class Element(name, input_type, default=None, label=None, hidden=False, disabled=False, options=None, compute_options_from=None, required=False, is_button_style=False, button_style_cols=None, builtin_filter=False, custom_formatting=None, cols=None)[source]

An element of a form.

Parameters:
  • name (str) – Form element name. Used to reference the value of the element on submit.
  • input_type (str) – Type of form input. (Form.Element.TEXT, Form.Element.SELECT, Form.Element.DATE, Form.Element.TIME, Form.Element.DATETIME, Form.Element.BOOL, Form.Element.TYPEAHEAD, Form.Element.TOGGLE)
  • default (Multiple possible types. Must be valid relative to options list and input_type.) – (optional) Default input value. Default defaults are: TEXT:"", SELECT: value of first option. If SELECT element, default must be an option value.
  • label (str) – (optional) Label of form element.
  • hidden (bool) – (optional) If true, form element will be hidden
  • disabled (bool) – (optional) If true, form element will be disabled
  • options (list of strings or list of tropofy.widgets.Form.Element.Option.) –

    (optional) Use for:

  • compute_options_from (str) – (optional - used if input_type==’select’ and options=None). String matching the name of a dependent_option_list of a tropofy.Form.Element.Option within a tropofy.Form.Element in this widget.
  • custom_formatting (dict) –

    dict of custom format options for the element. Accepts different keys for each form element.

    • Form.Element.TOGGLE keys: (‘width’, ‘height’, ‘onstyle’, ‘offstyle’, ‘size’, ‘style’). Details of allowable values.
    • Form.Element.DATE, Form.Element.Time, Form.Element.DATETIME keys: (‘minViewMode’, ‘viewMode’). Choose from {‘months’, ‘years’} to change the date picker depth.
class Option(value, text=None, dependent_option_lists=None)[source]

An option of a form select.

Parameters:
  • value (jsonifiable type (usually str or int)) – The value of this option submitted with the form if selected.
  • text (str) – (Optional) Option text displayed in select list. Default to value if not provided.
  • dependent_option_lists (list of dicts of form {name: <option list name> options: <list of tropofy.widgets.Form.Element.Option>) –
fullwidth_buttons(app_session)[source]

Makes the submit and clear buttons (if shown) take up the full width of the widget. If one is show, it takes up the full width, if both are shown they take up submit 8 : clear 4

Defaults to false

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:Boolean determining if the form submit and clear buttons take up the full width of the widget
Return type:bool
get_datetime_display_formats(app_session)[source]

Specify custom display formats to display datetimes, dates, and times in a form.

Use format strings specified by MomentJS. Note that these are slightly different to string-formats used in Python.

Allowable keys are: Form.Element.DATE, Form.Element.DATETIME, and Form.Element.DATE

Returns:dict
get_form_elements(app_session)[source]

Return a list of elements to use in the form.

Parameters:form_values – If provided, is a dict of form element {name: value}. Only passed if this function is being called when the form exists on the webpage, not for an initial load or refresh.
Return type:list of tropofy.widgets.Form.Element
get_title(app_session)[source]

A title for the form. If not implemented then there will be no title.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:Title for the form.
Return type:str
hide_submit_button(app_session)[source]

Hides the form submit button. Advanced use only - it is usually safe to rely on default value.

By default, submit button is hidden if tropofy.widgets.Form.is_autosubmit() returns True, and False otherwise.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:Boolean determining if the form submit button is hidden.
Return type:bool
is_autosubmit(app_session)[source]

Determines whether a form autosubmits on value change or has a submit button.

  • True (default): The entire form will autosubmit when any value is changed. No submit button will be shown.
  • False: A submit button will be shown and the form will submit only when the button is clicked.
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:Boolean determining if the form will autosubmit.
Return type:bool
is_submit_entire_form(app_session)[source]

Determines whether a form on submit submits the entire form.

Default False - means only form element that has changed is submitted.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:Boolean determining if autosubmit form with submit entire form.
Return type:bool
process_data(app_session, data)[source]

Process data from form submit.

Parameters:
  • app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
  • data (dict) – Dict of name:value pairs, submitted from the form.
Returns:

Dictionary in the following form - {‘success’: <bool>, ‘message’: <HTML string>, ‘results’: <results_list>}

  • success (optional bool): Indicates full form submit success or failure.
  • message (optional HTML string): Response message for full form submit.
  • results (optional list of dicts of the form): {‘name’: name, ‘success’: <bool>, ‘message’: <str>}.
    • name (str): Must match the name of a corresponding tropofy.widgets.Form.Element.
    • success (optional bool): defaults to true. Indicates single form element submit success or failure.
    • message (optional str): default to null. Response message for single form element submit.

‘name’, ‘success’, ‘message’, ‘value’ :rtype: dict

show_clear_button(app_session)[source]

Shows the form clear button. The clear button resets the form to default values when clicked by the user.

By default the clear button is hidden, but can be shown by returning True.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:Boolean determining if the form submit clear is shown.
Return type:bool
submit_button_css_classes(app_session)[source]

Additional css classes to add to the submit button element.

Return type:list of str
submit_button_text(app_session)[source]

Text displayed on the submity button.

Defaults to ‘Save’.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:Text displayed on the submit button (default ‘Save’)
Return type:str

ParameterForm

class tropofy.widgets.ParameterForm(title='Parameters', parameter_names_filter=None, *args, **kwargs)[source]

An implementation of tropofy.widgets.Form that displays all tropofy.app.Parameter defined in tropofy.app.AppWithDataSets.get_parameters()

Parameters:parameter_names_filter (list) – (Optional) List of parameter names to display on form. If none are specified, default is to display all parameters.

Filter

class tropofy.widgets.Filter(widget_subscriptions=None, cols=12, key=None)[source]

An implementation of tropofy.widgets.Form specifically designed to act as a filter for other widgets.

Only the method tropofy.widgets.Filter.get_form_elements() needs to be implemented for this widget.

Pass as the first parameter to a tropofy.widgets.FilteredChart to link the filter.

get_form_elements(app_session)[source]

Return a list of tropofy.widgets.Form.Element

When implementing tropofy.widgets.Form.get_form_elements(), ensure the tropofy.widgets.Form.Element() default values are that which you want your filtered widget to use on first use.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:list of tropofy.widgets.Form.Element
get_values(app_session)[source]

Values of filter, indexed by form element name.

It is possible to overide this method and return custom, computed values. For example, if the form has separate input date, and time fields, these could be combined for a datetime value. If doing this, it is required that all form values be returned also, and not replaced. This is necessary to ensure the form updates on reload appropriately.

Returns:dict
remember_filter_values_on_refresh()[source]

Determine if filter values will be stored between refresh’s (eg changing step or reloading data set).

If false, filter values will be set to default on each refresh.

Rtype bool:

KMLMap

class tropofy.widgets.KMLMap(widget_subscriptions=None, cols=12, key=None)[source]

Displays a map and a download button in the GUI. The map displays the contents of a KML file and the download button enables it to be downloaded.

To create a map you simply implement a function which returns the KML you want displayed. The map will only display static KML features. You can generate the KML content however you like but we recommend using the SimpleKml package which is included with Tropofy. The SimpleKML documentation can be found here

Below is an example of creating a KMLMap:

class MyKMLMap(KMLMap):
    
    def get_kml(self, app_session):
        kml = Kml()
        for p in [kml.newpoint(name=loc.name, coords=[(loc.longitude, loc.latitude)]) for loc in app_session.data_set.query(Location).all()]:
            p.style = Style(iconstyle=IconStyle(scale=0.8, icon=Icon(href='https://maps.google.com/mapfiles/kml/paddle/blu-circle-lv.png')))
        return kml.kml()

The following is a reference of the functions required to define a KMLMap.

get_kml(app_session)[source]

The KML to be downloadable and displayed on the map

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:valid KML as a string

The following example shows the data_set being queried to return a list of Locations and Lines. Each location has a longitude and latitude member. Lines have a start and end location. KML mixins representing each Location and Line are created, added to a KML folder and given a specific style

    def get_kml(self, app_session):

        kml = Kml()

        def LongLat(l):
            return (l.longitude, l.latitude)

        mylocstyle = Style(iconstyle=IconStyle(scale=0.8, icon=Icon(href='https://maps.google.com/mapfiles/kml/paddle/blu-circle-lv.png')))
        LocsFolder = kml.newfolder(name="Locations")
        for p in [LocsFolder.newpoint(name=loc.name, coords=[LongLat(loc)]) for loc in app_session.data_set.query(Location).all()]:
            p.style = mylocstyle

        mylinestyle = Style(linestyle=LineStyle(color='FF00F5FF', width=4))
        LinesFolder = kml.newfolder(name="Lines")
        for line in [LinesFolder.newlinestring(name='line', coords=[LongLat(l.start_location), LongLat(l.end_location)]) for l in app_session.data_set.query(Line).all()]:
            line.style = mylinestyle

        return kml.kml()

GridWidget

class tropofy.widgets.GridWidget(title=None, editable=True, create_update_form=None, desc_sort_cols=None, enable_search_by_column=False, widget_subscriptions=None, default_ordered_col_name_sort_direction_tuples=None, file_upload_widgets=None, file_export_widgets=None, hidden_column_names=None, cols=12)[source]

Display data in a grid.

All parameters are optional

Note

Most implementations of GridWidget will just use tropofy.widgets.SimpleGrid which inherits from GridWidget. The parameters below are relevant to tropofy.widgets.SimpleGrid as well as to GridWidget.

Parameters:
  • title (str) – A title for the grid.
  • create_update_formtropofy.widgets.FormWidget
  • desc_sort_cols (list of col names) – (Optional) cols to sort descending
  • editable (bool) – (Optional - default True). Enables grid to be edited.
  • enable_search_by_column (bool) – (Optional - default False). Enables search by column
  • file_upload_widgets (list of tropofy.widgets.FileUpload) – (Optional) File upload widgets to be embedded in the grid. On successful upload, will automatically refresh the grid.
  • file_export_widgets (list of tropofy.widgets.CustomExport) – (Optional) File export widgets to be embedded in the grid.
  • widget_subscriptions (list of tuples of (tropofy.widget, str of trigger_event_name, str of subscribed_action)) – (Optional) Widget to subscribe to a triggered event of
  • default_ordered_col_name_sort_direction_tuples (list of tuples) – (Optional) list of columns to sort on by default. Tuples are (‘column_name’, direction) - direction is GridWidget.ASCENDING or DESCENDING
Create_update_form:
 

Form used to add new rows and edit existing rows.

class Action(widget)[source]

Extended Actions available for the grid_widget. Also inherits Actions from tropofy.widgets.Widget.Action

DELETE_SELECTED_ROWS = 'deleteSelectedRows'

Delete the currently selected rows

EDIT_SELECTED_ROW = 'editButtonClick'

Open the dialogue to edit the currently selected row. Will do nothing unless exactly one row is selected

FILTER = 'filter'

Filter the columns of the grid based on data passed to it from a trigger. The trigger data’s keys should match the columns’ names after mappings are applied

HIDE_CREATE_UPDATE_FORM = 'hideCreateUpdateForm'

Hide the ‘create update form’

NEW_ROW = 'newButtonClick'

Open the dialogue to add a new row

SELECT_FIRST_ROW = 'selectFirstRow'

Highlight the first row in the grid

STANDING_REFRESH = 'standingRefresh'

Refresh the grid and keep the current paging/sorting

class StyleMeta(classes=None, styles=None)[source]

Builds the CSS styling of a grid / column / row / cell

The styles will override eachother, in the following order from lowest priority to highest:

Parameters:
  • classes (list of str) – The CSS classes to apply to the object
  • styles (dict) – The CSS styles to apply to the object, format: { ‘css-attribute-name’: ‘value’, .. }

Below is an example of styling all aspects of a grid using initialiser arguments and functions

class ExampleStyledSimpleGrid(SimpleGrid):

    def get_grid_style_metadata(self):
        """Get the :class:`tropofy.widgets.GridWidget.StyleMeta` object for this grid to apply custom styles.
        This method should be overridden

        :returns: :class:`tropofy.widgets.GridWidget.StyleMeta` or None
        """

        # Make the whole grid a light cyan
        return self.StyleMeta(styles={ 'background-color': '#D1EEEE' })

    def get_column_style_metadata(self):
        """Get the :class:`tropofy.widgets.GridWidget.StyleMeta` for the columns on this grid.
        This method should be overridden

        :returns: Dictionary of { 'columnName'\: :class:`tropofy.widgets.GridWidget.StyleMeta`, ... } or None
        """

        # Make the whole 'equipment_name' column a light strong blue
        return {
            'equipment_name': self.StyleMeta(classes=[ self.StyleMeta.CLASS_PRIMARY ])
        }

    def get_row_style_metadata(self, obj):
        """Get the :class:`tropofy.widgets.GridWidget.StyleMeta` for an entire row.
        This method should be overridden

        :returns: :class:`tropofy.widgets.GridWidget.StyleMeta` or None
        """

        # If the 'needs_maintenance' column is 'True', make the whole row italics and a light blue
        rowStyle = self.StyleMeta()

        if obj.needs_maintenance:
            rowStyle.add_class(self.StyleMeta.CLASS_INFO)
            rowStyle.add_style('font-style', 'italic')

        return rowStyle

    def get_cell_style_metadata(self, obj):
        """Get the :class:`tropofy.widgets.GridWidget.StyleMeta` for the cells in a row.
        This method should be overridden

        :returns: dict of { 'columnName'\: :class:`tropofy.widgets.GridWidget.StyleMeta`, ... } or None
        :rtype: dict or None
        """

        # If 'equipment_temperature' is over 100, turn the cell yellow and bold the text
        # If 'equipment_temperature' is over 200, turn the cell red, bold the text and make the cell flash
        equipment_tepmerature_style = self.StyleMeta()

        if obj.equipment_temperature > 200:
            equipment_tepmerature_style.add_class(self.StyleMeta.CLASS_DANGER)
            equipment_tepmerature_style.add_style('font-weight', 'bold')
            equipment_tepmerature_style.add_class(self.StyleMeta.CLASS_BACKGROUND_FLASHING)
        elif obj.equipment_temperature > 100:
            equipment_tepmerature_style.add_class(self.StyleMeta.CLASS_WARNING)
            equipment_tepmerature_style.add_style('font-weight', 'bold')

        # If 'equipment_output' is over 1000, make the output cell green
        equipment_output_style = self.StyleMeta()

        if obj.equipment_output > 1000:
            equipment_output_style.add_class(self.StyleMeta.CLASS_SUCCESS)

        return {
            'equipment_temperature': equipment_tepmerature_style,
            'equipment_output': equipment_output_style
        }
CLASS_ACTIVE = 'active'

Bootstrap strong blue

CLASS_BACKGROUND_FLASHING = 'background-flashing'

Animation - Flash the object’s background colour back and forward to white

CLASS_DANGER = 'danger'

Bootstrap red

CLASS_INFO = 'info'

Bootstrap light blue

CLASS_SUCCESS = 'success'

Bootstrap green

CLASS_WARNING = 'warning'

Bootstrap yellow

STYLE_BACKGROUND_COLOUR = 'background-color'

The background colour of the container

STYLE_TEXT_COLOUR = 'text-color'

The text colour

add_class(css_class)[source]

Add a CSS class to the StyleMeta

Parameters:css_class (str) – The CSS class to apply to the row
add_classes(css_classes)[source]

Add CSS classes to the StyleMeta

Parameters:css_classes (list of str) – The CSS classes to apply to the row
add_style(css_attribute, value)[source]

Add a CSS inline style to the StyleMeta

Parameters:
  • css_attribute (str) – The CSS attribute to set the value for
  • value (str) – The CSS value for the attribute
add_styles(css_styles)[source]

Add CSS inline styles to the StyleMeta

Parameters:css_styles (dict) – The CSS Styles to apply, format: { ‘css-property’: ‘value’, … }
static merge(*args)[source]

Merge StyleMetas in the order they are provided from lowest to highest priority

serialise()[source]

Turn the style into a JSON serialisable object

class Trigger[source]

Extended Triggers for grid_widget. Also inherits Triggers from tropofy.widgets.Widget.Trigger

REFRESHED = 'refreshed'

Triggered when the grid’s data is refreshed

delete_all(app_session)[source]

Delete all in grid

Returns:Num rows deleted.
delete_filtered(app_session)[source]

Delete all rows displayed with the current filters

Returns:Num rows deleted.
delete_others(app_session)[source]

Delete all rows not displayed with the current filters

Returns:Num rows deleted.
delete_row(app_session, obj_id)[source]

Delete selected row with obj_id in grid

Returns:Num rows deleted.
delete_rows(app_session, obj_ids)[source]

Delete multiple rows with obj_ids in grid

Returns:Num rows deleted.

Show text box for searching the while table.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Rtype bool:
enable_search_by_column(app_session)[source]

Show text box for each column for custom search.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Rtype bool:
get_cell_style_metadata(row)[source]

Get the tropofy.widgets.GridWidget.StyleMeta for the cells in a row. This method should be overridden

Returns:dict of { ‘columnName’: tropofy.widgets.GridWidget.StyleMeta, … } or None
Return type:dict or None
get_cols_to_be_excluded_from_updating_with_form_element_value(app_session)[source]

Writing a value (including None) to a DataSetMixin column will prevent its onupdate value from being written to the database. This is particularly problematic for columns such as data timestamp columns which are supposed to update with the current time when a model is modified.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:a list of column names that will be excluded from being written to when edit_row is called
get_column_name_to_form_default(app_session)[source]

Default values to use in the form corresponding to each column. Keys must correspond to column names.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:dict of {column_name: default_value}
get_column_name_to_form_input_types(app_session)[source]

Input types to use in the form for cols. Values must be in Form.Element.VALID_INPUT_TYPES.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.

If not specified for column, will default to Form.Element.TEXT

get_column_style_metadata()[source]

Get the tropofy.widgets.GridWidget.StyleMeta for the columns on this grid. This method should be overridden

Returns:Dictionary of { ‘columnName’: tropofy.widgets.GridWidget.StyleMeta, … } or None
get_custom_formatting_mappers(app_session)[source]

Customise the format of a particular column in the grid and edit form.

Access mappers with tropofy.widgets.GridWidget.CUSTOM_MAPPERS['mapper_name']

Available Mappers:
Returns:dict of {col_name: mapper}
get_datetime_display_formats(app_session)[source]

Specify custom display formats to display datetimes, dates, and times in a grid and its edit form.

Use format strings specified by MomentJS. Note that these are slightly different to string-formats used in Python.

Allowable keys are: ‘date’, ‘datetime’, and ‘time’

Returns:dict
get_filtered_rows(app_session, display_start, display_length, global_search_field, ordered_col_name_sort_direction_tuples, col_name_to_options)[source]

Rows returned is a list of lists. Each list represents a row of data in the grid. The elements of the row must be in the same order as the column names. ordered_col_name_sort_direction_tuples will be None if user has not done a sort. Set to self.default_ordered_col_name_sort_direction_tuples to use a default here

Returns:(filtered list of lists of row data to display in grid for this page/search, total records in data set before filter, total records in data set after filter)
Return type:tuple - (<list of lists of data>, <int>, <int>)
get_grid_style_metadata()[source]

Get the tropofy.widgets.GridWidget.StyleMeta object for this grid to apply custom styles. This method should be overridden

Returns:tropofy.widgets.GridWidget.StyleMeta or None
get_non_editable_cols(app_session)[source]

Will disable input boxes for these cols on edit in the GUI.

get_row_style_metadata(row)[source]

Get the tropofy.widgets.GridWidget.StyleMeta for an entire row. This method should be overridden

Returns:tropofy.widgets.GridWidget.StyleMeta or None
get_title(app_session)[source]

Display a title for the grid. Set once for the grid - can not be dynamically changed.

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Return type:str
show_delete_button(app_session)[source]
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Rtype bool:
show_edit_button(app_session)[source]
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Rtype bool:
show_export_buttons(app_session)[source]
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Rtype bool:
show_import_buttons(app_session)[source]
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Rtype bool:
show_new_button(app_session)[source]
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Rtype bool:
show_refresh_button(app_session)[source]
Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Rtype bool:

SimpleGrid

class tropofy.widgets.SimpleGrid(source_class, editable=True, title=None, create_update_form=None, desc_sort_cols=None, enable_search_by_column=True, widget_subscriptions=None, default_ordered_col_name_sort_direction_tuples=None, file_upload_widgets=None, file_export_widgets=None, hidden_column_names=None, cols=12, use_postgres_export=False)[source]

Basic Grid. This widget is special. It is not used like the other widgets. You do not need to create a class which implements function to use an instance of this widget.

Parameters:
  • source_class – A user defined SQLAlchemy Python class
  • title (str) – A title for the grid. Defaults to class name (removed camel case). Pass empty string to make blank.
  • enable_default_excel_file_upload (bool (default False)) – (Optional) Show an option to upload data from Excel into the table. Is equivelent to setting param file_upload_widget=SimpleGridFileUpload. If file_upload_widget is set, will be ignored. Excel workbook uploaded requires a worksheet with name as lowercase source_class name, and column names equal to the parameters of source_class.

Note

The source_class provided to a SimpleGrid must have the following properties:
  • The database column names must be the same as the member variable names, i.e. you cannot use code like some_name = Column('some_other_name', String(50))),
  • The initialisers parameter names must be the same as the member variable names. Note that SQLAlchemy provides a default initialiser with keyword arguments equal to the names of the column members defined for your class.

The following class satisfies the above requirements

class ConformingClass(TropofyBase()):
    name = Column(Text, nullable=False)
    latitude = Column(Float, nullable=False)
    longitude = Column(Float, nullable=False)
    demand = Column(Integer, nullable=False)

    def __init__(self, name, latitude, longitude, demand):
        self.name = name
        self.latitude = latitude
        self.longitude = longitude
        self.demand = demand
add_new_row(app_session, data)[source]

Assumes the data keys are a super set of the constructor arguments for the class type you are making i.e. that the grids column headers are a super set of the constructor arguments

edit_row(app_session, data)[source]

Assumption that the names of the members of a class are equal to the keys you get in the data object when editing, which in turn are the names of the columns in the grid, which are a subset of the columns in the table hierachy for this object

get_computed_column_names()[source]

Get a list of names of object properties which should be displayed as columns :return: List of String

get_qry_of_non_filtered_refresh_objects(app_session)[source]

Get the sqla query that will return sqla orm objects unfiltered by grid.

Returns:sqla qry object - that if executed would return all objects in the grid - unfiltered and unsorted

Assumes data_set exists.


StaticImage

class tropofy.widgets.StaticImage(file_path=None, *args, **kwargs)[source]

A static image displayed to screen.

Images may come from external urls, or reference local image files generated with an app. Use this widget to display images create with libraries such as Matplotlib, and R. The example below is a common usage pattern of StaticImage:

  1. Create and save an image within your app:

    #img is an in memory PLT.Image object created by your app
    data_set.save_image(name="output.png", image=img)
    
  2. Implement a StaticImage widget as follow:

    class OutputPlot(StaticImage):
        def get_file_path(self, app_session):
            return data_set.get_image_path('output.png')
    
  3. Include your StaticImage widget within tropofy.app.AppWithDataSets.get_gui()

get_file_path(app_session)[source]

A path to a static image file.

The path may be a url or file on disk. For a file on disk generated by your app, save the file in your app using tropofy.app.AppDataSet.save_image() and use tropofy.app.AppDataSet.get_image_path() to get the path of a file to serve statically.

Parameters:data_set – Advanced use only. For programatically defining file path, from the current DataSet.
Return type:string

For example, to point to a hosted file at a url:

def get_file_path(data_set):
    return 'http://www.tropofy.com/static/css/img/tropofy_example_app_icons/travelling_salesman.png'

To return the file path of an image saved with tropofy.app.AppDataSet.save_image():

class OutputPlot(StaticImage):
    def get_file_path(self, app_session):
        return data_set.get_image_path('output.png')

ForceGraphWidget

class tropofy.widgets.ForceGraphWidget(dimensions=(None, 800), widget_subscriptions=None, cols=12)[source]
class Direction[source]

Arrow heads on edges. direction from source to target.

get_force_params(app_session)[source]

A dictionary of d3.force.layout calls

By default, includes {“charge”: 60”}

The connections between nodes in the graph. At the very least, has a source and a target, which both refer to the name of a node that exists in the get_nodes function

Example” [{“source”: “A”, “target”: “B”, “distance”: 20, “direction: ForceGraphWidget.Direction.FORWARD”}]

The following parameters are accepted by the widget: d3 specific: distance, strength, source, target SVG styles: stroke, stroke-width, stroke-opacity Other: “title” (mouseover text)

get_nodes(app_session)[source]

The nodes of the force graph in a set of key-value pairs that must, at the very least, include a name

For example: [{“name”: “A”, “fill”: “yellow”}, {“name”: “B”, “r”: 2}]

The following parameters are accepted by the widget: d3 specific: name, x, y, fixed, weight, charge SVG styles: fill, fill-opacity, stroke, stroke-width, stroke-opacity SVG attribute: r (radius)

get_overlay_names(app_session)[source]
Returns:Whether or not to make node names appear on mouseover (False) vs. always (True)

CustomWidget

class tropofy.widgets.CustomWidget(widget_subscriptions=None, cols=12, key=None)[source]

Custom widgets allow users to define totally arbitrary widgets, using their own HTML, JavaScript, and Python code.

The Tropofy narrative documentation has a section on usage.

custom_static_content_locations()[source]

Dictionary telling the application which HTML, CSS, and Javascript files to load for the custom widget

Parameters:app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
Returns:A dictionary with keys “js”, “css”, “html” pointing to the path of the respective assets within the static directory
Return type:dict

File IO Utils

Excel

tropofy.file_io.read_write_xl

alias of tropofy.file_io.read_write_xl

class tropofy.file_io.read_write_xl.ExcelWriter[source]

Utility class for writing data to Microsoft Excel files.

classmethod create_excel_string_repr(app_session, ordered_class_ws_mappings=None, template_file_name_with_path=None, conditional_formats=None, export_empty_sheets=True, export_datetime_format='hh:mm:ss dd/mm/yyyy')[source]

Create an Excel file as a string, which has a worksheet for each class in ordered_class_ws_mappings.

Can be used as return value of tropofy.widgets.custom_export_widget.get_custom_export_data().

If ordered_class_ws_mappings is not passed, a ‘full export’ of all data in the app_session.data_set will be made, with one worksheet made for each SQLA ORM class.

If no mixins or get_objects param is passed to a ordered_class_ws_mapping, it is assumed that ordered_class_ws_mapping.class_ is a SQLA ORM class, and all mixins in the database for this app_session.data_set will be written to Excel.

Parameters:
  • app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
  • ordered_class_ws_mappings (list of tropofy.file_io.read_write_xl.ClassWsMapping) – (Optional) Default None. If None is passed, automatic mappings will be made to do a ‘full export’ of all data in all SQLA ORM classes in the app.
  • template_file_name_with_path (str) – (Optional) Default None. complete path/filename of a template if using one
  • conditional_formats (list of tropofy.file_io.read_write_xl.ConditionalFormat) – (Optional) Default None. All conditional formats to apply to the mapped worksheets.
  • export_datetime_format – (Optional) Default format for datetimes being exported.
Type:

export_datetime_format: string

Returns:

str

classmethod create_excel_string_repr_from_sqla_classes(app_session, sqla_classes)[source]

Create an Excel file as a string, which has a worksheet for each SQLA class passed with SQLA_classes.

Can be used as return value of tropofy.widgets.custom_export_widget.get_custom_export_data().

Parameters:
  • app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
  • sqla_classes (list of SQLA classes) – A list of SQLA ORM defined classes
Returns:

str

class tropofy.file_io.read_write_xl.ClassWsMapping(class_, ws_name, attribute_column_aliases, process_objects=None, get_objects=None, objects=None, styles=None, starting_cell='A1', password=None)[source]

Maps a Python class to a Microsoft Excel worksheet.

Used to both write to and read from Microsoft Excel with tropofy.file_io.read_write_xl.ExcelReader() and tropofy.file_io.read_write_xl.ExcelWriter().

Parameters:
  • class_ (class) – Python class in mapping.
  • ws_name (str) – Excel worksheet name in mapping.
  • attribute_column_aliases (dict) – dict of class attribute to col alias.
  • process_objects (function) – (Optional) Function that processes the objects of class_ loaded from Excel. Must accept two paramaters representing the app_session and the list of objects of class_. If no function is passed, default behaviour is to assume class_ is a SQLA class, and attempt to write the objects to the database.
  • get_objects (function) – (Optional - default tropofy.file_io.ClassTabularDataMapping.get_all_sqla_objects_of_class_in_data_set()) A function that accepts app_session and class_ as parameters and returns a list of mixins of class_.
  • objects (list) – (Optional - default None) Specify mixins instead of dynamically generating them with get_objects. A list of mixins of class_ to be included in export. Will overide get_objects if value is not None.
  • styles (dict) – (Optional - default None) Dictionary of object properties (columns of sqla class) mapped to openpyxl.styles.Style objects. Applicable only to writing, not reading.
  • starting_cell (str) – (Optional - default ‘A1’) Cell of worksheet to begin writing to, e.g. ‘A1’. Applicable only to writing, not reading.

Note

To specify the order in which columns are written, use a collections.OrderedDict (Python built-in) for attribute_column_aliases.

Note

For more information on openpyxl styles, refer to the Openpyxl Docs.

classmethod create_ordered_mappings_for_all_sqla_classes_in_app(app, include_parameters_if_any=True, metadata=None, schema_name=None)[source]

Inspect an app to get all imported SQLA classes, and create tropofy.file_io.read_write_xl.ClassWsMapping for them.

Parameters:
  • app (tropofy.app.App) – App in which sqla classes are defined.
  • include_parameters_if_any (bool) – Add a class_ws_mapping for Parameters in the app.
Returns:

list of tropofy.database.read_write_xl.ClassWsMapping

Return type:

list

classmethod create_ordered_mappings_from_sqla_classes(sqla_classes)[source]

Create tropofy.file_io.read_write_xl.ClassWsMapping for all sqla_classes passed..

Note

To automatically get all sqla_classes in an app instead of passed sqla_class, use tropofy.file_io.read_write_xl.ClassWsMapping.create_ordered_mappings_for_all_sqla_classes_in_app()

Warning

SQLA classes will be uploaded in the order listed. Ensure you consider database referential integrity constraints when ordering.

Parameters:sqla_classes (list) – List of SQLA classes to create mappings for.
Returns:list of tropofy.database.read_write_xl.ClassWsMapping
Return type:list
class tropofy.file_io.read_write_xl.ConditionalFormat(applicable_column_worksheet_name, applicable_column, comparitor_column, operator, fill=None, font=None, border=None, stopIfTrue=True)[source]

Conditional Formatting object to apply conditional formatting rules to a worksheet

Parameters:
  • applicable_column_worksheet_name (str) – A user defined SQLAlchemy Python class
  • applicable_column (str) – the sqla class parameter name representing the column to apply the conditional format to
  • comparitor_column (str) – the sqla class parameter name representing the column to compare the operator to
  • operator (str) – any key or value from the following dict: {“>”: “greaterThan”, “>=”: “greaterThanOrEqual”, “<”: “lessThan”, “<=”: “lessThanOrEqual”, “=”: “equal”, “==”: “equal”, “!=”: “notEqual”}
  • fill (openpyxl PatternFill() or GradientFill() object) – The fill to apply if condition is true
  • font (openpyxl Font() object) – The font to apply if condition is true
  • border (openpyxl Border() object) – The border to apply if condition is true
  • stopIfTrue (bool) – Stop processing further conditional formatting rules on a cell if condition is true

Note

For more information on openpyxl Fill, Font and Border objects, refer to the Openpyxl Docs.

apply_rule_to_worksheet(workbook, column_to_column_number_mapping, first_row_of_data, last_row_of_data)[source]

Applies the conditional formatting rule to the applicable worksheet in the workbook specified.

Parameters:
  • workbook – openpyxl Workbook() object to apply rule to
  • column_to_column_number_mapping (dict(string: int)) – dictionary of column names to column numbers
  • first_row_of_data (int) – first row of the data to apply conditional formatting rule
  • last_row_of_data (int) – last row of the data to apply conditional formatting rule

CSV

class tropofy.file_io.read_write_csv.CsvReader[source]

Utility class for reading data from .csv files.

classmethod load_tabular_data_from_csv_file_in_memory(app_session, file_in_memory, class_tabular_csv_mapping, delimiter=', ', user_feedback_csv_file_identifier_str='', file_ext='csv')[source]

Loads data from a csv in memory file in a table format. Assumes first row is headings, and each subsequent row is data corresponding to the headings.

Parameters:
  • app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
  • file_in_memory (FileIO) – File in memory. Common use case is to pass from tropofy.widget.file_upload_widget.process_file()
  • class_tabular_csv_mapping (tropofy.file_io.read_write_csv.ClassTabularCsvMapping) – Describes how the data and headings in the csv file map to a class.
  • delimiter (str) – (Optional) csv delimiter. Default ‘,’
  • user_feedback_csv_file_identifier_str – String to identify the csv file in error reporting.
Ty[e user_feedback_csv_file_identifier_str:
 

str

classmethod load_tabular_data_from_csv_file_on_disk(app_session, file_path, class_tabular_csv_mapping, delimiter=', ')[source]

Loads data from a csv file in a table format. Assumes first row is headings, and each subsequent row is data corresponding to the headings.

Parameters:
  • app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
  • file_path (str) – Path on disk to the csv file.
  • class_tabular_csv_mapping (tropofy.file_io.read_write_csv.ClassTabularCsvMapping) – Describes how the data and headings in the csv file map to a class.
  • delimiter (str) – (Optional) csv delimiter. Default ‘,’
class tropofy.file_io.read_write_csv.CsvWriter[source]
classmethod write_tabular_csv_data_to_stream(app_session, stream, class_tabular_csv_mapping, delimiter=', ')[source]

Write data to a csv stream in a table format. Sets first row as headings, and each subsequent row as data corresponding to the headings.

If class_tabular_csv_mapping is not instantiated with parameters process_objects or mixins, it will be assumed that the class_tabular_csv_mapping.class_ is a SQLA ORM class. All mixins in the database for this class_ in the data_set will be written to the csv file.

Note

Use a collections.OrderedDict in class_tabular_csv_mapping.attribute_column_alias to specify the output order.

Parameters:
classmethod write_tabular_data_to_csv_file_on_disk(app_session, file_path, class_tabular_csv_mapping, delimiter=', ')[source]

Write data to a csv file in a table format. Sets first row as headings, and each subsequent row as data corresponding to the headings.

If class_tabular_csv_mapping is not instantiated with parameters process_objects or mixins, it will be assumed that the class_tabular_csv_mapping.class_ is a SQLA ORM class. All mixins in the database for this class_ in the data_set will be written to the csv file.

Note

Use a collections.OrderedDict in class_tabular_csv_mapping.attribute_column_alias to specify the output order.

Parameters:
  • app_session (tropofy.app.meta.AppSession) – Use to access information about the app, the user’s interaction with it, and the data set.
  • file_path (str) – Path on disk to the csv file.
  • class_tabular_csv_mapping (tropofy.file_io.read_write_csv.ClassTabularCsvMapping) – Describes how a class maps to headings and data in the csv file.
  • delimiter (str) – (Optional) csv delimiter. Default ‘,’
class tropofy.file_io.read_write_csv.ClassTabularCsvMapping(class_, attribute_column_aliases, process_objects=None, get_objects=None, objects=None)[source]

Maps a Python class to a tabular csv file.

Used to both write to and read from csv with tropofy.file_io.read_write_xl.CsvReader() and tropofy.file_io.read_write_xl.CsvWriter().

Parameters:
  • class_ (class) – Python class in mapping.
  • attribute_column_aliases (dict) – dict of class attribute to col alias.
  • process_objects (function) – (Optional) Function that processes the mixins of class_ loaded from Excel. Must accept a single parameter which will be passed a list of mixins of class_. If no function is passed, default behaviour is to assume class_ is a SQLA class, and attempt to write the mixins to the database.
  • get_objects (function) – (Optional) A function that accepts app_session as parameter and returns a list of mixins of class_
  • objects (list) – (Optional) A list of mixins of class_ to be included in export. If get_objects is supplied, these mixins will be overridden.

Note

To specify the order in which columns are written, use a collections.OrderedDict (Python built-in) for attribute_column_aliases.

XML

class tropofy.file_io.read_write_xml.XmlWriter[source]

Utility class for writing data to XML files.

classmethod write_xml_file(items, file_name, folder_for_files)[source]
Parameters:
  • items – list of objects of classes that inherit from tropofy.file_io.read_write_xml.XmlInterfaceMixin
  • file_name (str) – name of the xml file, including ‘.xml’. Note that this does not include the path
  • folder_for_files (str) – absolute file path to save xml files to - (Tip: use data_set.get_file_save_folder(app_session.app_module_path) to get a unique folder for each data_set).
class tropofy.file_io.read_write_xml.XmlReader[source]

Utility class for reading data from XML files.

classmethod read_tabular_xml_file_into_list_of_dicts(file_name_with_path)[source]
Parameters:file_name_with_path (str) – absolute file path including .xml
Returns:list of dicts

Example usage of reading and writing to xml:

from tropofy.file_io import read_write_xml

# Example classes - could be a SQLA class or just a normal in memory Python class
class Factory(read_write_xml.XmlInterfaceMixin):
    def __init__(name, max_employees):
       self.name = name
       self.max_employees = max_employees

class Employee(read_write_xml.XmlInterfaceMixin):
    def __init__(name, factory_name):
       self.name = name
       self.factory_name = factory_name

# Create some factory objects
factories = [Factory('Factory 1', 100), Factory('Factory 1', 300)]

# Write factories to XML
folder_path = "/home/ubuntu/my_xml"
read_write_xml.XmlWriter.write_xml_file(factories, "factories.xml", folder_path)

# Run some code that assigns employees to factories

#Read from XML.
employees = [Employee(**row) for row in read_write_xml.XMLReader.read_tabular_xml_file_into_list_of_dicts(os.path.join(folder_path, 'Employees.xml'))]
classmethod read_xml_file(object_type, file_name_with_path)[source]

Parse tabular XML file into a list of objects of type object_class

Parameters:
  • object_type – Class to be constructed for each row. Could be a SQLA class or just a normal Python class Note: Initialiser for object_type must be able to handle raw strings (as extracted from XML) as kwargs.
  • file_name_with_path – absolute file path including .xml
Returns:

List of objects of type <object_type>

class tropofy.file_io.read_write_xml.XmlInterfaceMixin[source]

Inherit from this mixin to be able to use objects of the class as items in tropofy.file_io.read_write_xml.XmlWriter.write_xml_file()


AWS S3

class tropofy.file_io.read_write_aws_s3.AwsS3Utility[source]

Utility module for interacting with AWS S3.

Note

This is a helper utility module that is only used directly in advanced cases. For most use cases, use tropofy.file_io.read_write_aws_s3.AwsS3Writer and tropofy.file_io.read_write_aws_s3.AwsS3Reader

To use any of the AwsS3 modules you must:

  • Install Python module boto. From within your virtualenv type: pip install boto.

  • Set the parameter custom.aws_s3_bucket in your .ini file used to run your Tropofy app.

  • Create an environment var AWS_CREDENTIAL_FILE which points to a file with your AWS credentials in it. This file must take the form:

    AWSAccessKeyId=your_aws_access_key
    AWSSecretKey=your_aws_secret_key
    
classmethod delete_file(app_session, filename, s3_bucket_name=None)[source]

Delete key (and associated file) saved to AWS s3.

Uses bucket defined in .ini param custom.aws_s3_bucket and deletes the unique key created with tropofy.file_io.read_write_aws_s3.AwsS3Utility.get_unique_s3_key().

Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • filename (str) – filename of file to be deleted in s3 bucket
  • s3_bucket_name (str) – Name of an AWS S3 bucket. If not provided, defaults to value in .ini file custom.aws_s3_bucket
classmethod get_bucket(app_session, s3_bucket_name=None)[source]

Connect to and return the AWS S3 bucket specified in .ini parameter custom.aws_s3_bucket.

Note

It is recomended that bucket_names not be hardcoded into apps, and instead be specific in .ini file custom.aws_s3_bucket

Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • s3_bucket_name (str) – Name of an AWS S3 bucket. If not provided, defaults to value in .ini file custom.aws_s3_bucket
Return type:

boto.s3.bucket.Bucket

classmethod get_s3_key_obj(app_session, file_name=None, s3_key=None, s3_bucket_name=None)[source]
Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • s3_key (str) – (Default None) S3 key for file. If None, file_name must be provided, which will be used to generate a key unique for the data_set using tropofy.read_write_aws_s3.AwsS3Utility.get_unique_s3_key(). See func docs for details.
  • file_name (str) – (Default None) Name of file - not a full s3 key. e.g. output.xlsx. Only used if s3_key not provided.
  • s3_bucket_name (str) – Name of an AWS S3 bucket. If not provided, defaults to value in .ini file custom.aws_s3_bucket
classmethod get_unique_s3_key(app_session, file_name, user_unique=False, time_unique=False)[source]

Returns a unique s3 key for a file name in a data set given an app_session and file_name.

Uses app_session.data_set.created_datetime to make unique for multiple servers running the same app pointing at the same s3 bucket (e.g. dev and production). Will be unique as long as separate servers running the same app do not create data sets with the same id, at the same second.

Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • file_name (str) – Name of file - not a full s3 key. e.g. output.xlsx.
  • user_unique – (Default False) Will make path unique for a user.
  • time_unique – (Default False) Will make path unique for the time the key created.

Warning

If time_unique == True, the path to this file will not be able to be retrieved using this function, as the unique time will have changed from when it was generated.

class tropofy.file_io.read_write_aws_s3.AwsS3Writer[source]

Bases: tropofy.file_io.read_write_aws_s3.AwsS3Utility

Utility module for aiding in saving files to AWS S3.

classmethod save_file(app_session, in_memory_file, s3_bucket_name=None)[source]

Save file to AWS s3.

Uses bucket defined in .ini param custom.aws_s3_bucket and creates a unique key accessible with tropofy.file_io.read_write_aws_s3.AwsS3Utility.get_unique_s3_key().

Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • in_memory_file (FieldStorage) – file in memory to be uploaded to s3
  • s3_bucket_name (str) – Name of an AWS S3 bucket. If not provided, defaults to value in .ini file custom.aws_s3_bucket
classmethod save_file_from_file_path(app_session, filename, file_path, s3_bucket_name=None)[source]

Save file on disk to AWS s3.

Uses bucket defined in .ini param custom.aws_s3_bucket and creates a unique key accessible with tropofy.file_io.read_write_aws_s3.AwsS3Utility.get_unique_s3_key().

Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • filename (str) – filename of file on disk to be uploaded to s3, not including file path, e.g. ‘solution.xml’
  • file_path – path of file
  • s3_bucket_name (str) – Name of an AWS S3 bucket. If not provided, defaults to value in .ini file custom.aws_s3_bucket
classmethod save_file_string(app_session, string_data, s3_key=None, file_name=None, s3_bucket_name=None)[source]

Save file to AWS s3.

Uses bucket defined in .ini param custom.aws_s3_bucket and creates a unique key accessible with tropofy.file_io.read_write_aws_s3.AwsS3Utility.get_unique_s3_key().

Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • string_data (str) – Data to save
  • s3_key (str) – (Default None) S3 key for file. If None, file_name must be provided, which will be used to generate a key unique for the data_set using tropofy.read_write_aws_s3.AwsS3Utility.get_unique_s3_key(). See func docs for details.
  • file_name (str) – (Default None) Name of file - not a full s3 key. e.g. output.xlsx. Only used if s3_key not provided.
  • s3_bucket_name (str) – Name of an AWS S3 bucket. If not provided, defaults to value in .ini file custom.aws_s3_bucket
class tropofy.file_io.read_write_aws_s3.AwsS3Reader[source]

Bases: tropofy.file_io.read_write_aws_s3.AwsS3Utility

Utility module for aiding in reading files from AWS S3.

classmethod copy_file_from_s3(app_session, file_name, destination_stream, s3_bucket_name=None)[source]

Get a file from s3 into memory

..note:

:param app_session:
:type app_session: :class:`tropofy.app.meta.AppSession`
:param file_name: Name of file - not a full s3 key. e.g. `output.xlsx`.
:type file_name: str

Use in conjunction with tropofy.file_io.read_write_aws_s3.AwsS3Reader.get_file_access_url() to download file from S3 to disk.

classmethod get_file_access_url(app_session, s3_key=None, file_name=None, s3_bucket_name=None, seconds_url_expires_in=60)[source]

Returns a url from which a file can be accessed.

Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • s3_key (str) – (Default None) S3 key for file. If None, file_name must be provided, which will be used to generate a key unique for the data_set using tropofy.read_write_aws_s3.AwsS3Utility.get_unique_s3_key(). See func docs for details.
  • file_name (str) – (Default None) Name of file - not a full s3 key. e.g. output.xlsx. Only used if s3_key not provided.
  • s3_bucket_name (str) – Name of an AWS S3 bucket. If not provided, defaults to value in .ini file custom.aws_s3_bucket
  • seconds_url_expires_in (int) – Numbers of seconds the url is valid for.
Returns:

url string from which the file can be accessed from AWS S3 for the number of seconds specified by seconds_url_expires_in.

Return type:

str

classmethod get_file_access_url_of_zipped_s3_dir(app_session, s3_folder_path, zip_file_path=None, s3_bucket_name=None)[source]

Zips an S3 dir onto S3 and returns file access url for it.

Use with tropofy.widgets.DownloadFileFromUrl to download s3 as zip within an app..

Note

The actual folder zipped on s3 will include the unique path name generated as written through AwsS3Writer.

Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • s3_folder_path – subpath of folders on s3 - eg ‘/solver1/interface_files’
  • zip_file_path – path to zip on s3 - eg ‘tmp/myzip.zip’
classmethod write_s3_folder_to_local_disk(app_session, s3_folder_path, local_folder_path, s3_bucket_name=None, key_list=None)[source]
Parameters:
  • s3_folder_path – Will look for path within unique data_set subfolder of bucket,
  • local_folder_path – absolute path that keys will be written to and directories created if required.
classmethod zip_s3_folder_to_s3(app_session, s3_folder_path, zip_file_path, s3_bucket_name=None)[source]

Copy a folder of files on S3 to a zip file also on s3

Note

The actual folder zipped on s3 will include the unique path name generated as written through AwsS3Writer.

Parameters:
  • app_session (tropofy.app.meta.AppSession) –
  • s3_folder_path – subpath of folders on s3 - eg ‘/solver1/interface_files’
  • zip_file_path – path to zip on s3 - eg ‘tmp/myzip.zip’