Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Models not generating for requests with multiple content types #4734

Closed
mspearey opened this issue May 27, 2024 · 4 comments · Fixed by #4747
Closed

Models not generating for requests with multiple content types #4734

mspearey opened this issue May 27, 2024 · 4 comments · Fixed by #4747
Assignees
Labels
type:bug A broken experience
Milestone

Comments

@mspearey
Copy link
Contributor

mspearey commented May 27, 2024

What are you generating using Kiota, clients or plugins?

API Client/SDK

In what context or format are you using Kiota?

Nuget tool

Client library/SDK language

Csharp

Describe the bug

I am trying to generate a CSharp api client from an openapi document with kiota 1.14.0 but model files are not being generated when the requestBody content type does not match application/json, or if application/json exists along side multipart/form-data.

Based on the document, JWTObtainPairRequest should have a Model generated, but this is only true when the endpoint request content mime type is only application/json

Expected behavior

Model files should be generated regardless of mime types.

Based on the example, the models folder should have the type JWTObtainPairRequest

How to reproduce

kiota generate -l CSharp -c MyApiClient -n My.ApiClient -d ./test.yaml -o ./MyApiClient --include-path "**/token/**" --co --cc

Open API description file

`openapi: 3.0.3
info:
title: API
version: 2.0
paths:
/api/v2/token/new/:
post:
operationId: Obtain new access/refresh token pair
description: Obtain JWT pair
tags:
- token
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/JWTObtainPairRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/JWTObtainPairRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/JWTObtainPairRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SpectacularJWTObtain'
description: Obtain JWT response.
components:
schemas:
ErrorResponse:
type: object
properties:
summary:
type: string
detail:
type: string
type:
type: string
status_code:
type: integer
required:
- detail
- status_code
- summary
JWTObtainPairRequest:
type: object
description: Obtain JWT pair.
properties:
secret_id:
type: string
minLength: 1
description: Secret id from /user-secrets/
secret_key:
type: string
minLength: 1
description: Secret key from /user-secrets/
required:
- secret_id
- secret_key
SpectacularJWTObtain:
type: object
description: Obtain new JWT pair.
properties:
access:
type: string
readOnly: true
description: Your access token
access_expires:
type: integer
readOnly: true
default: 86400
description: Access token expires in seconds
refresh:
type: string
readOnly: true
description: Your refresh token
refresh_expires:
type: integer
readOnly: true
default: 2592000
description: Refresh token expires in seconds
securitySchemes:
jwtAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:

`

Kiota Version

1.14.0

Latest Kiota version known to work for scenario above?(Not required)

No response

Known Workarounds

Reduce request mime content types to just application/json

Configuration

  • OS: Windows 10
  • Arch: x64

Debug output

