Example #1
0
    def __init__(self, content=None, status_code=200, headers={},
                 content_was_truncated=False, final_url=None):
        self.content = content
        self.status_code = status_code
        self.content_was_truncated = content_was_truncated

        self.headers = urlfetch._CaselessDict()
        self.headers.update(headers)

        self.final_url = final_url
Example #2
0
  def GetTasks(self, queue_name):
    """Gets a queue's tasks.

    Args:
      queue_name: Queue's name to return tasks for.

    Returns:
      A list of dictionaries, where each dictionary contains one task's
      attributes.
    """
    tasks = self.taskqueues.get(queue_name, [])
    result_tasks = []
    for task_request in tasks:
      task = {}
      result_tasks.append(task)
      task['name'] = task_request.task_name()
      task['url'] = task_request.url()
      method = task_request.method()
      if (method == taskqueue_service_pb.TaskQueueAddRequest.GET):
        task['method'] = 'GET'
      elif (method == taskqueue_service_pb.TaskQueueAddRequest.POST):
        task['method'] = 'POST'
      elif (method == taskqueue_service_pb.TaskQueueAddRequest.HEAD):
        task['method'] = 'HEAD'
      elif (method == taskqueue_service_pb.TaskQueueAddRequest.PUT):
        task['method'] = 'PUT'
      elif (method == taskqueue_service_pb.TaskQueueAddRequest.DELETE):
        task['method'] = 'DELETE'

      task['eta'] = _FormatEta(task_request.eta_usec())
      task['eta_delta'] = _EtaDelta(task_request.eta_usec())
      task['body'] = base64.b64encode(task_request.body())
      headers = urlfetch._CaselessDict()
      task['headers'] = headers
      for req_header in task_request.header_list():
        headers[req_header.key()] = req_header.value()

      headers['X-AppEngine-QueueName'] = queue_name
      headers['X-AppEngine-TaskName'] = task['name']
      headers['X-AppEngine-TaskRetryCount'] = '0'
      headers['X-AppEngine-Development-Payload'] = '1'
      headers['Content-Length'] = len(task['body'])
      headers['Content-Type'] = headers.get(
          'Content-Type', 'application/octet-stream')

    return result_tasks
    def __init__(self, response_dict):
        """Constructor.

        Args:
          response_dict: the intercepted response dict to wrap.
        """
        try:
            from google.appengine.dist27 import httplib
        except ImportError:  # pragma: no cover
            import httplib

        self.__data = response_dict
        self.content = response_dict['content']
        self.status_code = response_dict['status_code']
        self.content_was_truncated = response_dict['content_was_truncated']
        self.final_url = response_dict['final_url'] or None
        self.header_msg = httplib.HTTPMessage(
            StringIO.StringIO(''.join([
                '%s: %s\n' % h for h in dict(response_dict['headers']).items()
            ] + ['\n'])))
        self.headers = _CaselessDict(self.header_msg.items())
