Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate jsonschema from pydantic v2 #159

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

.DS_Store
node_modules/
.venv
.venv
env
__pycache__
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,9 @@ _Do you use a different IDE which also supports JSON Schema? Please open a PR wi
## Contributing
PRs that improve these schemata are welcome!

Please ensure that JSON keys are sorted by [vscode-sort-json](https://marketplace.visualstudio.com/items?itemName=richie5um2.vscode-sort-json) according to the rules in `.vscode/settings`.
These schemas are generated from [pydantic models](https://docs.pydantic.dev/latest/concepts/json_schema/). To make updates, the process is as follows:

1. Create a virtual environment and install the dependencies: `pip install -r requirements.txt`
2. Make changes to the corresponding pydantic models in `src/latest.py`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to reference a directory, not a file

Suggested change
2. Make changes to the corresponding pydantic models in `src/latest.py`
2. Make changes to the corresponding pydantic models in `src/latest`

3. Run the generation script: `python3 src/generate.py`
4. Add tests for valid and invalid JSON files in `tests/latest`
56 changes: 56 additions & 0 deletions generate.py

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to move this to src/generate.py?

Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import json
from pathlib import Path
from typing import Any, Dict

from src.latest.dbt_cloud import DbtCloud
from src.latest.dbt_yml_files import DbtYmlFiles
from src.latest.dependencies import Dependencies, Packages
from src.latest.selectors import Selectors
from pydantic.json_schema import GenerateJsonSchema


class RemoveNullsGenerateJsonSchema(GenerateJsonSchema):
"""A GenerateJsonSchema which removes nullability from types.

We do not want to include optional values in the json schema because
that would inhibit code completion and validation.

Certain properties (such as freshness overrides) need to be nullable,
which can be achieved by setting the $comment value below.
"""

def _remove_null(self, json_schema: Dict[str, Any]):
if "$comment" in json_schema and json_schema["$comment"] == "truly_nullable":
return
if "anyOf" in json_schema:
json_schema["anyOf"] = [
item for item in json_schema["anyOf"] if item != {"type": "null"}
]
for v in json_schema.values():
if isinstance(v, dict):
self._remove_null(v)

def generate(self, schema, mode="validation"):
json_schema = super().generate(schema, mode=mode)
json_schema["$schema"] = "http://json-schema.org/draft-07/schema#"
self._remove_null(json_schema)
return json_schema


if __name__ == "__main__":
files = {
"dbt_yml_files": DbtYmlFiles,
"dependencies": Dependencies,
"packages": Packages,
"selectors": Selectors,
"dbt_cloud": DbtCloud,
}
output_directory = Path("schemas/latest")
for file_name, model in files.items():
schema_file = output_directory / f"{file_name}-latest.json"
schema_file.parent.mkdir(parents=True, exist_ok=True)
schema = model.model_json_schema(
mode="validation", schema_generator=RemoveNullsGenerateJsonSchema
)
print("Generating", schema_file)
schema_file.write_text(json.dumps(schema, indent=2))
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
datamodel-code-generator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary, right? This package was only necessary to initially transform json-schema to Pydantic, right?

14 changes: 14 additions & 0 deletions schemas/latest-originals/dbt_cloud-latest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"project-id": {
"type": "string"
},
"defer-env-id": {
"type": "string"
}
},
"required": ["project-id"],
"additionalProperties": false
}
Loading
Loading