| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
json2python-models is a Python tool that can generate Python models classes (pydantic, (sqlmodel, dataclasses, attrs) from JSON datasets.
from pydantic import BaseModel, Field
from typing import List, Optional
from typing_extensions import Literal
class Tab(BaseModel):
id_: str = Field(..., alias="id")
public: bool
stash_type: Literal["CurrencyStash", "NormalStash", "PremiumStash"] = Field(..., alias="stashType")
items: List['Item']
account_name: Optional[str] = Field(None, alias="accountName")
last_character_name: Optional[str] = Field(None, alias="lastCharacterName")
stash: Optional[str] = None
league: Optional[Literal["Hardcore", "Standard"]] = None
driver_standings.json
[
{
"season": "2019",
"round": "3",
"DriverStandings": [
{
"position": "1",
"positionText": "1",
"points": "68",
"wins": "2",
"Driver": {
"driverId": "hamilton",
"permanentNumber": "44",
"code": "HAM",
"url": "http://en.wikipedia.org/wiki/Lewis_Hamilton",
"givenName": "Lewis",
"familyName": "Hamilton",
"dateOfBirth": "1985-01-07",
"nationality": "British"
},
"Constructors": [
{
"constructorId": "mercedes",
"url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
"name": "Mercedes",
"nationality": "German"
}
]
},
...
]
}
]
json2models -f pydantic -m DriverStandings driver_standings.json
r"""
generated by json2python-models v0.2.0 at Mon May 4 17:46:30 2020
command: /opt/projects/json2python-models/venv/bin/json2models -f pydantic -s flat -m DriverStandings driver_standings.json
"""
from pydantic import BaseModel, Field
from typing import List
from typing_extensions import Literal
class DriverStandings(BaseModel):
season: int
round_: int = Field(..., alias="round")
DriverStandings: List['DriverStanding']
class DriverStanding(BaseModel):
position: int
position_text: int = Field(..., alias="positionText")
points: int
wins: int
driver: 'Driver' = Field(..., alias="Driver")
constructors: List['Constructor'] = Field(..., alias="Constructors")
class Driver(BaseModel):
driver_id: str = Field(..., alias="driverId")
permanent_number: int = Field(..., alias="permanentNumber")
code: str
url: str
given_name: str = Field(..., alias="givenName")
family_name: str = Field(..., alias="familyName")
date_of_birth: str = Field(..., alias="dateOfBirth")
nationality: str
class Constructor(BaseModel):
constructor_id: str = Field(..., alias="constructorId")
url: str
name: str
nationality: Literal["Austrian", "German", "American", "British", "Italian", "French"]
swagger.json from any online API (I tested file generated by drf-yasg and another one for Spotify API)
It requires a bit of tweaking:
json2models -f dataclasses -m Swagger testing_tools/swagger.json \
--dict-keys-fields securityDefinitions paths responses definitions properties \
--merge percent_50 number --max-strings-literals 0
r"""
generated by json2python-models v0.2.0 at Mon May 4 18:08:09 2020
command: /opt/projects/json2python-models/json_to_models/__main__.py -s flat -f dataclasses -m Swagger testing_tools/swagger.json --max-strings-literals 0 --dict-keys-fields securityDefinitions paths responses definitions properties --merge percent_50 number
"""
from dataclasses import dataclass, field
from json_to_models.dynamic_typing import FloatString
from typing import Any, Dict, List, Optional, Union
@dataclass
class Swagger:
swagger: FloatString
info: 'Info'
host: str
schemes: List[str]
base_path: str
consumes: List[str]
produces: List[str]
security_definitions: Dict[str, 'Parameter_SecurityDefinition']
security: List['Security']
paths: Dict[str, 'Path']
definitions: Dict[str, 'Definition_Schema']
@dataclass
class Info:
title: str
description: str
version: str
@dataclass
class Security:
api_key: Optional[List[Any]] = field(default_factory=list)
basic: Optional[List[Any]] = field(default_factory=list)
@dataclass
class Path:
parameters: List['Parameter_SecurityDefinition']
post: Optional['Delete_Get_Patch_Post_Put'] = None
get: Optional['Delete_Get_Patch_Post_Put'] = None
put: Optional['Delete_Get_Patch_Post_Put'] = None
patch: Optional['Delete_Get_Patch_Post_Put'] = None
delete: Optional['Delete_Get_Patch_Post_Put'] = None
@dataclass
class Property:
type_: str
format_: Optional[str] = None
xnullable: Optional[bool] = None
items: Optional['Item_Schema'] = None
@dataclass
class Property_2E:
type_: str
title: Optional[str] = None
read_only: Optional[bool] = None
max_length: Optional[int] = None
min_length: Optional[int] = None
items: Optional['Item'] = None
enum: Optional[List[str]] = field(default_factory=list)
maximum: Optional[int] = None
minimum: Optional[int] = None
format_: Optional[str] = None
@dataclass
class Item:
title: Optional[str] = None
type_: Optional[str] = None
ref: Optional[str] = None
max_length: Optional[int] = None
min_length: Optional[int] = None
@dataclass
class Parameter_SecurityDefinition:
name: Optional[str] = None
in_: Optional[str] = None
required: Optional[bool] = None
schema: Optional['Item_Schema'] = None
description: Optional[str] = None
type_: Optional[str] = None
@dataclass
class Delete_Get_Patch_Post_Put:
operation_id: str
description: str
parameters: List['Parameter_SecurityDefinition']
responses: Dict[str, 'Response']
tags: List[str]
@dataclass
class Item_Schema:
ref: str
@dataclass
class Response:
description: str
schema: Optional[Union['Item_Schema', 'Definition_Schema']] = None
@dataclass
class Definition_Schema:
type_: str
required: Optional[List[str]] = field(default_factory=list)
properties: Optional[Dict[str, Union['Property', 'Property_2E']]] = field(default_factory=dict)
ref: Optional[str] = None
Github-actions model based on files from starter-workflows
json2models -m Actions "./starter-workflows/ci/*.yml" -s flat -f pydantic -i yaml --dkf env with jobs
r"""
generated by json2python-models v0.2.3 at Tue Jul 13 19:52:43 2021
command: /opt/projects/json2python-models/venv/bin/json2models -m Actions ./starter-workflows/ci/*.yml -s flat -f pydantic -i yaml --dkf env with jobs
"""
from pydantic import BaseModel, Field
from typing import Dict, List, Optional, Union
from typing_extensions import Literal
class Actions(BaseModel):
on: Union['On', List[Literal["push"]]]
jobs: Dict[str, 'Job']
name: Optional[str] = None
env: Optional[Dict[str, Union[int, str]]] = {}
class On(BaseModel):
push: Optional['Push'] = None
pull_request: Optional['PullRequest'] = None
release: Optional['Release'] = None
schedule: Optional[List['Schedule']] = []
workflow_dispatch: Optional[None] = None
class Push(BaseModel):
branches: List[Literal["$default-branch"]]
tags: Optional[List[Literal["v*.*.*"]]] = []
class PullRequest(BaseModel):
branches: List[Literal["$default-branch"]]
class Release(BaseModel):
types: List[Literal["created", "published"]]
class Schedule(BaseModel):
cron: Literal["$cron-daily"]
class Job(BaseModel):
runson: Literal["${{ matrix.os }}", "macOS-latest", "macos-latest", "ubuntu-18.04", "ubuntu-latest", "windows-latest"] = Field(..., alias="runs-on")
steps: List['Step']
name: Optional[str] = None
environment: Optional[Literal["production"]] = None
outputs: Optional['Output'] = None
container: Optional['Container'] = None
needs: Optional[Literal["build"]] = None
permissions: Optional['Permission'] = None
strategy: Optional['Strategy'] = None
defaults: Optional['Default'] = None
env: Optional[Dict[str, str]] = {}
class Step(BaseModel):
uses: Optional[str] = None
name: Optional[str] = None
with_: Optional[Dict[str, Union[bool, float, str]]] = Field({}, alias="with")
run: Optional[str] = None
env: Optional[Dict[str, str]] = {}
workingdirectory: Optional[str] = Field(None, alias="working-directory")
id_: Optional[Literal["build-image", "composer-cache", "deploy-and-expose", "image-build", "login-ecr", "meta", "push-to-registry", "task-def"]] = Field(None, alias="id")
if_: Optional[str] = Field(None, alias="if")
shell: Optional[Literal["Rscript {0}"]] = None
class Output(BaseModel):
route: str = Field(..., alias="ROUTE")
selector: str = Field(..., alias="SELECTOR")
class Container(BaseModel):
image: Literal["crystallang/crystal", "erlang:22.0.7"]
class Permission(BaseModel):
contents: Literal["read"]
packages: Literal["write"]
class Strategy(BaseModel):
matrix: Optional['Matrix'] = None
maxparallel: Optional[int] = Field(None, alias="max-parallel")
failfast: Optional[bool] = Field(None, alias="fail-fast")
class Matrix(BaseModel):
rversion: Optional[List[float]] = Field([], alias="r-version")
pythonversion: Optional[List[float]] = Field([], alias="python-version")
deno: Optional[List[Literal["canary", "v1.x"]]] = []
os: Optional[List[Literal["macOS-latest", "ubuntu-latest", "windows-latest"]]] = []
rubyversion: Optional[List[float]] = Field([], alias="ruby-version")
nodeversion: Optional[List[Literal["12.x", "14.x", "16.x"]]] = Field([], alias="node-version")
configuration: Optional[List[Literal["Debug", "Release"]]] = []
class Default(BaseModel):
run: 'Run'
class Run(BaseModel):
shell: Literal["bash"]A simple example to demonstrate adding extra code before the class list.
json2models -f pydantic --preamble "# set up defaults
USERNAME = 'user'
SERVER_IP = '127.0.0.1'
" -m Swagger testing_tools/swagger.jsonr"""
generated by json2python-models v0.2.5 at Tue Aug 23 08:55:09 2022
command: json2models -f pydantic --preamble # set up defaults
USERNAME = 'user'
SERVER_IP = '127.0.0.1'
-m Swagger testing_tools/swagger.json -o output.py
"""
from pydantic import BaseModel, Field
from typing import Any, List, Literal, Optional, Union
# set up defaults
USERNAME = 'user'
SERVER_IP = '127.0.0.1'
class Swagger(BaseModel):
# etc.To install it, use pip:
pip install json2python-models
Or you can build it from source:
git clone https://github.com/bogdandm/json2python-models.git cd json2python-models python setup.py install
For regular usage CLI tool is the best option. After you install this package you can use it as json2models <arguments> or python -m json_to_models <arguments>. I.e.:
json2models -m Car car_*.json -f attrs > car.py
Arguments:
-h, --help - Show help message and exit
-m, --model - Model name and its JSON data as path or unix-like path pattern. *, ** or ? patterns symbols are supported. JSON data could be an array of models or single model. If this file contains dict with nested list than you can pass <JSON lookup>. Deep lookups are supported by dot-separated path. If no lookup needed pass '-' as <JSON lookup> (default)
-i, --input-format - Input file format (parser). Default is JSON parser. Yaml parser requires PyYaml or ruamel.yaml to be installed. Ini parser uses builtin configparser. To implement new one - add new method to cli.FileLoaders (and create pull request :) )
-o, --output - Output file
-f, --framework - Model framework for which python code is generated. base (default) mean no framework so code will be generated without any decorators and additional meta-data.
-s, --structure - Models composition style.
--preamble - Additional material to be
--preamble "# set up defaults
USERNAME = 'user'
SERVER = '127.0.0.1'"--datetime - Enable datetime/date/time strings parsing.
--disable-unicode-conversion, --no-unidecode - Disable unicode conversion in field labels and class names
--strings-converters - Enable generation of string types converters (i.e. IsoDatetimeString or BooleanString).
--max-strings-literals - Generate Literal['foo', 'bar'] when field have less than NUMBER string constants as values.
--merge - Merge policy settings. Possible values are:
--dict-keys-regex, --dkr - List of regular expressions (Python syntax). If all keys of some dict are match one of the pattern then this dict will be marked as dict field but not nested model.
--dict-keys-fields, --dkf - List of model fields names that will be marked as dict fields
--code-generator - Absolute import path to GenericModelCodeGenerator subclass.
--code-generator-kwargs - List of GenericModelCodeGenerator subclass arguments (for __init__ method, see docs of specific subclass). Each argument should be in following format: argument_name=value or "argument_name=value with space". Boolean values should be passed in JS style: true or false
--disable-str-serializable-types - List of python types for which StringSerializable should be disabled. Alternatively you could use the name of StringSerializable subclass itself (i.e. IntString).
-
To run tests you should clone project and run setup.py script:
git clone https://github.com/bogdandm/json2python-models.git cd json2python-models python setup.py test -a '<pytest additional arguments>'
Also, I would recommend you to install pytest-sugar for pretty printing test results
You can find out some examples of usage of this project at testing_tools/real_apis/...
Each file contains functions to download data from some online API (references included at the top of file) and main function that generates and prints code. Some examples may print debug data before actual code. Downloaded data will be saved at testing_tools/real_apis/<name of example>/<dataset>.json
Test tools:
Feel free to open pull requests with new features or bug fixes. Just follow few rules:
This project is licensed under the MIT License - see the LICENSE file for details
| Back | FazBrowse Home | New Git URL |