tensorbored 2.21.0rc1769983804__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. tensorbored/__init__.py +112 -0
  2. tensorbored/_vendor/__init__.py +0 -0
  3. tensorbored/_vendor/bleach/__init__.py +125 -0
  4. tensorbored/_vendor/bleach/_vendor/__init__.py +0 -0
  5. tensorbored/_vendor/bleach/_vendor/html5lib/__init__.py +35 -0
  6. tensorbored/_vendor/bleach/_vendor/html5lib/_ihatexml.py +289 -0
  7. tensorbored/_vendor/bleach/_vendor/html5lib/_inputstream.py +918 -0
  8. tensorbored/_vendor/bleach/_vendor/html5lib/_tokenizer.py +1735 -0
  9. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/__init__.py +5 -0
  10. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/_base.py +40 -0
  11. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/py.py +67 -0
  12. tensorbored/_vendor/bleach/_vendor/html5lib/_utils.py +159 -0
  13. tensorbored/_vendor/bleach/_vendor/html5lib/constants.py +2946 -0
  14. tensorbored/_vendor/bleach/_vendor/html5lib/filters/__init__.py +0 -0
  15. tensorbored/_vendor/bleach/_vendor/html5lib/filters/alphabeticalattributes.py +29 -0
  16. tensorbored/_vendor/bleach/_vendor/html5lib/filters/base.py +12 -0
  17. tensorbored/_vendor/bleach/_vendor/html5lib/filters/inject_meta_charset.py +73 -0
  18. tensorbored/_vendor/bleach/_vendor/html5lib/filters/lint.py +93 -0
  19. tensorbored/_vendor/bleach/_vendor/html5lib/filters/optionaltags.py +207 -0
  20. tensorbored/_vendor/bleach/_vendor/html5lib/filters/sanitizer.py +916 -0
  21. tensorbored/_vendor/bleach/_vendor/html5lib/filters/whitespace.py +38 -0
  22. tensorbored/_vendor/bleach/_vendor/html5lib/html5parser.py +2795 -0
  23. tensorbored/_vendor/bleach/_vendor/html5lib/serializer.py +409 -0
  24. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/__init__.py +30 -0
  25. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/genshi.py +54 -0
  26. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/sax.py +50 -0
  27. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/__init__.py +88 -0
  28. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/base.py +417 -0
  29. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/dom.py +239 -0
  30. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/etree.py +343 -0
  31. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/etree_lxml.py +392 -0
  32. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/__init__.py +154 -0
  33. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/base.py +252 -0
  34. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/dom.py +43 -0
  35. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/etree.py +131 -0
  36. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/etree_lxml.py +215 -0
  37. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/genshi.py +69 -0
  38. tensorbored/_vendor/bleach/_vendor/parse.py +1078 -0
  39. tensorbored/_vendor/bleach/callbacks.py +32 -0
  40. tensorbored/_vendor/bleach/html5lib_shim.py +757 -0
  41. tensorbored/_vendor/bleach/linkifier.py +633 -0
  42. tensorbored/_vendor/bleach/parse_shim.py +1 -0
  43. tensorbored/_vendor/bleach/sanitizer.py +638 -0
  44. tensorbored/_vendor/bleach/six_shim.py +19 -0
  45. tensorbored/_vendor/webencodings/__init__.py +342 -0
  46. tensorbored/_vendor/webencodings/labels.py +231 -0
  47. tensorbored/_vendor/webencodings/mklabels.py +59 -0
  48. tensorbored/_vendor/webencodings/x_user_defined.py +325 -0
  49. tensorbored/assets.py +36 -0
  50. tensorbored/auth.py +102 -0
  51. tensorbored/backend/__init__.py +0 -0
  52. tensorbored/backend/application.py +604 -0
  53. tensorbored/backend/auth_context_middleware.py +38 -0
  54. tensorbored/backend/client_feature_flags.py +113 -0
  55. tensorbored/backend/empty_path_redirect.py +46 -0
  56. tensorbored/backend/event_processing/__init__.py +0 -0
  57. tensorbored/backend/event_processing/data_ingester.py +276 -0
  58. tensorbored/backend/event_processing/data_provider.py +535 -0
  59. tensorbored/backend/event_processing/directory_loader.py +142 -0
  60. tensorbored/backend/event_processing/directory_watcher.py +272 -0
  61. tensorbored/backend/event_processing/event_accumulator.py +950 -0
  62. tensorbored/backend/event_processing/event_file_inspector.py +463 -0
  63. tensorbored/backend/event_processing/event_file_loader.py +292 -0
  64. tensorbored/backend/event_processing/event_multiplexer.py +521 -0
  65. tensorbored/backend/event_processing/event_util.py +68 -0
  66. tensorbored/backend/event_processing/io_wrapper.py +223 -0
  67. tensorbored/backend/event_processing/plugin_asset_util.py +104 -0
  68. tensorbored/backend/event_processing/plugin_event_accumulator.py +721 -0
  69. tensorbored/backend/event_processing/plugin_event_multiplexer.py +522 -0
  70. tensorbored/backend/event_processing/reservoir.py +266 -0
  71. tensorbored/backend/event_processing/tag_types.py +29 -0
  72. tensorbored/backend/experiment_id.py +71 -0
  73. tensorbored/backend/experimental_plugin.py +51 -0
  74. tensorbored/backend/http_util.py +263 -0
  75. tensorbored/backend/json_util.py +70 -0
  76. tensorbored/backend/path_prefix.py +67 -0
  77. tensorbored/backend/process_graph.py +74 -0
  78. tensorbored/backend/security_validator.py +202 -0
  79. tensorbored/compat/__init__.py +69 -0
  80. tensorbored/compat/proto/__init__.py +0 -0
  81. tensorbored/compat/proto/allocation_description_pb2.py +35 -0
  82. tensorbored/compat/proto/api_def_pb2.py +82 -0
  83. tensorbored/compat/proto/attr_value_pb2.py +80 -0
  84. tensorbored/compat/proto/cluster_pb2.py +58 -0
  85. tensorbored/compat/proto/config_pb2.py +271 -0
  86. tensorbored/compat/proto/coordination_config_pb2.py +45 -0
  87. tensorbored/compat/proto/cost_graph_pb2.py +87 -0
  88. tensorbored/compat/proto/cpp_shape_inference_pb2.py +70 -0
  89. tensorbored/compat/proto/debug_pb2.py +65 -0
  90. tensorbored/compat/proto/event_pb2.py +149 -0
  91. tensorbored/compat/proto/full_type_pb2.py +74 -0
  92. tensorbored/compat/proto/function_pb2.py +157 -0
  93. tensorbored/compat/proto/graph_debug_info_pb2.py +111 -0
  94. tensorbored/compat/proto/graph_pb2.py +41 -0
  95. tensorbored/compat/proto/histogram_pb2.py +39 -0
  96. tensorbored/compat/proto/meta_graph_pb2.py +254 -0
  97. tensorbored/compat/proto/node_def_pb2.py +61 -0
  98. tensorbored/compat/proto/op_def_pb2.py +81 -0
  99. tensorbored/compat/proto/resource_handle_pb2.py +48 -0
  100. tensorbored/compat/proto/rewriter_config_pb2.py +93 -0
  101. tensorbored/compat/proto/rpc_options_pb2.py +35 -0
  102. tensorbored/compat/proto/saved_object_graph_pb2.py +193 -0
  103. tensorbored/compat/proto/saver_pb2.py +38 -0
  104. tensorbored/compat/proto/step_stats_pb2.py +116 -0
  105. tensorbored/compat/proto/struct_pb2.py +144 -0
  106. tensorbored/compat/proto/summary_pb2.py +111 -0
  107. tensorbored/compat/proto/tensor_description_pb2.py +38 -0
  108. tensorbored/compat/proto/tensor_pb2.py +68 -0
  109. tensorbored/compat/proto/tensor_shape_pb2.py +46 -0
  110. tensorbored/compat/proto/tfprof_log_pb2.py +307 -0
  111. tensorbored/compat/proto/trackable_object_graph_pb2.py +90 -0
  112. tensorbored/compat/proto/types_pb2.py +105 -0
  113. tensorbored/compat/proto/variable_pb2.py +62 -0
  114. tensorbored/compat/proto/verifier_config_pb2.py +38 -0
  115. tensorbored/compat/proto/versions_pb2.py +35 -0
  116. tensorbored/compat/tensorflow_stub/__init__.py +38 -0
  117. tensorbored/compat/tensorflow_stub/app.py +124 -0
  118. tensorbored/compat/tensorflow_stub/compat/__init__.py +131 -0
  119. tensorbored/compat/tensorflow_stub/compat/v1/__init__.py +20 -0
  120. tensorbored/compat/tensorflow_stub/dtypes.py +692 -0
  121. tensorbored/compat/tensorflow_stub/error_codes.py +169 -0
  122. tensorbored/compat/tensorflow_stub/errors.py +507 -0
  123. tensorbored/compat/tensorflow_stub/flags.py +124 -0
  124. tensorbored/compat/tensorflow_stub/io/__init__.py +17 -0
  125. tensorbored/compat/tensorflow_stub/io/gfile.py +1011 -0
  126. tensorbored/compat/tensorflow_stub/pywrap_tensorflow.py +285 -0
  127. tensorbored/compat/tensorflow_stub/tensor_shape.py +1035 -0
  128. tensorbored/context.py +129 -0
  129. tensorbored/data/__init__.py +0 -0
  130. tensorbored/data/grpc_provider.py +365 -0
  131. tensorbored/data/ingester.py +46 -0
  132. tensorbored/data/proto/__init__.py +0 -0
  133. tensorbored/data/proto/data_provider_pb2.py +517 -0
  134. tensorbored/data/proto/data_provider_pb2_grpc.py +374 -0
  135. tensorbored/data/provider.py +1365 -0
  136. tensorbored/data/server_ingester.py +301 -0
  137. tensorbored/data_compat.py +159 -0
  138. tensorbored/dataclass_compat.py +224 -0
  139. tensorbored/default.py +124 -0
  140. tensorbored/errors.py +130 -0
  141. tensorbored/lazy.py +99 -0
  142. tensorbored/main.py +48 -0
  143. tensorbored/main_lib.py +62 -0
  144. tensorbored/manager.py +487 -0
  145. tensorbored/notebook.py +441 -0
  146. tensorbored/plugin_util.py +266 -0
  147. tensorbored/plugins/__init__.py +0 -0
  148. tensorbored/plugins/audio/__init__.py +0 -0
  149. tensorbored/plugins/audio/audio_plugin.py +229 -0
  150. tensorbored/plugins/audio/metadata.py +69 -0
  151. tensorbored/plugins/audio/plugin_data_pb2.py +37 -0
  152. tensorbored/plugins/audio/summary.py +230 -0
  153. tensorbored/plugins/audio/summary_v2.py +124 -0
  154. tensorbored/plugins/base_plugin.py +367 -0
  155. tensorbored/plugins/core/__init__.py +0 -0
  156. tensorbored/plugins/core/core_plugin.py +981 -0
  157. tensorbored/plugins/custom_scalar/__init__.py +0 -0
  158. tensorbored/plugins/custom_scalar/custom_scalars_plugin.py +320 -0
  159. tensorbored/plugins/custom_scalar/layout_pb2.py +85 -0
  160. tensorbored/plugins/custom_scalar/metadata.py +35 -0
  161. tensorbored/plugins/custom_scalar/summary.py +79 -0
  162. tensorbored/plugins/debugger_v2/__init__.py +0 -0
  163. tensorbored/plugins/debugger_v2/debug_data_multiplexer.py +631 -0
  164. tensorbored/plugins/debugger_v2/debug_data_provider.py +634 -0
  165. tensorbored/plugins/debugger_v2/debugger_v2_plugin.py +504 -0
  166. tensorbored/plugins/distribution/__init__.py +0 -0
  167. tensorbored/plugins/distribution/compressor.py +158 -0
  168. tensorbored/plugins/distribution/distributions_plugin.py +116 -0
  169. tensorbored/plugins/distribution/metadata.py +19 -0
  170. tensorbored/plugins/graph/__init__.py +0 -0
  171. tensorbored/plugins/graph/graph_util.py +129 -0
  172. tensorbored/plugins/graph/graphs_plugin.py +336 -0
  173. tensorbored/plugins/graph/keras_util.py +328 -0
  174. tensorbored/plugins/graph/metadata.py +42 -0
  175. tensorbored/plugins/histogram/__init__.py +0 -0
  176. tensorbored/plugins/histogram/histograms_plugin.py +144 -0
  177. tensorbored/plugins/histogram/metadata.py +63 -0
  178. tensorbored/plugins/histogram/plugin_data_pb2.py +34 -0
  179. tensorbored/plugins/histogram/summary.py +234 -0
  180. tensorbored/plugins/histogram/summary_v2.py +292 -0
  181. tensorbored/plugins/hparams/__init__.py +14 -0
  182. tensorbored/plugins/hparams/_keras.py +93 -0
  183. tensorbored/plugins/hparams/api.py +130 -0
  184. tensorbored/plugins/hparams/api_pb2.py +208 -0
  185. tensorbored/plugins/hparams/backend_context.py +606 -0
  186. tensorbored/plugins/hparams/download_data.py +158 -0
  187. tensorbored/plugins/hparams/error.py +26 -0
  188. tensorbored/plugins/hparams/get_experiment.py +71 -0
  189. tensorbored/plugins/hparams/hparams_plugin.py +206 -0
  190. tensorbored/plugins/hparams/hparams_util_pb2.py +69 -0
  191. tensorbored/plugins/hparams/json_format_compat.py +38 -0
  192. tensorbored/plugins/hparams/list_metric_evals.py +57 -0
  193. tensorbored/plugins/hparams/list_session_groups.py +1040 -0
  194. tensorbored/plugins/hparams/metadata.py +125 -0
  195. tensorbored/plugins/hparams/metrics.py +41 -0
  196. tensorbored/plugins/hparams/plugin_data_pb2.py +69 -0
  197. tensorbored/plugins/hparams/summary.py +205 -0
  198. tensorbored/plugins/hparams/summary_v2.py +597 -0
  199. tensorbored/plugins/image/__init__.py +0 -0
  200. tensorbored/plugins/image/images_plugin.py +232 -0
  201. tensorbored/plugins/image/metadata.py +65 -0
  202. tensorbored/plugins/image/plugin_data_pb2.py +34 -0
  203. tensorbored/plugins/image/summary.py +159 -0
  204. tensorbored/plugins/image/summary_v2.py +130 -0
  205. tensorbored/plugins/mesh/__init__.py +14 -0
  206. tensorbored/plugins/mesh/mesh_plugin.py +292 -0
  207. tensorbored/plugins/mesh/metadata.py +152 -0
  208. tensorbored/plugins/mesh/plugin_data_pb2.py +37 -0
  209. tensorbored/plugins/mesh/summary.py +251 -0
  210. tensorbored/plugins/mesh/summary_v2.py +214 -0
  211. tensorbored/plugins/metrics/__init__.py +0 -0
  212. tensorbored/plugins/metrics/metadata.py +17 -0
  213. tensorbored/plugins/metrics/metrics_plugin.py +623 -0
  214. tensorbored/plugins/pr_curve/__init__.py +0 -0
  215. tensorbored/plugins/pr_curve/metadata.py +75 -0
  216. tensorbored/plugins/pr_curve/plugin_data_pb2.py +34 -0
  217. tensorbored/plugins/pr_curve/pr_curves_plugin.py +241 -0
  218. tensorbored/plugins/pr_curve/summary.py +574 -0
  219. tensorbored/plugins/profile_redirect/__init__.py +0 -0
  220. tensorbored/plugins/profile_redirect/profile_redirect_plugin.py +49 -0
  221. tensorbored/plugins/projector/__init__.py +67 -0
  222. tensorbored/plugins/projector/metadata.py +26 -0
  223. tensorbored/plugins/projector/projector_config_pb2.py +54 -0
  224. tensorbored/plugins/projector/projector_plugin.py +795 -0
  225. tensorbored/plugins/projector/tf_projector_plugin/index.js +32 -0
  226. tensorbored/plugins/projector/tf_projector_plugin/projector_binary.html +524 -0
  227. tensorbored/plugins/projector/tf_projector_plugin/projector_binary.js +15536 -0
  228. tensorbored/plugins/scalar/__init__.py +0 -0
  229. tensorbored/plugins/scalar/metadata.py +60 -0
  230. tensorbored/plugins/scalar/plugin_data_pb2.py +34 -0
  231. tensorbored/plugins/scalar/scalars_plugin.py +181 -0
  232. tensorbored/plugins/scalar/summary.py +109 -0
  233. tensorbored/plugins/scalar/summary_v2.py +124 -0
  234. tensorbored/plugins/text/__init__.py +0 -0
  235. tensorbored/plugins/text/metadata.py +62 -0
  236. tensorbored/plugins/text/plugin_data_pb2.py +34 -0
  237. tensorbored/plugins/text/summary.py +114 -0
  238. tensorbored/plugins/text/summary_v2.py +124 -0
  239. tensorbored/plugins/text/text_plugin.py +288 -0
  240. tensorbored/plugins/wit_redirect/__init__.py +0 -0
  241. tensorbored/plugins/wit_redirect/wit_redirect_plugin.py +49 -0
  242. tensorbored/program.py +910 -0
  243. tensorbored/summary/__init__.py +35 -0
  244. tensorbored/summary/_output.py +124 -0
  245. tensorbored/summary/_tf/__init__.py +14 -0
  246. tensorbored/summary/_tf/summary/__init__.py +178 -0
  247. tensorbored/summary/_writer.py +105 -0
  248. tensorbored/summary/v1.py +51 -0
  249. tensorbored/summary/v2.py +25 -0
  250. tensorbored/summary/writer/__init__.py +13 -0
  251. tensorbored/summary/writer/event_file_writer.py +291 -0
  252. tensorbored/summary/writer/record_writer.py +50 -0
  253. tensorbored/util/__init__.py +0 -0
  254. tensorbored/util/encoder.py +116 -0
  255. tensorbored/util/grpc_util.py +311 -0
  256. tensorbored/util/img_mime_type_detector.py +40 -0
  257. tensorbored/util/io_util.py +20 -0
  258. tensorbored/util/lazy_tensor_creator.py +110 -0
  259. tensorbored/util/op_evaluator.py +104 -0
  260. tensorbored/util/platform_util.py +20 -0
  261. tensorbored/util/tb_logging.py +24 -0
  262. tensorbored/util/tensor_util.py +617 -0
  263. tensorbored/util/timing.py +122 -0
  264. tensorbored/version.py +21 -0
  265. tensorbored/webfiles.zip +0 -0
  266. tensorbored-2.21.0rc1769983804.dist-info/METADATA +49 -0
  267. tensorbored-2.21.0rc1769983804.dist-info/RECORD +271 -0
  268. tensorbored-2.21.0rc1769983804.dist-info/WHEEL +5 -0
  269. tensorbored-2.21.0rc1769983804.dist-info/entry_points.txt +6 -0
  270. tensorbored-2.21.0rc1769983804.dist-info/licenses/LICENSE +739 -0
  271. tensorbored-2.21.0rc1769983804.dist-info/top_level.txt +1 -0
