def _collect_tensor_events(self, request, step=None):
        """Collects list of tensor events based on request."""
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        run = request.args.get("run")
        tag = request.args.get("tag")

        tensor_events = []  # List of tuples (meta, tensor) that contain tag.
        for instance_tag in self._instance_tags(ctx, experiment, run, tag):
            tensors = self._data_provider.read_tensors(
                ctx,
                experiment_id=experiment,
                plugin_name=metadata.PLUGIN_NAME,
                run_tag_filter=provider.RunTagFilter(
                    runs=[run], tags=[instance_tag]
                ),
                downsample=self._downsample_to,
            )[run][instance_tag]
            meta = self._instance_tag_metadata(
                ctx, experiment, run, instance_tag
            )
            tensor_events += [(meta, tensor) for tensor in tensors]

        if step is not None:
            tensor_events = [
                event for event in tensor_events if event[1].step == step
            ]
        else:
            # Make sure tensors sorted by step in ascending order.
            tensor_events = sorted(
                tensor_events, key=lambda tensor_data: tensor_data[1].step
            )

        return tensor_events
Exemple #2
0
    def _serve_environment(self, request):
        """Serve a JSON object describing the TensorBoard parameters."""
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        md = self._data_provider.experiment_metadata(ctx,
                                                     experiment_id=experiment)

        environment = {
            "version": version.VERSION,
            "data_location": md.data_location,
            "window_title": self._window_title,
            "experiment_name": md.experiment_name,
            "experiment_description": md.experiment_description,
            "creation_time": md.creation_time,
        }
        if self._include_debug_info:
            environment["debug"] = {
                "data_provider": str(self._data_provider),
                "flags": self._render_flags(),
            }
        return http_util.Respond(
            request,
            environment,
            "application/json",
        )
    def pr_curves_route(self, request):
        """A route that returns a JSON mapping between runs and PR curve data.

        Returns:
          Given a tag and a comma-separated list of runs (both stored within GET
          parameters), fetches a JSON object that maps between run name and objects
          containing data required for PR curves for that run. Runs that either
          cannot be found or that lack tags will be excluded from the response.
        """
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)

        runs = request.args.getlist("run")
        if not runs:
            return http_util.Respond(
                request, "No runs provided when fetching PR curve data", 400)

        tag = request.args.get("tag")
        if not tag:
            return http_util.Respond(
                request, "No tag provided when fetching PR curve data", 400)

        try:
            response = http_util.Respond(
                request,
                self.pr_curves_impl(ctx, experiment, runs, tag),
                "application/json",
            )
        except ValueError as e:
            return http_util.Respond(request, str(e), "text/plain", 400)

        return response
Exemple #4
0
 def _serve_individual_image(self, request):
     """Serves an individual image."""
     try:
         if self._data_provider:
             ctx = plugin_util.context(request.environ)
             blob_key = request.args["blob_key"]
             data = self._get_generic_data_individual_image(ctx, blob_key)
         else:
             run = request.args.get("run")
             tag = request.args.get("tag")
             index = int(request.args.get("index", "0"))
             sample = int(request.args.get("sample", "0"))
             data = self._get_legacy_individual_image(
                 run, tag, index, sample)
     except (KeyError, IndexError):
         return http_util.Respond(
             request,
             "Invalid run, tag, index, or sample",
             "text/plain",
             code=400,
         )
     image_type = imghdr.what(None, data)
     content_type = _IMGHDR_TO_MIMETYPE.get(image_type,
                                            _DEFAULT_IMAGE_MIMETYPE)
     return http_util.Respond(request, data, content_type)
Exemple #5
0
    def scalars_route(self, request):
        """Given a tag regex and single run, return ScalarEvents.

        This route takes 2 GET params:
        run: A run string to find tags for.
        tag: A string that is a regex used to find matching tags.
        The response is a JSON object:
        {
          // Whether the regular expression is valid. Also false if empty.
          regexValid: boolean,

          // An object mapping tag name to a list of ScalarEvents.
          payload: Object<string, ScalarEvent[]>,
        }
        """
        ctx = plugin_util.context(request.environ)
        tag_regex_string = request.args.get("tag")
        run = request.args.get("run")
        experiment = plugin_util.experiment_id(request.environ)
        mime_type = "application/json"

        try:
            body = self.scalars_impl(ctx, run, tag_regex_string, experiment)
        except ValueError as e:
            return http_util.Respond(
                request=request,
                content=str(e),
                content_type="text/plain",
                code=400,
            )

        # Produce the response.
        return http_util.Respond(request, body, mime_type)
