This is an automated email from the ASF dual-hosted git repository. penghui pushed a commit to branch branch-2.8 in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/branch-2.8 by this push: new e5a5498 [Python Schema] Support setting namespace for python schema (#12175) e5a5498 is described below commit e5a54984656226246deb1f70de47f4f0764ce7cc Author: ran <gaoran...@126.com> AuthorDate: Sat Sep 25 10:34:50 2021 +0800 [Python Schema] Support setting namespace for python schema (#12175) * support set namespace for python schema * fix * fix * fix comment (cherry picked from commit f0d8fb066b382d3a3f8ecbc0b2fe3518e6df3950) --- .../python/pulsar/schema/definition.py | 28 +++++++++++++++------- pulsar-client-cpp/python/schema_test.py | 14 +++++++++-- site2/docs/client-libraries-python.md | 20 ++++++++++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/pulsar-client-cpp/python/pulsar/schema/definition.py b/pulsar-client-cpp/python/pulsar/schema/definition.py index 6db71d8..9335176 100644 --- a/pulsar-client-cpp/python/pulsar/schema/definition.py +++ b/pulsar-client-cpp/python/pulsar/schema/definition.py @@ -57,6 +57,9 @@ class RecordMeta(type): class Record(with_metaclass(RecordMeta, object)): + # This field is used to set namespace for Avro Record schema. + _avro_namespace = None + def __init__(self, default=None, required_default=False, required=False, *args, **kwargs): self._required_default = required_default self._default = default @@ -101,15 +104,22 @@ class Record(with_metaclass(RecordMeta, object)): @classmethod def schema_info(cls, defined_names): - if cls.__name__ in defined_names: - return cls.__name__ - - defined_names.add(cls.__name__) - schema = { - 'name': str(cls.__name__), - 'type': 'record', - 'fields': [] - } + namespace_prefix = '' + if cls._avro_namespace is not None: + namespace_prefix = cls._avro_namespace + '.' + namespace_name = namespace_prefix + cls.__name__ + + if namespace_name in defined_names: + return namespace_name + + defined_names.add(namespace_name) + + schema = {'name': str(cls.__name__)} + if cls._avro_namespace is not None: + schema['namespace'] = cls._avro_namespace + schema['type'] = 'record' + schema['fields'] = [] + for name in sorted(cls._fields.keys()): field = cls._fields[name] field_type = field.schema_info(defined_names) \ diff --git a/pulsar-client-cpp/python/schema_test.py b/pulsar-client-cpp/python/schema_test.py index 35d9316..40497ad 100755 --- a/pulsar-client-cpp/python/schema_test.py +++ b/pulsar-client-cpp/python/schema_test.py @@ -891,6 +891,7 @@ class SchemaTest(TestCase): na3 = Integer() class NestedObj4(Record): + _avro_namespace = 'xxx4' na4 = String() nb4 = Integer() @@ -900,6 +901,7 @@ class SchemaTest(TestCase): blue = 3 class ComplexRecord(Record): + _avro_namespace = 'xxx.xxx' a = Integer() b = Integer() color = Color @@ -914,16 +916,17 @@ class SchemaTest(TestCase): print('complex schema: ', ComplexRecord.schema()) self.assertEqual(ComplexRecord.schema(), { "name": "ComplexRecord", + "namespace": "xxx.xxx", "type": "record", "fields": [ {"name": "a", "type": ["null", "int"]}, {'name': 'arrayNested', 'type': ['null', {'type': 'array', 'items': - {'name': 'NestedObj4', 'type': 'record', 'fields': [ + {'name': 'NestedObj4', 'namespace': 'xxx4', 'type': 'record', 'fields': [ {'name': 'na4', 'type': ['null', 'string']}, {'name': 'nb4', 'type': ['null', 'int']} ]}} ]}, - {'name': 'arrayNested2', 'type': ['null', {'type': 'array', 'items': 'NestedObj4'}]}, + {'name': 'arrayNested2', 'type': ['null', {'type': 'array', 'items': 'xxx4.NestedObj4'}]}, {"name": "b", "type": ["null", "int"]}, {'name': 'color', 'type': ['null', {'type': 'enum', 'name': 'Color', 'symbols': [ 'red', 'green', 'blue']}]}, @@ -1104,5 +1107,12 @@ class SchemaTest(TestCase): client.close() + def test(self): + class NamespaceDemo(Record): + _namespace = 'xxx.xxx.xxx' + x = String() + y = Integer() + print('schema: ', NamespaceDemo.schema()) + if __name__ == '__main__': main() diff --git a/site2/docs/client-libraries-python.md b/site2/docs/client-libraries-python.md index d15cec6..501796a 100644 --- a/site2/docs/client-libraries-python.md +++ b/site2/docs/client-libraries-python.md @@ -304,6 +304,26 @@ class Example(Record): sub = MySubRecord() ``` +##### Set namespace for Avro schema + +Set the namespace for Avro Record schema using the special field `_avro_namespace`. +```python +class NamespaceDemo(Record): + _avro_namespace = 'xxx.xxx.xxx' + x = String() + y = Integer() +``` + +The schema definition is like this. +``` +{ + 'name': 'NamespaceDemo', 'namespace': 'xxx.xxx.xxx', 'type': 'record', 'fields': [ + {'name': 'x', 'type': ['null', 'string']}, + {'name': 'y', 'type': ['null', 'int']} + ] +} +``` + ## End-to-end encryption [End-to-end encryption](https://pulsar.apache.org/docs/en/next/cookbooks-encryption/#docsNav) allows applications to encrypt messages at producers and decrypt messages at consumers.