Skip to content

feat: generate pydantic models from smithy IDL#425

Open
layertwo wants to merge 1 commit into
mainlinefrom
feat/smithy-codegen
Open

feat: generate pydantic models from smithy IDL#425
layertwo wants to merge 1 commit into
mainlinefrom
feat/smithy-codegen

Conversation

@layertwo

@layertwo layertwo commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Use datamodel-code-generator to generate Pydantic models from Smithy generated OpenAPI spec.

@layertwo layertwo force-pushed the feat/smithy-codegen branch 2 times, most recently from 6220d17 to ee5711d Compare June 6, 2026 00:50
@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown

Diff for stage: DefaultStage

Warning

4 Destructive Changes

No Changes for stack: GitHubOidcStack ✅

Diff for stack: Service-prod - 4 to add, 8 to update, 4 to destroy

Details

[!WARNING]
Destructive Changes ‼️
Stack: Service-prod - Resource: AuthApiDeploymentB62B2E46932c576f5511d15a89b00bb0cc579c7a - Impact: WILL_DESTROY

Stack: Service-prod - Resource: TokenApiDeploymentB896C219b16a73c2bacf13dff150a851137e236c - Impact: WILL_DESTROY

Stack: Service-prod - Resource: ProfileApiDeployment84A54415e0158c62574d24c31b8dbd21e82873c4 - Impact: WILL_DESTROY

Stack: Service-prod - Resource: StorageApiDeployment3B4929C5e49a2791c6f843724643b35f6d5433f6 - Impact: WILL_DESTROY

Resources
[-] AWS::ApiGateway::Deployment AuthApiDeploymentB62B2E46932c576f5511d15a89b00bb0cc579c7a destroy
[-] AWS::ApiGateway::Deployment TokenApiDeploymentB896C219b16a73c2bacf13dff150a851137e236c destroy
[-] AWS::ApiGateway::Deployment ProfileApiDeployment84A54415e0158c62574d24c31b8dbd21e82873c4 destroy
[-] AWS::ApiGateway::Deployment StorageApiDeployment3B4929C5e49a2791c6f843724643b35f6d5433f6 destroy
[+] AWS::ApiGateway::Deployment AuthApiDeploymentB62B2E4675d39fd1733f70377d4a453cb043e0e2
[+] AWS::ApiGateway::Deployment TokenApiDeploymentB896C219ee4433fd7a430b8eb183e22b78e32990
[+] AWS::ApiGateway::Deployment ProfileApiDeployment84A54415dadeee5002a4db3160be90bf8c2ad143
[+] AWS::ApiGateway::Deployment StorageApiDeployment3B4929C5ecd0b40b6b55212c85a77f63d837e1e2
[~] AWS::Lambda::Function AuthApiHandlerED50ACFA
 ├─ [~] Code
 │   └─ [~] .S3Key:
 │       ├─ [-] f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1.zip
 │       └─ [+] 66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb.zip
 └─ [~] Metadata
     └─ [~] .aws:asset:path:
         ├─ [-] asset.f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1
         └─ [+] asset.66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb
[~] AWS::Lambda::Function TokenApiHandler2E66DB25
 ├─ [~] Code
 │   └─ [~] .S3Key:
 │       ├─ [-] f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1.zip
 │       └─ [+] 66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb.zip
 └─ [~] Metadata
     └─ [~] .aws:asset:path:
         ├─ [-] asset.f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1
         └─ [+] asset.66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb
[~] AWS::Lambda::Function ProfileApiHandler9B65A298
 ├─ [~] Code
 │   └─ [~] .S3Key:
 │       ├─ [-] f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1.zip
 │       └─ [+] 66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb.zip
 └─ [~] Metadata
     └─ [~] .aws:asset:path:
         ├─ [-] asset.f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1
         └─ [+] asset.66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb
[~] AWS::Lambda::Function ApiHandler5E7490E8
 ├─ [~] Code
 │   └─ [~] .S3Key:
 │       ├─ [-] f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1.zip
 │       └─ [+] 66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb.zip
 └─ [~] Metadata
     └─ [~] .aws:asset:path:
         ├─ [-] asset.f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1
         └─ [+] asset.66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb
