Esempio n. 1
0
    def append_columns(cls, columns, grid=None, grid_url=None):
        grid_id = _api_v2.parse_grid_id_args(grid, grid_url)

        # Verify unique column names
        column_names = [c.name for c in columns]
        if grid:
            existing_column_names = [c.name for c in grid]
            column_names.extend(existing_column_names)
        duplicate_name = utils.get_first_duplicate(column_names)
        if duplicate_name:
            err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name)
            raise exceptions.InputError(err)

        payload = {
            'cols': json.dumps(columns, cls=utils._plotlyJSONEncoder)
        }

        api_url = _api_v2.api_url('grids')+'/{grid_id}/col'.format(grid_id=grid_id)
        res = requests.post(api_url, data=payload, headers=_api_v2.headers(),
                            verify=get_config()['plotly_ssl_verification'])
        res = _api_v2.response_handler(res)

        cls._fill_in_response_column_ids(columns, res['cols'], grid_id)

        if grid:
            grid.extend(columns)
Esempio n. 2
0
 def _validate_insertion(self, column):
     """
     Raise an error if we're gonna add a duplicate column name
     """
     existing_column_names = [col.name for col in self._columns]
     if column.name in existing_column_names:
         err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(column.name)
         raise exceptions.InputError(err)
Esempio n. 3
0
    def __init__(self, iterable_of_columns):
        column_names = [column.name for column in iterable_of_columns]
        duplicate_name = utils.get_first_duplicate(column_names)
        if duplicate_name:
            err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name)
            raise exceptions.InputError(err)

        self._columns = list(iterable_of_columns)
        self.id = ''
Esempio n. 4
0
    def parse_grid_id_args(cls, grid, grid_url):
        """
        Return the grid_id from the non-None input argument.

        Raise an error if more than one argument was supplied.

        """
        if grid is not None:
            id_from_grid = grid.id
        else:
            id_from_grid = None
        args = [id_from_grid, grid_url]
        arg_names = ('grid', 'grid_url')

        supplied_arg_names = [
            arg_name for arg_name, arg in zip(arg_names, args)
            if arg is not None
        ]

        if not supplied_arg_names:
            raise exceptions.InputError(
                "One of the two keyword arguments is required:\n"
                "    `grid` or `grid_url`\n\n"
                "grid: a plotly.graph_objs.Grid object that has already\n"
                "    been uploaded to Plotly.\n\n"
                "grid_url: the url where the grid can be accessed on\n"
                "    Plotly, e.g. 'https://plot.ly/~chris/3043'\n\n")
        elif len(supplied_arg_names) > 1:
            raise exceptions.InputError(
                "Only one of `grid` or `grid_url` is required. \n"
                "You supplied both. \n")
        else:
            supplied_arg_name = supplied_arg_names.pop()
            if supplied_arg_name == 'grid_url':
                path = urlparse(grid_url).path
                file_owner, file_id = path.replace("/~", "").split('/')[0:2]
                return '{0}:{1}'.format(file_owner, file_id)
            else:
                return grid.id
Esempio n. 5
0
def assign_id_to_src(src_name, src_value):
    if isinstance(src_value, six.string_types):
        src_id = src_value
    else:
        try:
            src_id = src_value.id
        except:
            err = ("{0} does not have an `id` property. "
                   "{1} needs to be assigned to either an "
                   "object with an `id` (like a "
                   "plotly.grid_objs.Column) or a string. "
                   "The `id` is a unique identifier "
                   "assigned by the Plotly webserver "
                   "to this grid column.")
            src_value_str = str(src_value)
            err = err.format(src_name, src_value_str)
            raise exceptions.InputError(err)

    if src_id == '':
        err = exceptions.COLUMN_NOT_YET_UPLOADED_MESSAGE
        err.format(column_name=src_value.name, reference=src_name)
        raise exceptions.InputError(err)
    return src_id
Esempio n. 6
0
    def append_rows(cls, rows, grid=None, grid_url=None):
        grid_id = _api_v2.parse_grid_id_args(grid, grid_url)

        if grid:
            n_columns = len([column for column in grid])
            for row_i, row in enumerate(rows):
                if len(row) != n_columns:
                    raise exceptions.InputError(
                        "The number of entries in "
                        "each row needs to equal the number of columns in "
                        "the grid. Row {0} has {1} {2} but your "
                        "grid has {3} {4}. "
                        .format(row_i, len(row),
                                'entry' if len(row) == 1 else 'entries',
                                n_columns,
                                'column' if n_columns == 1 else 'columns'))

        payload = {
            'rows': json.dumps(rows, cls=utils._plotlyJSONEncoder)
        }

        api_url = (_api_v2.api_url('grids')+
                   '/{grid_id}/row'.format(grid_id=grid_id))
        res = requests.post(api_url, data=payload, headers=_api_v2.headers(),
                            verify=get_config()['plotly_ssl_verification'])
        _api_v2.response_handler(res)

        if grid:
            longest_column_length = max([len(col.data) for col in grid])

            for column in grid:
                n_empty_rows = longest_column_length - len(column.data)
                empty_string_rows = ['' for _ in range(n_empty_rows)]
                column.data.extend(empty_string_rows)

            column_extensions = zip(*rows)
            for local_column, column_extension in zip(grid, column_extensions):
                local_column.data.extend(column_extension)
