Skip to content

.Net: OpenAPI customization - #8182

Merged
SergeyMenshykh merged 2 commits into
microsoft:mainfrom
SergeyMenshykh:streaming-suuport-for-open-api-plugins
Aug 16, 2024
Merged

SergeyMenshykh merged 2 commits into
microsoft:mainfrom
SergeyMenshykh:streaming-suuport-for-open-api-plugins

Conversation

@SergeyMenshykh

@SergeyMenshykh SergeyMenshykh commented Aug 15, 2024 •

Copy link
Copy Markdown
Contributor

Motivation and Context

Today, OpenAPI functionality in SK supports a limited, predefined list of content types: text/plain, application/json, etc. Moreover, the way these content types are read from the "wire" might not be the most efficient for certain scenarios. For example, SK OpenAPI functionality reads JSON as a string and images as a byte array. While this may be sufficient for most cases, there could be situations where this approach is not optimal, and reading both JSON and image content as streams would be preferable.

Description

This PR adds functionality allowing to supply a HTTP content reader to customize HTTP content reading. The reader accepts HTTP request and HTTP response as parameters, so it can access all properties of both to decide on the best way to read content and support content types not supported by default. For example, this custom reader can read JSON as a stream and any content as stream if the x-stream heder is provided in HTTP request:

private static async Task<object?> ReadHttpResponseContentAsync(HttpResponseContentReaderContext context, CancellationToken cancellationToken)
{
    // Read JSON content as a stream rather than as a string, which is the default behavior
    if (context.Response.Content.Headers.ContentType?.MediaType == "application/json")
    {
        return await context.Response.Content.ReadAsStreamAsync(cancellationToken);
    }

    // Read any content as a stream if the request contains the "x-stream" header.
    if (context.Request.Headers.Contains("x-stream"))
    {
        return await context.Response.Content.ReadAsStreamAsync(cancellationToken);
    }

    // Return null to indicate that any other HTTP content not handled above should be read by the default reader.
    return null;
}

// Register the custom HTTP content reader
var executionParameters = new OpenApiFunctionExecutionParameters() { HttpResponseContentReader = ReadHttpResponseContentAsync };

// Create OpenAPI plugin
var plugin = await OpenApiKernelPluginFactory.CreateFromOpenApiAsync("RepairService", "Resources/Plugins/RepairServicePlugin/repair-service.json", executionParameters);

Closes: #8070

Contribution Checklist

@SergeyMenshykh SergeyMenshykh added .NET Issue or Pull requests regarding .NET code openapi Issues related to the OpenAPI function importer labels Aug 15, 2024
@SergeyMenshykh SergeyMenshykh self-assigned this Aug 15, 2024
@SergeyMenshykh
SergeyMenshykh requested a review from a team as a code owner August 15, 2024 14:33
@SergeyMenshykh
SergeyMenshykh added this pull request to the merge queue Aug 16, 2024
Merged via the queue into microsoft:main with commit 0aa04df Aug 16, 2024
@SergeyMenshykh
SergeyMenshykh deleted the streaming-suuport-for-open-api-plugins branch August 16, 2024 09:03
github-merge-queue Bot pushed a commit that referenced this pull request Aug 16, 2024
### Motivation, Context and Description
Today, the OpenAPI functionality that maps the data type of a parameter
from the OpenAPI spec to `KernelParameterMetadata` supports only the
mapping for string and boolean types. This PR extends the mapping to
support other primitive types like `number`, `integer`, and `object`.

Closes: #8182

Out of scope:
- Support for the `array` data type.
LudoCorporateShark pushed a commit to LudoCorporateShark/semantic-kernel that referenced this pull request Aug 25, 2024
### Motivation and Context
Today, OpenAPI functionality in SK supports a limited, predefined list
of content types: text/plain, application/json, etc. Moreover, the way
these content types are read from the "wire" might not be the most
efficient for certain scenarios. For example, SK OpenAPI functionality
reads JSON as a string and images as a byte array. While this may be
sufficient for most cases, there could be situations where this approach
is not optimal, and reading both JSON and image content as streams would
be preferable.

### Description
This PR adds functionality allowing to supply a HTTP content reader to
customize HTTP content reading. The reader accepts HTTP request and HTTP
response as parameters, so it can access all properties of both to
decide on the best way to read content and support content types not
supported by default. For example, this custom reader can read JSON as a
stream and any content as stream if the `x-stream` heder is provided in
HTTP request:
```csharp
private static async Task<object?> ReadHttpResponseContentAsync(HttpResponseContentReaderContext context, CancellationToken cancellationToken)
{
    // Read JSON content as a stream rather than as a string, which is the default behavior
    if (context.Response.Content.Headers.ContentType?.MediaType == "application/json")
    {
        return await context.Response.Content.ReadAsStreamAsync(cancellationToken);
    }

    // Read any content as a stream if the request contains the "x-stream" header.
    if (context.Request.Headers.Contains("x-stream"))
    {
        return await context.Response.Content.ReadAsStreamAsync(cancellationToken);
    }

    // Return null to indicate that any other HTTP content not handled above should be read by the default reader.
    return null;
}

// Register the custom HTTP content reader
var executionParameters = new OpenApiFunctionExecutionParameters() { HttpResponseContentReader = ReadHttpResponseContentAsync };

// Create OpenAPI plugin
var plugin = await OpenApiKernelPluginFactory.CreateFromOpenApiAsync("RepairService", "Resources/Plugins/RepairServicePlugin/repair-service.json", executionParameters);

```

Closes: microsoft#8070

### Contribution Checklist

- [x] The code builds clean without any errors or warnings
- [x] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [x] All unit tests pass, and I have added new tests where possible
- [x] I didn't break anyone 😄
LudoCorporateShark pushed a commit to LudoCorporateShark/semantic-kernel that referenced this pull request Aug 25, 2024
…t#8198)

### Motivation, Context and Description
Today, the OpenAPI functionality that maps the data type of a parameter
from the OpenAPI spec to `KernelParameterMetadata` supports only the
mapping for string and boolean types. This PR extends the mapping to
support other primitive types like `number`, `integer`, and `object`.

Closes: microsoft#8182

Out of scope:
- Support for the `array` data type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET Issue or Pull requests regarding .NET code openapi Issues related to the OpenAPI function importer

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

.Net: Support for streaming response in Open API plugins

3 participants