[~] AWS::ApiGateway::RestApi AuthApi4BD72F20
 └─ [~] Body
     ├─ [~] .components:
     │   └─ [~] .schemas:
     │       ├─ [~] .AccountCreateRequestContent:
     │       │   └─ [~] .properties:
     │       │       └─ [~] .authPW:
     │       │           ├─ [~] .description:
     │       │           │   ├─ [-] Stretched password (authPW) as hex string
     │       │           │   └─ [+] Stretched password (authPW) as 64-char hex string
     │       │           ├─ [+] Added: .maxLength
     │       │           ├─ [+] Added: .minLength
     │       │           └─ [+] Added: .pattern
     │       ├─ [~] .AccountLoginRequestContent:
     │       │   └─ [~] .properties:
     │       │       └─ [~] .authPW:
     │       │           ├─ [~] .description:
     │       │           │   ├─ [-] Stretched password (authPW) as hex string
     │       │           │   └─ [+] Stretched password (authPW) as 64-char hex string
     │       │           ├─ [+] Added: .maxLength
     │       │           ├─ [+] Added: .minLength
     │       │           └─ [+] Added: .pattern
     │       ├─ [~] .AttachedClient:
     │       │   └─ [~] .properties:
     │       │       ├─ [~] .createdTime:
     │       │       │   └─ [~] .type:
     │       │       │       ├─ [-] number
     │       │       │       └─ [+] integer
     │       │       ├─ [~] .lastAccessTime:
     │       │       │   └─ [~] .type:
     │       │       │       ├─ [-] number
     │       │       │       └─ [+] integer
     │       │       ├─ [+] Added: .location
     │       │       └─ [~] .scope:
     │       │           ├─ [+] Added: .items
     │       │           └─ [~] .type:
     │       │               ├─ [-] string
     │       │               └─ [+] array
     │       ├─ [~] .DeviceRecord:
     │       │   └─ [~] .properties:
     │       │       ├─ [+] Added: .createdAt
     │       │       ├─ [~] .lastAccessTime:
     │       │       │   └─ [~] .type:
     │       │       │       ├─ [-] number
     │       │       │       └─ [+] integer
     │       │       └─ [+] Added: .sessionTokenId
     │       ├─ [+] Added: .LocationMap
     │       ├─ [~] .OAuthTokenRequestContent:
     │       │   └─ [~] .properties:
     │       │       └─ [~] .ttl:
     │       │           └─ [~] .type:
     │       │               ├─ [-] number
     │       │               └─ [+] integer
     │       ├─ [~] .OAuthTokenResponseContent:
     │       │   ├─ [~] .properties:
     │       │   │   ├─ [~] .auth_at:
     │       │   │   │   └─ [~] .type:
     │       │   │   │       ├─ [-] number
     │       │   │   │       └─ [+] integer
     │       │   │   └─ [~] .expires_in:
     │       │   │       └─ [~] .type:
     │       │   │           ├─ [-] number
     │       │   │           └─ [+] integer
     │       │   └─ [~] .required:
     │       │       └─ @@ -1,6 +1,6 @@
     │       │          [ ] [
     │       │          [ ]   "access_token",
     │       │          [+]   "auth_at",
     │       │          [ ]   "expires_in",
     │       │          [-]   "scope",
     │       │          [-]   "token_type"
     │       │          [+]   "scope"
     │       │          [ ] ]
     │       ├─ [~] .RegisterDeviceResponseContent:
     │       │   └─ [~] .properties:
     │       │       ├─ [~] .createdAt:
     │       │       │   └─ [~] .type:
     │       │       │       ├─ [-] number
     │       │       │       └─ [+] integer
     │       │       └─ [~] .lastAccessTime:
     │       │           └─ [~] .type:
     │       │               ├─ [-] number
     │       │               └─ [+] integer
     │       └─ [~] .ScopedKeyDataEntry:
     │           └─ [~] .properties:
     │               └─ [~] .keyRotationTimestamp:
     │                   └─ [~] .type:
     │                       ├─ [-] number
     │                       └─ [+] integer
     └─ [~] .paths:
         └─ [~] ./v1/account/devices:
             └─ [~] .get:
                 └─ [~] .parameters:
                     └─ @@ -4,7 +4,7 @@
                        [ ]   "in": "query",
                        [ ]   "description": "Exclude devices not accessed since this timestamp (ms)",
                        [ ]   "schema": {
                        [-]     "type": "number",
                        [+]     "type": "integer",
                        [ ]     "description": "Exclude devices not accessed since this timestamp (ms)"
                        [ ]   }
                        [ ] }
[~] AWS::ApiGateway::Stage AuthApiDeploymentStageprodB0E4172A
 └─ [~] DeploymentId
     └─ [~] .Ref:
         ├─ [-] AuthApiDeploymentB62B2E46932c576f5511d15a89b00bb0cc579c7a
         └─ [+] AuthApiDeploymentB62B2E4675d39fd1733f70377d4a453cb043e0e2
