docs: def make_export_strategy(
          args,
          keep_target,
          assets_extra,
          features,
          schema,
          stats):
    """Makes prediction graph that takes json input.
  
    Args:
      args: command line args
      keep_target: If ture, target column is returned in prediction graph. Target
          column must also exist in input data
      assets_extra: other fiels to copy to the output folder
      job_dir: root job folder
      features: features dict
      schema: schema list
      stats: stats dict
    """
    target_name = feature_transforms.get_target_name(features)
    csv_header = [col['name'] for col in schema]
    if not keep_target:
      csv_header.remove(target_name)
  
    def export_fn(estimator, export_dir_base, checkpoint_path=None, eval_result=None):
      with ops.Graph().as_default() as g:
        contrib_variables.create_global_step(g)
  
        input_ops = feature_transforms.build_csv_serving_tensors_for_training_step(
            args.analysis, features, schema, stats, keep_target)
        model_fn_ops = estimator._call_model_fn(input_ops.features,
                                                None,
                                                model_fn_lib.ModeKeys.INFER)
        output_fetch_tensors = make_prediction_output_tensors(
            args=args,
            features=features,
            input_ops=input_ops,
            model_fn_ops=model_fn_ops,
            keep_target=keep_target)
  
        # Don't use signature_def_utils.predict_signature_def as that renames
        # tensor names if there is only 1 input/output tensor!
        signature_inputs = {key: tf.saved_model.utils.build_tensor_info(tensor)
                            for key, tensor in six.iteritems(input_ops.default_inputs)}
        signature_outputs = {key: tf.saved_model.utils.build_tensor_info(tensor)
                             for key, tensor in six.iteritems(output_fetch_tensors)}
        signature_def_map = {
            'serving_default':
                signature_def_utils.build_signature_def(
                    signature_inputs,
                    signature_outputs,
                    tf.saved_model.signature_constants.PREDICT_METHOD_NAME)}
  
        if not checkpoint_path:
          # Locate the latest checkpoint
          checkpoint_path = saver.latest_checkpoint(estimator._model_dir)
        if not checkpoint_path:
          raise ValueError("Couldn't find trained model at %s."
                           % estimator._model_dir)
  
        export_dir = saved_model_export_utils.get_timestamped_export_dir(
            export_dir_base)
  
        if (model_fn_ops.scaffold is not None and
           model_fn_ops.scaffold.saver is not None):
          saver_for_restore = model_fn_ops.scaffold.saver
        else:
          saver_for_restore = saver.Saver(sharded=True)
  
        with tf_session.Session('') as session:
          saver_for_restore.restore(session, checkpoint_path)
          init_op = control_flow_ops.group(
              variables.local_variables_initializer(),
              resources.initialize_resources(resources.shared_resources()),
              tf.tables_initializer())
  
          # Perform the export
          builder = saved_model_builder.SavedModelBuilder(export_dir)
          builder.add_meta_graph_and_variables(
              session, [tag_constants.SERVING],
              signature_def_map=signature_def_map,
              assets_collection=ops.get_collection(
                  ops.GraphKeys.ASSET_FILEPATHS),
              legacy_init_op=init_op)
          builder.save(False)
  
        # Add the extra assets
        if assets_extra:
          assets_extra_path = os.path.join(compat.as_bytes(export_dir),
                                           compat.as_bytes('assets.extra'))
          for dest_relative, source in assets_extra.items():
            dest_absolute = os.path.join(compat.as_bytes(assets_extra_path),
                                         compat.as_bytes(dest_relative))
            dest_path = os.path.dirname(dest_absolute)
            file_io.recursive_create_dir(dest_path)
            file_io.copy(source, dest_absolute)
  
      # only keep the last 3 models
      saved_model_export_utils.garbage_collect_exports(
          export_dir_base,
          exports_to_keep=3)
  
      # save the last model to the model folder.
      # export_dir_base = A/B/intermediate_models/
      if keep_target:
        final_dir = os.path.join(args.job_dir, 'evaluation_model')
      else:
        final_dir = os.path.join(args.job_dir, 'model')
      if file_io.is_directory(final_dir):
        file_io.delete_recursively(final_dir)
      file_io.recursive_create_dir(final_dir)
      recursive_copy(export_dir, final_dir)
  
      return export_dir
  
    if keep_target:
      intermediate_dir = 'intermediate_evaluation_models'
    else:
      intermediate_dir = 'intermediate_prediction_models'
  
    return export_strategy.ExportStrategy(intermediate_dir, export_fn)