Skip to content

Commit

Permalink
style: isort & black formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimhuet committed Nov 30, 2023
1 parent 85afa8c commit c345d4e
Show file tree
Hide file tree
Showing 16 changed files with 44 additions and 108 deletions.
3 changes: 2 additions & 1 deletion examples/fastapi/api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from jsf import JSF
from fastapi import FastAPI

from jsf import JSF

app = FastAPI(docs_url="/")
generator = JSF.from_json("custom.json")

Expand Down
58 changes: 15 additions & 43 deletions examples/fastapi/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,62 +11,34 @@

class NewbornItem(BaseModel):
surname: str = Field(..., description="The newborn's surname, eg: Reid")
givenNames: str = Field(
..., description="The newborn's given names, eg: Mathew David"
)
givenNames: str = Field(..., description="The newborn's given names, eg: Mathew David")
sex: str = Field(..., description="The newborn's sex, eg: M, F or U")
dateOfBirth: str = Field(
..., description="The newborn's date of birth, eg: 17/03/2021"
)
dateOfBirth: str = Field(..., description="The newborn's date of birth, eg: 17/03/2021")
birthOrder: str = Field(..., description="The newborn's birth order, eg: 1")
indigenousStatus: str = Field(
..., description="The newborn's indigenous status, eg: 14"
)
uniqueId: str = Field(
..., description="The newborn's unique birth event id, eg: 20474417"
)
indigenousStatus: str = Field(..., description="The newborn's indigenous status, eg: 14")
uniqueId: str = Field(..., description="The newborn's unique birth event id, eg: 20474417")


class Address(BaseModel):
suburb: str = Field(
..., description='The address suburb (Australia Only), eg: Watson'
)
postcode: str = Field(
..., description='The address postcode (Australia Only), eg: 2602'
)
suburb: str = Field(..., description="The address suburb (Australia Only), eg: Watson")
postcode: str = Field(..., description="The address postcode (Australia Only), eg: 2602")
street1: str = Field(
...,
description='The address street name line 1 (Australia Only), eg: 49 Aspinall St',
)
street2: str = Field(
..., description='The address street name line 2 (Australia Only), eg: Suite 1'
description="The address street name line 1 (Australia Only), eg: 49 Aspinall St",
)
street2: str = Field(..., description="The address street name line 2 (Australia Only), eg: Suite 1")


class Parent(BaseModel):
surname: Optional[str] = Field(
..., description="The mother's surname, eg: Mcdermott"
)
givenNames: str = Field(
..., description="The mother's given names, eg: Sarah Lousie"
)
surname: Optional[str] = Field(..., description="The mother's surname, eg: Mcdermott")
givenNames: str = Field(..., description="The mother's given names, eg: Sarah Lousie")
mailAddress: Address
residentialAddress: Address
mobile: str = Field(
..., description="The mother's mobile phone number, eg: 0400182545"
)
homePhone: str = Field(
..., description="The mother's home phone number, eg: 0245458450"
)
email: str = Field(
..., description="The mother's email address, eg: [email protected]"
)
hospital: str = Field(
..., description='The hospital where the birth took place, eg: ACTCC'
)
dateReceived: str = Field(
..., description='The date the birth event was received, eg: 17/03/2021'
)
mobile: str = Field(..., description="The mother's mobile phone number, eg: 0400182545")
homePhone: str = Field(..., description="The mother's home phone number, eg: 0245458450")
email: str = Field(..., description="The mother's email address, eg: [email protected]")
hospital: str = Field(..., description="The hospital where the birth took place, eg: ACTCC")
dateReceived: str = Field(..., description="The date the birth event was received, eg: 17/03/2021")
personId: str = Field(..., description="The mother's personId, eg: 123456789")


Expand Down
14 changes: 4 additions & 10 deletions jsf/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
JSFTuple,
Object,
OneOf,
PrimitiveTypes,
Primitives,
PrimitiveTypes,
)

