U
    Vcl                     @   s   d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddlm
Z
 ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ e ZdZddgZdZG dd dejZG dd dejZdd Zdd Zdd Z dS )z TensorBoard core plugin package.    N)utils)wrappers)plugin_util)	http_util)base_plugin)	grpc_util)
tb_logging)versioniv  ztext/javascriptzapplication/javascriptQ c                   @   s   e Zd ZdZdZd&ddZdd Zdd	 Zd
d Ze	j
jdd Ze	j
jdd Ze	j
jdd Ze	j
jdd Ze	j
jdd Zdd Ze	j
jdd Ze	j
jdd Ze	j
jdd Ze	j
jdd Zd d! Ze	j
jd"d# Ze	j
jd$d% ZdS )'
CorePluginzCore plugin for TensorBoard.

    This plugin serves runs, configuration data, and static assets. This
    plugin should always be present in a TensorBoard WSGI application.
    coreNc                 C   s`   |j | _|j r|j jnd}|jp"|| _|j| _|j r<|j jnd| _|j	| _
|j| _t|| _dS )aj  Instantiates CorePlugin.

        Args:
          context: A base_plugin.TBContext instance.
          include_debug_info: If true, `/data/environment` will include some
            basic information like the TensorBoard server version. Disabled by
            default to prevent surprising information leaks in custom builds of
            TensorBoard.
         N)flags_flagslogdir_speclogdir_logdirwindow_title_window_titlepath_prefix_path_prefixZassets_zip_provider_assets_zip_providerdata_provider_data_providerbool_include_debug_info)selfcontextinclude_debug_infor    r   H/tmp/pip-unpacked-wheel-g8kmtpbc/tensorboard/plugins/core/core_plugin.py__init__;   s    
zCorePlugin.__init__c                 C   s   dS )NTr   r   r   r   r    	is_activeN   s    zCorePlugin.is_activec                 C   sP   | j | j| j| j| j| j| j| j| j| j| j | j| j| jd}|	| 
  |S )N)z/___rPc_sWiTcH___z/audioz/data/environmentz/data/logdirz
/data/runsz/data/experimentsz/data/experiment_runsz/data/notificationsz/data/window_propertiesz/eventsz/favicon.icoz/graphsz/histogramsz/images)_send_404_without_logging_redirect_to_index_serve_environment_serve_logdir_serve_runs_serve_experiments_serve_experiment_runs_serve_notifications_serve_window_propertiesupdateget_resource_apps)r   appsr   r   r    get_plugin_appsQ   s"    zCorePlugin.get_plugin_appsc              
   C   s   i }| j s|S |   x}t|b}| D ]R}||}|dkrZt| j||d| < q,t|}t| j	||}||d| < q,W 5 Q R X W 5 Q R X |d |d< |S )Nz
index.html/z/index.html)
r   zipfileZipFilenamelistread	functoolspartial_serve_index_gzip_serve_asset)r   r/   fpZzip_pathcontentgzipped_asset_bytesZwsgi_appr   r   r    r.   e   s,    

   "zCorePlugin.get_resource_appsc                 C   s   t j|ddddS )Nz	Not foundz
text/plaini  )coder   Respondr   requestr   r   r    r$   }   s    z$CorePlugin._send_404_without_loggingc                 C   s
   t dS )Nr1   )r   redirect)r   Zunused_requestr   r   r    r%      s    zCorePlugin._redirect_to_indexc                 C   sB   t |d pd}|jdr*|tkr*tnd}tj|||d|dS )z4Serves a pre-gzipped static asset from the zip file.r   zapplication/octet-streamZ
_file_hashgzip)content_encodingexpires)	mimetypes
guess_typeargsgetJS_MIMETYPESJS_CACHE_EXPIRATION_IN_SECSr   rA   )r   r<   r>   rC   mimetyperG   r   r   r    r:      s    
zCorePlugin._serve_assetc                 C   sB   | j rt| j |jnd}d| }|d| }tj||dddS )a  Serves index.html content.

        Note that we opt out of gzipping index.html to write preamble before the
        resource content. This inflates the resource size from 2x kiB to 1xx
        kiB, but we require an ability to flush preamble with the HTML content.
        .z;<!doctype html><meta name="tb-relative-root" content="%s/">zutf-8z	text/htmlidentity)rF   )r   	posixpathrelpathZscript_rootencoder   rA   )r   Zindex_asset_bytesrC   rR   Zmeta_headerr=   r   r   r    r8      s    
   zCorePlugin._serve_indexc                 C   sr   t |j}t |j}| jj||d}tj|j| j	|j
|j|jd}| jrdt| j|  d|d< t||dS )z:Serve a JSON object describing the TensorBoard parameters.experiment_id)r	   data_locationr   experiment_nameexperiment_descriptioncreation_time)r   r   debugapplication/json)r   r   environrU   r   Zexperiment_metadatar	   VERSIONrV   r   rW   rX   rY   r   str_render_flagsr   rA   )r   rC   ctx
experimentZmdenvironmentr   r   r    r&      s,     
zCorePlugin._serve_environmentc                    s(   | j dkrdS  fdd  t| j S )zReturn a JSON-and-human-friendly version of `self._flags`.

        Like `json.loads(json.dumps(self._flags, default=str))` but
        without the wasteful serialization overhead.
        Nc                    sb   t | td tttfr| S t | ttfr: fdd| D S t | trZ fdd|  D S t| S )Nc                    s   g | ]} |qS r   r   ).0vgor   r    
<listcomp>   s     z8CorePlugin._render_flags.<locals>.go.<locals>.<listcomp>c                    s   i | ]\}}t | |qS r   )r^   )rc   krd   re   r   r    
<dictcomp>   s      z8CorePlugin._render_flags.<locals>.go.<locals>.<dictcomp>)	
isinstancetyper^   intfloatlisttupledictitems)xre   r   r    rf      s    
z$CorePlugin._render_flags.<locals>.go)r   varsr"   r   re   r    r_      s    
	zCorePlugin._render_flagsc                 C   s   t |d| jidS )z@Respond with a JSON object containing this TensorBoard's logdir.r   r[   )r   rA   r   rB   r   r   r    r'      s
      zCorePlugin._serve_logdirc                 C   s   t |d| jidS )zLServe a JSON object containing this TensorBoard's window
        properties.r   r[   )r   rA   r   rB   r   r   r    r,      s
      z#CorePlugin._serve_window_propertiesc                 C   sP   t |j}t |j}t| jj||ddd d}dd |D }t||dS )zServe 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.
        rT   c                 S   s   | j d k	r| j ntd| jfS )Ninf)
start_timerm   run_name)runr   r   r    <lambda>  s    z(CorePlugin._serve_runs.<locals>.<lambda>)keyc                 S   s   g | ]
}|j qS r   )rv   )rc   rw   r   r   r    rg     s     z*CorePlugin._serve_runs.<locals>.<listcomp>r[   )	r   r   r\   rU   sortedr   Z	list_runsr   rA   )r   rC   r`   ra   runsZ	run_namesr   r   r    r(      s    zCorePlugin._serve_runsc                 C   s   |   }t||dS )zServe a JSON array of experiments.

        Experiments are ordered by experiment started time (aka first
        event time) with empty times sorted last, and then ties are
        broken by sorting on the experiment name.
        r[   )list_experiments_implr   rA   r   rC   resultsr   r   r    r)   
  s    zCorePlugin._serve_experimentsc                 C   s   g S Nr   r"   r   r   r    r|     s    z CorePlugin.list_experiments_implc                 C   s   g }t ||dS )a  Serve a JSON runs of an experiment, specified with query param
        `experiment`, with their nested data, tag, populated.

        Runs returned are ordered by started time (aka first event time)
        with empty times sorted last, and then ties are broken by
        sorting on the run name. Tags are sorted by its name,
        displayName, and lastly, inserted time.
        r[   r@   r}   r   r   r    r*     s    
