Skip to content

Commit

Permalink
Merge branch 'aliencube:main' into feature/22-request-payload-definition
Browse files Browse the repository at this point in the history
  • Loading branch information
jihyunmoon16 authored Sep 7, 2024
2 parents 1e0205d + c8c1e83 commit ad5475f
Show file tree
Hide file tree
Showing 61 changed files with 3,997 additions and 177 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/azure-dev-build-only.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ jobs:
- name: Create openapi.json
shell: pwsh
run: |
$fileContent = Get-Content './src/AzureOpenAIProxy.ApiApp/Constants.cs'
$API_VERSION = [regex]::Match($fileContent, 'public const string Version = "([^"]+)"').Groups[1].Value
$API_VERSION = $(Get-Content ./src/AzureOpenAIProxy.ApiApp/appsettings.json | ConvertFrom-Json).OpenApi.DocVersion
Invoke-WebRequest -Uri "https://localhost:7001/swagger/$API_VERSION/swagger.json" -OutFile "openapi.json"
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/azure-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ jobs:
- name: Create openapi.json
shell: pwsh
run: |
$fileContent = Get-Content './src/AzureOpenAIProxy.ApiApp/Constants.cs'
$API_VERSION = [regex]::Match($fileContent, 'public const string Version = "([^"]+)"').Groups[1].Value
$API_VERSION = $(Get-Content ./src/AzureOpenAIProxy.ApiApp/appsettings.json | ConvertFrom-Json).OpenApi.DocVersion
Invoke-WebRequest -Uri "https://localhost:7001/swagger/$API_VERSION/swagger.json" -OutFile "openapi.json"
Expand Down
17 changes: 17 additions & 0 deletions src/AzureOpenAIProxy.ApiApp/Configurations/OpenApiSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace AzureOpenAIProxy.ApiApp.Configurations;

/// <summary>
/// This represents the settings entity for Open API.
/// </summary>
public class OpenApiSettings
{
/// <summary>
/// Gets the name of the configuration settings.
/// </summary>
public const string Name = "OpenApi";

/// <summary>
/// Gets or sets the Open API Doc version.
/// </summary>
public string? DocVersion { get; set; } = string.Empty;
}
5 changes: 0 additions & 5 deletions src/AzureOpenAIProxy.ApiApp/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@
/// </summary>
public static class Constants
{
/// <summary>
/// Declares the current version of the API.
/// </summary>
public const string Version = "v1.0.0";

/// <summary>
/// Declares the title of the OpenAPI doc.
/// </summary>
Expand Down
72 changes: 72 additions & 0 deletions src/AzureOpenAIProxy.ApiApp/Converters/EnumMemberConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Runtime.Serialization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace AzureOpenAIProxy.ApiApp.Converters;

/// <summary>
/// This represents the converter entity for <see cref="EnumMemberAttribute"/>.
/// </summary>
/// <typeparam name="T">The type of the enum to be converted.</typeparam>
public class EnumMemberConverter<T> : JsonConverter<T> where T : Enum
{
/// <inheritdoc />
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var enumText = reader.GetString();

if (enumText == null)
{
throw new JsonException($"Unable to convert null to Enum \"{typeToConvert}\".");
}

foreach (var field in typeToConvert.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field, typeof(EnumMemberAttribute)) as EnumMemberAttribute;

if (attribute != null && attribute.Value == enumText)
{
var value = field.GetValue(null);
if (value != null)
{
return (T)value;
}
}
else if (field.Name == enumText)
{
var value = field.GetValue(null);
if (value != null)
{
return (T)value;
}
}
}

throw new JsonException($"Unable to convert \"{enumText}\" to Enum \"{typeToConvert}\".");
}

/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
var field = value.GetType().GetField(value.ToString());

if (field != null)
{
var attribute = Attribute.GetCustomAttribute(field, typeof(EnumMemberAttribute)) as EnumMemberAttribute;

if (attribute != null)
{
writer.WriteStringValue(attribute.Value);
}
else
{
writer.WriteStringValue(value.ToString());
}
}
else
{
writer.WriteStringValue(value.ToString());
}
}

}
11 changes: 9 additions & 2 deletions src/AzureOpenAIProxy.ApiApp/Endpoints/AdminEndpointUrls.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
namespace AzureOpenAIProxy.ApiApp.Endpoints;

