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

Improvements and fixes #18

Merged
merged 9 commits into from
Oct 28, 2023
Merged

Conversation

davidmigloz
Copy link
Contributor

@davidmigloz davidmigloz commented Oct 25, 2023

  • Improve handling of descriptions in SchemaGenerator
    • Trims all descriptions
    • Replaces \n by \n/// after trimming to avoid comments with an empty line at the end
  • Use Future.value in middleware functions
    • Small performance improvement. Using Future.value Dart will create a new microtask event into the microtask queue instead of a new event into the event queue.
  • Fix nullable property not taken into account in objects and enum
  • Add possible values in enums descriptions
    • Edit: This is actually breaking the tests as we are modifying the spec content. Should I move this to the generator instead?
  • Use request schema description when null requestBody description
  • Allow to define global headers included in every request

cc @walsha2

- Trims all descriptions
- Replaces `\n` by `\n///` after trimming to avoid comments with an empty line at the end
Small performance improvement. Using `Future.value` Dart will create a new microtask event into the microtask queue instead of a new event into the event queue.
@@ -528,6 +528,8 @@ Map<String, dynamic> _formatSpecFromJson(
if (m.containsKey('type')) {
if (m['type'] == 'string' && m.containsKey('enum')) {
m['type'] = 'enumeration';
final d = m['description'] ?? '';
m['description'] = '$d\nPossible values: ${m['enum']}';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidmigloz yes, I would probably move this to the generator. Although, I do have a question:

Why are we re-documenting enum values in the doc strings. This seems redundant. Simply clicking on the type should take you to the enum definition (lives in its own file) that you can quickly inspect to see the values. I think this adds a lot of extra documentation that may be unnecessary and distracting, no?

Copy link
Contributor Author

@davidmigloz davidmigloz Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, if the enum is defined as an inner schema, it is generated with type String.

Eg.

schemas:
  CreateCompletionRequest:
    type: object
    description: Request object for the Create completion endpoint.
    properties:
      model:
        description: &model_description |
          ID of the model to use. You can use the [List models](https://platform.openai.com/docs/api-...
        type: string
        enum:
          [
            "babbage-002",
            "davinci-002",
            "gpt-3.5-turbo-instruct",
            "text-davinci-003",
            "text-davinci-002",
            "text-davinci-001",
            "code-davinci-002",
            "text-curie-001",
            "text-babbage-001",
            "text-ada-001",
          ]

It will be converted into:

/// Factory constructor for CreateCompletionRequest
const factory CreateCompletionRequest({
  /// ID of the model to use. You can use the [List models](https://platform.openai.com/doc...
  required String model,
})

So, in this case, documenting the possible values is nice. I agree, that when using an actual enum it is redundant.

I've moved that logic to the generator and only for this specific case. If you define the enum as a separate schema (which by the way is broken at the moment), it won't document the enum values.

Let me know if that works for you.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you define the enum as a separate schema (which by the way is broken at the moment)

What do you mean by this? Maybe I am misunderstanding, but I generate enum schemas all the time from defined component schemas. Here is an example:

"components": {
  "schemas": {
    "Task": {
      "title": "Task",
      "enum": [
        "pending",
        "completed",
        "failed"
      ],
      "type": "string",
      "description": "An enumeration."
    },
  }
}
enum Task {
  @JsonValue('pending')
  inProgress,
  @JsonValue('completed')
  canceled,
  @JsonValue('failed')
  failed,
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't dug into it yet, but if instead of this:

CreateCompletionRequest:
  type: object
  description: Request object for the Create completion endpoint.
  properties:
    model:
      description: ...
      type: string
      enum:
        [
          "babbage-002",
          "davinci-002",
          "gpt-3.5-turbo-instruct",
          "text-davinci-003",
          "text-davinci-002",
          "text-davinci-001",
          "code-davinci-002",
          "text-curie-001",
          "text-babbage-001",
          "text-ada-001",
        ]

I move it to its own schema:

CompletionModel:
  type: string
  enum:
    [
      "babbage-002",
      "davinci-002",
      "gpt-3.5-turbo-instruct",
      "text-davinci-003",
      "text-davinci-002",
      "text-davinci-001",
      "code-davinci-002",
      "text-curie-001",
      "text-babbage-001",
      "text-ada-001",
    ]
CreateCompletionRequest:
  type: object
  description: Request object for the Create completion endpoint.
  properties:
    model:
      $ref: "#/components/schemas/CompletionModel"

I get the following exception:

Unhandled exception:
'package:openapi_spec/src/open_api/index.freezed.dart': Failed assertion: line 10478 pos 13: 'values == null || ref == null': Cannot define both values and ref

I'll look into it in a bit.

Copy link
Contributor Author

@davidmigloz davidmigloz Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue seems to be that when dereferencing an enum the new _SchemaEnum will have both ref and values, which is not allowed by the assert.

I've removed the assert and it works as expected (but I guess it's not ideal), do you have a better suggestion?

@walsha2
Copy link
Contributor

walsha2 commented Oct 27, 2023

@davidmigloz I tested this out on a fairly complicated spec and everything looks good. My only comment is regarding "Add possible values in enums descriptions". Without more context regarding what benefit this adds, I think we should remove this change from this PR.

Let me know when you are ready for this to be merged and I will get it in.

@davidmigloz davidmigloz force-pushed the improvements branch 4 times, most recently from 3d52b6d to 9f4cae9 Compare October 27, 2023 17:54
@davidmigloz
Copy link
Contributor Author

I've included a couple more fixes in the PR (let me know if it's getting too big 😅)

  • Fix objects with additionalProperties=false generated as Map
  • Fix objects defined as typedef not preserving description and nullable

@walsha2
Copy link
Contributor

walsha2 commented Oct 28, 2023

No this is great stuff! I really want to add mini tests composed of small API spec snippets that test individual cases and ensure that the generated code is proper. In time!

Let's get this merged in and see if we can close out some of the other issues and cut a new release before the weekend is out.

@walsha2 walsha2 merged commit 2df1a87 into tazatechnology:main Oct 28, 2023
1 check passed
@davidmigloz
Copy link
Contributor Author

Awesome!

Yeah, the small API spec snippets will really help.

@davidmigloz davidmigloz deleted the improvements branch October 28, 2023 19:53
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.

2 participants