z!CorePlugin._serve_experiment_runsc                 C   s   t d}d|_|S )z6Serve JSON payload of notifications to show in the UI.z../notifications_note.jsonF)r   rD   Zautocorrect_location_header)r   rC   responser   r   r    r+   %  s    
zCorePlugin._serve_notifications)N)__name__
__module____qualname____doc__Zplugin_namer!   r#   r0   r.   r   RequestZapplicationr$   r%   r:   r8   r&   r_   r'   r,   r(   r)   r|   r*   r+   r   r   r   r    r   2   s<   






	
	



r   c                   @   s2   e Zd ZdZdddZdd Zdd Zd	d
 ZdS )CorePluginLoaderzCorePlugin factory.Nc                 C   s
   || _ d S r   )r   )r   r   r   r   r    r!   4  s    zCorePluginLoader.__init__c              	   C   s`  |j ddtddd |j ddtddd |j d	d
tddd |j dddd |j dddd ddt d |j dddd ddgddd |j dtdd dd!gd"d# |j d$tdd%d& |j d'tjtjjtj d(d# |j d)dtdd*d |j d+dd,d ddgdd-d |j d.d/tdd0d |j d1dd2d |j d3dd4d |j d5dd6d |j d7d8tdd9d |j d:dtdd;d |j d<dtdd=d |j d>d?tdd@d |j dAdBtdCdDd |j dEdFtdGdHd |j dIdJtdddKdLdMgdNdO |j dPddQd ddgddRd |j dSdFtdTdUd |j dVdJtdd dd!gdWdO |j dXt	ddYd& |j dZdd[d ddgdd\d dS )]z.Adds standard TensorBoard CLI flags to parser.z--logdirPATHr   a  Directory where TensorBoard will look to find TensorFlow event files
that it can display. TensorBoard will recursively walk the directory
structure rooted at logdir, looking for .*tfevents.* files.

A leading tilde will be expanded with the semantics of Python's
os.expanduser function.
)metavarrk   defaulthelpz--logdir_specZ	PATH_SPECa  Like `--logdir`, but with special interpretation for commas and colons:
commas separate multiple runs, where a colon specifies a new name for a
run. For example:
`tensorboard --logdir_spec=name1:/path/to/logs/1,name2:/path/to/logs/2`.

This flag is discouraged and can usually be avoided. TensorBoard walks
log directories recursively; for finer-grained control, prefer using a
symlink tree. Some features may not work when using `--logdir_spec`
instead of `--logdir`.
z--hostZADDRNzWhat host to listen to (default: localhost). To serve to the entire local
network on both IPv4 and IPv6, see `--bind_all`, with which this option is
mutually exclusive.
z
--bind_all
store_truezServe on all public interfaces. This will expose your TensorBoard instance to
the network on both IPv4 and IPv6 (where available). Mutually exclusive with
`--host`.
)actionr   z--portZPORTc                 S   s   | dkrd S t | S )Nr   )rl   )sr   r   r    rx   s      z/CorePluginLoader.define_flags.<locals>.<lambda>r   zPort to serve TensorBoard on. Pass 0 to request an unused port selected
by the operating system, or pass "default" to try to bind to the default
port (%s) but search for a nearby free port if the default port is
unavailable. (default: "default").z--reuse_portZBOOLc                 S   s   ddd |  | S NTF)truefalserK   lowerrd   r   r   r    rx     r   TFa  Enables the SO_REUSEPORT option on the socket opened by TensorBoard's HTTP
server, for platforms that support it. This is useful in cases when a parent
process has obtained the port already and wants to delegate access to the
port to TensorBoard as a subprocess.(default: %(default)s).)r   rk   choicesr   r   z--load_fastautor   r   a  Use alternate mechanism to load data. Typically 100x faster or more, but only
available on some platforms and invocations. Defaults to "auto" to use this new
mode only if available, otherwise falling back to the legacy loading path. Set
to "true" to suppress the advisory note and hard-fail if the fast codepath is
not available. Set to "false" to always fall back. Feedback/issues:
https://github.com/tensorflow/tensorboard/issues/4784
(default: %(default)s)
)rk   r   r   r   z--extra_data_server_flagszExperimental. With `--load_fast`, pass these additional command-line flags to
the data server. Subject to POSIX word splitting per `shlex.split`. Meant for
debugging; not officially supported.
)rk   r   r   z--grpc_creds_typezcExperimental. The type of credentials to use to connect to the data server.
(default: %(default)s)
z--grpc_data_providerzxExperimental. Address of a gRPC server exposing a data provider. Set to empty
string to disable. (default: %(default)s)
z--purge_orphaned_datac                 S   s   ddd |  | S r   r   r   r   r   r    rx     r   zWhether to purge data that may have been orphaned due to TensorBoard
restarts. Setting --purge_orphaned_data=False can be used to debug data
disappearance. (default: %(default)s)z--dbURIzw[experimental] sets SQL database URI and enables DB backend mode, which is
read-only unless --db_import is also passed.z--db_importz[experimental] enables DB read-and-import mode, which in combination with
--logdir imports event files into a DB backend on the fly. The backing DB is
temporary unless --db is also passed to specify a DB path to use.z	--inspectaO  Prints digests of event files to command line.

This is useful when no data is shown on TensorBoard, or the data shown
looks weird.

Must specify one of `logdir` or `event_file` flag.

Example usage:
  `tensorboard --inspect --logdir mylogdir --tag loss`

See tensorboard/backend/event_processing/event_file_inspector.py for more info.z--version_tbz!Prints the version of Tensorboardz--tagZTAGz%tag to query for; used with --inspectz--event_filezhThe particular event file to query for. Only used if --inspect is
present and --logdir is not specified.z--path_prefixa  An optional, relative prefix to the path, e.g. "/path/to/tensorboard".
resulting in the new base url being located at
localhost:6006/path/to/tensorboard under default settings. A leading
slash is required when specifying the path_prefix. A trailing slash is
optional and has no effect. The path_prefix can be leveraged for path
based routing of an ELB when the website base_url is not available e.g.
"example.site.com/path/to/tensorboard/".z--window_titleZTEXTzchanges title of browser windowz--max_reload_threadsZCOUNT   zThe max number of threads that TensorBoard can use to reload runs. Not
relevant for db read-only mode. Each thread reloads one run at a time.
(default: %(default)s)z--reload_intervalZSECONDSg      @zHow often the backend should load more data, in seconds. Set to 0 to
load just once at startup. Must be non-negative. (default: %(default)s)z--reload_taskZTYPEthreadprocessblockingas  [experimental] The mechanism to use for the background data reload task.
The default "auto" option will conditionally use threads for legacy reloading
and a child process for DB import reloading. The "process" option is only
useful with DB import mode. The "blocking" option will block startup until
reload finishes, and requires --load_interval=0. (default: %(default)s))r   rk   r   r   r   z--reload_multifilec                 S   s   ddd |  | S r   r   r   r   r   r    rx   Q  r   a  [experimental] If true, this enables experimental support for continuously
polling multiple event files in each run directory for newly appended data
(rather than only polling the last event file). Event files will only be
polled as long as their most recently read data is newer than the threshold
defined by --reload_multifile_inactive_secs, to limit resource usage. Beware
of running out of memory if the logdir contains many active event files.
(default: false)z --reload_multifile_inactive_secsr
   a8  [experimental] Configures the age threshold in seconds at which an event file
that has no event wall time more recent than that will be considered an
inactive file and no longer polled (to limit resource usage). If set to -1,
no maximum age will be enforced, but beware of running out of memory and
heavier filesystem read traffic. If set to 0, this reverts to the older
last-file-only polling strategy (akin to --reload_multifile=false).
(default: %(default)s - intended to ensure an event file remains active if
it receives new data at least once per 24 hour period)z--generic_dataa]  [experimental] Hints whether plugins should read from generic data
provider infrastructure. For plugins that support only the legacy
multiplexer APIs or only the generic data APIs, this option has no
effect. The "auto" option enables this only for plugins that are
considered to have stable support for generic data providers. (default:
%(default)s)z--samples_per_plugina>  An optional comma separated list of plugin_name=num_samples pairs to
explicitly specify how many samples to keep per tag for that plugin. For
unspecified plugins, TensorBoard randomly downsamples logged summaries
to reasonable values to prevent out-of-memory errors for long running
jobs. This flag allows fine control over that downsampling. Note that if a
plugin is not specified in this list, a plugin-specific default number of
samples will be enforced. (for example, 10 for images, 500 for histograms,
and 1000 for scalars). Most users should not need to set this flag.z--detect_file_replacementc                 S   s   ddd |  | S r   r   r   r   r   r    rx     r   aQ  [experimental] If true, this enables experimental support for detecting when
event files are replaced with new versions that contain additional data. This is
not needed in the normal case where new data is either appended to an existing
file or written to a brand new file, but it arises, for example, when using
rsync without the --inplace option, in which new versions of the original file
are first written to a temporary file, then swapped into the final location.

This option is currently incompatible with --load_fast=true, and if passed will
disable fast-loading mode. (default: false))
add_argumentr^   DEFAULT_PORTr   ZChannelCredsTypeZLOCALr   rl   _nonnegative_float_parse_samples_per_plugin)r   parserr   r   r    define_flags7  sv   


zCorePluginLoader.define_flagsc                 C   s   t j}|jrn|jrL|jr"|d|jr6|jr6|d|js|js|dnn|jrb|jrb|dnX|js|js|js|js|dn6|j	dk	r|j
r|dn|jdkr|jd	kr|d
|jd|_|jr|jds|d|j dS )z/Fixes standard TensorBoard CLI flags to parser.z.--logdir_spec is not supported with --inspect.z;Must specify either --logdir or --event_file, but not both.z-Must specify either --logdir or --event_file.z/May not specify both --logdir and --logdir_speczA logdir or db must be specified. For example `tensorboard --logdir mylogdir` or `tensorboard --db sqlite:~/.tensorboard.db`. Run `tensorboard --helpfull` for details and examples.Nz,Must not specify both --host and --bind_all.r   TzHMust not specify both --load_fast=true and--detect_file_replacement=truer1   z/Path prefix must start with slash, but got: %r.)r   
FlagsErrorZ
version_tbinspectr   r   Z
event_filedbZgrpc_data_providerhostZbind_allZ	load_fastZdetect_file_replacementr   rstrip
startswith)r   r   r   r   r   r    	fix_flags  sZ    

zCorePluginLoader.fix_flagsc                 C   s   t || jdS )zCreates CorePlugin instance.)r   )r   r   )r   r   r   r   r    load  s    zCorePluginLoader.load)N)r   r   r   r   r!   r   r   r   r   r   r   r    r   1  s   
  o1r   c              	   C   s8   t  }tj|dddd}||  W 5 Q R X | S )Nwb   r   )fileobjmodecompresslevelmtime)ioBytesIOrE   GzipFilewritegetvalue)Z
bytestringoutfr   r   r    r9     s    r9   c                 C   s:   i }|  dD ]&}|r|  d\}}t|||< q|S )zCParses `value` as a string-to-int dict in the form `foo=12,bar=34`.,=)splitstriprl   )valueresulttokenrh   rd   r   r   r    r     s    r   c                 C   sJ   zt | } W n" tk
r.   td|  Y nX | dksFtd|  | S )Nzinvalid float: %rr   zmust be non-negative: %r)rm   
ValueErrorargparseArgumentTypeErrorr   r   r   r    r     s    r   )!r   r   r6   rE   r   rH   rQ   r2   Zwerkzeugr   r   Ztensorboardr   Ztensorboard.backendr   Ztensorboard.pluginsr   Ztensorboard.utilr   r   r	   Z
get_loggerloggerr   rL   rM   ZTBPluginr   ZTBLoaderr   r9   r   r   r   r   r   r    <module>   s:        ,