Esempio n. 7
0
    def __init__(self, iterable_of_columns):
        """
        Initialize a grid with an iterable of
        `plotly.grid_objs.Column objects

        Usage example:
        ```
        column_1 = Column([1, 2, 3], 'time')
        column_2 = Column([4, 2, 5], 'voltage')
        grid = Grid([column_1, column_2])
        ```
        """

        # TODO: verify that columns are actually columns

        column_names = [column.name for column in iterable_of_columns]
        duplicate_name = utils.get_first_duplicate(column_names)
        if duplicate_name:
            err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name)
            raise exceptions.InputError(err)

        self._columns = list(iterable_of_columns)
        self.id = ''
    def __init__(self, columns_or_json, fid=None):
        """
        Initialize a grid with an iterable of `plotly.grid_objs.Column`
        objects or a json/dict describing a grid. See second usage example
        below for the necessary structure of the dict.

        :param (str|bool) fid: should not be accessible to users. Default
            is 'None' but if a grid is retrieved via `py.get_grid()` then the
            retrieved grid response will contain the fid which will be
            necessary to set `self.id` and `self._columns.id` below.

        Example from iterable of columns:
        ```
        column_1 = Column([1, 2, 3], 'time')
        column_2 = Column([4, 2, 5], 'voltage')
        grid = Grid([column_1, column_2])
        ```
        Example from json grid
        ```
        grid_json = {
            'cols': {
                'time': {'data': [1, 2, 3], 'order': 0, 'uid': '4cd7fc'},
                'voltage': {'data': [4, 2, 5], 'order': 1, 'uid': u'2744be'}
            }
        }
        grid = Grid(grid_json)
        ```
        """
        # TODO: verify that columns are actually columns
        if pd and isinstance(columns_or_json, pd.DataFrame):
            duplicate_name = utils.get_first_duplicate(columns_or_json.columns)
            if duplicate_name:
                err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name)
                raise exceptions.InputError(err)

            # create columns from dataframe
            all_columns = []
            for name in columns_or_json.columns:
                all_columns.append(Column(columns_or_json[name].tolist(), name))
            self._columns = all_columns
            self.id = ''

        elif isinstance(columns_or_json, dict):
            # check that fid is entered
            if fid is None:
                raise exceptions.PlotlyError(
                    "If you are manually converting a raw json/dict grid "
                    "into a Grid instance, you must ensure that 'fid' is "
                    "set to your file ID. This looks like 'username:187'."
                )

            self.id = fid

            # check if 'cols' is a root key
            if 'cols' not in columns_or_json:
                raise exceptions.PlotlyError(
                    "'cols' must be a root key in your json grid."
                )

            # check if 'data', 'order' and 'uid' are not in columns
            grid_col_keys = ['data', 'order', 'uid']

            for column_name in columns_or_json['cols']:
                for key in grid_col_keys:
                    if key not in columns_or_json['cols'][column_name]:
                        raise exceptions.PlotlyError(
                            "Each column name of your dictionary must have "
                            "'data', 'order' and 'uid' as keys."
                        )
            # collect and sort all orders in case orders do not start
            # at zero or there are jump discontinuities between them
            all_orders = []
            for column_name in columns_or_json['cols'].keys():
                all_orders.append(columns_or_json['cols'][column_name]['order'])
            all_orders.sort()

            # put columns in order in a list
            ordered_columns = []
            for order in all_orders:
                for column_name in columns_or_json['cols'].keys():
                    if columns_or_json['cols'][column_name]['order'] == order:
                        break

                ordered_columns.append(Column(
                    columns_or_json['cols'][column_name]['data'],
                    column_name)
                )
            self._columns = ordered_columns

            # fill in column_ids
            for column in self:
                column.id = self.id + ':' + columns_or_json['cols'][column.name]['uid']

        else:
            column_names = [column.name for column in columns_or_json]
            duplicate_name = utils.get_first_duplicate(column_names)
            if duplicate_name:
                err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name)
                raise exceptions.InputError(err)

            self._columns = list(columns_or_json)
            self.id = ''