File without changes
@@ -0,0 +1,320 @@
1
+ # Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """The TensorBoard Custom Scalars plugin.
16
+
17
+ This plugin lets the user create scalars plots with custom run-tag combinations
18
+ by specifying regular expressions.
19
+
20
+ See `http_api.md` in this directory for specifications of the routes for
21
+ this plugin.
22
+ """
23
+
24
+ import re
25
+
26
+ from werkzeug import wrappers
27
+
28
+ from tensorbored import plugin_util
29
+ from tensorbored.backend import http_util
30
+ from tensorbored.compat import tf
31
+ from tensorbored.data import provider
32
+ from tensorbored.plugins import base_plugin
33
+ from tensorbored.plugins.custom_scalar import layout_pb2
34
+ from tensorbored.plugins.custom_scalar import metadata
35
+ from tensorbored.plugins.scalar import metadata as scalars_metadata
36
+ from tensorbored.plugins.scalar import scalars_plugin
37
+
38
+ # The name of the property in the response for whether the regex is valid.
39
+ _REGEX_VALID_PROPERTY = "regex_valid"
40
+
41
+ # The name of the property in the response for the payload (tag to ScalarEvents
42
+ # mapping).
43
+ _TAG_TO_EVENTS_PROPERTY = "tag_to_events"
44
+
45
+ # The number of seconds to wait in between checks for the config file specifying
46
+ # layout.
47
+ _CONFIG_FILE_CHECK_THROTTLE = 60
48
+
49
+
50
+ class CustomScalarsPlugin(base_plugin.TBPlugin):
51
+ """CustomScalars Plugin for TensorBoard."""
52
+
53
+ plugin_name = metadata.PLUGIN_NAME
54
+
55
+ def __init__(self, context):
56
+ """Instantiates ScalarsPlugin via TensorBoard core.
57
+
58
+ Args:
59
+ context: A base_plugin.TBContext instance.
60
+ """
61
+ self._logdir = context.logdir
62
+ self._data_provider = context.data_provider
63
+ self._plugin_name_to_instance = context.plugin_name_to_instance
64
+
65
+ def _get_scalars_plugin(self):
66
+ """Tries to get the scalars plugin.
67
+
68
+ Returns:
69
+ The scalars plugin. Or None if it is not yet registered.
70
+ """
71
+ if scalars_metadata.PLUGIN_NAME in self._plugin_name_to_instance:
72
+ # The plugin is registered.
73
+ return self._plugin_name_to_instance[scalars_metadata.PLUGIN_NAME]
74
+ # The plugin is not yet registered.
75
+ return None
76
+
77
+ def get_plugin_apps(self):
78
+ return {
79
+ "/download_data": self.download_data_route,
80
+ "/layout": self.layout_route,
81
+ "/scalars": self.scalars_route,
82
+ }
83
+
84
+ def is_active(self):
85
+ """Plugin is active if there is a custom layout for the dashboard."""
86
+ return False # `list_plugins` as called by TB core suffices
87
+
88
+ def frontend_metadata(self):
89
+ return base_plugin.FrontendMetadata(
90
+ element_name="tf-custom-scalar-dashboard",
91
+ tab_name="Custom Scalars",
92
+ )
93
+
94
+ @wrappers.Request.application
95
+ def download_data_route(self, request):
96
+ ctx = plugin_util.context(request.environ)
97
+ run = request.args.get("run")
98
+ tag = request.args.get("tag")
99
+ experiment = plugin_util.experiment_id(request.environ)
100
+ response_format = request.args.get("format")
101
+ try:
102
+ body, mime_type = self.download_data_impl(
103
+ ctx, run, tag, experiment, response_format
104
+ )
105
+ except ValueError as e:
106
+ return http_util.Respond(
107
+ request=request,
108
+ content=str(e),
109
+ content_type="text/plain",
110
+ code=400,
111
+ )
112
+ return http_util.Respond(request, body, mime_type)
113
+
114
+ def download_data_impl(self, ctx, run, tag, experiment, response_format):
115
+ """Provides a response for downloading scalars data for a data series.
116
+
117
+ Args:
118
+ ctx: A tensorboard.context.RequestContext value.
119
+ run: The run.
120
+ tag: The specific tag.
121
+ experiment: An experiment ID, as a possibly-empty `str`.
122
+ response_format: A string. One of the values of the OutputFormat enum
123
+ of the scalar plugin.
124
+
125
+ Raises:
126
+ ValueError: If the scalars plugin is not registered.
127
+
128
+ Returns:
129
+ 2 entities:
130
+ - A JSON object response body.
131
+ - A mime type (string) for the response.
132
+ """
133
+ scalars_plugin_instance = self._get_scalars_plugin()
134
+ if not scalars_plugin_instance:
135
+ raise ValueError(
136
+ (
137
+ "Failed to respond to request for /download_data. "
138
+ "The scalars plugin is oddly not registered."
139
+ )
140
+ )
141
+
142
+ body, mime_type = scalars_plugin_instance.scalars_impl(
143
+ ctx, tag, run, experiment, response_format
144
+ )
145
+ return body, mime_type
146
+
147
+ @wrappers.Request.application
148
+ def scalars_route(self, request):
149
+ """Given a tag regex and single run, return ScalarEvents.
150
+
151
+ This route takes 2 GET params:
152
+ run: A run string to find tags for.
153
+ tag: A string that is a regex used to find matching tags.
154
+ The response is a JSON object:
155
+ {
156
+ // Whether the regular expression is valid. Also false if empty.
157
+ regexValid: boolean,
158
+
159
+ // An object mapping tag name to a list of ScalarEvents.
160
+ payload: Object<string, ScalarEvent[]>,
161
+ }
162
+ """
163
+ ctx = plugin_util.context(request.environ)
164
+ tag_regex_string = request.args.get("tag")
165
+ run = request.args.get("run")
166
+ experiment = plugin_util.experiment_id(request.environ)
167
+ mime_type = "application/json"
168
+
169
+ try:
170
+ body = self.scalars_impl(ctx, run, tag_regex_string, experiment)
171
+ except ValueError as e:
172
+ return http_util.Respond(
173
+ request=request,
174
+ content=str(e),
175
+ content_type="text/plain",
176
+ code=400,
177
+ )
178
+
179
+ # Produce the response.
180
+ return http_util.Respond(request, body, mime_type)
181
+
182
+ def scalars_impl(self, ctx, run, tag_regex_string, experiment):
183
+ """Given a tag regex and single run, return ScalarEvents.
184
+
185
+ Args:
186
+ ctx: A tensorboard.context.RequestContext value.
187
+ run: A run string.
188
+ tag_regex_string: A regular expression that captures portions of tags.
189
+
190
+ Raises:
191
+ ValueError: if the scalars plugin is not registered.
192
+
193
+ Returns:
194
+ A dictionary that is the JSON-able response.
195
+ """
196
+ if not tag_regex_string:
197
+ # The user provided no regex.
198
+ return {
199
+ _REGEX_VALID_PROPERTY: False,
200
+ _TAG_TO_EVENTS_PROPERTY: {},
201
+ }
202
+
203
+ # Construct the regex.
204
+ try:
205
+ regex = re.compile(tag_regex_string)
206
+ except re.error:
207
+ return {
208
+ _REGEX_VALID_PROPERTY: False,
209
+ _TAG_TO_EVENTS_PROPERTY: {},
210
+ }
211
+
212
+ # Fetch the tags for the run. Filter for tags that match the regex.
213
+ run_to_data = self._data_provider.list_scalars(
214
+ ctx,
215
+ experiment_id=experiment,
216
+ plugin_name=scalars_metadata.PLUGIN_NAME,
217
+ run_tag_filter=provider.RunTagFilter(runs=[run]),
218
+ )
219
+
220
+ tag_to_data = None
221
+ try:
222
+ tag_to_data = run_to_data[run]
223
+ except KeyError:
224
+ # The run could not be found. Perhaps a configuration specified a run that
225
+ # TensorBoard has not read from disk yet.
226
+ payload = {}
227
+
228
+ if tag_to_data:
229
+ scalars_plugin_instance = self._get_scalars_plugin()
230
+ if not scalars_plugin_instance:
231
+ raise ValueError(
232
+ (
233
+ "Failed to respond to request for /scalars. "
234
+ "The scalars plugin is oddly not registered."
235
+ )
236
+ )
237
+
238
+ form = scalars_plugin.OutputFormat.JSON
239
+ payload = {
240
+ tag: scalars_plugin_instance.scalars_impl(
241
+ ctx, tag, run, experiment, form
242
+ )[0]
243
+ for tag in tag_to_data.keys()
244
+ if regex.match(tag)
245
+ }
246
+
247
+ return {
248
+ _REGEX_VALID_PROPERTY: True,
249
+ _TAG_TO_EVENTS_PROPERTY: payload,
250
+ }
251
+
252
+ @wrappers.Request.application
253
+ def layout_route(self, request):
254
+ """Fetches the custom layout specified by the config file in the logdir.
255
+
256
+ If more than 1 run contains a layout, this method merges the layouts by
257
+ merging charts within individual categories. If 2 categories with the same
258
+ name are found, the charts within are merged. The merging is based on the
259
+ order of the runs to which the layouts are written.
260
+
261
+ The response is a JSON object mirroring properties of the Layout proto if a
262
+ layout for any run is found.
263
+
264
+ The response is an empty object if no layout could be found.
265
+ """
266
+ ctx = plugin_util.context(request.environ)
267
+ experiment = plugin_util.experiment_id(request.environ)
268
+ body = self.layout_impl(ctx, experiment)
269
+ return http_util.Respond(request, body, "application/json")
270
+
271
+ def layout_impl(self, ctx, experiment):
272
+ # Keep a mapping between and category so we do not create duplicate
273
+ # categories.
274
+ title_to_category = {}
275
+
276
+ merged_layout = None
277
+ data = self._data_provider.read_tensors(
278
+ ctx,
279
+ experiment_id=experiment,
280
+ plugin_name=metadata.PLUGIN_NAME,
281
+ run_tag_filter=provider.RunTagFilter(
282
+ tags=[metadata.CONFIG_SUMMARY_TAG]
283
+ ),
284
+ downsample=1,
285
+ )
286
+ for run in sorted(data):
287
+ points = data[run][metadata.CONFIG_SUMMARY_TAG]
288
+ content = points[0].numpy.item()
289
+ layout_proto = layout_pb2.Layout()
290
+ layout_proto.ParseFromString(tf.compat.as_bytes(content))
291
+
292
+ if merged_layout:
293
+ # Append the categories within this layout to the merged layout.
294
+ for category in layout_proto.category:
295
+ if category.title in title_to_category:
296
+ # A category with this name has been seen before. Do not create a
297
+ # new one. Merge their charts, skipping any duplicates.
298
+ title_to_category[category.title].chart.extend(
299
+ [
300
+ c
301
+ for c in category.chart
302
+ if c
303
+ not in title_to_category[category.title].chart
304
+ ]
305
+ )
306
+ else:
307
+ # This category has not been seen before.
308
+ merged_layout.category.add().MergeFrom(category)
309
+ title_to_category[category.title] = category
310
+ else:
311
+ # This is the first layout encountered.
312
+ merged_layout = layout_proto
313
+ for category in layout_proto.category:
314
+ title_to_category[category.title] = category
315
+
316
+ if merged_layout:
317
+ return plugin_util.proto_to_json(merged_layout)
318
+ else:
319
+ # No layout was found.
320
+ return {}
@@ -0,0 +1,85 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: tensorbored/plugins/custom_scalar/layout.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf import descriptor as _descriptor
6
+ from google.protobuf import descriptor_pool as _descriptor_pool
7
+ from google.protobuf import message as _message
8
+ from google.protobuf import reflection as _reflection
9
+ from google.protobuf import symbol_database as _symbol_database
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+
16
+
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n.tensorbored/plugins/custom_scalar/layout.proto\x12\x0btensorbored\"\x8d\x01\n\x05\x43hart\x12\r\n\x05title\x18\x01 \x01(\t\x12\x37\n\tmultiline\x18\x02 \x01(\x0b\x32\".tensorbored.MultilineChartContentH\x00\x12\x31\n\x06margin\x18\x03 \x01(\x0b\x32\x1f.tensorbored.MarginChartContentH\x00\x42\t\n\x07\x63ontent\"$\n\x15MultilineChartContent\x12\x0b\n\x03tag\x18\x01 \x03(\t\"\x83\x01\n\x12MarginChartContent\x12\x36\n\x06series\x18\x01 \x03(\x0b\x32&.tensorbored.MarginChartContent.Series\x1a\x35\n\x06Series\x12\r\n\x05value\x18\x01 \x01(\t\x12\r\n\x05lower\x18\x02 \x01(\t\x12\r\n\x05upper\x18\x03 \x01(\t\"L\n\x08\x43\x61tegory\x12\r\n\x05title\x18\x01 \x01(\t\x12!\n\x05\x63hart\x18\x02 \x03(\x0b\x32\x12.tensorbored.Chart\x12\x0e\n\x06\x63losed\x18\x03 \x01(\x08\"B\n\x06Layout\x12\x0f\n\x07version\x18\x01 \x01(\x05\x12\'\n\x08\x63\x61tegory\x18\x02 \x03(\x0b\x32\x15.tensorbored.Categoryb\x06proto3')
18
+
19
+
20
+
21
+ _CHART = DESCRIPTOR.message_types_by_name['Chart']
22
+ _MULTILINECHARTCONTENT = DESCRIPTOR.message_types_by_name['MultilineChartContent']
23
+ _MARGINCHARTCONTENT = DESCRIPTOR.message_types_by_name['MarginChartContent']
24
+ _MARGINCHARTCONTENT_SERIES = _MARGINCHARTCONTENT.nested_types_by_name['Series']
25
+ _CATEGORY = DESCRIPTOR.message_types_by_name['Category']
26
+ _LAYOUT = DESCRIPTOR.message_types_by_name['Layout']
27
+ Chart = _reflection.GeneratedProtocolMessageType('Chart', (_message.Message,), {
28
+ 'DESCRIPTOR' : _CHART,
29
+ '__module__' : 'tensorbored.plugins.custom_scalar.layout_pb2'
30
+ # @@protoc_insertion_point(class_scope:tensorbored.Chart)
31
+ })
32
+ _sym_db.RegisterMessage(Chart)
33
+
34
+ MultilineChartContent = _reflection.GeneratedProtocolMessageType('MultilineChartContent', (_message.Message,), {
35
+ 'DESCRIPTOR' : _MULTILINECHARTCONTENT,
36
+ '__module__' : 'tensorbored.plugins.custom_scalar.layout_pb2'
37
+ # @@protoc_insertion_point(class_scope:tensorbored.MultilineChartContent)
38
+ })
39
+ _sym_db.RegisterMessage(MultilineChartContent)
40
+
41
+ MarginChartContent = _reflection.GeneratedProtocolMessageType('MarginChartContent', (_message.Message,), {
42
+
43
+ 'Series' : _reflection.GeneratedProtocolMessageType('Series', (_message.Message,), {
44
+ 'DESCRIPTOR' : _MARGINCHARTCONTENT_SERIES,
45
+ '__module__' : 'tensorbored.plugins.custom_scalar.layout_pb2'
46
+ # @@protoc_insertion_point(class_scope:tensorbored.MarginChartContent.Series)
47
+ })
48
+ ,
49
+ 'DESCRIPTOR' : _MARGINCHARTCONTENT,
50
+ '__module__' : 'tensorbored.plugins.custom_scalar.layout_pb2'
51
+ # @@protoc_insertion_point(class_scope:tensorbored.MarginChartContent)
52
+ })
53
+ _sym_db.RegisterMessage(MarginChartContent)
54
+ _sym_db.RegisterMessage(MarginChartContent.Series)
55
+
56
+ Category = _reflection.GeneratedProtocolMessageType('Category', (_message.Message,), {
57
+ 'DESCRIPTOR' : _CATEGORY,
58
+ '__module__' : 'tensorbored.plugins.custom_scalar.layout_pb2'
59
+ # @@protoc_insertion_point(class_scope:tensorbored.Category)
60
+ })
61
+ _sym_db.RegisterMessage(Category)
62
+
63
+ Layout = _reflection.GeneratedProtocolMessageType('Layout', (_message.Message,), {
64
+ 'DESCRIPTOR' : _LAYOUT,
65
+ '__module__' : 'tensorbored.plugins.custom_scalar.layout_pb2'
66
+ # @@protoc_insertion_point(class_scope:tensorbored.Layout)
67
+ })
68
+ _sym_db.RegisterMessage(Layout)
69
+
70
+ if _descriptor._USE_C_DESCRIPTORS == False:
71
+
72
+ DESCRIPTOR._options = None
73
+ _CHART._serialized_start=64
74
+ _CHART._serialized_end=205
75
+ _MULTILINECHARTCONTENT._serialized_start=207
76
+ _MULTILINECHARTCONTENT._serialized_end=243
77
+ _MARGINCHARTCONTENT._serialized_start=246
78
+ _MARGINCHARTCONTENT._serialized_end=377
79
+ _MARGINCHARTCONTENT_SERIES._serialized_start=324
80
+ _MARGINCHARTCONTENT_SERIES._serialized_end=377
81
+ _CATEGORY._serialized_start=379
82
+ _CATEGORY._serialized_end=455
83
+ _LAYOUT._serialized_start=457
84
+ _LAYOUT._serialized_end=523
85
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,35 @@
1
+ # Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Information on the custom scalars plugin."""
16
+
17
+ from tensorbored.compat.proto import summary_pb2
18
+
19
+ # A special tag named used for the summary that stores the layout.
20
+ CONFIG_SUMMARY_TAG = "custom_scalars__config__"
21
+
22
+ PLUGIN_NAME = "custom_scalars"
23
+
24
+
25
+ def create_summary_metadata():
26
+ """Create a `SummaryMetadata` proto for custom scalar plugin data.
27
+
28
+ Returns:
29
+ A `summary_pb2.SummaryMetadata` protobuf object.
30
+ """
31
+ return summary_pb2.SummaryMetadata(
32
+ plugin_data=summary_pb2.SummaryMetadata.PluginData(
33
+ plugin_name=PLUGIN_NAME
34
+ )
35
+ )
@@ -0,0 +1,79 @@
1
+ # Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ # ==============================================================================
15
+ """Contains summaries related to laying out the custom scalars dashboard."""
16
+
17
+ from tensorbored.plugins.custom_scalar import layout_pb2
18
+ from tensorbored.plugins.custom_scalar import metadata
19
+
20
+
21
+ def op(scalars_layout, collections=None):
22
+ """Creates a summary that contains a layout.
23
+
24
+ When users navigate to the custom scalars dashboard, they will see a layout
25
+ based on the proto provided to this function.
26
+
27
+ Args:
28
+ scalars_layout: The scalars_layout_pb2.Layout proto that specifies the
29
+ layout.
30
+ collections: Optional list of graph collections keys. The new
31
+ summary op is added to these collections. Defaults to
32
+ `[Graph Keys.SUMMARIES]`.
33
+
34
+ Returns:
35
+ A tensor summary op that writes the layout to disk.
36
+ """
37
+ # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
38
+ import tensorflow.compat.v1 as tf
39
+
40
+ assert isinstance(scalars_layout, layout_pb2.Layout)
41
+ summary_metadata = metadata.create_summary_metadata()
42
+ return tf.summary.tensor_summary(
43
+ name=metadata.CONFIG_SUMMARY_TAG,
44
+ tensor=tf.constant(scalars_layout.SerializeToString(), dtype=tf.string),
45
+ collections=collections,
46
+ summary_metadata=summary_metadata,
47
+ )
48
+
49
+
50
+ def pb(scalars_layout):
51
+ """Creates a summary that contains a layout.
52
+
53
+ When users navigate to the custom scalars dashboard, they will see a layout
54
+ based on the proto provided to this function.
55
+
56
+ Args:
57
+ scalars_layout: The scalars_layout_pb2.Layout proto that specifies the
58
+ layout.
59
+
60
+ Returns:
61
+ A summary proto containing the layout.
62
+ """
63
+ # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
64
+ import tensorflow.compat.v1 as tf
65
+
66
+ assert isinstance(scalars_layout, layout_pb2.Layout)
67
+ tensor = tf.make_tensor_proto(
68
+ scalars_layout.SerializeToString(), dtype=tf.string
69
+ )
70
+ tf_summary_metadata = tf.SummaryMetadata.FromString(
71
+ metadata.create_summary_metadata().SerializeToString()
72
+ )
73
+ summary = tf.Summary()
74
+ summary.value.add(
75
+ tag=metadata.CONFIG_SUMMARY_TAG,
76
+ metadata=tf_summary_metadata,
77
+ tensor=tensor,
78
+ )
79
+ return summary
File without changes