Exemplo n.º 1
0
def GetMaskFieldPath(method):
    """Gets the dotted path of mask in the api method.

  Args:
    method: APIMethod, The method specification.

  Returns:
    String or None.
  """
    possible_mask_fields = ('updateMask', 'fieldMask')
    message = method.GetRequestType()()

    # If the mask field is found in the request message of the method, return
    # the mask name directly, e.g, updateMask
    for mask in possible_mask_fields:
        if hasattr(message, mask):
            return mask

    # If the mask field is found in the request field message, return the
    # request field and the mask name, e.g, updateRequest.fieldMask.
    if method.request_field:
        request_field = method.request_field
        request_message = None
        if hasattr(message, request_field):
            request_message = arg_utils.GetFieldFromMessage(
                message, request_field).type

        for mask in possible_mask_fields:
            if hasattr(request_message, mask):
                return '{}.{}'.format(request_field, mask)

    return None
Exemplo n.º 2
0
 def _GetType(self, message, field):
     f = arg_utils.GetFieldFromMessage(message, field.api_field)
     t = field.type or arg_utils.TYPES.get(f.variant)
     if not t:
         raise InvalidSchemaError('Unknown type for field: ' +
                                  field.api_field)
     return f, t
Exemplo n.º 3
0
    def CreateRequest(self,
                      namespace,
                      static_fields=None,
                      resource_method_params=None):
        """Generates the request object for the method call from the parsed args.

    Args:
      namespace: The argparse namespace.
      static_fields: {str, value}, A mapping of API field name to value to
        insert into the message. This is a convenient way to insert extra data
        while the request is being constructed for fields that don't have
        corresponding arguments.
      resource_method_params: {str: str}, A mapping of API method parameter name
        to resource ref attribute name when the API method uses non-standard
        names.

    Returns:
      The apitools message to be send to the method.
    """
        static_fields = static_fields or {}
        resource_method_params = resource_method_params or {}
        message_type = self.method.GetRequestType()
        message = message_type()

        # Insert static fields into message.
        for field_path, value in static_fields.iteritems():
            field = arg_utils.GetFieldFromMessage(message_type, field_path)
            arg_utils.SetFieldInMessage(message, field_path,
                                        arg_utils.ConvertValue(field, value))

        # Parse api Fields into message.
        self._ParseArguments(message, namespace)

        ref = self._ParseResourceArg(namespace)
        if not ref:
            return message

        # This only happens for non-list methods where the API method params don't
        # match the resource parameters (basically only create methods). In this
        # case, we re-parse the resource as its parent collection (to fill in the
        # API parameters, and we insert the name of the resource itself into the
        # correct position in the body of the request method.
        if (self.method.resource_argument_collection.detailed_params !=
                self.method.request_collection.detailed_params):
            # Sets the name of the resource in the message object body.
            arg_utils.SetFieldInMessage(message,
                                        self.resource_arg_info[-1].api_field,
                                        ref.Name())
            # Create a reference for the parent resource to put in the API params.
            ref = ref.Parent(
                parent_collection=self.method.request_collection.full_name)

        # For each method path field, get the value from the resource reference.
        relative_name = ref.RelativeName()
        for p in self.method.params:
            value = getattr(ref, resource_method_params.get(p, p),
                            relative_name)
            arg_utils.SetFieldInMessage(message, p, value)
        return message
Exemplo n.º 4
0
  def Generate(self, message):
    """Generates and returns the base argument.

    Args:
      message: The API message, None for non-resource args.

    Returns:
      The base argument.
    """
    if self.api_field:
      field = arg_utils.GetFieldFromMessage(message, self.api_field)
    else:
      field = None
    return arg_utils.GenerateFlag(field, self)
Exemplo n.º 5
0
 def Parse(arg_value):
     """Inner method that argparse actually calls."""
     result = arg_dict(arg_value)
     message_instance = message()
     for f in self.fields:
         value = result.get(f.arg_name)
         api_field = arg_utils.GetFieldFromMessage(message, f.api_field)
         value = arg_utils.ConvertValue(api_field,
                                        value,
                                        choices=Choice.ToChoiceMap(
                                            f.choices))
         arg_utils.SetFieldInMessage(message_instance, f.api_field,
                                     value)
     return message_instance
Exemplo n.º 6
0
    def _GenerateArguments(self):
        """Generates the arguments for the API fields of this method."""
        message = self.method.GetRequestType()
        args = self._CreateGroups()

        for attributes in self.arg_info:
            field_path = attributes.api_field
            field = arg_utils.GetFieldFromMessage(message, field_path)
            arg = arg_utils.GenerateFlag(field, attributes)
            if attributes.group:
                args[attributes.group.group_id].AddArgument(arg)
            else:
                args[arg.name] = arg
        return args