Exemple #6
0
 def download_data_route(self, request):
     ctx = plugin_util.context(request.environ)
     experiment_id = plugin_util.experiment_id(request.environ)
     try:
         response_format = request.args.get("format")
         columns_visibility = json.loads(
             request.args.get("columnsVisibility")
         )
         request_proto = _parse_request_argument(
             request, api_pb2.ListSessionGroupsRequest
         )
         session_groups = list_session_groups.Handler(
             ctx, self._context, experiment_id, request_proto
         ).run()
         experiment = get_experiment.Handler(
             ctx, self._context, experiment_id
         ).run()
         body, mime_type = download_data.Handler(
             self._context,
             experiment,
             session_groups,
             response_format,
             columns_visibility,
         ).run()
         return http_util.Respond(request, body, mime_type)
     except error.HParamsError as e:
         logger.error("HParams error: %s" % e)
         raise werkzeug.exceptions.BadRequest(description=str(e))
Exemple #7
0
 def text_route(self, request):
     ctx = plugin_util.context(request.environ)
     experiment = plugin_util.experiment_id(request.environ)
     run = request.args.get("run")
     tag = request.args.get("tag")
     response = self.text_impl(ctx, run, tag, experiment)
     return http_util.Respond(request, response, "application/json")
Exemple #8
0
    def _serve_greetings(self, request):
        """Serves greeting data for the specified tag and run.

        For details on how to use tags and runs, see
        https://github.com/tensorflow/tensorboard#tags-giving-names-to-data
        """
        run = request.args.get("run")
        tag = request.args.get("tag")
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)

        if run is None or tag is None:
            raise werkzeug.exceptions.BadRequest("Must specify run and tag")
        read_result = self.data_provider.read_tensors(
            ctx,
            downsample=1000,
            plugin_name=metadata.PLUGIN_NAME,
            experiment_id=experiment,
            run_tag_filter=provider.RunTagFilter(runs=[run], tags=[tag]),
        )

        data = read_result.get(run, {}).get(tag, [])
        if not data:
            raise werkzeug.exceptions.BadRequest("Invalid run or tag")
        event_data = [datum.numpy.item().decode("utf-8") for datum in data]

        contents = json.dumps(event_data, sort_keys=True)
        return werkzeug.Response(contents, content_type="application/json")
    def _serve_environment(self, request):
        """Serve a JSON object containing some base properties used by the
        frontend.

        * data_location is either a path to a directory or an address to a
          database (depending on which mode TensorBoard is running in).
        * window_title is the title of the TensorBoard web page.
        """
        if self._data_provider:
            ctx = plugin_util.context(request.environ)
            experiment = plugin_util.experiment_id(request.environ)
            data_location = self._data_provider.data_location(
                ctx, experiment_id=experiment
            )
            experiment_metadata = self._data_provider.experiment_metadata(
                ctx, experiment_id=experiment
            )
        else:
            data_location = self._logdir
            experiment_metadata = None

        environment = {
            "data_location": data_location,
            "window_title": self._window_title,
        }
        if experiment_metadata is not None:
            environment.update(
                {
                    "experiment_name": experiment_metadata.experiment_name,
                    "experiment_description": experiment_metadata.experiment_description,
                    "creation_time": experiment_metadata.creation_time,
                }
            )
        return http_util.Respond(request, environment, "application/json",)
