Exemple #1
0
    def test_schema_match_their_examples(self, schema_path_with_example):
        schema = Schema.get_schema(schema_path_with_example)
        validator = Schema.get_validator(schema_path_with_example)
        examples = schema["examples"]

        for example in examples:
            validator.validate_all(example)
Exemple #2
0
class CreateGroupMembership(JSONAPIData):
    """The data to add a user to a group."""

    validator = Schema.get_validator(
        "bulk_api/command/create_group_membership.json")

    @classmethod
    def create(cls, user_ref, group_ref):  # pylint: disable=arguments-differ
        """Create a create group membership body for adding users to groups.

        :param user_ref: Custom user reference
        :param group_ref: Custom group reference
        :return: A CreateGroupMembership instance
        """
        return super().create(
            DataType.GROUP_MEMBERSHIP,
            relationships={
                "member": {
                    "data": {
                        "type": DataType.USER.value,
                        "id": {
                            "$ref": user_ref
                        }
                    }
                },
                "group": {
                    "data": {
                        "type": DataType.GROUP.value,
                        "id": {
                            "$ref": group_ref
                        }
                    }
                },
            },
        )

    @property
    def member(self):
        """Get the user which is a member of this group.

        :return: A value object with `id` and `ref` properties.
        """
        return _IdRef(self.relationships["member"]["data"]["id"])

    @property
    def group(self):
        """Get the group which this user is a member of.

        :return: A value object with `id` and `ref` properties.
        """
        return _IdRef(self.relationships["group"]["data"]["id"])
Exemple #3
0
def schema_with_examples():
    for file_name in schema_file_names():
        schema = Schema.get_schema(file_name)

        if "examples" in schema:
            yield file_name

        defs = schema.get("$defs")
        if not defs:
            continue

        for key, sub_schema in defs.items():
            if "examples" in sub_schema:
                yield f"{file_name}#/$defs/{key}"
Exemple #4
0
class Command(Model):
    """A single abstract command provided to the API."""

    validator = Schema.get_validator("bulk_api/wrapper.json")
    validation_error_title = "Cannot interpret command as the wrapper is malformed"

    def validate(self):  # pylint: disable=arguments-differ
        """Validate this object and it's body meet their declared schema."""
        super().validate()

        if isinstance(self.body, Model):
            self.body.validate()

    @classmethod
    def create(cls, type_, body):
        """Create a command.

        :param type_: The CommandType of the command
        :param body: The payload for the command
        :return: An instance of Command
        """
        return cls([CommandType(type_).value, cls.extract_raw(body)])

    @property
    def type(self):
        """Get the command type.

        :return: The CommandType of this command
        """
        return CommandType(self.raw[0])

    @property
    def body(self):
        """Get the body of this command.

        :return: The raw body
        """
        return self.raw[1]

    def __repr__(self):
        return f"<{self.__class__.__name__} {self.body}>"
Exemple #5
0
class UpsertGroup(UpsertBody):
    """The data to upsert a group."""

    validator = Schema.get_validator("bulk_api/command/upsert_group.json")
    data_type = DataType.GROUP
    query_fields = ["authority", "authority_provided_id"]
Exemple #6
0
class UpsertUser(UpsertBody):
    """The data to upsert a user."""

    validator = Schema.get_validator("bulk_api/command/upsert_user.json")
    data_type = DataType.USER
    query_fields = ["authority", "username"]
Exemple #7
0
 def test_schema_is_a_valid_schema(self, schema_path):
     schema = Schema.get_schema(schema_path)
     Draft7Validator.check_schema(schema)
Exemple #8
0
def get_schema_example(schema_path):
    return deepcopy(Schema.get_schema(schema_path)["examples"][0])
Exemple #9
0
class Configuration(Model):
    """Configuration settings for a Bulk API request."""

    validator = Schema.get_validator("bulk_api/command/configuration.json")

    WILD_CARD = "*"

    @classmethod
    def create(cls, effective_user, total_instructions, view=None):
        """Create a configuration object.

        :param effective_user: User to execute the command as
        :param total_instructions: Number of instructions (including this)
        :param view: Return style requested by the client
        :return: A Configuration object
        """
        return cls({
            "view":
            ViewType(view).value,
            "user": {
                "effective": effective_user
            },
            "instructions": {
                "total": int(total_instructions)
            },
            "defaults": [
                ["create", "*", {
                    "on_duplicate": "continue"
                }],
                ["upsert", "*", {
                    "merge_query": True
                }],
            ],
        })

    @property
    def view(self):
        """Get the return type of view requested by the user."""
        return ViewType(self.raw["view"])

    @property
    def effective_user(self):
        """Get the user to execute the request as."""
        return self.raw["user"]["effective"]

    @property
    def total_instructions(self):
        """Get the number of instructions in the request.

        This count includes configuration commands.
        """
        return self.raw["instructions"]["total"]

    def defaults_for(self, command_type, data_type):
        """Provide default configuration for the given command and data type.

        This will use any wild card options first, overlaying more specific
        defaults as they are found.

        :param command_type: Type of modification (e.g. Types.UPSERT)
        :param data_type: Data type being modified
        :return: A dict of config
        """
        defaults = self._command_defaults

        config = {}

        wild = defaults.get(self.WILD_CARD, {})
        specific = defaults.get(CommandType(command_type), {})
        data_type = DataType(data_type)

        for container in (wild, specific):
            if self.WILD_CARD in container:
                config.update(container[self.WILD_CARD])

            if data_type in container:
                config.update(container[data_type])

        return config

    @property
    @lru_cache(1)
    def _command_defaults(self):
        config = defaultdict(dict)

        for command_type, data_type, defaults in self.raw["defaults"]:
            if command_type != self.WILD_CARD:
                command_type = CommandType(command_type)

            if data_type != self.WILD_CARD:
                data_type = DataType(data_type)

            config[command_type][data_type] = defaults

        return config