jsf
jsf copied to clipboard
Add support for schema composition
https://json-schema.org/understanding-json-schema/reference/combining.html#schema-composition
Do you have any full examples of this? The docs don't really give muc detail on it imo.
This is an example from the documentation
{
"anyOf": [
{ "type": "string", "maxLength": 5 },
{ "type": "number", "minimum": 0 }
]
}
On my project I have something like this
{
"$ref": "#/definitions/objOrString",
"definitions": {
"refObj": {
"type": "object",
"properties": {
"field_1": {
"type": ["string", "null"]
},
"field_2": {
"type": ["string", "null"]
}
},
},
"objOrString": {
"anyOf": [
{ "$ref": "#/definitions/refObj" },
{ "type": "string" }
]
}
}
}
I will make pull request, review it when you have time
Have a similar issue. Using JSF to generate data for Pydantic models for unint tests via:
from typing import List, Type, TypeVar
from jsf import JSF # type: ignore
from pydantic import BaseModel
TModel = TypeVar("TModel", bound=BaseModel)
class AutoFixture:
@staticmethod
def create(model_type: Type[TModel]) -> TModel:
schema = model_type.schema()
data = JSF(schema).generate()
return model_type(**data)
Everything works fine for built-in types and flat models, but fails immediately with something else. For example, having model with a field of Enum type:
class Model(BaseModel):
environment: Environment
version: str
Where first field type is:
from enum import Enum
class Environment(str, Enum):
LOCAL = "local"
DEV = "development"
Throws with:
ValueError: Cannot parse schema {'env_names': {'app_environment'}, 'allOf': [{'$ref': '#/definitions/Environment'}]}
Could you add a minimal json schema you're using and wa hat you expect it to produce? Can add into the tests then get green. PR's welcome
@ghandic for sure, here it is:
{
"title":"AppSettings",
"description":"test",
"type":"object",
"properties":{
"environment":{
"env_names":[
"environment"
],
"allOf":[
{
"$ref":"#/definitions/Environment"
}
]
}
},
"required":[
"environment"
],
"additionalProperties":false,
"definitions":{
"Environment":{
"title":"Environment",
"description":"Defines application environment",
"enum":[
"local",
"development"
],
"type":"string"
}
}
}
I think it is not because of inner schema, but just because it can not work with Enums for some reason.
Was this issue picked up / resolved? I am facing the same issue with allOf
key.
Could you add an example and what you expect?
I'm a little confused by the original example
Please see the following code and output. I am trying to use jsf in conjunction with Pydantic
Code
import json
from typing import Optional
from jsf import JSF
from pydantic import schema_of, BaseModel, Field
class Prometheus(BaseModel):
port: int = Field(..., description="Port at which Prometheus metrics are exposed")
path: str = Field(..., description="Path at which Prometheus metrics are exposed")
class PodConfig(BaseModel):
prometheus: Optional[Prometheus] = Field(None, description="Prometheus details")
if __name__ == '__main__':
obj = schema_of(PodConfig)
print(json.dumps(obj, indent=2))
faker = JSF(obj)
fake_json = faker.generate()
print(fake_json)
Logs
/Users/gautamsinghania/Desktop/work/envs/seldon/bin/python /Users/gautamsinghania/Desktop/work/repos/holmes/services/seldon/main_schema.py
Traceback (most recent call last):
File "/Users/gautamsinghania/Desktop/work/repos/holmes/services/seldon/main_schema.py", line 27, in <module>
faker = JSF(obj)
File "/Users/gautamsinghania/Desktop/work/envs/seldon/lib/python3.9/site-packages/jsf/parser.py", line 42, in __init__
self._parse(schema)
File "/Users/gautamsinghania/Desktop/work/envs/seldon/lib/python3.9/site-packages/jsf/parser.py", line 126, in _parse
item = self.__parse_definition(name, path="#/definitions", schema=definition)
File "/Users/gautamsinghania/Desktop/work/envs/seldon/lib/python3.9/site-packages/jsf/parser.py", line 97, in __parse_definition
return self.__parse_object(name, path, schema)
File "/Users/gautamsinghania/Desktop/work/envs/seldon/lib/python3.9/site-packages/jsf/parser.py", line 54, in __parse_object
props.append(self.__parse_definition(_name, path=f"{path}/{_name}", schema=definition))
File "/Users/gautamsinghania/Desktop/work/envs/seldon/lib/python3.9/site-packages/jsf/parser.py", line 122, in __parse_definition
raise ValueError(f"Cannot parse schema {repr(schema)}") # pragma: no cover
ValueError: Cannot parse schema {'title': 'Prometheus', 'description': 'Prometheus details', 'allOf': [{'$ref': '#/definitions/Prometheus'}]}
{
"title": "ParsingModel[PodConfig]",
"$ref": "#/definitions/PodConfig",
"definitions": {
"Prometheus": {
"title": "Prometheus",
"type": "object",
"properties": {
"port": {
"title": "Port",
"description": "Port at which Prometheus metrics are exposed",
"type": "integer"
},
"path": {
"title": "Path",
"description": "Path at which Prometheus metrics are exposed",
"type": "string"
}
},
"required": [
"port",
"path"
]
},
"PodConfig": {
"title": "PodConfig",
"type": "object",
"properties": {
"prometheus": {
"title": "Prometheus",
"description": "Prometheus details",
"allOf": [
{
"$ref": "#/definitions/Prometheus"
}
]
}
}
}
}
}
Process finished with exit code 1
@ghandic any updates?
I'm not free to work on this this month as I'm maxed out at work. However the repo is open for PR's if you have some suggestions :)
See https://github.com/ghandic/jsf/pull/54
If acceptable, will be released in next minor version