Exemple #10
0
    def _serve_image_metadata(self, request):
        """Given a tag and list of runs, serve a list of metadata for images.

        Note that the images themselves are not sent; instead, we respond with URLs
        to the images. The frontend should treat these URLs as opaque and should not
        try to parse information about them or generate them itself, as the format
        may change.

        Args:
          request: A werkzeug.wrappers.Request object.

        Returns:
          A werkzeug.Response application.
        """
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        tag = request.args.get("tag")
        run = request.args.get("run")
        sample = int(request.args.get("sample", 0))
        try:
            response = self._image_response_for_run(ctx, experiment, run, tag,
                                                    sample)
        except KeyError:
            return http_util.Respond(request,
                                     "Invalid run or tag",
                                     "text/plain",
                                     code=400)
        return http_util.Respond(request, response, "application/json")
Exemple #11
0
    def _serve_tags(self, request):
        """A route (HTTP handler) that returns a response with tags.

        Args:
          request: The werkzeug.Request object.

        Returns:
          A response that contains a JSON object. The keys of the object
          are all the runs. Each run is mapped to a (potentially empty)
          list of all tags that are relevant to this plugin.
        """
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        all_runs = self._data_provider.list_tensors(
            ctx,
            experiment_id=experiment,
            plugin_name=metadata.PLUGIN_NAME,
        )

        # tagToContent is itself a dictionary mapping tag name to string
        # SummaryMetadata.plugin_data.content. Retrieve the keys of that dictionary
        # to obtain a list of tags associated with each run. For each tag estimate
        # number of samples.
        response = dict()
        for run, tags in all_runs.items():
            response[run] = dict()
            for instance_tag in tags:
                # Make sure we only operate on user-defined tags here.
                tag = self._tag(ctx, experiment, run, instance_tag)
                meta = self._instance_tag_metadata(ctx, experiment, run,
                                                   instance_tag)
                # Batch size must be defined, otherwise we don't know how many
                # samples were there.
                response[run][tag] = {"samples": meta.shape[0]}
        return http_util.Respond(request, response, "application/json")
Exemple #12
0
 def scalars_route(self, request):
     """Given a tag and single run, return array of ScalarEvents."""
     tag = request.args.get("tag")
     run = request.args.get("run")
     ctx = plugin_util.context(request.environ)
     experiment = plugin_util.experiment_id(request.environ)
     body = self.scalars_impl(ctx, experiment, tag, run)
     return http_util.Respond(request, body, "application/json")
 def _foo_handler(self, request):
     ctx = plugin_util.context(request.environ)
     header_auth = ctx.auth.get(HeaderAuthProvider)
     if header_auth is None:
         response = "hello world"
     else:
         response = "%s access granted" % (header_auth,)
     return wrappers.Response(response=response, status=200)
 def auth_check_app(environ, start_response):
     request = wrappers.Request(environ)
     if request.path != "/auth_check":
         return app(environ, start_response)
     ctx = plugin_util.context(environ)
     header_auth = ctx.auth.get(HeaderAuthProvider)
     rapp = wrappers.Response(response=header_auth, status=200)
     return rapp(environ, start_response)
Exemple #15
0
 def text_route(self, request):
     ctx = plugin_util.context(request.environ)
     experiment = plugin_util.experiment_id(request.environ)
     run = request.args.get("run")
     tag = request.args.get("tag")
     markdown_arg = request.args.get("markdown")
     enable_markdown = markdown_arg != "false"  # Default to enabled.
     response = self.text_impl(ctx, run, tag, experiment, enable_markdown)
     return http_util.Respond(request, response, "application/json")
    def _serve_image_data(self, request):
        """Serves an individual image."""
        ctx = plugin_util.context(request.environ)
        blob_key = request.args["imageId"]
        if not blob_key:
            raise errors.InvalidArgumentError("Missing 'imageId' field")

        (data, content_type) = self._image_data_impl(ctx, blob_key)
        return http_util.Respond(request, data, content_type)