Esempio n. 9
0
    def append_rows(cls, rows, grid=None, grid_url=None):
        """
        Append rows to a Plotly grid.

        `rows` is an iterable of rows, where each row is a
        list of numbers, strings, or dates. The number of items
        in each row must be equal to the number of columns
        in the grid. If appending rows to a grid with columns of
        unequal length, Plotly will fill the columns with shorter
        length with empty strings.

        Only one of `grid` and `grid_url` needs to specified.

        `grid` is a ploty.grid_objs.Grid object that has already been
        uploaded to plotly with the grid_ops.upload method.

        `grid_url` is a unique URL of a `grid` in your plotly account.

        Usage example 1: Upload a grid to Plotly, and then append rows
        ```
        from plotly.grid_objs import Grid, Column
        import plotly.plotly as py
        column_1 = Column([1, 2, 3], 'time')
        column_2 = Column([5, 2, 7], 'voltage')
        grid = Grid([column_1, column_2])
        py.grid_ops.upload(grid, 'time vs voltage')

        # append a row to the grid
        row = [1, 5]
        py.grid_ops.append_rows([row], grid=grid)
        ```

        Usage example 2: Append a row to a grid that already exists on Plotly
        ```
        from plotly.grid_objs import Grid
        import plotly.plotly as py

        grid_url = 'https://plot.ly/~chris/3143'

        row = [1, 5]
        py.grid_ops.append_rows([row], grid=grid_url)
        ```

        """
        grid_id = _api_v2.parse_grid_id_args(grid, grid_url)

        if grid:
            n_columns = len([column for column in grid])
            for row_i, row in enumerate(rows):
                if len(row) != n_columns:
                    raise exceptions.InputError(
                        "The number of entries in "
                        "each row needs to equal the number of columns in "
                        "the grid. Row {0} has {1} {2} but your "
                        "grid has {3} {4}. ".format(
                            row_i, len(row),
                            'entry' if len(row) == 1 else 'entries', n_columns,
                            'column' if n_columns == 1 else 'columns'))

        payload = {'rows': json.dumps(rows, cls=utils.PlotlyJSONEncoder)}

        api_url = (_api_v2.api_url('grids') +
                   '/{grid_id}/row'.format(grid_id=grid_id))
        res = requests.post(api_url,
                            data=payload,
                            headers=_api_v2.headers(),
                            verify=get_config()['plotly_ssl_verification'])
        _api_v2.response_handler(res)

        if grid:
            longest_column_length = max([len(col.data) for col in grid])

            for column in grid:
                n_empty_rows = longest_column_length - len(column.data)
                empty_string_rows = ['' for _ in range(n_empty_rows)]
                column.data.extend(empty_string_rows)

            column_extensions = zip(*rows)
            for local_column, column_extension in zip(grid, column_extensions):
                local_column.data.extend(column_extension)
Esempio n. 10
0
    def append_columns(cls, columns, grid=None, grid_url=None):
        """
        Append columns to a Plotly grid.

        `columns` is an iterable of plotly.grid_objs.Column objects
        and only one of `grid` and `grid_url` needs to specified.

        `grid` is a ploty.grid_objs.Grid object that has already been
        uploaded to plotly with the grid_ops.upload method.

        `grid_url` is a unique URL of a `grid` in your plotly account.

        Usage example 1: Upload a grid to Plotly, and then append a column
        ```
        from plotly.grid_objs import Grid, Column
        import plotly.plotly as py
        column_1 = Column([1, 2, 3], 'time')
        grid = Grid([column_1])
        py.grid_ops.upload(grid, 'time vs voltage')

        # append a column to the grid
        column_2 = Column([4, 2, 5], 'voltage')
        py.grid_ops.append_columns([column_2], grid=grid)
        ```

        Usage example 2: Append a column to a grid that already exists on Plotly
        ```
        from plotly.grid_objs import Grid, Column
        import plotly.plotly as py

        grid_url = 'https://plot.ly/~chris/3143'
        column_1 = Column([1, 2, 3], 'time')
        py.grid_ops.append_columns([column_1], grid_url=grid_url)
        ```

        """
        grid_id = _api_v2.parse_grid_id_args(grid, grid_url)

        # Verify unique column names
        column_names = [c.name for c in columns]
        if grid:
            existing_column_names = [c.name for c in grid]
            column_names.extend(existing_column_names)
        duplicate_name = utils.get_first_duplicate(column_names)
        if duplicate_name:
            err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name)
            raise exceptions.InputError(err)

        payload = {'cols': json.dumps(columns, cls=utils.PlotlyJSONEncoder)}

        api_url = (_api_v2.api_url('grids') +
                   '/{grid_id}/col'.format(grid_id=grid_id))
        res = requests.post(api_url,
                            data=payload,
                            headers=_api_v2.headers(),
                            verify=get_config()['plotly_ssl_verification'])
        res = _api_v2.response_handler(res)

        cls._fill_in_response_column_ids(columns, res['cols'], grid_id)

        if grid:
            grid.extend(columns)