Example #4
0
  def GetTasks(self, queue_name):
    """Gets a queue's tasks.

    Args:
      queue_name: Queue's name to return tasks for.

    Returns:
      A list of dictionaries, where each dictionary contains one task's
      attributes. E.g.
        [{'name': 'task-123',
          'url': '/update',
          'method': 'GET',
          'eta': '2009/02/02 05:37:42',
          'eta_delta': '0:00:06.342511 ago',
          'body': '',
          'headers': {'X-AppEngine-QueueName': 'update-queue',
                      'X-AppEngine-TaskName': 'task-123',
                      'X-AppEngine-TaskRetryCount': '0',
                      'X-AppEngine-Development-Payload': '1',
                      'Content-Length': 0,
                      'Content-Type': 'application/octet-streamn'}, ...]

    Raises:
      ValueError: A task request contains an unknown HTTP method type.
    """
    tasks = self._taskqueues.get(queue_name, [])
    result_tasks = []
    for task_request in tasks:
      task = {}
      result_tasks.append(task)
      task['name'] = task_request.task_name()
      task['url'] = task_request.url()
      method = task_request.method()
      if method == taskqueue_service_pb.TaskQueueAddRequest.GET:
        task['method'] = 'GET'
      elif method == taskqueue_service_pb.TaskQueueAddRequest.POST:
        task['method'] = 'POST'
      elif method == taskqueue_service_pb.TaskQueueAddRequest.HEAD:
        task['method'] = 'HEAD'
      elif method == taskqueue_service_pb.TaskQueueAddRequest.PUT:
        task['method'] = 'PUT'
      elif method == taskqueue_service_pb.TaskQueueAddRequest.DELETE:
        task['method'] = 'DELETE'
      else:
        raise ValueError('Unexpected method: %d' % method)

      task['eta'] = _FormatEta(task_request.eta_usec())
      task['eta_delta'] = _EtaDelta(task_request.eta_usec())
      task['body'] = base64.b64encode(task_request.body())
      headers = urlfetch._CaselessDict()
      task['headers'] = headers
      for req_header in task_request.header_list():
        headers[req_header.key()] = req_header.value()

      headers['X-AppEngine-QueueName'] = queue_name
      headers['X-AppEngine-TaskName'] = task['name']
      headers['X-AppEngine-TaskRetryCount'] = '0'
      headers['X-AppEngine-Development-Payload'] = '1'
      headers['Content-Length'] = len(task['body'])
      headers['Content-Type'] = headers.get(
          'Content-Type', 'application/octet-stream')

    return result_tasks
Example #5
0
  def __init__(self, payload=None, **kwargs):
    """Initializer.

    All parameters are optional.

    Args:
      payload: The payload data for this Task that will be delivered to the
        webhook as the HTTP request body. This is only allowed for POST and PUT
        methods.
      countdown: Time in seconds into the future that this Task should execute.
        Defaults to zero.
      eta: Absolute time when the Task should execute. May not be specified
        if 'countdown' is also supplied. This may be timezone-aware or
        timezone-naive.
      headers: Dictionary of headers to pass to the webhook. Values in the
        dictionary may be iterable to indicate repeated header fields.
      method: Method to use when accessing the webhook. Defaults to 'POST'.
      name: Name to give the Task; if not specified, a name will be
        auto-generated when added to a queue and assigned to this object. Must
        match the _TASK_NAME_PATTERN regular expression.
      params: Dictionary of parameters to use for this Task. For POST requests
        these params will be encoded as 'application/x-www-form-urlencoded' and
        set to the payload. For all other methods, the parameters will be
        converted to a query string. May not be specified if the URL already
        contains a query string.
      url: Relative URL where the webhook that should handle this task is
        located for this application. May have a query string unless this is
        a POST method.
      retry_options: TaskRetryOptions used to control when the task will be
        retried if it fails.

    Raises:
      InvalidTaskError if any of the parameters are invalid;
      InvalidTaskNameError if the task name is invalid; InvalidUrlError if
      the task URL is invalid or too long; TaskTooLargeError if the task with
      its payload is too large.
    """
    args_diff = set(kwargs.iterkeys()) - self.__CONSTRUCTOR_KWARGS
    if args_diff:
      raise TypeError('Invalid arguments: %s' % ', '.join(args_diff))

    self.__name = kwargs.get('name')
    if self.__name and not _TASK_NAME_RE.match(self.__name):
      raise InvalidTaskNameError(
          'Task name does not match expression "%s"; found %s' %
          (_TASK_NAME_PATTERN, self.__name))

    self.__default_url, self.__relative_url, query = Task.__determine_url(
        kwargs.get('url', ''))
    self.__headers = urlfetch._CaselessDict()
    self.__headers.update(kwargs.get('headers', {}))
    self.__method = kwargs.get('method', 'POST').upper()
    self.__payload = None
    params = kwargs.get('params', {})


    for header_name, environ_name in _PRESERVE_ENVIRONMENT_HEADERS:
      value = os.environ.get(environ_name)
      if value is not None:
        self.__headers.setdefault(header_name, value)

    self.__headers.setdefault('X-AppEngine-Current-Namespace',
                              namespace_manager.get_namespace())
    if query and params:
      raise InvalidTaskError('Query string and parameters both present; '
                             'only one of these may be supplied')

    if self.__method == 'POST':
      if payload and params:
        raise InvalidTaskError('Message body and parameters both present for '
                               'POST method; only one of these may be supplied')
      elif query:
        raise InvalidTaskError('POST method may not have a query string; '
                               'use the "params" keyword argument instead')
      elif params:
        self.__payload = Task.__encode_params(params)
        self.__headers.setdefault(
            'content-type', 'application/x-www-form-urlencoded')
      elif payload is not None:
        self.__payload = Task.__convert_payload(payload, self.__headers)
    elif self.__method in _NON_POST_METHODS:
      if payload and self.__method not in _BODY_METHODS:
        raise InvalidTaskError('Payload may only be specified for methods %s' %
                               ', '.join(_BODY_METHODS))
      if payload:
        self.__payload = Task.__convert_payload(payload, self.__headers)
      if params:
        query = Task.__encode_params(params)
      if query:
        self.__relative_url = '%s?%s' % (self.__relative_url, query)
    else:
      raise InvalidTaskError('Invalid method: %s' % self.__method)

    self.__headers_list = _flatten_params(self.__headers)
    self.__eta_posix = Task.__determine_eta_posix(
        kwargs.get('eta'), kwargs.get('countdown'))
    self.__eta = None
    self.__retry_options = kwargs.get('retry_options')
    self.__enqueued = False

    if self.size > MAX_TASK_SIZE_BYTES:
      raise TaskTooLargeError('Task size must be less than %d; found %d' %
                              (MAX_TASK_SIZE_BYTES, self.size))
