
Xc           @` s  d  Z  d d l m Z d d l m Z d d l m 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 Z d d l Z d d l m Z d d l m Z d d l m 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 Z d e j Z d e j Z d e j  Z! d e j" Z# d Z$ d e j% Z& i d d 6d d 6d d 6d d 6Z' d Z( d   Z) d e* f d     YZ+ d e j, f d     YZ- d S(   s   TensorBoard server handler logic.

TensorboardHandler contains all the logic for serving static files off of disk
and for handling the API calls to endpoints like /tags that require information
about loaded events.
i    (   t   absolute_import(   t   division(   t   print_functionN(   t   urllib(   t   xrange(   t   text_format(   t   logging(   t   resource_loader(   t   event_accumulator(   t   float_wrappers   /runst   /s   /individualImages	   image/bmpt   bmps	   image/gift   gifs
   image/jpegt   jpegs	   image/pngt   pngs   application/octet-streamc         C` s"   t  j d  |   } t j | t  S(   N(   t   imghdrt   whatt   Nonet   _IMGHDR_TO_MIMETYPEt   gett   _DEFAULT_IMAGE_MIMETYPE(   t   encoded_image_stringt
   image_type(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _content_type_for_image@   s    t   _OutputFormatc           B` s   e  Z d  Z d Z d Z RS(   s   An enum used to list the valid output formats for API calls.

  Not all API calls support all formats (for example, only scalars and
  compressed histograms support CSV).
  t   jsont   csv(   t   __name__t
   __module__t   __doc__t   JSONt   CSV(    (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyR   E   s   t   TensorboardHandlerc           B` s   e  Z d  Z d   Z d   Z d   Z d d  Z d d  Z d d  Z d   Z	 d	   Z
 d
   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z RS(   s   Handler class for use with BaseHTTPServer.HTTPServer.

  This is essentially a thin wrapper around calls to an EventMultiplexer object
  as well as serving files off disk.
  c         G` s    | |  _  t j j |  |  d  S(   N(   t   _multiplexert   BaseHTTPServert   BaseHTTPRequestHandlert   __init__(   t   selft   multiplexert   args(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyR$   V   s    	c         C` sr   g  } xe t  |  D]W \ } } | j i | j d 6| j d 6| j d 6| j d 6|  j | | |  d 6 q W| S(   sl  Builds a JSON-serializable object with information about run_images.

    Args:
      run_images: A list of event_accumulator.ImageValueEvent objects.
      run: The name of the run.
      tag: The name of the tag the images all belong to.

    Returns:
      A list of dictionaries containing the wall time, step, URL, width, and
      height for each image.
    t	   wall_timet   stept   widtht   heightt   query(   t	   enumeratet   appendR(   R)   R*   R+   t   _query_for_individual_image(   R%   t
   run_imagest   runt   tagt   responset   indext	   run_image(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _image_response_for_run\   s    	



c         C` sI   t  j j t  j  } t  j j |  } t  j j | | g  } | | k S(   s  Check path is safe (stays within current directory).

    This is for preventing directory-traversal attacks.

    Args:
      path: The path to check for safety.

    Returns:
      True if the given path stays within the current directory, and false
      if it would escape to a higher directory. E.g. _path_is_safe('index.html')
      returns true, but _path_is_safe('../../../etc/password') returns false.
    (   t   ost   patht   abspatht   curdirt   commonprefix(   R%   R8   t   baset   absolute_patht   prefix(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _path_is_safeu   s    i   c         C` s   t  j    } t j d | d d  } | j |  | j   | j   } |  j |  |  j d |  |  j d t |   |  j d d  |  j	   |  j
 j |  d S(	   s   Writes the given content as gzip response using the given content type.

    Args:
      content: The content to respond with.
      content_type: The mime type of the content.
      code: The numeric HTTP status code to use.
    t   fileobjt   modet   ws   Content-Types   Content-Lengths   Content-Encodingt   gzipN(   t   StringIORC   t   GzipFilet   writet   closet   getvaluet   send_responset   send_headert   lent   end_headerst   wfile(   R%   t   contentt   content_typet   codet   outt   ft   gzip_content(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _send_gzip_response   s    

c         C` si   t  j t j |   } |  j |  |  j d d  |  j d t |   |  j   |  j j	 |  d S(   s   Writes out the given object as JSON using the given HTTP status code.

    This also replaces special float values with stringified versions.

    Args:
      obj: The object to respond with.
      code: The numeric HTTP status code to use.
    s   Content-Types   application/jsons   Content-LengthN(
   R   t   dumpsR	   t   WrapSpecialFloatsRI   RJ   RK   RL   RM   RF   (   R%   t   objRP   t   output(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _send_json_response   s    

c         C` sQ   |  j  |  |  j d d  |  j d t |   |  j   |  j j |  d S(   s.  Writes out the given string, which represents CSV data.

    Unlike _send_json_response, this does *not* perform the CSV serialization
    for you. It only sets the proper headers.

    Args:
      serialized_csv: A string containing some CSV data.
      code: The numeric HTTP status code to use.
    s   Content-Types   text/csvs   Content-LengthN(   RI   RJ   RK   RL   RM   RF   (   R%   t   serialized_csvRP   (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _send_csv_response   s
    
c         C` s   | j  d  } | j  d  } |  j j | |  } | j  d  t j k r t j   } t j |  } | j d d d g  | j	 |  |  j
 | j    n |  j |  d S(   s9   Given a tag and single run, return array of ScalarEvents.R2   R1   t   formats	   Wall timet   Stept   ValueN(   R   R!   t   ScalarsR   R   RD   R   t   writert   writerowt	   writerowsR[   RH   RY   (   R%   t   query_paramsR2   R1   t   valuest	   string_ioR`   (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _serve_scalars   s    c         C` s   | j  d d  } | d k r2 |  j d d  d Sy |  j j |  } Wn t k
 ri |  j d  d SXt j |  } |  j	 | d  d S(   s?   Given a single run, return the graph definition in json format.R1   i  s!   query parameter "run" is requiredNi  s
   text/plain(
   R   R   t
   send_errorR!   t   Grapht
   ValueErrorRI   R   t   MessageToStringRT   (   R%   Rc   R1   t   grapht   graph_pbtxt(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _serve_graph   s    c         C` sD   | j  d  } | j  d  } |  j j | |  } |  j |  d S(   s@   Given a tag and single run, return an array of histogram values.R2   R1   N(   R   R!   t
   HistogramsRY   (   R%   Rc   R2   R1   Rd   (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _serve_histograms   s    c         C` sK  | j  d  } | j  d  } |  j j | |  } | j  d  t j k r:t j   } t j |  } d d g } | r t | d j	  } x/ t
 |  D] }	 | d |	 d |	 g 7} q Wn  | j |  xW | D]O }
 |
 j |
 j g } x' |
 j	 D] } | | j | j g 7} q W| j |  q W|  j | j    n |  j |  d	 S(
   sE   Given a tag and single run, return an array of compressed histograms.R2   R1   R\   s	   Wall timeR]   i    s   Edge %d basis pointss   Edge %d valueN(   R   R!   t   CompressedHistogramsR   R   RD   R   R`   RK   t   compressed_histogram_valuesR   Ra   R(   R)   t   rank_in_bpst   valueR[   RH   RY   (   R%   Rc   R2   R1   t   compressed_histogramsRe   R`   t   headerst   bucket_countt   it   compressed_histogramt   rowRs   (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _serve_compressed_histograms   s&    c         C` sY   | j  d  } | j  d  } |  j j | |  } |  j | | |  } |  j |  d S(   sz  Given a tag and list of runs, serve a list of 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:
      query_params: The query parameters as a dict.
    R2   R1   N(   R   R!   t   ImagesR6   RY   (   R%   Rc   R2   R1   t   imagesR3   (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _serve_images  s
    c         C` s   | j  d  } | j  d  } t | j  d   } |  j j | |  | } | j } t |  } |  j d  |  j d |  |  j d t |   |  j	   |  j
 j |  d S(   s   Serves an individual image.R2   R1   R4   i   s   Content-Types   Content-LengthN(   R   t   intR!   R{   R   R   RI   RJ   RK   RL   RM   RF   (   R%   Rc   R2   R1   R4   t   imageR   RO   (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _serve_image  s    	
c         C` s+   t  j j i | d 6| d 6| d 6 } | S(   s  Builds a URL for accessing the specified image.

    This should be kept in sync with _serve_image. Note that the URL is *not*
    guaranteed to always return the same image, since images may be unloaded
    from the reservoir as new images come in.

    Args:
      run: The name of the run.
      tag: The tag.
      index: The index of the image. Negative values are OK.

    Returns:
      A string representation of a URL that will load the index-th
      sampled image in the given run with the given tag.
    R1   R2   R4   (   R   t   parset	   urlencode(   R%   R1   R2   R4   t   query_string(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyR/   #  s
    c         C` s   |  j  |  j j    d S(   s  Return a JSON object about runs and tags.

    Returns a mapping from runs to tagType to list of tags for that run.

    Returns:
      {runName: {images: [tag1, tag2, tag3],
                 scalars: [tagA, tagB, tagC],
                 histograms: [tagX, tagY, tagZ]}}
    N(   RY   R!   t   Runs(   R%   t   unused_query_params(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _serve_runs:  s    
c         C` s   |  j  d  d S(   s9   Serves the index page (i.e., the tensorboard app itself).s   /dist/index.htmlN(   t   _serve_static_file(   R%   R   (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   _serve_indexF  s    c         C` s   |  j  d  d S(   s)   Serves the JavaScript for the index page.s   /dist/app.jsN(   R   (   R%   R   (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt	   _serve_jsJ  s    c         C` s  | j  d  } |  j |  s? t j d |  |  j d  d S| j d  rf t j j d |  } n t j j d |  } y t	 j
 |  } Wn/ t k
 r t j d |  |  j d  d SX|  j d	  t j |  d
 p d } |  j d |  |  j   |  j j |  d S(   s   Serves the static file located at the given path.

    Args:
      path: The path of the static file, relative to the tensorboard/ directory.
    R
   s   path %s not safe, sending 404i  Nt   externals   ../t   tensorboards   path %s not found, sending 404i   i    s   application/octet-streams   Content-Type(   t   lstripR?   R   t   infoRg   t
   startswithR7   R8   t   joinR   t   load_resourcet   IOErrorRI   t	   mimetypest
   guess_typeRJ   RL   RM   RF   (   R%   R8   t   contentst   mimetype(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyR   N  s&    
c         C` s4  t  j  |  j  } | j } | j d  r7 | d  } n  i	 |  j t 6|  j t 6|  j t 6|  j	 t
 6|  j t 6|  j t 6|  j t 6|  j d 6|  j d 6} | | k r#t  j | j  } xZ | D]R } t | |  } | d k r |  j d d | | f  d S| | d	 | | <q W| | |  n |  j |  d S(
   s   Handler for all get requests.R
   it    s   /app.jsi   i  s8   query parameter %s should have exactly one value, had %dNi    (   t   urlparseR8   t   endswithRf   t   SCALARS_ROUTERm   t   GRAPH_ROUTERo   t   HISTOGRAMS_ROUTERz   t   COMPRESSED_HISTOGRAMS_ROUTER}   t   IMAGES_ROUTER   t   INDIVIDUAL_IMAGE_ROUTER   t
   RUNS_ROUTER   R   t   parse_qsR,   RK   Rg   R   (   R%   t
   parsed_urlt
   clean_patht   handlersRc   t   keyt   value_count(    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   do_GETo  s6    	







(   R   R   R   R$   R6   R?   RT   RY   R[   Rf   Rm   Ro   Rz   R}   R   R/   R   R   R   R   R   (    (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyR    O   s&   														!(.   R   t
   __future__R    R   R   R"   R   RC   R   R   R   R7   RD   R   t	   six.movesR   R   t   google.protobufR   t   tensorflow.python.platformt
   tensorflowR   R   t   tensorflow.python.summaryR   t   tensorflow.tensorboardR	   R   t   SCALARSR   t   IMAGESR   t
   HISTOGRAMSR   t   COMPRESSED_HISTOGRAMSR   R   t   GRAPHR   R   R   R   t   objectR   R#   R    (    (    (    sl   /tmp/pip-build-UG86a1/tensorflow/tensorflow-0.6.0.data/purelib/tensorflow/tensorboard/tensorboard_handler.pyt   <module>   sH   
	