Exemple #17
0
    def graph_route(self, request):
        """Given a single run, return the graph definition in protobuf
        format."""
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        run = request.args.get("run")
        tag = request.args.get("tag")
        conceptual_arg = request.args.get("conceptual", False)
        is_conceptual = True if conceptual_arg == "true" else False

        if run is None:
            return http_util.Respond(request,
                                     'query parameter "run" is required',
                                     "text/plain", 400)

        limit_attr_size = request.args.get("limit_attr_size", None)
        if limit_attr_size is not None:
            try:
                limit_attr_size = int(limit_attr_size)
            except ValueError:
                return http_util.Respond(
                    request,
                    "query parameter `limit_attr_size` must be an integer",
                    "text/plain",
                    400,
                )

        large_attrs_key = request.args.get("large_attrs_key", None)

        try:
            result = self.graph_impl(
                ctx,
                run,
                tag,
                is_conceptual,
                experiment,
                limit_attr_size,
                large_attrs_key,
            )
        except ValueError as e:
            return http_util.Respond(request,
                                     e.message,
                                     "text/plain",
                                     code=400)
        else:
            if result is not None:
                (
                    body,
                    mime_type,
                ) = result  # pylint: disable=unpacking-non-sequence
                return http_util.Respond(request, body, mime_type)
            else:
                return http_util.Respond(request,
                                         "404 Not Found",
                                         "text/plain",
                                         code=404)
Exemple #18
0
 def scalars_route(self, request):
     """Given a tag and single run, return array of ScalarEvents."""
     tag = request.args.get("tag")
     run = request.args.get("run")
     ctx = plugin_util.context(request.environ)
     experiment = plugin_util.experiment_id(request.environ)
     output_format = request.args.get("format")
     (body, mime_type) = self.scalars_impl(ctx, tag, run, experiment,
                                           output_format)
     return http_util.Respond(request, body, mime_type)
 def histograms_route(self, request):
     """Given a tag and single run, return array of histogram values."""
     ctx = plugin_util.context(request.environ)
     experiment = plugin_util.experiment_id(request.environ)
     tag = request.args.get("tag")
     run = request.args.get("run")
     (body, mime_type) = self.histograms_impl(
         ctx, tag, run, experiment=experiment, downsample_to=self.SAMPLE_SIZE
     )
     return http_util.Respond(request, body, mime_type)
Exemple #20
0
 def _serve_individual_audio(self, request):
     """Serve encoded audio data."""
     ctx = plugin_util.context(request.environ)
     experiment = plugin_util.experiment_id(request.environ)
     mime_type = request.args["content_type"]
     if mime_type not in _ALLOWED_MIME_TYPES:
         raise errors.InvalidArgumentError("Illegal mime type %r" %
                                           mime_type)
     blob_key = request.args["blob_key"]
     data = self._data_provider.read_blob(ctx, blob_key=blob_key)
     return http_util.Respond(request, data, mime_type)
 def distributions_route(self, request):
     """Given a tag and single run, return an array of compressed
     histograms."""
     ctx = plugin_util.context(request.environ)
     experiment = plugin_util.experiment_id(request.environ)
     tag = request.args.get("tag")
     run = request.args.get("run")
     (body, mime_type) = self.distributions_impl(ctx,
                                                 tag,
                                                 run,
                                                 experiment=experiment)
     return http_util.Respond(request, body, mime_type)
Exemple #22
0
    def _serve_time_series(self, request):
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        series_requests_string = request.form.get("requests")
        if not series_requests_string:
            raise errors.InvalidArgumentError("Missing 'requests' field")
        try:
            series_requests = json.loads(series_requests_string)
        except ValueError:
            raise errors.InvalidArgumentError(
                "Unable to parse 'requests' as JSON")

        response = self._time_series_impl(ctx, experiment, series_requests)
        return http_util.Respond(request, response, "application/json")
Exemple #23
0
    def _serve_tags(self, request):
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)

        mapping = self.data_provider.list_tensors(
            ctx, experiment_id=experiment, plugin_name=metadata.PLUGIN_NAME)

        result = {run: {} for run in mapping}
        for (run, tag_to_timeseries) in mapping.items():
            for (tag, timeseries) in tag_to_timeseries.items():
                result[run][tag] = {
                    "description": timeseries.description,
                }
        contents = json.dumps(result, sort_keys=True)
        return werkzeug.Response(contents, content_type="application/json")
