'Asynchronous Put operation.
Args:
config: A Configuration object or None.  Defaults are taken from
the connection\'s default configuration.
entities: An iterable of user-level entity objects.
extra_hook: Optional function to be called on the result once the
RPC has completed.
Returns:
A MultiRpc object.
NOTE: If any of the entities has an incomplete key, this will
*not* patch up those entities with the complete key.'

def async_put(self, config, entities, extra_hook=None):

    def make_put_call(base_req, pbs, user_data=None):
        req = copy.deepcopy(base_req)
        if (self._api_version == _CLOUD_DATASTORE_V1):
            for entity in pbs:
                mutation = req.mutations.add()
                mutation.upsert.CopyFrom(entity)
            method = 'Commit'
            resp = googledatastore.CommitResponse()
        else:
            req.entity_list().extend(pbs)
            method = 'Put'
            resp = datastore_pb.PutResponse()
        user_data = (pbs, user_data)
        return self._make_rpc_call(config, method, req, resp, get_result_hook=self.__put_hook, user_data=user_data, service_name=self._api_version)
    if (self._api_version == _CLOUD_DATASTORE_V1):
        base_req = googledatastore.CommitRequest()
        base_req.mode = googledatastore.CommitRequest.NON_TRANSACTIONAL
        entity_to_pb = self.__adapter.entity_to_pb_v1
    else:
        base_req = datastore_pb.PutRequest()
        entity_to_pb = self.__adapter.entity_to_pb
    self._set_request_transaction(base_req)
    if Configuration.force_writes(config, self.__config):
        self.__force(base_req)
    if (isinstance(config, apiproxy_stub_map.UserRPC) or (len(entities) <= 1)):
        pbs = [entity_to_pb(entity) for entity in entities]
        return make_put_call(base_req, pbs, extra_hook)
    max_count = (Configuration.max_put_entities(config, self.__config) or self.MAX_PUT_ENTITIES)
    if (((self._api_version == _CLOUD_DATASTORE_V1) and (not base_req.transaction)) or (not base_req.has_transaction())):
        max_egs_per_rpc = self.__get_max_entity_groups_per_rpc(config)
    else:
        max_egs_per_rpc = None
    indexed_entities_by_entity_group = self._map_and_group(entities, entity_to_pb, self._extract_entity_group)
    pbsgen = self._generate_pb_lists(indexed_entities_by_entity_group, base_req.ByteSize(), max_count, max_egs_per_rpc, config)
    rpcs = []
    for (pbs, indexes) in pbsgen:
        rpcs.append(make_put_call(base_req, pbs, self.__create_result_index_pairs(indexes)))
    return MultiRpc(rpcs, self.__sort_result_index_pairs(extra_hook))