Click to expand log ``` > kiota generate -l CSharp -c MyApiClient -n My.Client -d ./test.yaml -o ./MyApiClient --include-path "**/token/**" --co --cc --ll debug info: Kiota.Builder.KiotaBuilder[0] Cleaning output directory C:\Project\.\ClientTest dbug: Kiota.Builder.KiotaBuilder[0] kiota version 1.14.0 info: Kiota.Builder.KiotaBuilder[0] loaded description from local source dbug: Kiota.Builder.KiotaBuilder[0] step 1 - reading the stream - took 00:00:00.0187292 dbug: Kiota.Builder.KiotaBuilder[0] step 2 - parsing the document - took 00:00:00.2263048 dbug: Kiota.Builder.KiotaBuilder[0] step 3 - updating generation configuration from kiota extension - took 00:00:00.0001934 dbug: Kiota.Builder.KiotaBuilder[0] step 4 - filtering API paths with patterns - took 00:00:00.0348416 dbug: Kiota.Builder.KiotaBuilder[0] step 5 - checking whether the output should be updated - took 00:00:00.0281600 dbug: Kiota.Builder.KiotaBuilder[0] step 6 - create uri space - took 00:00:00.0048704 dbug: Kiota.Builder.KiotaBuilder[0] InitializeInheritanceIndex 00:00:00.0072927 dbug: Kiota.Builder.KiotaBuilder[0] CreateRequestBuilderClass 00:00:00 dbug: Kiota.Builder.KiotaBuilder[0] MapTypeDefinitions 00:00:00.0181795 dbug: Kiota.Builder.KiotaBuilder[0] TrimInheritedModels 00:00:00 dbug: Kiota.Builder.KiotaBuilder[0] CleanUpInternalState 00:00:00 dbug: Kiota.Builder.KiotaBuilder[0] step 7 - create source model - took 00:00:00.2189239 dbug: Kiota.Builder.KiotaBuilder[0] 77ms: Language refinement applied dbug: Kiota.Builder.KiotaBuilder[0] step 8 - refine by language - took 00:00:00.0798026 dbug: Kiota.Builder.KiotaBuilder[0] step 9 - writing files - took 00:00:00.0837791 info: Kiota.Builder.KiotaBuilder[0] loaded description from local source dbug: Kiota.Builder.KiotaBuilder[0] step 10 - writing lock file - took 00:00:00.0277753 Generation completed successfully dbug: Kiota.Builder.KiotaBuilder[0] Api manifest path: C:\Project\apimanifest.json

Hint: use the info command to get the list of dependencies you need to add to your project.
Example: kiota info -d "C:\Project.\test.yaml" -l CSharp

</details>


### Other information

_No response_
@mspearey mspearey added status:waiting-for-triage An issue that is yet to be reviewed or assigned type:bug A broken experience labels May 27, 2024
@github-project-automation github-project-automation bot moved this to Needs Triage 🔍 in Kiota May 27, 2024
@mspearey
Copy link
Contributor Author

Screenshot showing the output of the created client. JWTObtainPairRequest model is missing.

image

@mspearey
Copy link
Contributor Author

mspearey commented May 27, 2024

So even with --structured-mime-types "application/json" the issue still persists.

From what I can see the check that happens here https://github.com/microsoft/kiota/blob/main/src/Kiota.Builder/KiotaBuilder.cs#L1476
The call to IsMultipartFormDataSchema (https://github.com/microsoft/kiota/blob/main/src/Kiota.Builder/Extensions/OpenApiOperationExtensions.cs#L45) returns true because the multipart/form-data exists as part of the schema.

Would it be valid to add a check in IsMultipartFormDataSchema, that checks for "multipart/form-data" in structuredMimeTypes? Although this would still cause the issue with the default structuredMimeTypes value

return structuredMimeTypes.Contains(multipartMimeTypes.First()) && source.GetValidSchemas(structuredMimeTypes).FirstOrDefault() is OpenApiSchema schema && source.GetValidSchemas(multipartMimeTypes).FirstOrDefault() == schema;

@andrueastman
Copy link
Member

Thanks for raising this @mspearey

Any chance you can re-share the input openApi document?
I belive the issue may be around the passing of the configuration --structured-mime-types "application/json really as IsMultipartFormDataSchema would return false if multipart/form-data is not present in the input configuration which is passed as the second parameter at

https://github.com/microsoft/kiota/blob/main/src/Kiota.Builder/KiotaBuilder.cs#L1476

@andrueastman andrueastman moved this from Needs Triage 🔍 to Todo 📃 in Kiota May 30, 2024
@andrueastman andrueastman added needs more information status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close and removed status:waiting-for-triage An issue that is yet to be reviewed or assigned labels May 30, 2024
@mspearey
Copy link
Contributor Author

Sure, here is the document openapi.json

I managed to step through the project in debug mode. So can possibly provide more insight.

I get the same result with or without using --structured-mime-types.
The default value of structuredMimeTypes is
"application/json;q=1", "text/plain;q=0.9", "application/x-www-form-urlencoded;q=0.2", "multipart/form-data;q=0.1",

multipartMimeTypes = new(new string[] { "multipart/form-data" });

The IsMultipartFormDataSchema is currently this
return source.GetValidSchemas(structuredMimeTypes).FirstOrDefault() is OpenApiSchema schema && source.GetValidSchemas(multipartMimeTypes).FirstOrDefault() == schema;

With either passing the argument with "application/json" or not the first element in structuredMimeTypes is set to "application/json".
The source variable has a list of the types from the schema, in this case it will be "application/json", "application/x-www-form-urlencoded", and "multipart/form-data".
So the first part of that statement returns true, and the second statement also returns true as the schema has the multipart mime type.

I've believe I have narrowed the issue down though.
There are a few assumptions being made.

  1. The IsMultipartFormDataSchema call assumes it will be the only content type.
  2. That when Multipart is used, that the encoding field will be present, the openapi documentation doesn't state the field is required.

I have addressed these in a PR #4747 .

  1. Have added an additional method that checks for the multipart content type, if it's the only content type, and then finally if it is the top priority type.
  2. If the type is identified as multipart, I have added a check for encoding property, if not present it follows the non multipart model declaration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:bug A broken experience
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants