Skip to content

Commit f863110

Browse files
committed
Add OpenAPI doc definitions
1 parent 9cde777 commit f863110

File tree

8 files changed

+110
-15
lines changed

8 files changed

+110
-15
lines changed

src/AzureOpenAIProxy.ApiApp/Controllers/ChatCompletionsController.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using Azure.AI.OpenAI;
44

5+
using AzureOpenAIProxy.ApiApp.Filters;
56
using AzureOpenAIProxy.ApiApp.Models;
67
using AzureOpenAIProxy.ApiApp.Services;
78

@@ -36,8 +37,8 @@ public class ChatCompletionsController(
3637
/// <returns>Returns the chat completions response.</returns>
3738
[HttpPost("deployments/{deploymentName}/chat/completions", Name = "GetChatCompletions")]
3839
public async Task<IActionResult> GetChatCompletionsAsync(
40+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
3941
[FromRoute] string deploymentName,
40-
[FromHeader(Name = "api-key")] string apiKey,
4142
[FromQuery(Name = "api-version")] string apiVersion,
4243
[FromBody] ChatCompletionsOptions req)
4344
{
@@ -87,8 +88,8 @@ public async Task<IActionResult> GetChatCompletionsAsync(
8788
/// <returns>Returns the chat completions response.</returns>
8889
[HttpPost("deployments/{deploymentName}/extensions/chat/completions", Name = "GetExtensionsChatCompletions")]
8990
public async Task<IActionResult> GetExtensionsChatCompletionsAsync(
91+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
9092
[FromRoute] string deploymentName,
91-
[FromHeader(Name = "api-key")] string apiKey,
9293
[FromQuery(Name = "api-version")] string apiVersion,
9394
[FromBody] ChatCompletionsOptions req)
9495
{

src/AzureOpenAIProxy.ApiApp/Controllers/CompletionsController.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using Azure.AI.OpenAI;
44

5+
using AzureOpenAIProxy.ApiApp.Filters;
56
using AzureOpenAIProxy.ApiApp.Models;
67
using AzureOpenAIProxy.ApiApp.Services;
78

@@ -36,8 +37,8 @@ public class CompletionsController(
3637
/// <returns>Returns the chat completions response.</returns>
3738
[HttpPost("deployments/{deploymentName}/completions", Name = "GetCompletions")]
3839
public async Task<IActionResult> GetCompletionsAsync(
40+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
3941
[FromRoute] string deploymentName,
40-
[FromHeader(Name = "api-key")] string apiKey,
4142
[FromQuery(Name = "api-version")] string apiVersion,
4243
[FromBody] CompletionsOptions req)
4344
{
@@ -87,8 +88,8 @@ public async Task<IActionResult> GetCompletionsAsync(
8788
/// <returns>Returns the completions response.</returns>
8889
[HttpPost("deployments/{deploymentName}/extensions/completions", Name = "GetExtensionsCompletions")]
8990
public async Task<IActionResult> GetExtensionsCompletionsAsync(
91+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
9092
[FromRoute] string deploymentName,
91-
[FromHeader(Name = "api-key")] string apiKey,
9293
[FromQuery(Name = "api-version")] string apiVersion,
9394
[FromBody] CompletionsOptions req)
9495
{

src/AzureOpenAIProxy.ApiApp/Controllers/ManagementAccessCodeController.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using AzureOpenAIProxy.ApiApp.Models;
1+
using AzureOpenAIProxy.ApiApp.Filters;
2+
using AzureOpenAIProxy.ApiApp.Models;
23

34
using Microsoft.AspNetCore.Mvc;
45

@@ -19,7 +20,7 @@ public partial class ManagementController
1920
/// <returns>Returns the <see cref="AccessCodeResponseCollection"/> instance.</returns>
2021
[HttpGet("events/{eventId}/access-codes", Name = "GetListOfEventAccessCodes")]
2122
public async Task<IActionResult> GetEventAccessCodesByEventIdAsync(
22-
[FromHeader(Name = "Authorization")] string apiKey,
23+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
2324
[FromRoute] string eventId,
2425
[FromQuery(Name = "page")] int? page = 0,
2526
[FromQuery(Name = "size")] int? size = 20)
@@ -66,7 +67,7 @@ public async Task<IActionResult> GetEventAccessCodesByEventIdAsync(
6667
/// <returns>Returns the <see cref="AccessCodeResponse"/> instance.</returns>
6768
[HttpPost("events/{eventId}/access-codes", Name = "CreateEventAccessCode")]
6869
public async Task<IActionResult> CreateEventAccessCodeAsync(
69-
[FromHeader(Name = "Authorization")] string apiKey,
70+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
7071
[FromRoute] string eventId,
7172
[FromBody] AccessCodeRequest req)
7273
{
@@ -119,7 +120,7 @@ public async Task<IActionResult> CreateEventAccessCodeAsync(
119120
/// <returns>Returns the <see cref="AccessCodeResponse"/> instance.</returns>
120121
[HttpGet("events/{eventId}/access-codes/{gitHubAlias}", Name = "GetEventAccessCodeByGitHubAlias")]
121122
public async Task<IActionResult> GetEventAccessCodeByGitHubAliasAsync(
122-
[FromHeader(Name = "Authorization")] string apiKey,
123+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
123124
[FromRoute] string eventId,
124125
[FromRoute] string gitHubAlias)
125126
{

src/AzureOpenAIProxy.ApiApp/Controllers/ManagementEventController.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using AzureOpenAIProxy.ApiApp.Models;
1+
using AzureOpenAIProxy.ApiApp.Filters;
2+
using AzureOpenAIProxy.ApiApp.Models;
23
using AzureOpenAIProxy.ApiApp.Services;
34

45
using Microsoft.AspNetCore.Mvc;
@@ -31,7 +32,7 @@ public partial class ManagementController(
3132
/// <returns>Returns the <see cref="EventResponseCollection"/> instance.</returns>
3233
[HttpGet("events", Name = "GetListOfEvents")]
3334
public async Task<IActionResult> GetEventsAsync(
34-
[FromHeader(Name = "Authorization")] string apiKey,
35+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
3536
[FromQuery(Name = "page")] int? page = 0,
3637
[FromQuery(Name = "size")] int? size = 20)
3738
{
@@ -69,7 +70,7 @@ public async Task<IActionResult> GetEventsAsync(
6970
/// <returns>Returns the <see cref="EventResponse"/> instance.</returns>
7071
[HttpPost("events", Name = "CreateEvent")]
7172
public async Task<IActionResult> CreateEventAsync(
72-
[FromHeader(Name = "Authorization")] string apiKey,
73+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
7374
[FromBody] EventRequest req)
7475
{
7576
this._logger.LogInformation("Received a request to generate an event");
@@ -113,7 +114,7 @@ public async Task<IActionResult> CreateEventAsync(
113114
/// <returns>Returns the <see cref="EventResponse"/> instance.</returns>
114115
[HttpGet("events/{eventId}", Name = "GetEventById")]
115116
public async Task<IActionResult> GetEventByEventIdAsync(
116-
[FromHeader(Name = "Authorization")] string apiKey,
117+
[OpenApiParameterIgnore][FromHeader(Name = "api-key")] string apiKey,
117118
[FromRoute] string eventId)
118119
{
119120
this._logger.LogInformation("Received a request to get an event details by event ID");
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using Microsoft.AspNetCore.Mvc.ApiExplorer;
2+
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
3+
using Microsoft.OpenApi.Models;
4+
5+
using Swashbuckle.AspNetCore.SwaggerGen;
6+
7+
namespace AzureOpenAIProxy.ApiApp.Filters;
8+
9+
/// <summary>
10+
/// This represents the attribute entity for parameters to be ignored from the OpenAPI document generation.
11+
/// </summary>
12+
[AttributeUsage(AttributeTargets.Parameter)]
13+
public class OpenApiParameterIgnoreAttribute : Attribute
14+
{
15+
}
16+
17+
/// <summary>
18+
/// This represents the filter entity for parameters to be ignored from the OpenAPI document generation.
19+
/// </summary>
20+
/// <remarks>https://stackoverflow.com/questions/69651135/hide-parameter-from-swagger-swashbuckle</remarks>
21+
public class OpenApiParameterIgnoreFilter : IOperationFilter
22+
{
23+
/// <inheritdoc />
24+
public void Apply(OpenApiOperation operation, OperationFilterContext context)
25+
{
26+
if (operation == null || context == null || context.ApiDescription?.ParameterDescriptions == null)
27+
{
28+
return;
29+
}
30+
31+
var parametersToHide = context.ApiDescription.ParameterDescriptions
32+
.Where(ParameterHasIgnoreAttribute);
33+
34+
if (parametersToHide.Any() == false)
35+
{
36+
return;
37+
}
38+
39+
foreach (var parameterToHide in parametersToHide)
40+
{
41+
var parameter = operation.Parameters
42+
.FirstOrDefault(parameter => parameter.Name.Equals(parameterToHide.Name, StringComparison.InvariantCultureIgnoreCase));
43+
if (parameter != null)
44+
{
45+
operation.Parameters.Remove(parameter);
46+
}
47+
}
48+
}
49+
50+
private static bool ParameterHasIgnoreAttribute(ApiParameterDescription parameterDescription)
51+
{
52+
return parameterDescription.ModelMetadata is DefaultModelMetadata metadata
53+
? metadata.Attributes.ParameterAttributes.Any(attribute => attribute.GetType() == typeof(OpenApiParameterIgnoreAttribute))
54+
: false;
55+
}
56+
}

src/AzureOpenAIProxy.ApiApp/Program.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
using AzureOpenAIProxy.ApiApp.Configurations;
2+
using AzureOpenAIProxy.ApiApp.Filters;
23
using AzureOpenAIProxy.ApiApp.Models;
34
using AzureOpenAIProxy.ApiApp.Services;
45

6+
using Microsoft.OpenApi.Models;
7+
58
var builder = WebApplication.CreateBuilder(args);
69

710
builder.AddServiceDefaults();
@@ -17,7 +20,37 @@
1720
builder.Services.AddControllers();
1821
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
1922
builder.Services.AddEndpointsApiExplorer();
20-
builder.Services.AddSwaggerGen();
23+
builder.Services.AddSwaggerGen(options =>
24+
{
25+
options.SwaggerDoc(
26+
"v1",
27+
new OpenApiInfo()
28+
{
29+
Version = "1.0.0",
30+
Title = "Azure OpenAI Proxy Service",
31+
Description = "Providing a proxy service to Azure OpenAI",
32+
});
33+
options.AddSecurityDefinition(
34+
"apiKey",
35+
new OpenApiSecurityScheme()
36+
{
37+
Name = "api-key",
38+
Type = SecuritySchemeType.ApiKey,
39+
Description = "API key needed to access the endpoints.",
40+
In = ParameterLocation.Header,
41+
});
42+
options.AddSecurityRequirement(new OpenApiSecurityRequirement
43+
{
44+
{
45+
new OpenApiSecurityScheme
46+
{
47+
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "apiKey" }
48+
},
49+
new string[] {}
50+
}
51+
});
52+
options.OperationFilter<OpenApiParameterIgnoreFilter>();
53+
});
2154

2255
var app = builder.Build();
2356

src/AzureOpenAIProxy.ApiApp/appsettings.Development.sample.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"Instances": [
1515
{
1616
"Endpoint": "https://{account_name}.openai.azure.com/",
17-
"ApiKey": "random.apikey.aoai"
17+
"ApiKey": "random.api-key.aoai",
18+
"DeploymentName": "random.deployment-name.aoai"
1819
}
1920
]
2021
}

src/AzureOpenAIProxy.ApiApp/appsettings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"Instances": [
1515
{
1616
"Endpoint": "https://{account_name}.openai.azure.com/",
17-
"ApiKey": "random.apikey.aoai"
17+
"ApiKey": "random.api-key.aoai",
18+
"DeploymentName": "random.deployment-name.aoai"
1819
}
1920
]
2021
},

0 commit comments

Comments
 (0)