U
    Ucq'                     @   s   d Z ddlZddlmZ ddlmZ ddlZddl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d
lmZ ddlmZ dd Zdd ZdddZdddde
jjfddZdd Zdd ZdS )z@Shared utils among inference plugins that are platform-specific.    N)glob)implementations)urlparse)common_utils)	types_pb2)classification_pb2)predict_pb2)prediction_service_pb2)regression_pb2c                 C   s"   |   } d| krt| S | gS dS )zReturns a list of files given by a filepath.

  Args:
    file_path: A path, possibly representing a single file, or containing a
        wildcard or sharded path.

  Returns:
    A list of files represented by the provided path.
  *N)stripr   )	file_path r   P/tmp/pip-unpacked-wheel-15h0ro02/tensorboard_plugin_wit/_utils/platform_utils.pyfilepath_to_filepath_list!   s    
r   c                 C   s6   t j| } t j|}t j| gt j| |gkS )zReturns if the provided parent path is a parent of the provided child path.

  Args:
    parent_path: File path to check as parent.
    child_path: File path to check as child.

  Returns:
    True if parent_path is a parent of the child_path.
  )ospathnormpath
commonpath)parent_pathZ
child_pathr   r   r   path_is_parent2   s
    r   c                 C   sN   t | }|st| d |D ]*}t||s|r:t||st|d qdS )ag  Throws an error if a file cannot be loaded for inference.

  Args:
    file_path: A file path.
    logdir: The path to the logdir of the TensorBoard context.
    allowed_dir: An optional path to allow loading files from, outside of
    the logdir.

  Raises:
    InvalidUserInputError: If the file is not in the logdir and is not globally
        readable.
  z contains no fileszN is not inside the TensorBoard logdir or --whatif-data-dir argument directory.N)r   r   InvalidUserInputErrorr   )r   ZlogdirZallowed_dirZ
file_pathsr   r   r   r    throw_if_file_access_not_allowedH   s    
r   
   T   c              
      s   fdd}g }|  drdd }tjddd tjt| dd	}	|	D ]}
d
k rht krhqNtj }|
	 D ]f}dd |
| 
dD }||r|jj| jjdd |D  qz|jj| jjdd |D  qz|r|n|  t|krN qqN|S t| }dddg}d}d}|t|k r|t|k rzNtjjjj|| tj|| d}||| |d
7 }t|krW qW nV tjjk
r   |d
7 }Y n6 ttjjfk
r } zt |W 5 d}~X Y nX q*|r|S t d|  d dS )a  Returns a number of examples from the provided path.

  Args:
    path: A string path to the examples.
    num_examples: The maximum number of examples to return from the path.
    parse_examples: If true then parses the serialized proto from the path into
        proto objects. Defaults to True.
    sampling_odds: Odds of loading an example, used for sampling. When >= 1
        (the default), then all examples are loaded.
    example_class: tf.train.Example or tf.train.SequenceExample class to load.
        Defaults to tf.train.Example.

  Returns:
    A list of Example protos or serialized proto strings at the path.

  Raises:
    InvalidUserInputError: If examples cannot be procured from the path.
  c                    sL   | D ]B}dkst   k r|r. |n| t|kr d S qd S )Nr   )randomappendZ
FromStringlen)iterableexamplesvalueexample_classnum_examplesparse_examplessampling_oddsr   r   append_examples_from_iterable|   s    z?example_protos_from_path.<locals>.append_examples_from_iterablez.csvc              	   S   s4   | D ]*}zt | W q tk
r,   Y  dS X qdS )NFT)float
ValueError)valuesr    r   r   r   
are_floats   s    z,example_protos_from_path.<locals>.are_floatsZ
CsvDialectT)skipinitialspace)dialectr   c                 S   s   g | ]}|  qS r   )r   .0valr   r   r   
<listcomp>   s     z,example_protos_from_path.<locals>.<listcomp>|c                 S   s   g | ]}t |qS r   )r'   r-   r   r   r   r0      s     c                 S   s   g | ]}| d qS )zutf-8)encoder-   r   r   r   r0      s      ZGZIPZZLIBr   )r   optionsNzNo examples found at z#. Valid formats are TFRecord files.)!endswithcsvregister_dialect
DictReaderopenr   tftrainExamplekeyssplitfeaturesZfeatureZ
float_listr    extendZ
bytes_listr   SerializeToStringr   r   compatv1Z	python_ioZtf_record_iteratorioZTFRecordOptionserrorsZDataLossErrorIOErrorZNotFoundErrorr   r   )r   r#   start_indexr$   r%   r"   r&   r   r*   ZrowsrowZexamplecolr)   	filenamesZcompression_typesZcurrent_compression_idxZcurrent_file_indexZrecord_iteratorer   r!   r   example_protos_from_pathc   sr    




 rL   c                    s   d}t d j }t|j|j}t| fdd}d}g }d}|t| k sV|rd}|| }	| ||	 }
|	||
 |	}qFt
| jdkS )	a7  Send an RPC request to the Servomatic prediction service.

  Args:
    examples: A list of examples that matches the model spec.
    serving_bundle: A `ServingBundle` object that contains the information to
      make the serving request.

  Returns:
    A ClassificationResponse or RegressionResponse proto.
  i zhttp://c                    s    j rt }n jdkr$t }nt } j|j	_
 jd k	rL j|j	j_ jd k	r` j|j	_ j r|j j tjjjdd | D tjd n|jjj|   j rt|d S  jdkrԈ |dS !|dS d S )Nclassificationc                 S   s   g | ]}|  qS r   )rA   )r.   exr   r   r   r0      s     z2call_servo.<locals>.batch_call.<locals>.<listcomp>)r)   Zdtypeg      >@)"Zuse_predictr   ZPredictRequest
model_typer   ZClassificationRequestr
   ZRegressionRequestZ
model_nameZ
model_specnameZmodel_versionversionr    	signatureZsignature_nameinputsZpredict_input_tensorZCopyFromr:   rB   rC   Zmake_tensor_protor   Z	DT_STRINGinputZexample_listr   r@   r   Zconvert_predict_responseZPredictZClassifyZRegress)batch_examplesrequestserving_bundleZstubr   r   
batch_call   s4    







 
zcall_servo.<locals>.batch_callr   TFrM   )r   Zinference_addressr   Zinsecure_channelhostnameportr	   Z"beta_create_PredictionService_stubr   r   combine_resultsrO   )r   rX   Z
batch_size
parsed_urlZchannelrY   Zstart_exampleresultsZ
first_loopZend_examplerU   r   rW   r   
call_servo   s"    
 r_   c                 C   s   t dt| D ]}|rTt t| | jjD ]&}| d jjj| | jj| jd q*qt t| | jjD ]&}| d jjj| | jj| jd qhq| d S )z6Combine results protos from batches into single proto.r   r   )classes)r    )ranger   resultZclassificationsaddr`   Zregressionsr    )Zresult_protosZis_classificationijr   r   r   r\      s    &&r\   )N)__doc__r6   r   Z	grpc.betar   r   r   six.moves.urllib.parser   Z
tensorflowr:   Ztensorboard_plugin_wit._utilsr   Ztensorflow.core.frameworkr   Z6tensorboard_plugin_wit._vendor.tensorflow_serving.apisr   r   r	   r
   r   r   r   r;   r<   rL   r_   r\   r   r   r   r   <module>   s0   

_>