async def test_encode_primitive(self, schemaregistry_fully_qualified_namespace, schemaregistry_group, **kwargs):
        sr_client = self.create_client(fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client, group_name=schemaregistry_group, auto_register_schemas=True)

        null_type = """{"type": "null"}"""
        encoded_metadata = await sr_avro_encoder.encode(None, schema=null_type) 
        assert len(encoded_metadata["data"]) == 0 # assert no data encoded
Example #2
0
    async def test_parse_invalid_type(self,
                                      schemaregistry_fully_qualified_namespace,
                                      schemaregistry_group, **kwargs):
        sr_client = self.create_client(
            fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client,
                                      group_name=schemaregistry_group,
                                      auto_register=True)

        schema_no_type = """{
            "name": "User",
            "namespace":"example.avro",
            "fields":[{"name":"name","type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_no_type)

        schema_wrong_type_type = """{
            "name":"User",
            "type":1,
            "namespace":"example.avro",
            "fields":[{"name":"name","type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_wrong_type_type)
    async def test_parse_primitive_types(self, schemaregistry_fully_qualified_namespace, schemaregistry_group, **kwargs):
        sr_client = self.create_client(fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client, group_name=schemaregistry_group, auto_register_schemas=True)

        primitive_string = "string"
        with pytest.raises(SchemaParseError) as e:
            await sr_avro_encoder.encode("hello", schema=primitive_string) 
    async def test_basic_sr_avro_encoder_decode_readers_schema(self, schemaregistry_fully_qualified_namespace, schemaregistry_group, **kwargs):
        sr_client = self.create_client(schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client, group_name=schemaregistry_group, auto_register_schemas=True)

        schema_str = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}]}"""

        dict_data = {"name": u"Ben", "favorite_number": 7, "favorite_color": u"red"}
        encoded_metadata = await sr_avro_encoder.encode(dict_data, schema=schema_str)
        content_type = encoded_metadata["content_type"]
        encoded_data = encoded_metadata["data"]

        # readers_schema with removed field
        readers_schema_remove_field = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]}]}"""
        encoded_data_dict = {"data": encoded_data, "content_type": content_type}
        decoded_data = await sr_avro_encoder.decode(encoded_data_dict, readers_schema=readers_schema_remove_field)
        assert decoded_data["name"] == u"Ben"
        assert decoded_data["favorite_number"] == 7

        # readers_schema with extra field with default
        readers_schema_extra_field = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}, {"name":"favorite_city","type":["string","null"], "default": "Redmond"}]}"""
        encoded_data_dict = {"data": encoded_data, "content_type": content_type}
        decoded_data = await sr_avro_encoder.decode(encoded_data_dict, readers_schema=readers_schema_extra_field)
        assert decoded_data["name"] == u"Ben"
        assert decoded_data["favorite_number"] == 7
        assert decoded_data["favorite_color"] == "red"
        assert decoded_data["favorite_city"] == "Redmond"

        # readers_schema with changed name results in error
        readers_schema_change_name = """{"namespace":"fakeexample.avro","type":"record","name":"fake_user","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}]}"""
        with pytest.raises(SchemaDecodeError):
            encoded_data_dict = {"data": encoded_data, "content_type": content_type}
            decoded_data = await sr_avro_encoder.decode(encoded_data_dict, readers_schema=readers_schema_change_name)
            print(decoded_data)
Example #5
0
    async def test_parse_fixed_types(self,
                                     schemaregistry_fully_qualified_namespace,
                                     schemaregistry_group, **kwargs):
        sr_client = self.create_client(
            fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client,
                                      group_name=schemaregistry_group,
                                      auto_register=True)

        # avro bug: should give warning from IgnoredLogicalType error since precision < 0
        #fixed_type_ignore_logical_type_error = """{"type": "fixed", "size": 4, "namespace":"example.avro", "name":"User", "precision": -1}"""
        #await sr_avro_encoder.encode({}, schema=fixed_type_ignore_logical_type_error)

        schema_no_size = """{"type": "fixed", "name":"User"}"""
        with pytest.raises(InvalidSchemaError):  # caught AvroException
            await sr_avro_encoder.encode({}, schema=schema_no_size)

        schema_no_name = """{"type": "fixed", "size": 3}"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({}, schema=schema_no_name)

        schema_wrong_name = """{"type": "fixed", "name": 1, "size": 3}"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({}, schema=schema_wrong_name)

        schema_wrong_namespace = """{"type": "fixed", "name": "User", "size": 3, "namespace": 1}"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({}, schema=schema_wrong_namespace)
    async def test_encode_record(self, schemaregistry_fully_qualified_namespace, schemaregistry_group, **kwargs):
        sr_client = self.create_client(fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client, group_name=schemaregistry_group, auto_register_schemas=True)

        # add below to schema later if possible
        # {"name":"example.innerrec","type":"record","fields":[{"name":"a","type":"int"}]},
        # {"name":"innerenum","type":"enum","symbols":["FOO", "BAR"]},
        # {"name":"innerarray","type":"array","items":"int"},
        # {"name":"innermap","type":"map","values":"int"},
        # {"name":"innerfixed","type":"fixed","size":74}
        schema_record = """{
            "name":"User",
            "namespace":"example.avro.populatedrecord",
            "type":"record",
            "fields":[
                {"name":"name","type":"string"},
                {"name":"age","type":"int"},
                {"name":"married","type":"boolean"},
                {"name":"height","type":"float"},
                {"name":"randb","type":"bytes"}
            ]
        }"""
        data = {
            "name": u"Ben",
            "age": 3,
            "married": False,
            "height": 13.5,
            "randb": b"\u00FF"
        }

        encoded_metadata = await sr_avro_encoder.encode(data, schema=schema_record)
        decoded_data = await sr_avro_encoder.decode(encoded_metadata)
        assert decoded_data == data
Example #7
0
async def main():
    schema_registry = SchemaRegistryClient(
        fully_qualified_namespace=SCHEMAREGISTRY_FULLY_QUALIFIED_NAMESPACE,
        credential=token_credential,
    )
    encoder = AvroEncoder(client=schema_registry,
                          group_name=GROUP_NAME,
                          auto_register_schemas=True)
    event_data_ben = await encode_with_callback(encoder)
    await encoder.close()
    await token_credential.close()
 async def test_parse_invalid_json_string(self, schemaregistry_fully_qualified_namespace, schemaregistry_group, **kwargs):
     sr_client = self.create_client(fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
     sr_avro_encoder = AvroEncoder(client=sr_client, group_name=schemaregistry_group, auto_register_schemas=True)
     invalid_schema = {
         "name":"User",
         "type":"record",
         "namespace":"example.avro",
         "fields":[{"name":"name","type":"string"}]
     }
     invalid_schema_string = "{}".format(invalid_schema)
     with pytest.raises(SchemaParseError):    # caught avro SchemaParseError
         await sr_avro_encoder.encode({"name": u"Ben"}, schema=invalid_schema_string) 
Example #9
0
async def main():
    schema_registry = SchemaRegistryClient(
        fully_qualified_namespace=SCHEMAREGISTRY_FULLY_QUALIFIED_NAMESPACE,
        credential=token_credential,
    )
    encoder = AvroEncoder(client=schema_registry,
                          group_name=GROUP_NAME,
                          auto_register_schemas=True)
    event_data = await encode_metadata_dict(encoder)
    decoded_data = await decode_with_data_and_content_type(encoder, event_data)
    await encoder.close()
    await token_credential.close()
    async def test_parse_error_schema_as_record(self, schemaregistry_fully_qualified_namespace, schemaregistry_group, **kwargs):
        sr_client = self.create_client(fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client, group_name=schemaregistry_group, auto_register_schemas=True)

        schema_error_type = """{
            "name":"User",
            "namespace":"example.avro.error",
            "type":"error",
            "fields":[{"name":"name","type":"string"}]
        }"""
        encoded_metadata = await sr_avro_encoder.encode({"name": u"Ben"}, schema=schema_error_type) 
        schema_id = encoded_metadata["content_type"].split("+")[1]
        registered_schema = await sr_client.get_schema(schema_id)
        decoded_registered_schema = json.loads(registered_schema.definition)
        assert decoded_registered_schema["type"] == "error"
async def main():
    schema_registry = SchemaRegistryClient(
        fully_qualified_namespace=SCHEMAREGISTRY_FULLY_QUALIFIED_NAMESPACE,
        credential=token_credential,
    )
    encoder = AvroEncoder(client=schema_registry,
                          group_name=GROUP_NAME,
                          auto_register=True)
    event_data_ben, event_data_alice = await encode_to_event_data_message(
        encoder)
    decoded_content_ben = await decode_event_data_message(
        encoder, event_data_ben)
    decoded_content_alice = await decode_event_data_message(
        encoder, event_data_alice)
    await encoder.close()
    await token_credential.close()
Example #12
0
    async def test_basic_sr_avro_encoder_without_auto_register_schemas(
            self, schemaregistry_fully_qualified_namespace,
            schemaregistry_group, **kwargs):
        sr_client = self.create_client(
            fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client,
                                      group_name=schemaregistry_group,
                                      auto_register=True)

        async with sr_client:
            schema_str = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}]}"""
            schema_str = "{\"type\": \"record\", \"name\": \"User\", \"namespace\": \"example.avro\", \"fields\": [{\"type\": \"string\", \"name\": \"name\"}, {\"type\": [\"int\", \"null\"], \"name\": \"favorite_number\"}, {\"type\": [\"string\", \"null\"], \"name\": \"favorite_color\"}]}"
            schema = avro.schema.parse(schema_str)

            dict_content = {
                "name": u"Ben",
                "favorite_number": 7,
                "favorite_color": u"red"
            }
            encoded_message_content = await sr_avro_encoder.encode(
                dict_content, schema=schema_str)
            content_type = encoded_message_content["content_type"]
            encoded_content = encoded_message_content["content"]

            assert content_type.split("+")[0] == 'avro/binary'
            schema_properties = await sr_client.get_schema_properties(
                schemaregistry_group, schema.fullname, str(schema), "Avro")
            schema_id = schema_properties.id
            assert content_type.split("+")[1] == schema_id

            encoded_content_dict = {
                "content": encoded_content,
                "content_type": content_type
            }
            decoded_content = await sr_avro_encoder.decode(encoded_content_dict
                                                           )
            assert decoded_content["name"] == u"Ben"
            assert decoded_content["favorite_number"] == 7
            assert decoded_content["favorite_color"] == u"red"
Example #13
0
    async def test_basic_sr_avro_encoder_with_request_options(self, **kwargs):
        schemaregistry_fully_qualified_namespace = kwargs.pop(
            "schemaregistry_fully_qualified_namespace")
        schemaregistry_group = kwargs.pop("schemaregistry_group")
        sr_client = self.create_client(
            fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client,
                                      group_name=schemaregistry_group,
                                      auto_register=True)

        schema_str = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}]}"""

        dict_content = {
            "name": u"Ben",
            "favorite_number": 7,
            "favorite_color": u"red"
        }
        with pytest.raises(TypeError) as e:
            encoded_message_content = await sr_avro_encoder.encode(
                dict_content,
                schema=schema_str,
                request_options={"fake_kwarg": True})
        assert 'request() got an unexpected keyword' in str(e.value)
        encoded_message_content = await sr_avro_encoder.encode(
            dict_content, schema=schema_str)
        content_type = encoded_message_content["content_type"]
        encoded_content = encoded_message_content["content"]

        encoded_content_dict = {
            "content": encoded_content,
            "content_type": content_type
        }
        with pytest.raises(TypeError) as e:
            decoded_content = await sr_avro_encoder.decode(
                encoded_content_dict, request_options={"fake_kwarg": True})
        assert 'request() got an unexpected keyword' in str(e.value)
Example #14
0
    async def test_parse_record_fields(
            self, schemaregistry_fully_qualified_namespace,
            schemaregistry_group, **kwargs):
        sr_client = self.create_client(
            fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client,
                                      group_name=schemaregistry_group,
                                      auto_register=True)

        schema_no_fields = """{
            "name":"User",
            "namespace":"example.avro",
            "type":"record"
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_no_fields)

        schema_wrong_type_fields = """{
            "name":"User",
            "namespace":"example.avro",
            "type":"record"
            "fields": "hello"
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_wrong_type_fields)

        schema_wrong_field_item_type = """{
            "name":"User",
            "namespace":"example.avro",
            "type":"record"
            "fields": ["hello"]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_wrong_field_item_type)

        schema_record_field_no_name = """{
            "name":"User",
            "namespace":"example.avro",
            "type":"record",
            "fields":[{"type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_record_field_no_name)

        schema_record_field_wrong_type_name = """{
            "name":"User",
            "namespace":"example.avro",
            "type":"record",
            "fields":[{"name": 1, "type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode(
                {"name": u"Ben"}, schema=schema_record_field_wrong_type_name)

        schema_record_field_with_invalid_order = """{
            "name":"User",
            "namespace":"example.avro.order",
            "type":"record",
            "fields":[{"name":"name","type":"string","order":"fake_order"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode(
                {"name": u"Ben"},
                schema=schema_record_field_with_invalid_order)

        schema_record_duplicate_fields = """{
            "name":"User",
            "namespace":"example.avro",
            "type":"record",
            "fields":[{"name":"name","type":"string"}, {"name":"name","type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_record_duplicate_fields)

        schema_field_type_invalid = """{
            "name":"User",
            "namespace":"example.avro",
            "type":"record",
            "fields":[{"name":"name","type":1}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_field_type_invalid)
Example #15
0
    async def test_parse_record_name(self,
                                     schemaregistry_fully_qualified_namespace,
                                     schemaregistry_group, **kwargs):
        sr_client = self.create_client(
            fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client,
                                      group_name=schemaregistry_group,
                                      auto_register=True)

        schema_name_has_dot = """{
            "namespace": "thrownaway",
            "name":"User.avro",
            "type":"record",
            "fields":[{"name":"name","type":"string"}]
        }"""
        encoded_schema = await sr_avro_encoder.encode(
            {"name": u"Ben"}, schema=schema_name_has_dot)
        schema_id = encoded_schema["content_type"].split("+")[1]
        registered_schema = await sr_client.get_schema(schema_id)
        decoded_registered_schema = json.loads(registered_schema.definition)

        assert decoded_registered_schema["name"] == "User.avro"
        assert decoded_registered_schema["namespace"] == "thrownaway"

        schema_name_no_namespace = """{
            "name":"User",
            "type":"record",
            "fields":[{"name":"name","type":"string"}]
        }"""
        encoded_schema = await sr_avro_encoder.encode(
            {"name": u"Ben"}, schema=schema_name_no_namespace)
        schema_id = encoded_schema["content_type"].split("+")[1]
        registered_schema = await sr_client.get_schema(schema_id)
        decoded_registered_schema = json.loads(registered_schema.definition)

        assert decoded_registered_schema["name"] == "User"
        assert "namespace" not in decoded_registered_schema

        schema_invalid_fullname = """{
            "name":"abc",
            "type":"record",
            "namespace":"9example.avro",
            "fields":[{"name":"name","type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_invalid_fullname)

        schema_invalid_name_in_fullname = """{
            "name":"1abc",
            "type":"record",
            "fields":[{"name":"name","type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode(
                {"name": u"Ben"}, schema=schema_invalid_name_in_fullname)

        schema_invalid_name_reserved_type = """{
            "name":"record",
            "type":"record",
            "fields":[{"name":"name","type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode(
                {"name": u"Ben"}, schema=schema_invalid_name_reserved_type)

        schema_wrong_type_name = """{
            "name":1,
            "type":"record",
            "namespace":"example.avro",
            "fields":[{"name":"name","type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_wrong_type_name)

        schema_no_name = """{
            "namespace":"example.avro",
            "type":"record",
            "fields":[{"name":"name","type":"string"}]
        }"""
        with pytest.raises(InvalidSchemaError):
            await sr_avro_encoder.encode({"name": u"Ben"},
                                         schema=schema_no_name)
Example #16
0
    async def test_basic_sr_avro_encoder_with_auto_register_schemas(
            self, schemaregistry_fully_qualified_namespace,
            schemaregistry_group, **kwargs):
        sr_client = self.create_client(
            fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client,
                                      group_name=schemaregistry_group,
                                      auto_register=True)

        async with sr_client:
            schema_str = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}]}"""
            schema_str = "{\"type\": \"record\", \"name\": \"User\", \"namespace\": \"example.avro\", \"fields\": [{\"type\": \"string\", \"name\": \"name\"}, {\"type\": [\"int\", \"null\"], \"name\": \"favorite_number\"}, {\"type\": [\"string\", \"null\"], \"name\": \"favorite_color\"}]}"
            schema = avro.schema.parse(schema_str)

            dict_content = {
                "name": u"Ben",
                "favorite_number": 7,
                "favorite_color": u"red"
            }
            encoded_message_content = await sr_avro_encoder.encode(
                dict_content, schema=schema_str)
            content_type = encoded_message_content["content_type"]
            encoded_content = encoded_message_content["content"]

            # wrong data type
            dict_content_bad = {
                "name": u"Ben",
                "favorite_number": 7,
                "favorite_color": 7
            }
            with pytest.raises(InvalidContentError) as e:
                encoded_message_content = await sr_avro_encoder.encode(
                    dict_content_bad, schema=schema_str)
            assert "schema_id" in e.value.details

            assert content_type.split("+")[0] == 'avro/binary'
            schema_properties = await sr_client.get_schema_properties(
                schemaregistry_group, schema.fullname, str(schema), "Avro")
            schema_id = schema_properties.id
            assert content_type.split("+")[1] == schema_id

            encoded_content_dict = {
                "content": encoded_content,
                "content_type": content_type
            }
            decoded_content = await sr_avro_encoder.decode(encoded_content_dict
                                                           )
            assert decoded_content["name"] == u"Ben"
            assert decoded_content["favorite_number"] == 7
            assert decoded_content["favorite_color"] == u"red"

            # bad content type
            encoded_content_dict["content_type"] = 'a+b+c'
            with pytest.raises(InvalidContentError) as e:
                decoded_content = await sr_avro_encoder.decode(
                    encoded_content_dict)

            # check that AvroEncoder won't work with message types that don't follow protocols
            class BadExample:
                def __init__(self, not_content):
                    self.not_content = not_content

            with pytest.raises(TypeError) as e:
                await sr_avro_encoder.encode({"name": u"Ben"},
                                             schema=schema_str,
                                             message_type=BadExample)
            assert "subtype of the MessageType" in (str(e.value))

            bad_ex = BadExample('fake')
            with pytest.raises(TypeError) as e:
                await sr_avro_encoder.decode(message=bad_ex)
            assert "subtype of the MessageType" in (str(e.value))

            # check that AvroEncoder will work with message types that follow protocols
            class GoodExample:
                def __init__(self, content, **kwargs):
                    self.content = content
                    self.content_type = None
                    self.extra = kwargs.pop('extra', None)

                @classmethod
                def from_message_content(cls, content: bytes,
                                         content_type: str, **kwargs):
                    ge = cls(content)
                    ge.content_type = content_type
                    return ge

                def __message_content__(self):
                    return {
                        "content": self.content,
                        "content_type": self.content_type
                    }

            good_ex_obj = await sr_avro_encoder.encode(
                dict_content,
                schema=schema_str,
                message_type=GoodExample,
                extra='val')
            decoded_content_obj = await sr_avro_encoder.decode(
                message=good_ex_obj)

            assert decoded_content_obj["name"] == u"Ben"
            assert decoded_content_obj["favorite_number"] == 7
            assert decoded_content_obj["favorite_color"] == u"red"
Example #17
0
    async def test_basic_sr_avro_encoder_decode_readers_schema(
            self, schemaregistry_fully_qualified_namespace,
            schemaregistry_group, **kwargs):
        sr_client = self.create_client(
            fully_qualified_namespace=schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client,
                                      group_name=schemaregistry_group,
                                      auto_register=True)

        schema_str = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}]}"""

        dict_content = {
            "name": u"Ben",
            "favorite_number": 7,
            "favorite_color": u"red"
        }
        encoded_message_content = await sr_avro_encoder.encode(
            dict_content, schema=schema_str)
        content_type = encoded_message_content["content_type"]
        encoded_content = encoded_message_content["content"]

        # readers_schema with removed field
        readers_schema_remove_field = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]}]}"""
        encoded_content_dict = {
            "content": encoded_content,
            "content_type": content_type
        }
        decoded_content = await sr_avro_encoder.decode(
            encoded_content_dict, readers_schema=readers_schema_remove_field)
        assert decoded_content["name"] == u"Ben"
        assert decoded_content["favorite_number"] == 7

        # readers_schema with extra field with default
        readers_schema_extra_field = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}, {"name":"favorite_city","type":["string","null"], "default": "Redmond"}]}"""
        encoded_content_dict = {
            "content": encoded_content,
            "content_type": content_type
        }
        decoded_content = await sr_avro_encoder.decode(
            encoded_content_dict, readers_schema=readers_schema_extra_field)
        assert decoded_content["name"] == u"Ben"
        assert decoded_content["favorite_number"] == 7
        assert decoded_content["favorite_color"] == "red"
        assert decoded_content["favorite_city"] == "Redmond"

        # readers_schema with changed name results in error
        readers_schema_change_name = """{"namespace":"fakeexample.avro","type":"record","name":"fake_user","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}]}"""
        with pytest.raises(InvalidSchemaError) as e:
            decoded_content = await sr_avro_encoder.decode(
                encoded_content_dict,
                readers_schema=readers_schema_change_name)
        assert "Incompatible schemas" in e.value.message
        assert "schema_id" in e.value.details
        assert "schema_definition" in e.value.details

        # invalid readers_schema
        invalid_schema = {
            "name": "User",
            "type": "record",
            "namespace": "example.avro",
            "fields": [{
                "name": "name",
                "type": "string"
            }]
        }
        invalid_schema_string = "{}".format(invalid_schema)
        with pytest.raises(InvalidSchemaError) as e:
            decoded_content = await sr_avro_encoder.decode(
                encoded_content_dict, readers_schema=invalid_schema_string)
        assert "Invalid schema" in e.value.message
        assert "schema_id" in e.value.details
        assert "schema_definition" in e.value.details
 "fields": [
     {"name": "name", "type": "string"},
     {"name": "favorite_number",  "type": ["int", "null"]},
     {"name": "favorite_color", "type": ["string", "null"]}
 ]
}"""

# create an EventHubProducerClient instance
eventhub_producer = EventHubProducerClient.from_connection_string(
    conn_str=EVENTHUB_CONNECTION_STR, eventhub_name=EVENTHUB_NAME)
# create a AvroEncoder instance
azure_credential = DefaultAzureCredential()
# create a AvroEncoder instance
avro_encoder = AvroEncoder(client=SchemaRegistryClient(
    fully_qualified_namespace=SCHEMAREGISTRY_FULLY_QUALIFIED_NAMESPACE,
    credential=azure_credential),
                           group_name=GROUP_NAME,
                           auto_register=True)


async def send_event_data_batch(producer, encoder):
    event_data_batch = await producer.create_batch()
    dict_content = {
        "name": "Bob",
        "favorite_number": 7,
        "favorite_color": "red"
    }
    # Use the encode method to convert dict object to bytes with the given avro schema and set body of EventData.
    # The encode method will automatically register the schema into the Schema Registry Service and
    # schema will be cached locally for future usage.
    event_data = await encoder.encode(content=dict_content,
    async def test_basic_sr_avro_encoder_with_auto_register_schemas(self, schemaregistry_fully_qualified_namespace, schemaregistry_group, **kwargs):
        sr_client = self.create_client(schemaregistry_fully_qualified_namespace)
        sr_avro_encoder = AvroEncoder(client=sr_client, group_name=schemaregistry_group, auto_register_schemas=True)

        async with sr_client:
            schema_str = """{"namespace":"example.avro","type":"record","name":"User","fields":[{"name":"name","type":"string"},{"name":"favorite_number","type":["int","null"]},{"name":"favorite_color","type":["string","null"]}]}"""
            schema_str = "{\"type\": \"record\", \"name\": \"User\", \"namespace\": \"example.avro\", \"fields\": [{\"type\": \"string\", \"name\": \"name\"}, {\"type\": [\"int\", \"null\"], \"name\": \"favorite_number\"}, {\"type\": [\"string\", \"null\"], \"name\": \"favorite_color\"}]}"
            schema = avro.schema.parse(schema_str)

            dict_data = {"name": u"Ben", "favorite_number": 7, "favorite_color": u"red"}
            encoded_metadata = await sr_avro_encoder.encode(dict_data, schema=schema_str)
            content_type = encoded_metadata["content_type"]
            encoded_data = encoded_metadata["data"]

            assert content_type.split("+")[0] == 'avro/binary'
            schema_properties = await sr_client.get_schema_properties(schemaregistry_group, schema.fullname, str(schema), "Avro")
            schema_id = schema_properties.id
            assert content_type.split("+")[1] == schema_id

            encoded_data_dict = {"data": encoded_data, "content_type": content_type}
            decoded_data = await sr_avro_encoder.decode(encoded_data_dict)
            assert decoded_data["name"] == u"Ben"
            assert decoded_data["favorite_number"] == 7
            assert decoded_data["favorite_color"] == u"red"

            # check that AvroEncoder won't work with message types that don't follow protocols
            class BadExample:
                def __init__(self, not_data):
                    self.not_data = not_data

            with pytest.raises(SchemaEncodeError) as e:    # caught avro SchemaParseError
                await sr_avro_encoder.encode({"name": u"Ben"}, schema=schema_str, message_type=BadExample) 
            assert "subtype of the MessageType" in (str(e.value))

            bad_ex = BadExample('fake')
            with pytest.raises(SchemaDecodeError) as e:    # caught avro SchemaParseError
                await sr_avro_encoder.decode(message=bad_ex) 
            assert "subtype of the MessageType" in (str(e.value))

            # check that AvroEncoder will work with message types that follow protocols
            class GoodExample:
                def __init__(self, data: bytes, content_type: str, **kwargs):
                    self.data = data
                    self.content_type = content_type
                    self.extra = kwargs.pop('extra', None)

                def __message_data__(self):
                    return {"data": self.data, "content_type": self.content_type}

            def good_callback(data: bytes, content_type: str, **kwargs):
                return GoodExample(data, content_type, **kwargs)
                
            good_ex_obj = await sr_avro_encoder.encode(dict_data, schema=schema_str, message_type=GoodExample, extra='val')
            good_ex_callback = await sr_avro_encoder.encode(dict_data, schema=schema_str, message_type=good_callback, extra='val')
            decoded_data_obj = await sr_avro_encoder.decode(message=good_ex_obj)
            decoded_data_callback = await sr_avro_encoder.decode(message=good_ex_callback)

            assert decoded_data_obj["name"] == u"Ben"
            assert decoded_data_obj["favorite_number"] == 7
            assert decoded_data_obj["favorite_color"] == u"red"
            assert decoded_data_callback["name"] == u"Ben"
            assert decoded_data_callback["favorite_number"] == 7
            assert decoded_data_callback["favorite_color"] == u"red"