Exemple #24
0
    def scalars_route(self, request):
        """Given a tag and single run, return array of ScalarEvents."""
        tag = request.args.get("tag")
        run = request.args.get("run")
        if tag is None or run is None:
            raise errors.InvalidArgumentError(
                "Both run and tag must be specified: tag=%r, run=%r" %
                (tag, run))

        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        output_format = request.args.get("format")
        (body, mime_type) = self.scalars_impl(ctx, tag, run, experiment,
                                              output_format)
        return http_util.Respond(request, body, mime_type)
Exemple #25
0
 def run_metadata_route(self, request):
     """Given a tag and a run, return the session.run() metadata."""
     ctx = plugin_util.context(request.environ)
     experiment = plugin_util.experiment_id(request.environ)
     tag = request.args.get("tag")
     run = request.args.get("run")
     if tag is None:
         return http_util.Respond(request,
                                  'query parameter "tag" is required',
                                  "text/plain", 400)
     if run is None:
         return http_util.Respond(request,
                                  'query parameter "run" is required',
                                  "text/plain", 400)
     (body, mime_type) = self.run_metadata_impl(ctx, experiment, run, tag)
     return http_util.Respond(request, body, mime_type)
Exemple #26
0
    def scalars_multirun_route(self, request):
        """Given a tag and list of runs, return dict of ScalarEvent arrays."""
        if request.method != "POST":
            raise werkzeug.exceptions.MethodNotAllowed(["POST"])
        tags = request.form.getlist("tag")
        runs = request.form.getlist("runs")
        if len(tags) != 1:
            raise errors.InvalidArgumentError(
                "tag must be specified exactly once")
        tag = tags[0]

        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        (body, mime_type) = self.scalars_multirun_impl(ctx, tag, runs,
                                                       experiment)
        return http_util.Respond(request, body, mime_type)
Exemple #27
0
    def _serve_tags(self, request):
        """Serves run to tag info.

        Frontend clients can use the Multiplexer's run+tag structure to request data
        for a specific run+tag. Responds with a map of the form:
        {runName: [tagName, tagName, ...]}
        """
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        run_tag_mapping = self._data_provider.list_scalars(
            ctx,
            experiment_id=experiment,
            plugin_name=metadata.PLUGIN_NAME,
        )
        run_info = {run: list(tags) for (run, tags) in run_tag_mapping.items()}

        return http_util.Respond(request, run_info, "application/json")
Exemple #28
0
    def layout_route(self, request):
        """Fetches the custom layout specified by the config file in the logdir.

        If more than 1 run contains a layout, this method merges the layouts by
        merging charts within individual categories. If 2 categories with the same
        name are found, the charts within are merged. The merging is based on the
        order of the runs to which the layouts are written.

        The response is a JSON object mirroring properties of the Layout proto if a
        layout for any run is found.

        The response is an empty object if no layout could be found.
        """
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        body = self.layout_impl(ctx, experiment)
        return http_util.Respond(request, body, "application/json")
Exemple #29
0
 def download_data_route(self, request):
     ctx = plugin_util.context(request.environ)
     run = request.args.get("run")
     tag = request.args.get("tag")
     experiment = plugin_util.experiment_id(request.environ)
     response_format = request.args.get("format")
     try:
         body, mime_type = self.download_data_impl(ctx, run, tag,
                                                   experiment,
                                                   response_format)
     except ValueError as e:
         return http_util.Respond(
             request=request,
             content=str(e),
             content_type="text/plain",
             code=400,
         )
     return http_util.Respond(request, body, mime_type)
Exemple #30
0
    def _serve_runs(self, request):
        """Serve a JSON array of run names, ordered by run started time.

        Sort order is by started time (aka first event time) with empty
        times sorted last, and then ties are broken by sorting on the
        run name.
        """
        ctx = plugin_util.context(request.environ)
        experiment = plugin_util.experiment_id(request.environ)
        runs = sorted(
            self._data_provider.list_runs(ctx, experiment_id=experiment),
            key=lambda run: (
                run.start_time if run.start_time is not None else float("inf"),
                run.run_name,
            ),
        )
        run_names = [run.run_name for run in runs]
        return http_util.Respond(request, run_names, "application/json")