You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by hu...@apache.org on 2023/01/26 17:47:39 UTC
[superset] 01/01: first iteration
This is an automated email from the ASF dual-hosted git repository.
hugh pushed a commit to branch api-contracts
in repository https://gitbox.apache.org/repos/asf/superset.git
commit c0381b756dc1f84bd172a7288228d54b7bebe3b0
Author: hughhhh <hu...@gmail.com>
AuthorDate: Thu Jan 26 19:47:19 2023 +0200
first iteration
---
api_to_ts.py | 12 +++++++
output.ts | 6 ++++
superset/typemallow.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 104 insertions(+)
diff --git a/api_to_ts.py b/api_to_ts.py
new file mode 100644
index 0000000000..6a5516b027
--- /dev/null
+++ b/api_to_ts.py
@@ -0,0 +1,12 @@
+from superset import typemallow as tm
+from marshmallow import Schema, fields
+
+
+@tm.ts_interface()
+class Foo(Schema):
+ some_field_one = fields.Str(required=True)
+ another_field = fields.Date()
+ one_more_field = fields.Integer()
+
+
+tm.generate_ts('./output.ts')
\ No newline at end of file
diff --git a/output.ts b/output.ts
new file mode 100644
index 0000000000..bdea128497
--- /dev/null
+++ b/output.ts
@@ -0,0 +1,6 @@
+export interface Foo {
+ some_field_one?: string;
+ another_field?: any;
+ one_more_field?: number;
+}
+
diff --git a/superset/typemallow.py b/superset/typemallow.py
new file mode 100644
index 0000000000..507874885f
--- /dev/null
+++ b/superset/typemallow.py
@@ -0,0 +1,86 @@
+from marshmallow import Schema, fields
+
+mappings = {
+ fields.Bool: 'boolean',
+ fields.Boolean: 'boolean',
+ fields.Constant: 'any',
+ fields.DateTime: 'Date',
+ fields.Decimal: 'number',
+ fields.Dict: 'object',
+ fields.Email: 'string',
+ fields.Field: 'any',
+ fields.Float: 'number',
+ fields.Function: 'any',
+ fields.Int: 'number',
+ fields.Integer: 'number',
+ fields.List: 'any[]',
+ fields.Mapping: 'any',
+ fields.Method: 'any',
+ fields.Number: 'number',
+ fields.Raw: 'any',
+ fields.Str: 'string',
+ fields.String: 'string',
+ fields.TimeDelta: 'any',
+ fields.Url: 'string',
+ fields.UUID: 'string',
+}
+
+__schemas = dict()
+
+def ts_interface(context='default'):
+ '''
+ Any valid Marshmallow schemas with this class decorator will
+ be added to a list in a dictionary. An optional parameter: 'context'
+ may be provided, which will create separate dictionary keys per context.
+ Otherwise, all values will be inserted into a list with a key of 'default'.
+ e.g.
+ @ts_interface(context='internal')
+ class Foo(Schema):
+ first_field = fields.Integer()
+ '''
+ def decorator(cls):
+ if issubclass(cls, Schema):
+ if not context in __schemas:
+ __schemas[context] = []
+ __schemas[context].append(cls)
+ return cls
+ return decorator
+
+
+def __get_ts_interface(schema):
+ '''
+ Generates and returns a Typescript Interface by iterating
+ through the declared Marshmallow fields of the Marshmallow Schema class
+ passed in as a parameter, and mapping them to the appropriate Typescript
+ data type.
+ '''
+ name = schema.__name__.replace('Schema', '')
+ ts_fields = []
+ for key, value in schema._declared_fields.items():
+ if isinstance(value, fields.Nested):
+ ts_type = value.nested.__name__.replace('Schema', '')
+ if value.many:
+ ts_type += '[]'
+ else:
+ ts_type = mappings.get(type(value), 'any')
+
+ ts_fields.append(
+ f'\t{key}: {ts_type};'
+ )
+ ts_fields = '\n'.join(ts_fields)
+ return f'export interface {name} {{\n{ts_fields}\n}}\n\n'
+
+
+def generate_ts(output_path, context='default'):
+ '''
+ When this function is called, a Typescript interface will be generated
+ for each Marshmallow schema in the schemas dictionary, depending on the
+ optional context parameter provided. If the parameter is ignored, all
+ schemas in the default value, 'default' will be iterated over and a list
+ of Typescript interfaces will be returned via a list comprehension.
+
+ The Typescript interfaces will then be outputted to the file provided.
+ '''
+ with open(output_path, 'w') as output_file:
+ interfaces = [__get_ts_interface(schema) for schema in __schemas[context]]
+ output_file.write(''.join(interfaces))
\ No newline at end of file