[~] AWS::ApiGateway::RestApi TokenApiA934D4AB
 └─ [~] Body
     ├─ [~] .components:
     │   └─ [~] .schemas:
     │       └─ [~] .GetTokenResponseContent:
     │           └─ [~] .properties:
     │               ├─ [~] .duration:
     │               │   └─ [~] .type:
     │               │       ├─ [-] number
     │               │       └─ [+] integer
     │               └─ [~] .uid:
     │                   └─ [~] .type:
     │                       ├─ [-] number
     │                       └─ [+] integer
     └─ [~] .paths:
         └─ [~] ./1.0/sync/1.5:
             └─ [~] .get:
                 └─ [~] .responses:
                     └─ [~] .200:
                         └─ [~] .headers:
                             └─ [~] .X-Timestamp:
                                 └─ [~] .schema:
                                     └─ [~] .type:
                                         ├─ [-] number
                                         └─ [+] integer
[~] AWS::ApiGateway::Stage TokenApiDeploymentStageprod11035AE4
 └─ [~] DeploymentId
     └─ [~] .Ref:
         ├─ [-] TokenApiDeploymentB896C219b16a73c2bacf13dff150a851137e236c
         └─ [+] TokenApiDeploymentB896C219ee4433fd7a430b8eb183e22b78e32990
[~] AWS::ApiGateway::RestApi ProfileApiABF5D3F3
 └─ [~] Body
     └─ [~] .components:
         └─ [~] .schemas:
             └─ [~] .GetProfileResponseContent:
                 ├─ [~] .properties:
                 │   ├─ [+] Added: .avatar
                 │   ├─ [+] Added: .avatarDefault
                 │   ├─ [~] .locale:
                 │   │   └─ [~] .description:
                 │   │       ├─ [-] User locale
                 │   │       └─ [+] User locale (BCP-47 tag)
                 │   └─ [+] Added: .sub
                 └─ [~] .required:
                     └─ @@ -1,4 +1,7 @@
                        [ ] [
                        [+]   "avatar",
                        [+]   "avatarDefault",
                        [ ]   "email",
                        [+]   "sub",
                        [ ]   "uid"
                        [ ] ]
[~] AWS::ApiGateway::Stage ProfileApiDeploymentStageprodF609D968
 └─ [~] DeploymentId
     └─ [~] .Ref:
         ├─ [-] ProfileApiDeployment84A54415e0158c62574d24c31b8dbd21e82873c4
         └─ [+] ProfileApiDeployment84A54415dadeee5002a4db3160be90bf8c2ad143
[~] AWS::ApiGateway::RestApi StorageApiAD520CAE
 └─ [~] Body
     ├─ [~] .components:
     │   └─ [~] .schemas:
     │       ├─ [~] .BasicStorageObject:
     │       │   └─ [~] .properties:
     │       │       └─ [~] .sortindex:
     │       │           └─ [~] .type:
     │       │               ├─ [-] number
     │       │               └─ [+] integer
     │       ├─ [~] .BasicStorageObjectInput:
     │       │   ├─ [~] .description:
     │       │   │   ├─ [-] Storage Object input for create/update operations
     │       │   │   └─ [+] Storage Object input for create/update operations.