logger = logging.getLogger()
Expand Down Expand Up @@ -66,9 +66,7 @@ def __parse_object(self, name: str, path: str, schema: Dict[str, Any]) -> Object
model.properties = props
pattern_props = []
for _name, definition in schema.get("patternProperties", {}).items():
pattern_props.append(
self.__parse_definition(_name, path=f"{path}/{_name}", schema=definition)
)
pattern_props.append(self.__parse_definition(_name, path=f"{path}/{_name}", schema=definition))
model.patternProperties = pattern_props

return model
Expand Down Expand Up @@ -142,9 +140,7 @@ def __parse_definition(self, name: str, path: str, schema: Dict[str, Any]) -> Al
assert all(
isinstance(item, (int, float, str, type(None))) for item in enum_list
), "Enum Type is not null, int, float or string"
return JSFEnum.from_dict(
{"name": name, "path": path, "is_nullable": is_nullable, **schema}
)
return JSFEnum.from_dict({"name": name, "path": path, "is_nullable": is_nullable, **schema})
elif "type" in schema:
if item_type == "object" and "properties" in schema:
return self.__parse_object(name, path, schema)
Expand All @@ -157,9 +153,7 @@ def __parse_definition(self, name: str, path: str, schema: Dict[str, Any]) -> Al
elif item_type == "array":
if (schema.get("contains") is not None) or isinstance(schema.get("items"), dict):
return self.__parse_array(name, path, schema)
if isinstance(schema.get("items"), list) and all(
isinstance(x, dict) for x in schema.get("items", [])
):
if isinstance(schema.get("items"), list) and all(isinstance(x, dict) for x in schema.get("items", [])):
return self.__parse_tuple(name, path, schema)
else:
return self.__parse_primitive(name, path, schema)
Expand Down
4 changes: 1 addition & 3 deletions jsf/schema_types/_tuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@

class JSFTuple(BaseSchema):
items: Optional[List[BaseSchema]] = None
additionalItems: Optional[
Union[bool, BaseSchema]
] = None # TODO: Random additional items to be appended
additionalItems: Optional[Union[bool, BaseSchema]] = None # TODO: Random additional items to be appended
minItems: Optional[int] = 0
maxItems: Optional[int] = 5
uniqueItems: Optional[bool] = False
Expand Down
6 changes: 1 addition & 5 deletions jsf/schema_types/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,12 @@ def generate(self, context: Dict[str, Any]) -> Optional[List[Any]]:
try:
return super().generate(context)
except ProviderNotSetException:

if isinstance(self.fixed, str):
self.minItems = self.maxItems = eval(self.fixed, context)()
elif isinstance(self.fixed, int):
self.minItems = self.maxItems = self.fixed

output = [
self.items.generate(context)
for _ in range(random.randint(self.minItems, self.maxItems))
]
output = [self.items.generate(context) for _ in range(random.randint(self.minItems, self.maxItems))]
if self.uniqueItems and self.items.type == "object":
output = [dict(s) for s in {frozenset(d.items()) for d in output}]
while len(output) < self.minItems:
Expand Down
1 change: 0 additions & 1 deletion jsf/schema_types/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def from_dict(d):
raise NotImplementedError # pragma: no cover

def generate(self, context: Dict[str, Any]) -> Any:

if self.set_state is not None:
context["state"][self.path] = {k: eval(v, context)() for k, v in self.set_state.items()}

Expand Down
5 changes: 1 addition & 4 deletions jsf/schema_types/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ def generate(self, context: Dict[str, Any]) -> Optional[float]:
try:
return super().generate(context)
except ProviderNotSetException:

step = self.multipleOf if self.multipleOf is not None else 1

if isinstance(self.exclusiveMinimum, bool):
Expand All @@ -34,9 +33,7 @@ def generate(self, context: Dict[str, Any]) -> Optional[float]:
else:
_max = self.maximum

return float(
step * random.randint(math.ceil(float(_min) / step), math.floor(float(_max) / step))
)
return float(step * random.randint(math.ceil(float(_min) / step), math.floor(float(_max) / step)))