/// <summary>
/// This represents the collection of the admin endpoint URLs.
/// </summary>
public static class AdminEndpointUrls
{
/// <summary>
/// Declares the admin event details endpoint.
/// </summary>
/// <remarks>
/// - GET method for an event details
/// - PUT method for update an event details
/// </remarks>
public const string AdminEventDetails = "/admin/events/{eventId}";

/// <summary>
/// Declares the admin event list endpoint.
/// </summary>
/// <remarks>
/// - Get method for listing all events
/// - Post method for new event creation
/// - GET method for listing all events
/// - POST method for new event creation
/// </remarks>
public const string AdminEvents = "/admin/events";
}
101 changes: 63 additions & 38 deletions src/AzureOpenAIProxy.ApiApp/Endpoints/AdminEventEndpoints.cs
Original file line number Diff line number Diff line change
@@ -1,39 +1,65 @@
using AzureOpenAIProxy.ApiApp.Models;
using AzureOpenAIProxy.ApiApp.Services;

using Microsoft.AspNetCore.Mvc;

namespace AzureOpenAIProxy.ApiApp.Endpoints;

/// <summary>
/// This represents the endpoint entity for get event details by admin
/// This represents the endpoint entity for event details by admin
/// </summary>
public static class AdminEventEndpoints
{
/// <summary>
/// Adds the get event details by admin endpoint
/// Adds the admin event endpoint
/// </summary>
/// <param name="app"><see cref="WebApplication"/> instance.</param>
/// <returns>Returns <see cref="RouteHandlerBuilder"/> instance.</returns>
public static RouteHandlerBuilder AddAdminEvents(this WebApplication app)
public static RouteHandlerBuilder AddNewAdminEvent(this WebApplication app)
{
// Todo: Issue #19 https://github.com/aliencube/azure-openai-sdk-proxy/issues/19
// Need authorization by admin
var builder = app.MapGet(AdminEndpointUrls.AdminEventDetails, (
[FromRoute] string eventId) =>
var builder = app.MapPost(AdminEndpointUrls.AdminEvents, async (
[FromBody] AdminEventDetails payload,
IAdminEventService service,
ILoggerFactory loggerFactory) =>
{
// Todo: Issue #208 https://github.com/aliencube/azure-openai-sdk-proxy/issues/208
return Results.Ok();
// Todo: Issue #208
var logger = loggerFactory.CreateLogger(nameof(AdminEventEndpoints));
logger.LogInformation("Received a new event request");
if (payload is null)
{
logger.LogError("No payload found");
return Results.BadRequest("Payload is null");
}
//try
//{
// var result = await service.CreateEvent(payload);
// logger.LogInformation("Created a new event");
// return Results.Ok(result);
//}
//catch (Exception ex)
//{
// logger.LogError(ex, "Failed to create a new event");
// return Results.Problem(ex.Message, statusCode: StatusCodes.Status500InternalServerError);
//}
return await Task.FromResult(Results.Ok());
})
.Accepts<AdminEventDetails>(contentType: "application/json")
.Produces<AdminEventDetails>(statusCode: StatusCodes.Status200OK, contentType: "application/json")
.Produces(statusCode: StatusCodes.Status400BadRequest)
.Produces(statusCode: StatusCodes.Status401Unauthorized)
.Produces<string>(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain")
.WithTags("admin")
.WithName("GetAdminEventDetails")
.WithName("CreateAdminEvent")
.WithOpenApi(operation =>
{
operation.Summary = "Gets event details from the given event ID";
operation.Description = "This endpoint gets the event details from the given event ID.";
operation.Summary = "Create admin event";
operation.Description = "Create admin event";
return operation;
});
Expand All @@ -46,7 +72,7 @@ public static RouteHandlerBuilder AddAdminEvents(this WebApplication app)
/// </summary>
/// <param name="app"><see cref="WebApplication"/> instance.</param>
/// <returns>Returns <see cref="RouteHandlerBuilder"/> instance.</returns>
public static RouteHandlerBuilder AddAdminEventList(this WebApplication app)
public static RouteHandlerBuilder AddListAdminEvents(this WebApplication app)
{
// Todo: Issue #19 https://github.com/aliencube/azure-openai-sdk-proxy/issues/19
// Need authorization by admin
Expand All @@ -73,65 +99,64 @@ public static RouteHandlerBuilder AddAdminEventList(this WebApplication app)
}

/// <summary>
/// Adds the update event details by admin endpoint
/// Adds the get event details by admin endpoint
/// </summary>
/// <param name="app"><see cref="WebApplication"/> instance.</param>
/// <returns>Returns <see cref="RouteHandlerBuilder"/> instance.</returns>
public static RouteHandlerBuilder AddUpdateAdminEvents(this WebApplication app)
public static RouteHandlerBuilder AddGetAdminEvent(this WebApplication app)
{
// Todo: Issue #19 https://github.com/aliencube/azure-openai-sdk-proxy/issues/19
// Need authorization by admin
var builder = app.MapPut(AdminEndpointUrls.AdminEventDetails, (
[FromRoute] string eventId,
[FromBody] AdminEventDetails payload) =>
var builder = app.MapGet(AdminEndpointUrls.AdminEventDetails, (
[FromRoute] string eventId) =>
{
// Todo: Issue #203 https://github.com/aliencube/azure-openai-sdk-proxy/issues/203
// Todo: Issue #208 https://github.com/aliencube/azure-openai-sdk-proxy/issues/208
return Results.Ok();
// Todo: Issue #208
})
.Accepts<AdminEventDetails>(contentType: "application/json")
.Produces<AdminEventDetails>(statusCode: StatusCodes.Status200OK, contentType: "application/json")
.Produces(statusCode: StatusCodes.Status401Unauthorized)
.Produces(statusCode: StatusCodes.Status404NotFound)
.Produces<string>(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain")
.WithTags("admin")
.WithName("UpdateAdminEventDetails")
.WithName("GetAdminEvent")
.WithOpenApi(operation =>
{
operation.Summary = "Updates event details from the given event ID";
operation.Description = "This endpoint updates the event details from the given event ID.";
operation.Summary = "Gets event details from the given event ID";
operation.Description = "This endpoint gets the event details from the given event ID.";
return operation;
});

return builder;
}

/// <summary>
/// Adds the admin event endpoint
/// Adds the update event details by admin endpoint
/// </summary>
/// <param name="app"><see cref="WebApplication"/> instance.</param>
/// <returns>Returns <see cref="RouteHandlerBuilder"/> instance.</returns>
public static RouteHandlerBuilder CreateAdminEvent(this WebApplication app)
public static RouteHandlerBuilder AddUpdateAdminEvent(this WebApplication app)
{
var builder = app.MapPost(AdminEndpointUrls.AdminEvents, async (
[FromBody] AdminEventDetails payload,
HttpRequest request) =>
// Todo: Issue #19 https://github.com/aliencube/azure-openai-sdk-proxy/issues/19
// Need authorization by admin
var builder = app.MapPut(AdminEndpointUrls.AdminEventDetails, (
[FromRoute] string eventId,
[FromBody] AdminEventDetails payload) =>
{
return await Task.FromResult(Results.Ok());
// Todo: Issue #203 https://github.com/aliencube/azure-openai-sdk-proxy/issues/203
return Results.Ok();
})
// TODO: Check both request/response payloads
.Accepts<AdminEventDetails>(contentType: "application/json")
.Produces<AdminEventDetails>(statusCode: StatusCodes.Status200OK, contentType: "application/json")
// TODO: Check both request/response payloads
.Produces(statusCode: StatusCodes.Status400BadRequest)
.Produces(statusCode: StatusCodes.Status401Unauthorized)
.Produces(statusCode: StatusCodes.Status404NotFound)
.Produces<string>(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain")
.WithTags("admin")
.WithName("CreateAdminEvent")
.WithName("UpdateAdminEvent")
.WithOpenApi(operation =>
{
operation.Summary = "Create admin event";
operation.Description = "Create admin event";
operation.Summary = "Updates event details from the given event ID";
operation.Description = "This endpoint updates the event details from the given event ID.";
return operation;
});
Expand Down
15 changes: 15 additions & 0 deletions src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpointUrls.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace AzureOpenAIProxy.ApiApp.Endpoints;

/// <summary>
/// This represents the collection of the playground endpoint URLs.
/// </summary>
public static class PlaygroundEndpointUrls
{
/// <summary>
/// Declares the event endpoint.
/// </summary>
/// <remarks>
/// - GET method for listing all events
/// </remarks>
public const string Events = "/events";
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
using System.Text.Json;

using AzureOpenAIProxy.ApiApp.Models;

namespace AzureOpenAIProxy.ApiApp.Endpoints;

/// <summary>
/// This represents the endpoint entity for events that the logged user joined.
/// </summary>
public static class EventEndpoint
public static class PlaygroundEndpoints
{
/// <summary>
/// Adds the event endpoint.
/// </summary>
/// <param name="app"><see cref="WebApplication"/> instance.</param>
/// <returns>Returns <see cref="RouteHandlerBuilder"/> instance.</returns>
public static RouteHandlerBuilder AddEventList(this WebApplication app)
public static RouteHandlerBuilder AddListEvents(this WebApplication app)
{
var builder = app.MapGet(EndpointUrls.Events, () =>
var builder = app.MapGet(PlaygroundEndpointUrls.Events, () =>
{
// TODO: Issue #179 https://github.com/aliencube/azure-openai-sdk-proxy/issues/179
return Results.Ok();
Expand Down
Loading

0 comments on commit ad5475f

Please sign in to comment.