diff --git a/.github/workflows/manual_regenerate_models.yaml b/.github/workflows/manual_regenerate_models.yaml index 84b37df2..86793801 100644 --- a/.github/workflows/manual_regenerate_models.yaml +++ b/.github/workflows/manual_regenerate_models.yaml @@ -79,9 +79,9 @@ jobs: - name: Generate models from OpenAPI spec run: | if [[ -f openapi-spec/openapi.json ]]; then - uv run datamodel-codegen --input openapi-spec/openapi.json + uv run poe generate-models-from-file openapi-spec/openapi.json else - uv run datamodel-codegen + uv run poe generate-models fi - name: Commit model changes diff --git a/pyproject.toml b/pyproject.toml index cee47d80..10a60135 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -208,7 +208,6 @@ context = 7 # https://koxudaxi.github.io/datamodel-code-generator/ [tool.datamodel-codegen] -url = "https://docs.apify.com/api/openapi.json" input_file_type = "openapi" output = "src/apify_client/_models.py" target_python_version = "3.11" @@ -269,4 +268,8 @@ shell = "./build_api_reference.sh && corepack enable && yarn && uv run yarn star cwd = "website" [tool.poe.tasks.generate-models] -shell = "uv run datamodel-codegen" +shell = "uv run datamodel-codegen --url https://docs.apify.com/api/openapi.json && python scripts/postprocess_generated_models.py" + +[tool.poe.tasks.generate-models-from-file] +shell = "uv run datamodel-codegen --input $input_file && python scripts/postprocess_generated_models.py" +args = [{ name = "input-file", positional = true, required = true }] diff --git a/scripts/postprocess_generated_models.py b/scripts/postprocess_generated_models.py new file mode 100644 index 00000000..46a1d0ab --- /dev/null +++ b/scripts/postprocess_generated_models.py @@ -0,0 +1,46 @@ +"""Post-process the generated _models.py to fix known datamodel-codegen issues. + +Currently fixes: +- Discriminator field names: datamodel-codegen sometimes emits the JSON property name (camelCase) + instead of the Python field name (snake_case) in `Field(discriminator='...')` annotations, + particularly when the discriminator is on a schema referenced inside array items. +""" + +from __future__ import annotations + +import re +from pathlib import Path + +MODELS_PATH = Path(__file__).resolve().parent.parent / 'src' / 'apify_client' / '_models.py' + +# Map of camelCase discriminator values to their snake_case equivalents. +# Add new entries here as needed when the OpenAPI spec introduces new discriminators. +DISCRIMINATOR_FIXES: dict[str, str] = { + 'pricingModel': 'pricing_model', +} + + +def fix_discriminators(content: str) -> str: + """Replace camelCase discriminator values with their snake_case equivalents.""" + for camel, snake in DISCRIMINATOR_FIXES.items(): + content = re.sub( + rf"discriminator='{camel}'", + f"discriminator='{snake}'", + content, + ) + return content + + +def main() -> None: + content = MODELS_PATH.read_text() + fixed = fix_discriminators(content) + + if fixed != content: + MODELS_PATH.write_text(fixed) + print(f'Fixed discriminator values in {MODELS_PATH}') + else: + print('No discriminator fixes needed') + + +if __name__ == '__main__': + main()