You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by pe...@apache.org on 2021/09/25 05:01:40 UTC
[pulsar] branch branch-2.8 updated: [Python Schema] Support setting
namespace for python schema (#12175)
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 <ga...@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.