From b2e4920c367d27da76613a9b81af14e75b1b974a Mon Sep 17 00:00:00 2001 From: Roman Isecke Date: Wed, 26 Jun 2024 08:24:55 -0400 Subject: [PATCH 1/2] Add new cli to print schema as yaml --- setup.py | 5 ++-- test/test_schema.py | 2 +- test/test_utils.py | 2 +- .../{ => cli}/etl_uvicorn/__init__.py | 0 .../{ => cli}/etl_uvicorn/api_generator.py | 2 +- .../{ => cli}/etl_uvicorn/main.py | 2 +- .../cli/schema_yaml/main.py | 25 +++++++++++++++++++ .../{etl_uvicorn => cli}/utils.py | 0 .../{validate_api.py => cli/validate/main.py} | 0 9 files changed, 32 insertions(+), 6 deletions(-) rename unstructured_platform_plugins/{ => cli}/etl_uvicorn/__init__.py (100%) rename unstructured_platform_plugins/{ => cli}/etl_uvicorn/api_generator.py (97%) rename unstructured_platform_plugins/{ => cli}/etl_uvicorn/main.py (97%) create mode 100644 unstructured_platform_plugins/cli/schema_yaml/main.py rename unstructured_platform_plugins/{etl_uvicorn => cli}/utils.py (100%) rename unstructured_platform_plugins/{validate_api.py => cli/validate/main.py} (100%) diff --git a/setup.py b/setup.py index ad59f8e..d1ef8c7 100644 --- a/setup.py +++ b/setup.py @@ -32,8 +32,9 @@ def load_requirements(file: Union[str, Path]) -> List[str]: packages=find_packages(), entry_points={ "console_scripts": [ - "etl-uvicorn=unstructured_platform_plugins.etl_uvicorn.main:cmd", - "etl-validate=unstructured_platform_plugins.validate_api:validate_api", + "etl-uvicorn=unstructured_platform_plugins.cli.etl_uvicorn.main:cmd", + "etl-validate=unstructured_platform_plugins.cli.validate.main:validate_api", + "etl-schema=unstructured_platform_plugins.cli.schema_yaml.main:generate_yaml", ], }, install_requires=load_requirements("requirements/cli.in") diff --git a/test/test_schema.py b/test/test_schema.py index 35b92d9..7d81366 100644 --- a/test/test_schema.py +++ b/test/test_schema.py @@ -6,7 +6,7 @@ from pydantic import BaseModel import unstructured_platform_plugins.schema.json_schema as js -from unstructured_platform_plugins.etl_uvicorn.utils import get_input_schema +from unstructured_platform_plugins.cli.utils import get_input_schema from unstructured_platform_plugins.schema.model import is_validate_dict diff --git a/test/test_utils.py b/test/test_utils.py index 1ec34b2..3422a5f 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -4,7 +4,7 @@ from pydantic import BaseModel from uvicorn.importer import import_from_string -from unstructured_platform_plugins.etl_uvicorn import utils +from unstructured_platform_plugins.cli import utils def test_get_func_simple(): diff --git a/unstructured_platform_plugins/etl_uvicorn/__init__.py b/unstructured_platform_plugins/cli/etl_uvicorn/__init__.py similarity index 100% rename from unstructured_platform_plugins/etl_uvicorn/__init__.py rename to unstructured_platform_plugins/cli/etl_uvicorn/__init__.py diff --git a/unstructured_platform_plugins/etl_uvicorn/api_generator.py b/unstructured_platform_plugins/cli/etl_uvicorn/api_generator.py similarity index 97% rename from unstructured_platform_plugins/etl_uvicorn/api_generator.py rename to unstructured_platform_plugins/cli/etl_uvicorn/api_generator.py index 71c8325..546eb13 100644 --- a/unstructured_platform_plugins/etl_uvicorn/api_generator.py +++ b/unstructured_platform_plugins/cli/etl_uvicorn/api_generator.py @@ -10,7 +10,7 @@ from pydantic import BaseModel from uvicorn.importer import import_from_string -from unstructured_platform_plugins.etl_uvicorn.utils import ( +from unstructured_platform_plugins.cli.utils import ( get_func, get_input_schema, get_output_sig, diff --git a/unstructured_platform_plugins/etl_uvicorn/main.py b/unstructured_platform_plugins/cli/etl_uvicorn/main.py similarity index 97% rename from unstructured_platform_plugins/etl_uvicorn/main.py rename to unstructured_platform_plugins/cli/etl_uvicorn/main.py index 3f19df3..1254bbe 100644 --- a/unstructured_platform_plugins/etl_uvicorn/main.py +++ b/unstructured_platform_plugins/cli/etl_uvicorn/main.py @@ -5,7 +5,7 @@ from uvicorn.config import LOGGING_CONFIG, Config, RawConfigParser from uvicorn.main import main, run -from unstructured_platform_plugins.etl_uvicorn.api_generator import generate_fast_api +from unstructured_platform_plugins.cli.etl_uvicorn.api_generator import generate_fast_api @dataclass diff --git a/unstructured_platform_plugins/cli/schema_yaml/main.py b/unstructured_platform_plugins/cli/schema_yaml/main.py new file mode 100644 index 0000000..38e2fa8 --- /dev/null +++ b/unstructured_platform_plugins/cli/schema_yaml/main.py @@ -0,0 +1,25 @@ +from typing import Optional + +import click +from uvicorn.importer import import_from_string +from yaml import Dumper, dump + +from unstructured_platform_plugins.cli.utils import get_func, get_schema_dict + + +@click.command() +@click.argument("app", envvar="UVICORN_APP") +@click.option( + "--method-name", + required=False, + type=str, + default=None, + help="If passed in instance is a class, what method to wrap. " + "Will fall back to __call__ if none is provided.", +) +def generate_yaml(app: str, method_name: Optional[str] = None) -> None: + instance = import_from_string(app) + func = get_func(instance=instance, method_name=method_name) + schemas = get_schema_dict(func) + output = dump(schemas, Dumper=Dumper) + print(output) diff --git a/unstructured_platform_plugins/etl_uvicorn/utils.py b/unstructured_platform_plugins/cli/utils.py similarity index 100% rename from unstructured_platform_plugins/etl_uvicorn/utils.py rename to unstructured_platform_plugins/cli/utils.py diff --git a/unstructured_platform_plugins/validate_api.py b/unstructured_platform_plugins/cli/validate/main.py similarity index 100% rename from unstructured_platform_plugins/validate_api.py rename to unstructured_platform_plugins/cli/validate/main.py From c9718b9553bd76afc4989359f934523a5be1bc4c Mon Sep 17 00:00:00 2001 From: Roman Isecke Date: Mon, 1 Jul 2024 10:57:14 -0400 Subject: [PATCH 2/2] Add a simple unit test for yaml generation --- test/expected_results/simple.yaml | 22 +++++++++++++++++++ test/test_yaml.py | 14 ++++++++++++ .../cli/schema_yaml/main.py | 11 +++------- .../cli/schema_yaml/yaml_generator.py | 14 ++++++++++++ 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 test/expected_results/simple.yaml create mode 100644 test/test_yaml.py create mode 100644 unstructured_platform_plugins/cli/schema_yaml/yaml_generator.py diff --git a/test/expected_results/simple.yaml b/test/expected_results/simple.yaml new file mode 100644 index 0000000..396769a --- /dev/null +++ b/test/expected_results/simple.yaml @@ -0,0 +1,22 @@ +inputs: + properties: + content: + properties: + name: + type: string + value: + type: number + required: + - name + - value + type: object + required: + - content + type: object +outputs: + properties: + response: + type: object + required: + - response + type: object diff --git a/test/test_yaml.py b/test/test_yaml.py new file mode 100644 index 0000000..87271e8 --- /dev/null +++ b/test/test_yaml.py @@ -0,0 +1,14 @@ +from pathlib import Path + +from unstructured_platform_plugins.cli.schema_yaml.yaml_generator import generate_yaml + +test_path = Path(__file__).parent +results_path = test_path / "expected_results" + + +def test_generate_yaml_simple(): + output = generate_yaml(app="test.assets.typed_dict_response:sample_function") + file_path = results_path / "simple.yaml" + with file_path.open("r") as f: + expected = f.read() + assert expected == output diff --git a/unstructured_platform_plugins/cli/schema_yaml/main.py b/unstructured_platform_plugins/cli/schema_yaml/main.py index 38e2fa8..78fc68f 100644 --- a/unstructured_platform_plugins/cli/schema_yaml/main.py +++ b/unstructured_platform_plugins/cli/schema_yaml/main.py @@ -1,10 +1,8 @@ from typing import Optional import click -from uvicorn.importer import import_from_string -from yaml import Dumper, dump -from unstructured_platform_plugins.cli.utils import get_func, get_schema_dict +from unstructured_platform_plugins.cli.schema_yaml.yaml_generator import generate_yaml @click.command() @@ -17,9 +15,6 @@ help="If passed in instance is a class, what method to wrap. " "Will fall back to __call__ if none is provided.", ) -def generate_yaml(app: str, method_name: Optional[str] = None) -> None: - instance = import_from_string(app) - func = get_func(instance=instance, method_name=method_name) - schemas = get_schema_dict(func) - output = dump(schemas, Dumper=Dumper) +def yaml(app: str, method_name: Optional[str] = None) -> None: + output = generate_yaml(app=app, method_name=method_name) print(output) diff --git a/unstructured_platform_plugins/cli/schema_yaml/yaml_generator.py b/unstructured_platform_plugins/cli/schema_yaml/yaml_generator.py new file mode 100644 index 0000000..143a9eb --- /dev/null +++ b/unstructured_platform_plugins/cli/schema_yaml/yaml_generator.py @@ -0,0 +1,14 @@ +from typing import Optional + +from uvicorn.importer import import_from_string +from yaml import Dumper, dump + +from unstructured_platform_plugins.cli.utils import get_func, get_schema_dict + + +def generate_yaml(app: str, method_name: Optional[str] = None) -> str: + instance = import_from_string(app) + func = get_func(instance=instance, method_name=method_name) + schemas = get_schema_dict(func) + output = dump(schemas, Dumper=Dumper) + return output