def model(self, context: Dict[str, Any]):
return self.to_pydantic(context, float)
Expand Down
4 changes: 1 addition & 3 deletions jsf/schema_types/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ def generate(self, context: Dict[str, Any]) -> Optional[Dict[str, Any]]:
try:
return super().generate(context)
except ProviderNotSetException:
explicit_properties = {
o.name: o.generate(context) for o in self.properties if self.should_keep(o.name)
}
explicit_properties = {o.name: o.generate(context) for o in self.properties if self.should_keep(o.name)}
pattern_props = {}
if self.patternProperties:
for o in self.patternProperties:
Expand Down
8 changes: 2 additions & 6 deletions jsf/schema_types/string.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,7 @@ def fake_duration():
"iri": faker.uri,
"iri-reference": lambda: faker.uri() + rstr.xeger(PARAM_PATTERN),
"uri-template": lambda: rstr.xeger(
URI_PATTERN.format(hostname=re.escape(faker.hostname())).replace(
"(?:", "(?:/\\{[a-z][:a-zA-Z0-9-]*\\}|"
)
URI_PATTERN.format(hostname=re.escape(faker.hostname())).replace("(?:", "(?:/\\{[a-z][:a-zA-Z0-9-]*\\}|")
),
"json-pointer": lambda: rstr.xeger(f"(/(?:${FRAGMENT.replace(']*', '/]*')}|~[01]))+"),
"relative-json-pointer": lambda: rstr.xeger(
Expand All @@ -132,9 +130,7 @@ def generate(self, context: Dict[str, Any]) -> Optional[str]:
return str(content_encoding.encode(s, self.contentEncoding)) if s else s
except ProviderNotSetException:
format_map["regex"] = lambda: rstr.xeger(self.pattern)
format_map["relative-json-pointer"] = lambda: random.choice(
context["state"]["__all_json_paths__"]
)
format_map["relative-json-pointer"] = lambda: random.choice(context["state"]["__all_json_paths__"])
if format_map.get(self.format) is not None:
return content_encoding.encode(format_map[self.format](), self.contentEncoding)
if self.pattern is not None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ def base64url_encode(input: bytes):


def jwt(api_key, expiry, api_sec):

segments = []

header = {"typ": "JWT", "alg": "HS256"}
Expand All @@ -39,7 +38,6 @@ def jwt(api_key, expiry, api_sec):


def create_random_jwt(*args, **kwargs):

api_key = secrets.token_urlsafe(16)
api_sec = secrets.token_urlsafe(16)

Expand Down
4 changes: 1 addition & 3 deletions jsf/schema_types/string_utils/content_type/image__jpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,5 @@

def random_jpg(*args, **kwargs) -> str:
return bytes_str_repr(
requests.get(
f"https://picsum.photos/{random.randint(1,50)*10}/{random.randint(1,50)*10}.jpg"
).content
requests.get(f"https://picsum.photos/{random.randint(1,50)*10}/{random.randint(1,50)*10}.jpg").content
)
4 changes: 1 addition & 3 deletions jsf/schema_types/string_utils/content_type/image__webp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,5 @@

def random_webp(*args, **kwargs) -> str:
return bytes_str_repr(
requests.get(
f"https://picsum.photos/{random.randint(1,50)*10}/{random.randint(1,50)*10}.webp"
).content
requests.get(f"https://picsum.photos/{random.randint(1,50)*10}/{random.randint(1,50)*10}.webp").content
)
7 changes: 3 additions & 4 deletions jsf/tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import json
from pathlib import Path

from jsf.cli import app
from jsonschema import validate
from typer.testing import CliRunner # pants: no-infer-dep

from jsf.cli import app

runner = CliRunner()


def test_app(TestData):
file = Path("tmp.json")
try:
result = runner.invoke(
app, ["--schema", TestData / "custom.json", "--instance", "tmp.json"]
)
result = runner.invoke(app, ["--schema", TestData / "custom.json", "--instance", "tmp.json"])
assert result.exit_code == 0
assert file.exists()
with open(file, "r") as f:
Expand Down
24 changes: 7 additions & 17 deletions jsf/tests/test_default_fake.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import re

import jwt # pants: no-infer-dep

from jsf.parser import JSF


Expand Down Expand Up @@ -234,12 +235,8 @@ def test_fake_array_dicts(TestData):
assert isinstance(p.generate(), dict)
fake_data = [p.generate() for _ in range(1000)]
assert all(len(d["Basket"]) == 2 for d in fake_data), fake_data
assert all(
d["Basket"][0]["Item Name"] in ["A", "B", "C", "D", "E"] for d in fake_data
), fake_data
assert all(
d["Basket"][1]["Item Name"] in ["A", "B", "C", "D", "E"] for d in fake_data
), fake_data
assert all(d["Basket"][0]["Item Name"] in ["A", "B", "C", "D", "E"] for d in fake_data), fake_data
assert all(d["Basket"][1]["Item Name"] in ["A", "B", "C", "D", "E"] for d in fake_data), fake_data
assert all(0 <= d["Basket"][0]["Amount"] < 5 for d in fake_data), fake_data
assert all(0 <= d["Basket"][1]["Amount"] < 5 for d in fake_data), fake_data

Expand Down Expand Up @@ -324,8 +321,7 @@ def test_fake_string_format(TestData):
assert all(bool(re.match(r".*@.*", d["email"])) for d in fake_data), fake_data
assert all(bool(re.match(r".*@.*", d["idn-email"])) for d in fake_data), fake_data
assert all(
bool(re.match(r"\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\+\d{2}\:\d{2}", d["date-time"]))
for d in fake_data
bool(re.match(r"\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\+\d{2}\:\d{2}", d["date-time"])) for d in fake_data
), fake_data
assert all(bool(re.match(r"\d{4}-\d{2}-\d{2}", d["date"])) for d in fake_data), fake_data
assert all(
Expand All @@ -337,15 +333,9 @@ def test_fake_string_format(TestData):
)
for d in fake_data
), fake_data
assert all(
bool(re.match(r"\d{2}\:\d{2}\:\d{2}\+\d{2}\:\d{2}", d["time"])) for d in fake_data
), fake_data
assert all(
bool(re.match(r"[a-zA-Z0-9+-\.]{1,33}\.[a-z]{2,4}", d["hostname"])) for d in fake_data
)
assert all(
bool(re.match(r"[a-zA-Z0-9+-\.]{1,33}\.[a-z]{2,4}", d["idn-hostname"])) for d in fake_data
)
assert all(bool(re.match(r"\d{2}\:\d{2}\:\d{2}\+\d{2}\:\d{2}", d["time"])) for d in fake_data), fake_data
assert all(bool(re.match(r"[a-zA-Z0-9+-\.]{1,33}\.[a-z]{2,4}", d["hostname"])) for d in fake_data)
assert all(bool(re.match(r"[a-zA-Z0-9+-\.]{1,33}\.[a-z]{2,4}", d["idn-hostname"])) for d in fake_data)
assert all(bool(re.match(r"[a-f0-9]{0,4}(:[a-f0-9]{0,4}){7}", d["ipv6"])) for d in fake_data), [
d["ipv6"] for d in fake_data
]
Expand Down
3 changes: 2 additions & 1 deletion jsf/tests/test_model_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
from typing import List, _GenericAlias

