Exemple #1
0
    def _ParseArguments(self, namespace, prefix, message):
        """Recursively generates the request message and any sub-messages.

    Args:
      namespace: The argparse namespace containing the all the parsed arguments.
      prefix: str, The flag prefix for the sub-message being generated.
      message: The apitools class for the message.

    Returns:
      The instantiated apitools Message with all fields filled in from flags.
    """
        kwargs = {}
        for field in message.all_fields():
            arg_name = self._GetArgName(field.name)
            if not arg_name:
                continue
            arg_name = prefix + arg_name
            # Field is a sub-message, recursively generate it.
            if field.variant == messages.Variant.MESSAGE:
                sub_kwargs = self._ParseArguments(namespace, arg_name + '.',
                                                  field.type)
                if sub_kwargs:
                    # Only construct the sub-message if we have something to put in it.
                    value = field.type(**sub_kwargs)
                    # TODO(b/38000796): Handle repeated fields correctly.
                    kwargs[field.name] = value if not field.repeated else [
                        value
                    ]
            # Field is a scalar, just get the value.
            else:
                value = arg_utils.GetFromNamespace(namespace, arg_name)
                if value is not None:
                    kwargs[field.name] = arg_utils.ConvertValue(field, value)
        return kwargs
Exemple #2
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
 def Parse(arg_value):
     """Inner method that argparse actually calls."""
     result = arg_dict(arg_value)
     messages = []
     for k, v in sorted(six.iteritems(result)):
         message_instance = message()
         arg_utils.SetFieldInMessage(
             message_instance, self.key_spec.api_field,
             arg_utils.ConvertValue(key_field,
                                    k,
                                    choices=self.key_spec.ChoiceMap()))
         arg_utils.SetFieldInMessage(
             message_instance, self.value_spec.api_field,
             arg_utils.ConvertValue(
                 value_field, v, choices=self.value_spec.ChoiceMap()))
         messages.append(message_instance)
     return messages
Exemple #4
0
  def testConvertValueEnum(self):
    choices = [
        yaml_command_schema_util.Choice({'arg_value': 'a',
                                         'enum_value': 'thing-one'}),
        yaml_command_schema_util.Choice({'arg_value': 'c',
                                         'enum_value': 'thing-two'})]
    choices = yaml_command_schema_util.Choice.ToChoiceMap(choices)

    # Non-repeated.
    self.assertEqual(
        fm.FakeMessage.FakeEnum.THING_ONE,
        arg_utils.ConvertValue(fm.FakeMessage.enum1, 'a', choices=choices))
    self.assertEqual(
        fm.FakeMessage.FakeEnum.THING_TWO,
        arg_utils.ConvertValue(fm.FakeMessage.enum1, 'c', choices=choices))
    self.assertEqual(
        fm.FakeMessage.FakeEnum.THING_ONE,
        arg_utils.ConvertValue(fm.FakeMessage.enum1, 'thing-one',
                               choices=choices))
    self.assertEqual(
        fm.FakeMessage.FakeEnum.THING_TWO,
        arg_utils.ConvertValue(fm.FakeMessage.enum1, 'thing-two',
                               choices=choices))

    # Repeated.
    self.assertEqual(
        [fm.FakeMessage.FakeEnum.THING_ONE, fm.FakeMessage.FakeEnum.THING_TWO],
        arg_utils.ConvertValue(fm.FakeMessage.enum2, ['a', 'c'],
                               choices=choices))

    # Repeated field, but forced singular arg.
    self.assertEqual(
        [fm.FakeMessage.FakeEnum.THING_ONE],
        arg_utils.ConvertValue(
            fm.FakeMessage.enum2, 'a', repeated=False, choices=choices))
    self.assertEqual(
        [fm.FakeMessage.FakeEnum.THING_TWO],
        arg_utils.ConvertValue(
            fm.FakeMessage.enum2, 'c', repeated=False, choices=choices))
    self.assertEqual(
        [fm.FakeMessage.FakeEnum.THING_ONE],
        arg_utils.ConvertValue(
            fm.FakeMessage.enum2, 'thing-one', repeated=False, choices=choices))
    self.assertEqual(
        [fm.FakeMessage.FakeEnum.THING_TWO],
        arg_utils.ConvertValue(
            fm.FakeMessage.enum2, 'thing-two', repeated=False, choices=choices))
Exemple #5
0
  def testConvertValueWithProcessor(self):

    def P(value):
      return '!' + value

    def Q(value):
      return ['!' + v for v in value]

    # Non-repeated.
    self.assertEqual(
        '!a',
        arg_utils.ConvertValue(fm.FakeMessage.string1, 'a', processor=P))
    # Repeated.
    self.assertEqual(
        ['!a', '!b'],
        arg_utils.ConvertValue(fm.FakeMessage.string2, ['a', 'b'], processor=Q))
    # Repeated field, but forced singular arg.
    self.assertEqual(
        ['!a'],
        arg_utils.ConvertValue(fm.FakeMessage.string2, 'a', processor=P,
                               repeated=False))
Exemple #6
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)
 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
    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)
Exemple #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)
Exemple #10
0
  def testConvertValueWithChoices(self):
    choices = [
        yaml_command_schema_util.Choice({'arg_value': 'a', 'enum_value': 'b'}),
        yaml_command_schema_util.Choice({'arg_value': 'c', 'enum_value': 'd'})]
    choices = yaml_command_schema_util.Choice.ToChoiceMap(choices)

    # Value not provided.
    self.assertEqual(
        None,
        arg_utils.ConvertValue(fm.FakeMessage.string1, None, choices=choices))

    # Non-repeated.
    self.assertEqual(
        'b',
        arg_utils.ConvertValue(fm.FakeMessage.string1, 'a', choices=choices))
    self.assertEqual(
        'd',
        arg_utils.ConvertValue(fm.FakeMessage.string1, 'c', choices=choices))
    # Make sure case insensitive works.
    self.assertEqual(
        'b',
        arg_utils.ConvertValue(fm.FakeMessage.string1, 'A', choices=choices))
    # Repeated.
    self.assertEqual(
        ['b', 'b', 'd', 'd'],
        arg_utils.ConvertValue(
            fm.FakeMessage.string2, ['a', 'b', 'c', 'd'], choices=choices))

    # Repeated field, but forced singular arg.
    self.assertEqual(
        ['b'],
        arg_utils.ConvertValue(
            fm.FakeMessage.string2, 'a', repeated=False, choices=choices))
    self.assertEqual(
        ['d'],
        arg_utils.ConvertValue(
            fm.FakeMessage.string2, 'c', repeated=False, choices=choices))