Example #6
0
    def __init__(self, payload=None, **kwargs):
        """Initializer.

    All parameters are optional.

    Args:
      payload: The payload data for this Task that will be delivered to the
        webhook as the HTTP request body. This is only allowed for POST and PUT
        methods.
      countdown: Time in seconds into the future that this Task should execute.
        Defaults to zero.
      eta: Absolute time when the Task should execute. May not be specified
        if 'countdown' is also supplied. This may be timezone-aware or
        timezone-naive.
      headers: Dictionary of headers to pass to the webhook. Values in the
        dictionary may be iterable to indicate repeated header fields.
      method: Method to use when accessing the webhook. Defaults to 'POST'.
      name: Name to give the Task; if not specified, a name will be
        auto-generated when added to a queue and assigned to this object. Must
        match the _TASK_NAME_PATTERN regular expression.
      params: Dictionary of parameters to use for this Task. For POST requests
        these params will be encoded as 'application/x-www-form-urlencoded' and
        set to the payload. For all other methods, the parameters will be
        converted to a query string. May not be specified if the URL already
        contains a query string.
      url: Relative URL where the webhook that should handle this task is
        located for this application. May have a query string unless this is
        a POST method.
      retry_options: TaskRetryOptions used to control when the task will be
        retried if it fails.

    Raises:
      InvalidTaskError if any of the parameters are invalid;
      InvalidTaskNameError if the task name is invalid; InvalidUrlError if
      the task URL is invalid or too long; TaskTooLargeError if the task with
      its payload is too large.
    """
        args_diff = set(kwargs.iterkeys()) - self.__CONSTRUCTOR_KWARGS
        if args_diff:
            raise TypeError('Invalid arguments: %s' % ', '.join(args_diff))

        self.__name = kwargs.get('name')
        if self.__name and not _TASK_NAME_RE.match(self.__name):
            raise InvalidTaskNameError(
                'Task name does not match expression "%s"; found %s' %
                (_TASK_NAME_PATTERN, self.__name))

        self.__default_url, self.__relative_url, query = Task.__determine_url(
            kwargs.get('url', ''))
        self.__headers = urlfetch._CaselessDict()
        self.__headers.update(kwargs.get('headers', {}))
        self.__method = kwargs.get('method', 'POST').upper()
        self.__payload = None
        params = kwargs.get('params', {})

        for header_name, environ_name in _PRESERVE_ENVIRONMENT_HEADERS:
            value = os.environ.get(environ_name)
            if value is not None:
                self.__headers.setdefault(header_name, value)

        self.__headers.setdefault('X-AppEngine-Current-Namespace',
                                  namespace_manager.get_namespace())
        if query and params:
            raise InvalidTaskError('Query string and parameters both present; '
                                   'only one of these may be supplied')

        if self.__method == 'POST':
            if payload and params:
                raise InvalidTaskError(
                    'Message body and parameters both present for '
                    'POST method; only one of these may be supplied')
            elif query:
                raise InvalidTaskError(
                    'POST method may not have a query string; '
                    'use the "params" keyword argument instead')
            elif params:
                self.__payload = Task.__encode_params(params)
                self.__headers.setdefault('content-type',
                                          'application/x-www-form-urlencoded')
            elif payload is not None:
                self.__payload = Task.__convert_payload(
                    payload, self.__headers)
        elif self.__method in _NON_POST_METHODS:
            if payload and self.__method not in _BODY_METHODS:
                raise InvalidTaskError(
                    'Payload may only be specified for methods %s' %
                    ', '.join(_BODY_METHODS))
            if payload:
                self.__payload = Task.__convert_payload(
                    payload, self.__headers)
            if params:
                query = Task.__encode_params(params)
            if query:
                self.__relative_url = '%s?%s' % (self.__relative_url, query)
        else:
            raise InvalidTaskError('Invalid method: %s' % self.__method)

        self.__headers_list = _flatten_params(self.__headers)
        self.__eta_posix = Task.__determine_eta_posix(kwargs.get('eta'),
                                                      kwargs.get('countdown'))
        self.__eta = None
        self.__retry_options = kwargs.get('retry_options')
        self.__enqueued = False

        if self.size > MAX_TASK_SIZE_BYTES:
            raise TaskTooLargeError(
                'Task size must be less than %d; found %d' %
                (MAX_TASK_SIZE_BYTES, self.size))
