def put_events(environment, start_response, headers):
  """
  Store events in backends
  POST body should contain a JSON encoded version of:
    { namespace: namespace_name (optional),
      events: { stream_name1 : [event1, event2, ...],
                stream_name2 : [event1, event2, ...],
                ... }
    }
  Where each event is a dictionary of keys and values.
  """
  errors = []
  events_to_insert = defaultdict(list)
  request_json = environment['json']
  namespace = request_json.get('namespace', settings.default_namespace)

  # Validate streams and events
  for stream, events in request_json.get('events', {}).iteritems():
    try:
      validate_stream(stream)
    except Exception, e:
      log.exception('put_events: stream validation failed for `%s`', stream)
      errors.append(repr(e))
      continue

    for event in events:
      try:
        events_to_insert[stream].append(validate_event_and_assign_id(event))
      except Exception, e:
        log.exception('put_events: event validation failed for `%s`', event)
        errors.append(repr(e))

  results = {}
  for stream, events in events_to_insert.iteritems():
    backends = router.backends_to_mutate(namespace, stream)
    for backend, configuration in backends.iteritems():
      results[(stream, backend.name)] = execute_greenlet_async(
        backend.insert, namespace, stream, events, configuration)
  wait(results.values())

  # Did any insertion fail?
  success = True
  response = defaultdict(dict)
  for (stream, backend), result in results.iteritems():
    try:
      result.get()
      response[stream][backend] = {
        'num_inserted': len(events_to_insert[stream])
      }
    except Exception, e:
      log.exception('put_events: insertion to backend `%s` failed.', backend)
      success = False
      response[stream][backend] = {'num_inserted': -1,
                                   ERRORS_FIELD: [repr(e)]}

  response[SUCCESS_FIELD] = success and not errors
  if errors:
    response[ERRORS_FIELD] = errors

  start_response('200 OK', headers)
  return response