Exemplo n.º 7
0
  def GetEffectiveResponseType(self):
    """Gets the effective apitools response class for this method.

    This will be different from GetResponseType for List methods if we are
    extracting the list of response items from the overall response. This will
    always match the type of response that Call() returns.

    Returns:
      The apitools Message object.
    """
    response_type = self.GetResponseType()
    item_field = self.ListItemField()
    if item_field:
      response_type = arg_utils.GetFieldFromMessage(
          response_type, item_field).type
    return response_type
Exemplo n.º 8
0
    def _ParseArguments(self, message, namespace):
        """Parse all the arguments from the namespace into the message object.

    Args:
      message: A constructed apitools message object to inject the value into.
      namespace: The argparse namespace.
    """
        message_type = self.method.GetRequestType()
        for attributes in self.arg_info:
            value = arg_utils.GetFromNamespace(namespace, attributes.arg_name)
            if value is None:
                continue
            field = arg_utils.GetFieldFromMessage(message_type,
                                                  attributes.api_field)
            value = arg_utils.ConvertValue(field, value, attributes)
            arg_utils.SetFieldInMessage(message, attributes.api_field, value)
Exemplo n.º 9
0
  def Parse(self, message, namespace):
    """Sets the argument message value, if any, from the parsed args.

    Args:
      message: The API message, None for non-resource args.
      namespace: The parsed command line argument namespace.
    """
    if self.api_field is None:
      return
    value = arg_utils.GetFromNamespace(
        namespace, self.arg_name, fallback=self.fallback)
    if value is None:
      return
    field = arg_utils.GetFieldFromMessage(message, self.api_field)
    value = arg_utils.ConvertValue(field, value, self)
    arg_utils.SetFieldInMessage(message, self.api_field, value)
Exemplo n.º 10
0
    def GenerateType(self, message):
        """Generates an argparse type function to use to parse the argument.

    The return of the type function will be an instance of the given message
    with the fields filled in.

    Args:
      message: The apitools message class.

    Raises:
      InvalidSchemaError: If a type for a field could not be determined.

    Returns:
      f(str) -> message, The type function that parses the ArgDict and returns
      a message instance.
    """
        spec = {}
        for f in self.fields:
            api_field = arg_utils.GetFieldFromMessage(message, f.api_field)
            t = f.type or arg_utils.TYPES.get(api_field.variant)
            if not t:
                raise InvalidSchemaError('Unknown type for field: ' +
                                         f.api_field)
            spec[f.arg_name] = t

        required = [f.arg_name for f in self.fields if f.required]
        arg_dict = arg_parsers.ArgDict(spec=spec, required_keys=required)

        def Parse(arg_value):
            """Inner method that argparse actually calls."""
            result = arg_dict(arg_value)
            message_instance = message()
            for f in self.fields:
                value = result.get(f.arg_name)
                api_field = arg_utils.GetFieldFromMessage(message, f.api_field)
                value = arg_utils.ConvertValue(api_field,
                                               value,
                                               choices=Choice.ToChoiceMap(
                                                   f.choices))
                arg_utils.SetFieldInMessage(message_instance, f.api_field,
                                            value)
            return message_instance

        return Parse
Exemplo n.º 11
0
    def _GetFieldFromMessage(self, message, field_path, section):
        """Digs into the given message to extract the dotted field.

    If the field does not exist, and error is logged.

    Args:
      message: The apitools message to dig into.
      field_path: str, The dotted path of attributes and sub-attributes.
      section: str, The schema section being process (for error reporting).

    Returns:
      The Field or None if that attribute does not exist.
    """
        if not field_path:
            return None
        try:
            return arg_utils.GetFieldFromMessage(message, field_path)
        except arg_utils.UnknownFieldError as e:
            self.E(section, str(e))
            return None
Exemplo n.º 12
0
def ParseDynamicFieldsIntoMessage(message, parameters):
    """Set fields in message corresponding to a dict of usually static fields.

  For repeated fields interpreted as json.

  Args:
    message: The source spec.
    parameters: dict of fields to values. The values are by default interpreted
      as raw string, but values are interpreted as a nested data structure,
      depending on the whitelist.
  """
    parameters = parameters or {}
    for field_path, value in parameters.items():
        field = arg_utils.GetFieldFromMessage(message, field_path)

        if field.repeated and not isinstance(value, list):
            value = arg_utils.ConvertValue(field,
                                           value,
                                           processor=JSONProcessor)
        value = arg_utils.ConvertValue(field, value)

        arg_utils.SetFieldInMessage(message, field_path, value)
Exemplo n.º 13
0
def _GetLabelsClass(message, api_field):
  return arg_utils.GetFieldFromMessage(message, api_field).type
Exemplo n.º 14
0
 def testGetFieldFromMessageError(self):
   with self.assertRaises(arg_utils.UnknownFieldError):
     arg_utils.GetFieldFromMessage(fm.FakeMessage, 'string3')
Exemplo n.º 15
0
 def testGetFieldFromMessage(self, field_path, result):
   self.assertEqual(result,
                    arg_utils.GetFieldFromMessage(fm.FakeMessage, field_path))