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
@@ -0,0 +1,223 @@
1
+ # Copyright 2015 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
+ """IO helper functions."""
16
+
17
+ import collections
18
+ import os
19
+ import re
20
+
21
+
22
+ from tensorbored.compat import tf
23
+ from tensorbored.util import io_util
24
+ from tensorbored.util import tb_logging
25
+
26
+ logger = tb_logging.get_logger()
27
+
28
+ _ESCAPE_GLOB_CHARACTERS_REGEX = re.compile("([*?[])")
29
+
30
+
31
+ def PathSeparator(path):
32
+ return "/" if io_util.IsCloudPath(path) else os.sep
33
+
34
+
35
+ def IsTensorFlowEventsFile(path):
36
+ """Check the path name to see if it is probably a TF Events file.
37
+
38
+ Args:
39
+ path: A file path to check if it is an event file.
40
+
41
+ Raises:
42
+ ValueError: If the path is an empty string.
43
+
44
+ Returns:
45
+ If path is formatted like a TensorFlowEventsFile. Dummy files such as
46
+ those created with the '.profile-empty' suffixes and meant to hold
47
+ no `Summary` protos are treated as true TensorFlowEventsFiles. For
48
+ background, see: https://github.com/tensorflow/tensorboard/issues/2084.
49
+ """
50
+ if not path:
51
+ raise ValueError("Path must be a nonempty string")
52
+ return "tfevents" in tf.compat.as_str_any(os.path.basename(path))
53
+
54
+
55
+ def IsSummaryEventsFile(path):
56
+ """Check whether the path is probably a TF Events file containing Summary.
57
+
58
+ Args:
59
+ path: A file path to check if it is an event file containing `Summary`
60
+ protos.
61
+
62
+ Returns:
63
+ If path is formatted like a TensorFlowEventsFile. Dummy files such as
64
+ those created with the '.profile-empty' suffixes and meant to hold
65
+ no `Summary` protos are treated as `False`. For background, see:
66
+ https://github.com/tensorflow/tensorboard/issues/2084.
67
+ """
68
+ return IsTensorFlowEventsFile(path) and not path.endswith(".profile-empty")
69
+
70
+
71
+ def ListDirectoryAbsolute(directory):
72
+ """Yields all files in the given directory.
73
+
74
+ The paths are absolute.
75
+ """
76
+ return (
77
+ os.path.join(directory, path) for path in tf.io.gfile.listdir(directory)
78
+ )
79
+
80
+
81
+ def _EscapeGlobCharacters(path):
82
+ """Escapes the glob characters in a path.
83
+
84
+ Python 3 has a glob.escape method, but python 2 lacks it, so we manually
85
+ implement this method.
86
+
87
+ Args:
88
+ path: The absolute path to escape.
89
+
90
+ Returns:
91
+ The escaped path string.
92
+ """
93
+ drive, path = os.path.splitdrive(path)
94
+ return "%s%s" % (drive, _ESCAPE_GLOB_CHARACTERS_REGEX.sub(r"[\1]", path))
95
+
96
+
97
+ def ListRecursivelyViaGlobbing(top):
98
+ """Recursively lists all files within the directory.
99
+
100
+ This method does not list subdirectories (in addition to regular files), and
101
+ the file paths are all absolute. If the directory does not exist, this yields
102
+ nothing.
103
+
104
+ This method does so by glob-ing deeper and deeper directories, ie
105
+ foo/*, foo/*/*, foo/*/*/* and so on until all files are listed. All file
106
+ paths are absolute, and this method lists subdirectories too.
107
+
108
+ For certain file systems, globbing via this method may prove significantly
109
+ faster than recursively walking a directory. Specifically, TF file systems
110
+ that implement TensorFlow's FileSystem.GetMatchingPaths method could save
111
+ costly disk reads by using this method. However, for other file systems, this
112
+ method might prove slower because the file system performs a walk per call to
113
+ glob (in which case it might as well just perform 1 walk).
114
+
115
+ Args:
116
+ top: A path to a directory.
117
+
118
+ Yields:
119
+ A (dir_path, file_paths) tuple for each directory/subdirectory.
120
+ """
121
+ current_glob_string = os.path.join(_EscapeGlobCharacters(top), "*")
122
+ level = 0
123
+
124
+ while True:
125
+ logger.info("GlobAndListFiles: Starting to glob level %d", level)
126
+ glob = tf.io.gfile.glob(current_glob_string)
127
+ logger.info(
128
+ "GlobAndListFiles: %d files glob-ed at level %d", len(glob), level
129
+ )
130
+
131
+ if not glob:
132
+ # This subdirectory level lacks files. Terminate.
133
+ return
134
+
135
+ # Map subdirectory to a list of files.
136
+ pairs = collections.defaultdict(list)
137
+ for file_path in glob:
138
+ pairs[os.path.dirname(file_path)].append(file_path)
139
+ for dir_name, file_paths in pairs.items():
140
+ yield (dir_name, tuple(file_paths))
141
+
142
+ if len(pairs) == 1:
143
+ # If at any point the glob returns files that are all in a single
144
+ # directory, replace the current globbing path with that directory as the
145
+ # literal prefix. This should improve efficiency in cases where a single
146
+ # subdir is significantly deeper than the rest of the sudirs.
147
+ current_glob_string = os.path.join(list(pairs.keys())[0], "*")
148
+
149
+ # Iterate to the next level of subdirectories.
150
+ current_glob_string = os.path.join(current_glob_string, "*")
151
+ level += 1
152
+
153
+
154
+ def ListRecursivelyViaWalking(top):
155
+ """Walks a directory tree, yielding (dir_path, file_paths) tuples.
156
+
157
+ For each of `top` and its subdirectories, yields a tuple containing the path
158
+ to the directory and the path to each of the contained files. Note that
159
+ unlike os.Walk()/tf.io.gfile.walk()/ListRecursivelyViaGlobbing, this does not
160
+ list subdirectories. The file paths are all absolute. If the directory does
161
+ not exist, this yields nothing.
162
+
163
+ Walking may be incredibly slow on certain file systems.
164
+
165
+ Args:
166
+ top: A path to a directory.
167
+
168
+ Yields:
169
+ A (dir_path, file_paths) tuple for each directory/subdirectory.
170
+ """
171
+ for dir_path, _, filenames in tf.io.gfile.walk(top, topdown=True):
172
+ yield (
173
+ dir_path,
174
+ (os.path.join(dir_path, filename) for filename in filenames),
175
+ )
176
+
177
+
178
+ def GetLogdirSubdirectories(path):
179
+ """Obtains all subdirectories with events files.
180
+
181
+ The order of the subdirectories returned is unspecified. The internal logic
182
+ that determines order varies by scenario.
183
+
184
+ Args:
185
+ path: The path to a directory under which to find subdirectories.
186
+
187
+ Returns:
188
+ A tuple of absolute paths of all subdirectories each with at least 1 events
189
+ file directly within the subdirectory.
190
+
191
+ Raises:
192
+ ValueError: If the path passed to the method exists and is not a directory.
193
+ """
194
+ if not tf.io.gfile.exists(path):
195
+ # No directory to traverse.
196
+ return ()
197
+
198
+ if not tf.io.gfile.isdir(path):
199
+ raise ValueError(
200
+ "GetLogdirSubdirectories: path exists and is not a "
201
+ "directory, %s" % path
202
+ )
203
+
204
+ if io_util.IsCloudPath(path):
205
+ # Glob-ing for files can be significantly faster than recursively
206
+ # walking through directories for some file systems.
207
+ logger.info(
208
+ "GetLogdirSubdirectories: Starting to list directories via glob-ing."
209
+ )
210
+ traversal_method = ListRecursivelyViaGlobbing
211
+ else:
212
+ # For other file systems, the glob-ing based method might be slower because
213
+ # each call to glob could involve performing a recursive walk.
214
+ logger.info(
215
+ "GetLogdirSubdirectories: Starting to list directories via walking."
216
+ )
217
+ traversal_method = ListRecursivelyViaWalking
218
+
219
+ return (
220
+ subdir
221
+ for (subdir, files) in traversal_method(path)
222
+ if any(IsTensorFlowEventsFile(f) for f in files)
223
+ )
@@ -0,0 +1,104 @@
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
+ """Load plugin assets from disk."""
16
+
17
+ import os.path
18
+
19
+ from tensorbored.compat import tf
20
+
21
+ _PLUGINS_DIR = "plugins"
22
+
23
+
24
+ def _IsDirectory(parent, item):
25
+ """Helper that returns if parent/item is a directory."""
26
+ return tf.io.gfile.isdir(os.path.join(parent, item))
27
+
28
+
29
+ def PluginDirectory(logdir, plugin_name):
30
+ """Returns the plugin directory for plugin_name."""
31
+ return os.path.join(logdir, _PLUGINS_DIR, plugin_name)
32
+
33
+
34
+ def ListPlugins(logdir):
35
+ """List all the plugins that have registered assets in logdir.
36
+
37
+ If the plugins_dir does not exist, it returns an empty list. This maintains
38
+ compatibility with old directories that have no plugins written.
39
+
40
+ Args:
41
+ logdir: A directory that was created by a TensorFlow events writer.
42
+
43
+ Returns:
44
+ a list of plugin names, as strings
45
+ """
46
+ plugins_dir = os.path.join(logdir, _PLUGINS_DIR)
47
+ try:
48
+ entries = tf.io.gfile.listdir(plugins_dir)
49
+ except tf.errors.NotFoundError:
50
+ return []
51
+ # Strip trailing slashes, which listdir() includes for some filesystems
52
+ # for subdirectories, after using them to bypass IsDirectory().
53
+ return [
54
+ x.rstrip("/")
55
+ for x in entries
56
+ if x.endswith("/") or _IsDirectory(plugins_dir, x)
57
+ ]
58
+
59
+
60
+ def ListAssets(logdir, plugin_name):
61
+ """List all the assets that are available for given plugin in a logdir.
62
+
63
+ Args:
64
+ logdir: A directory that was created by a TensorFlow summary.FileWriter.
65
+ plugin_name: A string name of a plugin to list assets for.
66
+
67
+ Returns:
68
+ A string list of available plugin assets. If the plugin subdirectory does
69
+ not exist (either because the logdir doesn't exist, or because the plugin
70
+ didn't register) an empty list is returned.
71
+ """
72
+ plugin_dir = PluginDirectory(logdir, plugin_name)
73
+ try:
74
+ # Strip trailing slashes, which listdir() includes for some filesystems.
75
+ return [x.rstrip("/") for x in tf.io.gfile.listdir(plugin_dir)]
76
+ except tf.errors.NotFoundError:
77
+ return []
78
+
79
+
80
+ def RetrieveAsset(logdir, plugin_name, asset_name):
81
+ """Retrieve a particular plugin asset from a logdir.
82
+
83
+ Args:
84
+ logdir: A directory that was created by a TensorFlow summary.FileWriter.
85
+ plugin_name: The plugin we want an asset from.
86
+ asset_name: The name of the requested asset.
87
+
88
+ Returns:
89
+ string contents of the plugin asset.
90
+
91
+ Raises:
92
+ KeyError: if the asset does not exist.
93
+ """
94
+
95
+ asset_path = os.path.join(PluginDirectory(logdir, plugin_name), asset_name)
96
+ try:
97
+ with tf.io.gfile.GFile(asset_path, "r") as f:
98
+ return f.read()
99
+ except tf.errors.NotFoundError:
100
+ raise KeyError("Asset path %s not found" % asset_path)
101
+ except tf.errors.OpError as e:
102
+ raise KeyError(
103
+ "Couldn't read asset path: %s, OpError %s" % (asset_path, e)
104
+ )