fix(spec): resolve UserType name collision with inline User.type schema - #575
Open
BinoyOza-okta wants to merge 2 commits into
Open
fix(spec): resolve UserType name collision with inline User.type schema#575BinoyOza-okta wants to merge 2 commits into
BinoyOza-okta wants to merge 2 commits into
Conversation
The top-level UserType component schema (api.yaml) was being generated with only an `id` field, dropping all other properties (name, displayName, description, created, createdBy, default, lastUpdated, lastUpdatedBy, _links).
Root cause: OpenAPI Generator 7.x auto-promotes inline object schemas to standalone models, naming them <ParentSchema><PropertyName> in TitleCase. The `User` schema's inline `type` property (an anonymous object with a single `id` field) was therefore promoted to a model named `UserType`, colliding with the real component of the same name. The inline `{id}`-only shape won, shadowing the full schema.
Fix: extract the inline `User.type` object into a new named component `UserTypeRef` and `$ref` it from `User.type`. This frees the `UserType` name for the real component and preserves the on-wire JSON shape (User.type payload is unchanged — still `{ "id": "..." }`).
Regenerated SDK reflects the fix:
- okta/models/user_type.py now carries the full component schema
- okta/models/user_type_ref.py (new) holds the {id}-only shape
- okta/models/user.py, user_get_singleton.py: User.type now typed as
UserTypeRef instead of UserType
- okta/__init__.py, okta/models/__init__.py: export UserTypeRef
- docs/UserType.md, docs/UserTypeRef.md, docs/User.md,
docs/UserGetSingleton.md updated by generator
Added tests/test_user_type.py to guard against regressions of the collision — asserts UserType declares the full component field set, UserTypeRef stays id-only, and covers from_dict/to_dict/JSON roundtrips including the readOnly-field exclusion behavior on serialization.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a long-standing bug where
okta.models.UserTypewas generated with only anidfield, missing every other property (name,displayName,description,created,createdBy,default,lastUpdated,lastUpdatedBy,_links) that theUserTypecomponent schema defines inopenapi/api.yaml.Customer-reported: any deserialization of a
/api/v1/meta/types/user/*response intoUserTypesilently dropped every field exceptid.Root cause
Two schemas in
api.yamlcompete for the same generated class name:components/schemas/UserType(line 82944) — the full model.User.type(line 80775) — an inline anonymous object with a singleidproperty.OpenAPI Generator 7.x auto-promotes inline object schemas into standalone models and names them
<ParentSchema <PropertyName>in TitleCase. Parent =User, property =type→ generated name =UserType, which collides with the real component. The inline{id}-only shape wins, shadowing the full schema.Evidence (pre-fix
okta/models/user_type.py):User.typedescription ("The user type that determines the schema for the user's profile..."), not the component schema.id: Optional[StrictStr]with description"The ID of the user type"— the inline schema's exact wording.This is why no other model is affected —
User.typeis the only spot in the spec where an inline object's auto-derived name matches an existing component name.Fix
Spec-side change in
openapi/api.yaml:UserTypeRefthat captures the{id}-only shape used byUser.type.User.typewith$ref: '#/components/schemas/serTypeRef'.The on-wire JSON shape of
User.typeis unchanged (still{ "id": "..." }), so this is backward-compatible for API consumers.Regenerated artifacts
Ran
openapi/generate.sh(OpenAPI Generator 7.7.0). Resulting changes:okta/models/user_type.py_links)okta/models/user_type_ref.py{id}-only model used byUser.typeokta/models/user.pytypefield re-typed fromUserType→UserTypeRefokta/models/user_get_singleton.pyokta/__init__.py,okta/models/__init__.pyUserTypeRefdocs/UserType.mddocs/UserTypeRef.mddocs/User.md,docs/UserGetSingleton.mdUserTypeRefTests
Added
tests/test_user_type.py(12 cases, all passing) to lock in the fix and guard against regression:UserTypedeclares the full component field set andUserTypeRefstays{id}-only.from_dict: hydrates all response fields (incl.datetimeparsing oncreated/lastUpdated), nested_links→UserTypeLinks,Noneinput, and missing-optional handling.name/displayNameas required; accepts both alias and Python-field-name kwargs.to_dict: verifies the generator's read-only exclusion behavior (id,created,createdBy,default,lastUpdated,lastUpdatedByare omitted on serialization) and that_linksserializes via nestedto_dict().from_json→to_jsonpreserves writable fields.Run:
pytest tests/test_user_type.py -v # 12 passedBreaking-change note
The Python-level type of
User.typechanges fromUserTypetoUserTypeRef. Any user code that explicitly annotates orisinstance-checksUser.typeagainstUserTypewill need to switch toUserTypeRef. Runtime/JSON behavior is unchanged.Checklist
openapi/api.yamlopenapi/generate.shFixes
id#535