diff --git a/client/src/App.tsx b/client/src/App.tsx
index ea6b3ca..3ce1ad5 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -9,13 +9,14 @@ import "ace-builds/src-noconflict/theme-monokai";
const apiUrl = "https://ufgjji253b.execute-api.us-east-1.amazonaws.com/prod";
const defaultJsonObject = '{\n\t"foo": 5, \n\t"barBaz": "hello"\n}';
-const defaultOptions = { forceOptional: false, snakeCased: false };
+const defaultOptions = { forceOptional: false, snakeCased: false, includeExamples: false };
const loadingMessage = "# loading...";
const invalidJsonMessage = "# invalid json";
type RequestOptions = {
forceOptional: boolean;
snakeCased: boolean;
+ includeExamples: boolean;
};
type RequestBody = {
@@ -30,7 +31,7 @@ function App() {
useEffect(() => {
if (validJson(jsonObject)) {
- fetchConversion(jsonObject, options.forceOptional, options.snakeCased);
+ fetchConversion(jsonObject, options.forceOptional, options.snakeCased, options.includeExamples);
} else {
setPydanticModel(invalidJsonMessage);
}
@@ -52,11 +53,12 @@ function App() {
function fetchConversion(
newValue: string,
forceOptional: boolean,
- snakeCased: boolean
+ snakeCased: boolean,
+ includeExamples: boolean
) {
console.log("fetching");
setPydanticModel(loadingMessage);
- const requestOptions: RequestOptions = { forceOptional, snakeCased };
+ const requestOptions: RequestOptions = { forceOptional, snakeCased, includeExamples };
const requestBody: RequestBody = {
data: newValue,
options: requestOptions,
@@ -124,8 +126,8 @@ function App() {
-
-
+
+
+
+
+
+
diff --git a/server/app/main.py b/server/app/main.py
index 1a26be9..b0a6c3c 100644
--- a/server/app/main.py
+++ b/server/app/main.py
@@ -23,6 +23,7 @@
class Options(BaseModel):
force_optional: bool = Field(False, alias="forceOptional")
snake_cased: bool = Field(False, alias="snakeCased")
+ include_examples: bool = Field(False, alias="includeExamples")
class BasicRequest(BaseModel):
@@ -39,6 +40,7 @@ async def convert(basic_request: BasicRequest):
basic_request.data,
options.force_optional,
options.snake_cased,
+ options.include_examples,
)
}
diff --git a/server/app/scripts/generator.py b/server/app/scripts/generator.py
index dabfd48..52e3164 100644
--- a/server/app/scripts/generator.py
+++ b/server/app/scripts/generator.py
@@ -3,12 +3,44 @@
from pydantic import Json
from datamodel_code_generator.parser.jsonschema import JsonSchemaParser
from genson import SchemaBuilder
+from genson.schema.strategies import String, Number
+
+
+class StringWithExample(String):
+
+ def add_object(self, obj):
+ super().add_object(obj)
+ if not hasattr(self, "example"):
+ self.example = obj
+
+ def to_schema(self):
+ schema = super().to_schema()
+ if hasattr(self, "example"):
+ schema['example'] = self.example
+ return schema
+
+
+class NumberWithExample(Number):
+ def add_object(self, obj):
+ super().add_object(obj)
+ if not hasattr(self, "example"):
+ self.example = obj
+
+ def to_schema(self):
+ schema = super().to_schema()
+ if hasattr(self, "example"):
+ schema['example'] = self.example
+ return schema
+
+
+class ExampleSchemaBuilder(SchemaBuilder):
+ EXTRA_STRATEGIES = (StringWithExample, NumberWithExample)
def translate(
- input_text: Union[Json, Dict[str, Any]], all_optional: bool, snake_case_field: bool
+ input_text: Union[Json, Dict[str, Any]], all_optional: bool, snake_case_field: bool, include_examples: bool = False
) -> str:
- builder = SchemaBuilder()
+ builder = ExampleSchemaBuilder() if include_examples else SchemaBuilder()
builder.add_object(input_text)
schema = builder.to_schema()
if all_optional:
@@ -18,6 +50,7 @@ def translate(
source=json.dumps(schema),
base_class="pydantic.BaseModel",
snake_case_field=snake_case_field,
+ field_extra_keys={"example"} if include_examples else {},
)
return parser.parse()