Example #7
0
  def __init__(self, payload=None, **kwargs):
    """Initializer.

    All parameters are optional.

    Args:
      payload: The payload data for this Task that will either be delivered
        to the webhook as the HTTP request body or fetched by workers for pull
        queues. This is only allowed for POST, PUT and PULL methods.
      name: Name to give the Task; if not specified, a name will be
        auto-generated when added to a queue and assigned to this object. Must
        match the _TASK_NAME_PATTERN regular expression.
      method: Method to use when accessing the webhook. Defaults to 'POST'. If
        set to 'PULL', task will not be automatiacally delivered to the webhook,
        instead it stays in the queue until leased.
      url: Relative URL where the webhook that should handle this task is
        located for this application. May have a query string unless this is
        a POST method. Must not be specified if method is PULL.
      headers: Dictionary of headers to pass to the webhook. Values in the
        dictionary may be iterable to indicate repeated header fields. Must not
        be specified if method is PULL.
      params: Dictionary of parameters to use for Task. For POST and PULL
        requests these params will be encoded as
        'application/x-www-form-urlencoded' and set to the payload. For all
        other methods, the parameters will be converted to a query string. Must
        not be specified if the URL already contains a query string, or the
        task already has payload.
      countdown: Time in seconds into the future that this Task should execute.
        Defaults to zero.
      eta: A datetime.datetime specifying the absolute time at which the task
        should be executed. Must not be specified if 'countdown' is specified.
        This may be timezone-aware or timezone-naive. If None, defaults to now.
        For pull tasks, no worker will be able to lease this task before the
        time indicated by eta.
      retry_options: TaskRetryOptions used to control when the task will be
        retried if it fails.
      target: The alternate version/server on which to execute this task.

    Raises:
      InvalidTaskError: if any of the parameters are invalid;
      InvalidTaskNameError: if the task name is invalid;
      InvalidUrlError: if the task URL is invalid or too long;
      TaskTooLargeError: if the task with its payload is too large.
    """
    args_diff = set(kwargs.iterkeys()) - self.__CONSTRUCTOR_KWARGS
    if args_diff:
      raise TypeError('Invalid arguments: %s' % ', '.join(args_diff))

    self.__name = kwargs.get('name')
    if self.__name and not _TASK_NAME_RE.match(self.__name):
      raise InvalidTaskNameError(
          'Task name does not match expression "%s"; found %s' %
          (_TASK_NAME_PATTERN, self.__name))

    self.__default_url, self.__relative_url, query = Task.__determine_url(
        kwargs.get('url', ''))
    self.__headers = urlfetch._CaselessDict()
    self.__headers.update(kwargs.get('headers', {}))
    self.__method = kwargs.get('method', 'POST').upper()
    self.__payload = None
    self.__retry_count = 0
    params = kwargs.get('params', {})


    for header_name, environ_name in _PRESERVE_ENVIRONMENT_HEADERS:
      value = os.environ.get(environ_name)
      if value is not None:
        self.__headers.setdefault(header_name, value)

    self.__headers.setdefault('X-AppEngine-Current-Namespace',
                              namespace_manager.get_namespace())
    if query and params:
      raise InvalidTaskError('Query string and parameters both present; '
                             'only one of these may be supplied')

    if self.__method == 'PULL':
      if not self.__default_url:
        raise InvalidTaskError('url must not be specified for PULL task')
      if kwargs.get('headers'):
        raise InvalidTaskError('headers must not be specified for PULL task')
      if params:
        if payload:
          raise InvalidTaskError(
              'Message body and parameters both present for '
              'POST method; only one of these may be supplied')
        payload = Task.__encode_params(params)
      if payload is None:
        raise InvalidTaskError('payload must be specified for PULL task')
      self.__payload = Task.__convert_payload(payload, self.__headers)
    elif self.__method == 'POST':
      if payload and params:
        raise InvalidTaskError('Message body and parameters both present for '
                               'POST method; only one of these may be supplied')
      elif query:
        raise InvalidTaskError('POST method may not have a query string; '
                               'use the "params" keyword argument instead')
      elif params:
        self.__payload = Task.__encode_params(params)
        self.__headers.setdefault(
            'content-type', 'application/x-www-form-urlencoded')
      elif payload is not None:
        self.__payload = Task.__convert_payload(payload, self.__headers)
    elif self.__method in _NON_POST_HTTP_METHODS:
      if payload and self.__method not in _BODY_METHODS:
        raise InvalidTaskError('Payload may only be specified for methods %s' %
                               ', '.join(_BODY_METHODS))
      if payload:
        self.__payload = Task.__convert_payload(payload, self.__headers)
      if params:
        query = Task.__encode_params(params)
      if query:
        self.__relative_url = '%s?%s' % (self.__relative_url, query)
    else:
      raise InvalidTaskError('Invalid method: %s' % self.__method)

    host_suffix = '.%s' % os.environ.get('DEFAULT_VERSION_HOSTNAME', '')
    self.__target = kwargs.get('target')
    if self.__target is not None and 'Host' in self.__headers:
      raise InvalidTaskError(
          'A host header may not set when a target is specified.')
    elif self.__target is not None:
      self.__headers['Host'] = '%s%s' % (
          self.__target, host_suffix)
    elif 'Host' in self.__headers:
      host = self.__headers['Host']
      if host.endswith(host_suffix):
        self.__target = host[:-len(host_suffix)]

    self.__headers_list = _flatten_params(self.__headers)
    self.__eta_posix = Task.__determine_eta_posix(
        kwargs.get('eta'), kwargs.get('countdown'))
    self.__eta = None
    self.__retry_options = kwargs.get('retry_options')
    self.__enqueued = False
    self.__deleted = False

    if self.__method == 'PULL':
      max_task_size_bytes = MAX_PULL_TASK_SIZE_BYTES
    else:
      max_task_size_bytes = MAX_PUSH_TASK_SIZE_BYTES
    if self.size > max_task_size_bytes:
      raise TaskTooLargeError('Task size must be less than %d; found %d' %
                              (max_task_size_bytes, self.size))
