Write the INFO file next to local file.

  Although the method is synchronized, there is still a risk two processes
  running at the same time overlap here. Risk accepted, since potentially lost
  data (`dataset_name`) is only for human consumption.

  Args:
    resource: resource for which to write the INFO file.
    path: path of downloaded file.
    dataset_name: data used to dl the file.
    original_fname: name of file as downloaded.

def write_info_file(resource, path, dataset_name, original_fname):
  """Write the INFO file next to local file.

  Although the method is synchronized, there is still a risk two processes
  running at the same time overlap here. Risk accepted, since potentially lost
  data (`dataset_name`) is only for human consumption.

  Args:
    resource: resource for which to write the INFO file.
    path: path of downloaded file.
    dataset_name: data used to dl the file.
    original_fname: name of file as downloaded.
  """
  info_path = _get_info_path(path)
  info = _read_info(info_path) or {}
  urls = set(info.get('urls', []) + [resource.url])
  dataset_names = info.get('dataset_names', [])
  if dataset_name:
    dataset_names.append(dataset_name)
  if 'original_fname' in info and info['original_fname'] != original_fname:
    raise AssertionError(
        '`original_fname` "%s" stored in %s does NOT match "%s".' % (
            info['original_fname'], info_path, original_fname))
  info = dict(urls=list(urls), dataset_names=list(set(dataset_names)),
              original_fname=original_fname)
  with py_utils.atomic_write(info_path, 'w') as info_f:
    json.dump(info, info_f, sort_keys=True)