Environment
- clientele version: 2.1.0
- Python: 3.14.2
- Command used:
uv run clientele start-api -u <openapi-url> -o server
Bug 1: Forward reference "FaceTypeEnum" not resolvable in client.py
When an endpoint has an enum query parameter, the generator emits it as a quoted forward reference:
# client.py (generated)
def get_faces_api_v1_gallery_faces(
result: schemas.HTTPValidationError | schemas.PageFacesresponsedataitem,
faces_type: typing.Optional[list["FaceTypeEnum"] | None] = None,
...
"FaceTypeEnum" is not imported directly in client.py — only schemas is imported. When build_request_context calls typing.get_type_hints(func), it raises NameError: name 'FaceTypeEnum' is not defined, then falls back to raw string annotations. The result annotation becomes a plain string instead of a resolved type, so the validation in _validate_response_map always fails:
ValueError: Response model 'PageFacesresponsedataitem' for status code 200 is not in the
'result' parameter's type annotation.
Fix: The generator should emit schemas.FaceTypeEnum (without quotes) instead of "FaceTypeEnum".
Bug 2: Array response types generated as type aliases instead of RootModel subclasses
When an OpenAPI endpoint returns an array type, the generator creates a plain type alias in schemas.py:
# schemas.py (generated)
ResponseUploadFacesApiV1GalleryFacesUploadPost = list[FacesResponseDataItem]
ResponseDetectFacesApiV1GalleryFacesDetectFacesPost = list[list[DetectedFace]]
But RequestContext (a Pydantic model) declares response_map: dict[int, type[Any]], which requires actual classes. A GenericAlias like list[...] is not a type, so Pydantic rejects it:
pydantic_core.ValidationError: 1 validation error for RequestContext
response_map.200
Input should be a type [type=is_type, input_value=list[...], input_type=GenericAlias]
Fix: The generator should emit pydantic.RootModel subclasses for array responses:
class ResponseUploadFacesApiV1GalleryFacesUploadPost(pydantic.RootModel[list[FacesResponseDataItem]]):
pass
Same issue applies to union type aliases (e.g. ResponseX = A | B) — these are also not type instances and fail the same validation.
Bug 3: Generated .env uses API_BASE_URL but BaseConfig reads BASE_URL
The generator creates .env with:
API_BASE_URL="https://..."
But BaseConfig has a field named base_url, so pydantic-settings reads the env variable BASE_URL. The variable API_BASE_URL is silently ignored (extra="ignore" in SettingsConfigDict), and the client falls back to the default http://localhost.
Fix: Either rename the generated env variable to BASE_URL, or rename the BaseConfig field to api_base_url to match the generated .env.
Environment
uv run clientele start-api -u <openapi-url> -o serverBug 1: Forward reference
"FaceTypeEnum"not resolvable inclient.pyWhen an endpoint has an enum query parameter, the generator emits it as a quoted forward reference:
"FaceTypeEnum"is not imported directly inclient.py— onlyschemasis imported. Whenbuild_request_contextcallstyping.get_type_hints(func), it raisesNameError: name 'FaceTypeEnum' is not defined, then falls back to raw string annotations. Theresultannotation becomes a plain string instead of a resolved type, so the validation in_validate_response_mapalways fails:Fix: The generator should emit
schemas.FaceTypeEnum(without quotes) instead of"FaceTypeEnum".Bug 2: Array response types generated as type aliases instead of
RootModelsubclassesWhen an OpenAPI endpoint returns an
arraytype, the generator creates a plain type alias inschemas.py:But
RequestContext(a Pydantic model) declaresresponse_map: dict[int, type[Any]], which requires actual classes. AGenericAliaslikelist[...]is not atype, so Pydantic rejects it:Fix: The generator should emit
pydantic.RootModelsubclasses for array responses:Same issue applies to union type aliases (e.g.
ResponseX = A | B) — these are also nottypeinstances and fail the same validation.Bug 3: Generated
.envusesAPI_BASE_URLbutBaseConfigreadsBASE_URLThe generator creates
.envwith:But
BaseConfighas a field namedbase_url, so pydantic-settings reads the env variableBASE_URL. The variableAPI_BASE_URLis silently ignored (extra="ignore"inSettingsConfigDict), and the client falls back to the defaulthttp://localhost.Fix: Either rename the generated env variable to
BASE_URL, or rename theBaseConfigfield toapi_base_urlto match the generated.env.