Example #8
0
    def __init__(self, payload=None, **kwargs):
        """Initializer.

    All parameters are optional.

    Args:
      payload: The payload data for this Task that will be delivered to the
        webhook as the HTTP request body. This is only allowed for POST and PUT
        methods.
      countdown: Time in seconds into the future that this Task should execute.
        Defaults to zero.
      eta: Absolute time when the Task should execute. May not be specified
        if 'countdown' is also supplied.
      headers: Dictionary of headers to pass to the webhook. Values in the
        dictionary may be iterable to indicate repeated header fields.
      method: Method to use when accessing the webhook. Defaults to 'POST'.
      name: Name to give the Task; if not specified, a name will be
        auto-generated when added to a queue and assigned to this object. Must
        match the _TASK_NAME_PATTERN regular expression.
      params: Dictionary of parameters to use for this Task. For POST requests
        these params will be encoded as 'application/x-www-form-urlencoded' and
        set to the payload. For all other methods, the parameters will be
        converted to a query string. May not be specified if the URL already
        contains a query string.
      url: Relative URL where the webhook that should handle this task is
        located for this application. May have a query string unless this is
        a POST method.

    Raises:
      InvalidTaskError if any of the parameters are invalid;
      InvalidTaskNameError if the task name is invalid; InvalidUrlError if
      the task URL is invalid or too long; TaskTooLargeError if the task with
      its payload is too large.
    """
        args_diff = set(kwargs.iterkeys()) - self.__CONSTRUCTOR_KWARGS
        if args_diff:
            raise TypeError("Invalid arguments: %s" % ", ".join(args_diff))

        self.__name = kwargs.get("name")
        if self.__name and not _TASK_NAME_RE.match(self.__name):
            raise InvalidTaskNameError(
                'Task name does not match expression "%s"; found %s' % (_TASK_NAME_PATTERN, self.__name)
            )

        self.__default_url, self.__relative_url, query = Task.__determine_url(kwargs.get("url", ""))
        self.__headers = urlfetch._CaselessDict()
        self.__headers.update(kwargs.get("headers", {}))
        self.__method = kwargs.get("method", "POST").upper()
        self.__payload = None
        params = kwargs.get("params", {})

        if query and params:
            raise InvalidTaskError("Query string and parameters both present; " "only one of these may be supplied")

        if self.__method == "POST":
            if payload and params:
                raise InvalidTaskError(
                    "Message body and parameters both present for " "POST method; only one of these may be supplied"
                )
            elif query:
                raise InvalidTaskError(
                    "POST method may not have a query string; " 'use the "params" keyword argument instead'
                )
            elif params:
                self.__payload = Task.__encode_params(params)
                self.__headers.setdefault("content-type", "application/x-www-form-urlencoded")
            elif payload is not None:
                self.__payload = Task.__convert_payload(payload, self.__headers)
        elif self.__method in _NON_POST_METHODS:
            if payload and self.__method not in _BODY_METHODS:
                raise InvalidTaskError("Payload may only be specified for methods %s" % ", ".join(_BODY_METHODS))
            if payload:
                self.__payload = Task.__convert_payload(payload, self.__headers)
            if params:
                query = Task.__encode_params(params)
            if query:
                self.__relative_url = "%s?%s" % (self.__relative_url, query)
        else:
            raise InvalidTaskError("Invalid method: %s" % self.__method)

        self.__headers_list = _flatten_params(self.__headers)
        self.__eta = Task.__determine_eta(kwargs.get("eta"), kwargs.get("countdown"))
        self.__enqueued = False

        if self.size > MAX_TASK_SIZE_BYTES:
            raise TaskTooLargeError("Task size must be less than %d; found %d" % (MAX_TASK_SIZE_BYTES, self.size))