Per SyncStorage 1.5, PUT bodies are partial updates: any field may be
omitted. Use this same shape for both single-object PUT and batch POST.
     │       │   ├─ [~] .properties:
     │       │   │   ├─ [~] .sortindex:
     │       │   │   │   ├─ [+] Added: .maximum
     │       │   │   │   ├─ [+] Added: .minimum
     │       │   │   │   └─ [~] .type:
     │       │   │   │       ├─ [-] number
     │       │   │   │       └─ [+] integer
     │       │   │   └─ [~] .ttl:
     │       │   │       ├─ [+] Added: .maximum
     │       │   │       ├─ [+] Added: .minimum
     │       │   │       └─ [~] .type:
     │       │   │           ├─ [-] number
     │       │   │           └─ [+] integer
     │       │   └─ [-] Removed: .required
     │       ├─ [~] .BatchResult:
     │       │   └─ [+] Added: .required
     │       ├─ [~] .CollectionCounts:
     │       │   └─ [~] .additionalProperties:
     │       │       └─ [~] .type:
     │       │           ├─ [-] number
     │       │           └─ [+] integer
     │       ├─ [~] .CollectionData:
     │       │   └─ [~] .properties:
     │       │       ├─ [~] .count:
     │       │       │   └─ [~] .type:
     │       │       │       ├─ [-] number
     │       │       │       └─ [+] integer
     │       │       └─ [~] .usage:
     │       │           └─ [~] .type:
     │       │               ├─ [-] number
     │       │               └─ [+] integer
     │       ├─ [~] .CollectionUsage:
     │       │   └─ [~] .additionalProperties:
     │       │       └─ [~] .type:
     │       │           ├─ [-] number
     │       │           └─ [+] integer
     │       ├─ [~] .FailedOperations:
     │       │   ├─ [~] .additionalProperties:
     │       │   │   ├─ [+] Added: .description
     │       │   │   ├─ [+] Added: .items
     │       │   │   └─ [~] .type:
     │       │   │       ├─ [-] string
     │       │   │       └─ [+] array
     │       │   └─ [~] .description:
     │       │       ├─ [-] Failed operation details (ID -> error message string)
     │       │       └─ [+] Failed operation details (ID -> list of error messages)
     │       ├─ [~] .GetCollectionResponseContent:
     │       │   └─ [~] .properties:
     │       │       └─ [~] .next_offset:
     │       │           └─ [~] .type:
     │       │               ├─ [-] number
     │       │               └─ [+] integer
     │       ├─ [~] .GetConfigurationInfoResponseContent:
     │       │   └─ [~] .properties:
     │       │       ├─ [~] .max_post_bytes:
     │       │       │   └─ [~] .type:
     │       │       │       ├─ [-] number
     │       │       │       └─ [+] integer
     │       │       ├─ [~] .max_post_records:
     │       │       │   └─ [~] .type:
     │       │       │       ├─ [-] number
     │       │       │       └─ [+] integer
     │       │       ├─ [~] .max_record_payload_bytes:
     │       │       │   └─ [~] .type:
     │       │       │       ├─ [-] number
     │       │       │       └─ [+] integer
     │       │       ├─ [+] Added: .max_request_bytes
     │       │       ├─ [~] .max_total_bytes:
     │       │       │   └─ [~] .type:
     │       │       │       ├─ [-] number
     │       │       │       └─ [+] integer
     │       │       └─ [~] .max_total_records:
     │       │           └─ [~] .type:
     │       │               ├─ [-] number
     │       │               └─ [+] integer
     │       ├─ [~] .GetQuotaInfoResponseContent:
     │       │   └─ [~] .properties:
     │       │       └─ [~] .quota:
     │       │           └─ [~] .items:
     │       │               └─ [~] .type:
     │       │                   ├─ [-] number
     │       │                   └─ [+] integer
     │       └─ [~] .ListCollectionsResponseContent:
     │           └─ [+] Added: .required
     └─ [~] .paths:
         └─ [~] ./1.5/{uid}/storage/{collectionName}:
             └─ [~] .get:
                 └─ [~] .parameters:
                     └─ @@ -63,7 +63,7 @@
                        [ ]   "in": "query",
                        [ ]   "description": "Maximum number of objects to return",
                        [ ]   "schema": {
                        [-]     "type": "number",
                        [+]     "type": "integer",
                        [ ]     "description": "Maximum number of objects to return"
                        [ ]   }
                        [ ] },
                        @@ -72,7 +72,7 @@
                        [ ]   "in": "query",
                        [ ]   "description": "Number of objects to skip",
                        [ ]   "schema": {
                        [-]     "type": "number",
                        [+]     "type": "integer",
                        [ ]     "description": "Number of objects to skip"
                        [ ]   }
                        [ ] },
[~] AWS::ApiGateway::Stage StorageApiDeploymentStageprodF84F218F
 └─ [~] DeploymentId
     └─ [~] .Ref:
         ├─ [-] StorageApiDeployment3B4929C5e49a2791c6f843724643b35f6d5433f6
         └─ [+] StorageApiDeployment3B4929C5ecd0b40b6b55212c85a77f63d837e1e2
[~] AWS::Lambda::Function ChannelApiHandler02759D57
 ├─ [~] Code
 │   └─ [~] .S3Key:
 │       ├─ [-] f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1.zip
 │       └─ [+] 66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb.zip
 └─ [~] Metadata
     └─ [~] .aws:asset:path:
         ├─ [-] asset.f37a7ccd93d952d11a8cace726477f26a3b5b9b9e17a01d6fcd07a6ee2f234b1
         └─ [+] asset.66d2af210881ec57fffe4a3ed58ac4f0d1653555d459883cd32f8e8c71ea8feb

No Changes for stack: Frontend-prod ✅
No Changes for stack: Monitoring-prod ✅

Generated for commit 7ee0dc1 at 2026-06-09T06:05:05.338Z

@layertwo layertwo force-pushed the feat/smithy-codegen branch 8 times, most recently from 32fcc5d to e968485 Compare June 6, 2026 20:41
@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  lambda/src/routes/bso
  read.py
  update.py
  lambda/src/routes/collections
  create.py
  list.py
  read.py
  update.py
  lambda/src/routes/info
  read_collections.py
  lambda/src/services
  storage_manager.py
  user_manager.py
  lambda/src/shared
  _codegen_base.py
  models.py
  user.py
Project Total  

This report was generated by python-coverage-comment-action

@layertwo layertwo force-pushed the feat/smithy-codegen branch 2 times, most recently from d682506 to 65c8926 Compare June 9, 2026 05:54
@layertwo layertwo force-pushed the feat/smithy-codegen branch from 65c8926 to 7ee0dc1 Compare June 9, 2026 06:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant