Spaces:
Sleeping
Sleeping
from enum import Enum # do not remove this import for exec | |
from typing import List # do not remove this import for exec | |
from typing import Any, Dict | |
import jsonschema | |
from jsf import JSF | |
from pydantic import BaseModel, Field # do not remove this import for exec | |
from app.core.errors import VendorError | |
from app.schemas.requests import Attribute | |
from app.utils.converter import to_snake_case | |
from app.utils.logger import exception_to_str | |
def validate_json_data(data: Dict[str, Any], schema: Dict[str, Any]): | |
""" | |
Standalone JSON schema validation utility | |
""" | |
try: | |
jsonschema.validate(instance=data, schema=schema) | |
except jsonschema.ValidationError as e: | |
raise VendorError(f"Vendor generated invalid data {exception_to_str(e)}") | |
def validate_json_schema(schema: Dict[str, Any]): | |
""" | |
Standalone JSON schema validation utility | |
""" | |
if schema == {}: | |
raise ValueError(f"JSON Schema validation failed") | |
try: | |
faker = JSF(schema) | |
_ = faker.generate() | |
except: | |
raise ValueError(f"JSON Schema validation failed") | |
SUPPORTED_DATA_TYPE = [ | |
"string", | |
"int", | |
"float", | |
"bool", | |
"list[string]", | |
"list[int]", | |
"list[float]", | |
"list[bool]", | |
] | |
def convert_attribute_to_model(attributes: Dict[str, Attribute]) -> Dict[str, Any]: | |
import_code = "" | |
enum_code_list = [] | |
master_class_code = "class Product(BaseModel):\n" | |
for key, value in attributes.items(): | |
description = value.description | |
data_type = value.data_type | |
allowed_values = value.allowed_values | |
is_list = False | |
if data_type not in SUPPORTED_DATA_TYPE: | |
raise ValueError(f"Data type {data_type} is not supported") | |
if "list" in data_type: | |
is_list = True | |
if "int" in data_type: | |
data_type = "int" | |
elif "float" in data_type: | |
data_type = "float" | |
elif "bool" in data_type: | |
data_type = "bool" | |
elif "string" in data_type: | |
data_type = "str" | |
if len(allowed_values) > 0: | |
enum_code = f"class {key.capitalize()}Enum(str, Enum):\n" | |
for i, allowed_value in enumerate(allowed_values): | |
enum_name = f'{to_snake_case(allowed_value).upper()}_{i}' | |
if "'" in allowed_value: | |
enum_code += f' E{enum_name} = "{allowed_value}"\n' | |
else: | |
enum_code += f" E{enum_name} = '{allowed_value}'\n" | |
enum_code_list.append(enum_code) | |
data_type = f"{key.capitalize()}Enum" | |
if is_list: | |
data_type = f"List[{data_type}]" | |
if "'" in description: | |
master_class_code += ( | |
f' {key}: {data_type} = Field(..., description="{description}")\n' | |
) | |
else: | |
master_class_code += ( | |
f" {key}: {data_type} = Field(..., description='{description}')\n" | |
) | |
entire_code = import_code + "\n".join(enum_code_list) + "\n" + master_class_code | |
exec(entire_code, globals()) | |
return Product # type: ignore | |