def test_dump_templates(): with NamedTemporaryFile('w') as dummy_template: assert dump_templates(A(dummy_template.name, 'abc')) == 'abc' assert ( dump_templates( [A(dummy_template.name, 'abc'), A(dummy_template.name, 'def')] ) == 'abc\n\n\ndef' )
def parse(self, with_import: Optional[bool] = True, format_: Optional[bool] = True) -> str: for obj_name, raw_obj in self.base_parser.specification['components'][ 'schemas'].items(): # type: str, Dict obj = JsonSchemaObject.parse_obj(raw_obj) if obj.is_object: self.parse_object(obj_name, obj) elif obj.is_array: self.parse_array(obj_name, obj) elif obj.enum: self.parse_enum(obj_name, obj) elif obj.allOf: self.parse_all_of(obj_name, obj) else: self.parse_root_type(obj_name, obj) result: str = '' if with_import: if self.target_python_version == PythonVersion.PY_37: self.imports.append(IMPORT_ANNOTATIONS) result += f'{self.imports.dump()}\n\n\n' _, sorted_data_models, require_update_action_models = sort_data_models( self.results) result += dump_templates(list(sorted_data_models.values())) if self.dump_resolve_reference_action: result += f'\n\n{self.dump_resolve_reference_action(require_update_action_models)}' if format_: result = format_code(result, self.target_python_version) return result
def test_json_schema_object_cached_ref_url_yaml(mocker): parser = JsonSchemaParser('') obj = JsonSchemaObject.parse_obj({ 'type': 'object', 'properties': { 'pet': { '$ref': 'https://example.org/schema.yaml#/definitions/Pet' }, 'user': { '$ref': 'https://example.org/schema.yaml#/definitions/User' }, }, }) mock_get = mocker.patch('httpx.get') mock_get.return_value.text = yaml.safe_dump( json.load((DATA_PATH / 'user.json').open())) parser.parse_ref(obj, []) assert (dump_templates(list(parser.results)) == '''class Pet(BaseModel): name: Optional[str] = Field(None, examples=['dog', 'cat']) class User(BaseModel): name: Optional[str] = Field(None, example='ken')''') mock_get.assert_called_once_with('https://example.org/schema.yaml', )
def test_parse_object(source_obj, generated_classes): parser = JsonSchemaParser( data_model_field_type=DataModelFieldBase, source='', ) parser.parse_object('Person', JsonSchemaObject.parse_obj(source_obj), []) assert dump_templates(list(parser.results)) == generated_classes
def test_json_schema_object_ref_url_json(mocker): parser = JsonSchemaParser('') obj = JsonSchemaObject.parse_obj( {'$ref': 'https://example.com/person.schema.json#/definitions/User'}) mock_get = mocker.patch('httpx.get') mock_get.return_value.text = json.dumps( { "$id": "https://example.com/person.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "User": { "type": "object", "properties": { "name": { "type": "string", } }, } }, }, ) parser.parse_ref(obj, ['Model']) assert (dump_templates(list(parser.results)) == '''class User(BaseModel): name: Optional[str] = None''') parser.parse_ref(obj, ['Model']) mock_get.assert_has_calls([ call('https://example.com/person.schema.json'), ])
def test_json_schema_ref_url_json(mocker): parser = JsonSchemaParser('') obj = { "type": "object", "properties": { "user": { '$ref': 'https://example.org/schema.json#/definitions/User' } }, } mock_get = mocker.patch('httpx.get') mock_get.return_value.text = json.dumps( json.load((DATA_PATH / 'user.json').open())) parser.parse_raw_obj('Model', obj, ['Model']) assert (dump_templates(list(parser.results)) == '''class Model(BaseModel): user: Optional[User] = None class User(BaseModel): name: Optional[str] = Field(None, example='ken') class Pet(BaseModel): name: Optional[str] = Field(None, examples=['dog', 'cat'])''') mock_get.assert_called_once_with('https://example.org/schema.json', )
def test_parse_any_root_object(source_obj, generated_classes): parser = JsonSchemaParser(BaseModel, CustomRootType, data_model_field_type=DataModelField) parser.parse_root_type('AnyObject', JsonSchemaObject.parse_obj(source_obj), []) assert dump_templates(list(parser.results)) == generated_classes
def test_parse_nested_array(): parser = JsonSchemaParser( DATA_PATH / 'nested_array.json', data_model_field_type=DataModelFieldBase, ) parser.parse() assert (dump_templates(list( parser.results)) == (DATA_PATH / 'nested_array.json.snapshot').read_text())
def test_json_schema_object_ref_url_yaml(mocker): parser = JsonSchemaParser(BaseModel, CustomRootType, data_model_field_type=DataModelField) obj = JsonSchemaObject.parse_obj( {'$ref': 'https://example.org/schema.yaml#/definitions/User'}) mock_get = mocker.patch('httpx.get') mock_get.return_value.text = yaml.safe_dump( json.load((DATA_PATH / 'user.json').open())) parser.parse_ref(obj, ['User']) assert (dump_templates(list(parser.results)) == '''class User(BaseModel): name: Optional[str] = None''') parser.parse_ref(obj, []) mock_get.assert_called_once_with('https://example.org/schema.yaml', )
def test_parse_nested_array(): parser = JsonSchemaParser( BaseModel, CustomRootType, data_model_field_type=DataModelField, text=(DATA_PATH / 'nested_array.json').read_text(), ) parser.parse() assert (dump_templates(list(parser.results)) == """\ class BoundingBox(BaseModel): type: str coordinates: List[Union[float, str]] class Model(BaseModel): bounding_box: Optional[BoundingBox] = None attributes: Optional[Dict[str, Any]] = None""")
def test_parse_root_type(source_obj, generated_classes): parser = OpenAPIParser('') parser.parse_root_type('Name', JsonSchemaObject.parse_obj(source_obj), []) assert dump_templates(list(parser.results)) == generated_classes
def test_parse_array(source_obj, generated_classes): parser = OpenAPIParser('') parser.parse_array('Pets', JsonSchemaObject.parse_obj(source_obj), []) assert dump_templates(list(parser.results)) == generated_classes
def test_parse_root_type(source_obj, generated_classes): parser = OpenAPIParser(BaseModel, CustomRootType) parsed_templates = parser.parse_root_type( 'Name', JsonSchemaObject.parse_obj(source_obj)) assert dump_templates(list(parsed_templates)) == generated_classes
def test_parse_object(source_obj, generated_classes): parser = OpenAPIParser(BaseModel, CustomRootType) parser.parse_object('Pets', JsonSchemaObject.parse_obj(source_obj), []) assert dump_templates(list(parser.results)) == generated_classes
def test_parse_default(source_obj, generated_classes): parser = JsonSchemaParser('') parser.parse_raw_obj('Defaults', source_obj, []) assert dump_templates(list(parser.results)) == generated_classes
def test_parse_one_of_object(source_obj, generated_classes): parser = JsonSchemaParser('') parser.parse_raw_obj('onOfObject', source_obj, []) assert dump_templates(list(parser.results)) == generated_classes
def test_parse_any_root_object(source_obj, generated_classes): parser = JsonSchemaParser('') parser.parse_root_type('AnyObject', JsonSchemaObject.parse_obj(source_obj), []) assert dump_templates(list(parser.results)) == generated_classes
def test_parse_default(source_obj, generated_classes): parser = JsonSchemaParser(BaseModel, CustomRootType, data_model_field_type=DataModelField) parser.parse_raw_obj('Defaults', source_obj, []) assert dump_templates(list(parser.results)) == generated_classes
def parse( self, with_import: Optional[bool] = True, format_: Optional[bool] = True ) -> Union[str, Dict[Tuple[str, ...], str]]: for obj_name, raw_obj in self.base_parser.specification['components'][ 'schemas'].items(): # type: str, Dict obj = JsonSchemaObject.parse_obj(raw_obj) if obj.is_object: self.parse_object(obj_name, obj) elif obj.is_array: self.parse_array(obj_name, obj) elif obj.enum: self.parse_enum(obj_name, obj) elif obj.allOf: self.parse_all_of(obj_name, obj) else: self.parse_root_type(obj_name, obj) if with_import: if self.target_python_version == PythonVersion.PY_37: self.imports.append(IMPORT_ANNOTATIONS) _, sorted_data_models, require_update_action_models = sort_data_models( self.results) results: Dict[Tuple[str, ...], str] = {} module_key = lambda x: (*x.name.split('.')[:-1], ) grouped_models = groupby(sorted(sorted_data_models.values(), key=module_key), key=module_key) for module, models in ((k, [*v]) for k, v in grouped_models): module_path = '.'.join(module) result: List[str] = [] imports = Imports() models_to_update: List[str] = [] for model in models: if model.name in require_update_action_models: models_to_update += [model.name] imports.append(model.imports) for ref_name in model.reference_classes: if '.' not in ref_name: continue ref_path = ref_name.rsplit('.', 1)[0] if ref_path == module_path: continue imports.append(Import(from_='.', import_=ref_path)) if with_import: result += [imports.dump(), self.imports.dump(), '\n'] code = dump_templates(models) result += [code] if self.dump_resolve_reference_action is not None: result += [ '\n', self.dump_resolve_reference_action(models_to_update) ] body = '\n'.join(result) if format_: body = format_code(body, self.target_python_version) if module: module = (*module[:-1], f'{module[-1]}.py') parent = (*module[:-1], '__init__.py') if parent not in results: results[parent] = '' else: module = ('__init__.py', ) results[module] = body # retain existing behaviour if [*results] == [('__init__.py', )]: return results[('__init__.py', )] return results