diff --git a/end_to_end_tests/regen_golden_master.py b/end_to_end_tests/regen_golden_master.py index ca392ab79..1c8ea1c45 100644 --- a/end_to_end_tests/regen_golden_master.py +++ b/end_to_end_tests/regen_golden_master.py @@ -7,9 +7,6 @@ from openapi_python_client.cli import app if __name__ == "__main__": - from .fastapi_app import generate_openapi_json - - generate_openapi_json() runner = CliRunner() openapi_path = Path(__file__).parent / "fastapi_app" / "openapi.json" gm_path = Path(__file__).parent / "golden-master" diff --git a/openapi_python_client/__init__.py b/openapi_python_client/__init__.py index 8c3c65f08..d8846ace0 100644 --- a/openapi_python_client/__init__.py +++ b/openapi_python_client/__init__.py @@ -83,7 +83,7 @@ def _get_document(*, url: Optional[str], path: Optional[Path]) -> Union[Dict[str class Project: - TEMPLATE_FILTERS = {"snakecase": utils.snake_case, "spinalcase": utils.spinal_case} + TEMPLATE_FILTERS = {"snakecase": utils.snake_case, "kebabcase": utils.kebab_case} project_name_override: Optional[str] = None package_name_override: Optional[str] = None @@ -91,7 +91,7 @@ def __init__(self, *, openapi: GeneratorData) -> None: self.openapi: GeneratorData = openapi self.env: Environment = Environment(loader=PackageLoader(__package__), trim_blocks=True, lstrip_blocks=True) - self.project_name: str = self.project_name_override or f"{openapi.title.replace(' ', '-').lower()}-client" + self.project_name: str = self.project_name_override or f"{utils.kebab_case(openapi.title).lower()}-client" self.project_dir: Path = Path.cwd() / self.project_name self.package_name: str = self.package_name_override or self.project_name.replace("-", "_") @@ -231,6 +231,7 @@ def _build_api(self) -> None: endpoint_template = self.env.get_template("endpoint_module.pyi") async_endpoint_template = self.env.get_template("async_endpoint_module.pyi") for tag, collection in self.openapi.endpoint_collections_by_tag.items(): + tag = utils.snake_case(tag) module_path = api_dir / f"{tag}.py" module_path.write_text(endpoint_template.render(collection=collection)) async_module_path = async_api_dir / f"{tag}.py" diff --git a/openapi_python_client/templates/endpoint_macros.pyi b/openapi_python_client/templates/endpoint_macros.pyi index 555968e41..50529a197 100644 --- a/openapi_python_client/templates/endpoint_macros.pyi +++ b/openapi_python_client/templates/endpoint_macros.pyi @@ -2,10 +2,10 @@ {% if endpoint.header_parameters %} {% for parameter in endpoint.header_parameters %} {% if parameter.required %} -headers["{{ parameter.python_name | spinalcase}}"] = {{ parameter.python_name }} +headers["{{ parameter.python_name | kebabcase}}"] = {{ parameter.python_name }} {% else %} if {{ parameter.python_name }} is not None: - headers["{{ parameter.python_name | spinalcase}}"] = {{ parameter.python_name }} + headers["{{ parameter.python_name | kebabcase}}"] = {{ parameter.python_name }} {% endif %} {% endfor %} {% endif %} diff --git a/openapi_python_client/utils.py b/openapi_python_client/utils.py index 09ab12e02..bf209316a 100644 --- a/openapi_python_client/utils.py +++ b/openapi_python_client/utils.py @@ -3,15 +3,23 @@ import stringcase -def snake_case(value: str) -> str: +def _sanitize(value: str) -> str: + return re.sub(r"[^\w _-]+", "", value) + + +def group_title(value: str) -> str: value = re.sub(r"([A-Z]{2,})([A-Z][a-z]|[ -_]|$)", lambda m: m.group(1).title() + m.group(2), value.strip()) value = re.sub(r"(^|[ _-])([A-Z])", lambda m: m.group(1) + m.group(2).lower(), value) - return stringcase.snakecase(value) + return value + + +def snake_case(value: str) -> str: + return stringcase.snakecase(group_title(_sanitize(value))) def pascal_case(value: str) -> str: - return stringcase.pascalcase(value) + return stringcase.pascalcase(_sanitize(value)) -def spinal_case(value: str) -> str: - return stringcase.spinalcase(value) +def kebab_case(value: str) -> str: + return stringcase.spinalcase(group_title(_sanitize(value))) diff --git a/tests/test___init__.py b/tests/test___init__.py index d920e6921..15ee5e358 100644 --- a/tests/test___init__.py +++ b/tests/test___init__.py @@ -486,8 +486,8 @@ def test__build_api(self, mocker): from openapi_python_client import GeneratorData, Project openapi = mocker.MagicMock(autospec=GeneratorData, title="My Test API") - tag_1 = mocker.MagicMock(autospec=str) - tag_2 = mocker.MagicMock(autospec=str) + tag_1 = "a_tag" + tag_2 = "another_tag" collection_1 = mocker.MagicMock() collection_2 = mocker.MagicMock() openapi.endpoint_collections_by_tag = {tag_1: collection_1, tag_2: collection_2} diff --git a/tests/test_templates/conftest.py b/tests/test_templates/conftest.py index a11db3cd1..09fd63f6c 100644 --- a/tests/test_templates/conftest.py +++ b/tests/test_templates/conftest.py @@ -6,7 +6,7 @@ def env() -> Environment: from openapi_python_client import utils - TEMPLATE_FILTERS = {"snakecase": utils.snake_case, "spinalcase": utils.spinal_case} + TEMPLATE_FILTERS = {"snakecase": utils.snake_case, "kebabcase": utils.kebab_case} env = Environment(loader=PackageLoader("openapi_python_client"), trim_blocks=True, lstrip_blocks=True) env.filters.update(TEMPLATE_FILTERS) return env diff --git a/tests/test_utils.py b/tests/test_utils.py index a7aa0942f..3bed213ca 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -20,5 +20,5 @@ def test_snake_case_from_camel(): assert utils.snake_case("httpResponseLowerCamel") == "http_response_lower_camel" -def test_spinal_case(): - assert utils.spinal_case("keep_alive") == "keep-alive" +def test_kebab_case(): + assert utils.kebab_case("keep_alive") == "keep-alive"