import pytest # pants: no-infer-dep
from jsf.parser import JSF
from pydantic.main import create_model

from jsf.parser import JSF

Object = create_model("Object")

expected = [
Expand Down
5 changes: 3 additions & 2 deletions jsf/tests/test_parser.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import json

import pytest # pants: no-infer-dep
from jsf.parser import JSF

from jsf.parser import JSF
from jsf.schema_types import (
Array,
Boolean,
Expand Down Expand Up @@ -95,6 +95,7 @@ def test_nested_object_ref(TestData):
}
assert {prop.name: type(prop) for prop in p.root.properties[0].properties} == expected_types


def test_ordered_refs_object(TestData):
with open(TestData / "ordered-refs.json", "r") as file:
schema = json.load(file)
Expand All @@ -109,6 +110,7 @@ def test_ordered_refs_object(TestData):
}
assert {prop.name: type(prop) for prop in p.root.properties[0].properties} == expected_types


def test_unordered_refs_object(TestData):
with open(TestData / "unordered-refs.json", "r") as file:
schema = json.load(file)
Expand All @@ -122,4 +124,3 @@ def test_unordered_refs_object(TestData):
"bar": JSFEnum,
}
assert {prop.name: type(prop) for prop in p.root.properties[0].properties} == expected_types

0 comments on commit c345d4e

Please sign in to comment.