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

Add endpoints for access code #14

Merged
merged 1 commit into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
using AzureOpenAIProxy.ApiApp.Models;

using Microsoft.AspNetCore.Mvc;

namespace AzureOpenAIProxy.ApiApp.Controllers;

/// <summary>
/// This represents the controller entity for management.
/// </summary>
public partial class ManagementController
{
/// <summary>
/// Gets the list of access codes by event ID.
/// </summary>
/// <param name="apiKey">API key.</param>
/// <param name="eventId">Event ID.</param>
/// <param name="page">Page number.</param>
/// <param name="size">Page size.</param>
/// <returns>Returns the <see cref="AccessCodeResponseCollection"/> instance.</returns>
[HttpGet("events/{eventId}/access-codes", Name = "GetListOfEventAccessCodes")]
public async Task<IActionResult> GetEventAccessCodesByEventIdAsync(
[FromHeader(Name = "Authorization")] string apiKey,
[FromRoute] string eventId,
[FromQuery(Name = "page")] int? page = 0,
[FromQuery(Name = "size")] int? size = 20)
{
this._logger.LogInformation("Received a request to get the list of access codes for the given event");

var record = await this._auth.ValidateAsync(apiKey);
if (record == null)
{
this._logger.LogError("Invalid API key");

return new UnauthorizedResult();
}

if (string.IsNullOrWhiteSpace(eventId))
{
this._logger.LogError("No event ID");

return new NotFoundResult();
}

try
{
var result = await this._management.GetAccessCodesAsync(eventId, page, size);

this._logger.LogInformation("Completed the request to get the list of access codes for the given event");

return new OkObjectResult(result);
}
catch (Exception ex)
{
this._logger.LogError(ex, "Failed to get the list of access codes for the given event");

return new ObjectResult(ex.Message) { StatusCode = StatusCodes.Status500InternalServerError };
}
}

/// <summary>
/// Creates the access code.
/// </summary>
/// <param name="apiKey">API key.</param>
/// <param name="eventId">Event ID.</param>
/// <param name="req"><see cref="AccessCodeRequest"/> instance.</param>
/// <returns>Returns the <see cref="AccessCodeResponse"/> instance.</returns>
[HttpPost("events/{eventId}/access-codes", Name = "CreateEventAccessCode")]
public async Task<IActionResult> CreateEventAccessCodeAsync(
[FromHeader(Name = "Authorization")] string apiKey,
[FromRoute] string eventId,
[FromBody] AccessCodeRequest req)
{
this._logger.LogInformation("Received a request to generate an access code");

var record = await this._auth.ValidateAsync(apiKey);
if (record == null)
{
this._logger.LogError("Invalid API key");

return new UnauthorizedResult();
}

if (string.IsNullOrWhiteSpace(eventId))
{
this._logger.LogError("No event ID");

return new NotFoundResult();
}

if (req == null)
{
this._logger.LogError("No request payload");

return new BadRequestResult();
}

try
{
var result = await this._management.CreateAccessCodeAsync(eventId, req);

this._logger.LogInformation("Completed the request to generate the access code");

return new OkObjectResult(result);
}
catch (Exception ex)
{
this._logger.LogError(ex, "Failed to generate the access code");

return new ObjectResult(ex.Message) { StatusCode = StatusCodes.Status500InternalServerError };
}
}

/// <summary>
/// Gets the access code by GitHub alias.
/// </summary>
/// <param name="apiKey">API key.</param>
/// <param name="eventId">Event ID.</param>
/// <param name="gitHubAlias">GitHub alias.</param>
/// <returns>Returns the <see cref="AccessCodeResponse"/> instance.</returns>
[HttpGet("events/{eventId}/access-codes/{gitHubAlias}", Name = "GetEventAccessCodeByGitHubAlias")]
public async Task<IActionResult> GetEventAccessCodeByGitHubAliasAsync(
[FromHeader(Name = "Authorization")] string apiKey,
[FromRoute] string eventId,
[FromRoute] string gitHubAlias)
{
this._logger.LogInformation("Received a request to get the access code belongs to the given GitHub alias");

var record = await this._auth.ValidateAsync(apiKey);
if (record == null)
{
this._logger.LogError("Invalid API key");

return new UnauthorizedResult();
}

if (string.IsNullOrWhiteSpace(eventId))
{
this._logger.LogError("No event ID");

return new NotFoundResult();
}

if (string.IsNullOrWhiteSpace(gitHubAlias))
{
this._logger.LogError("No GitHub alias");

return new NotFoundResult();
}

try
{
var result = await this._management.GetAccessCodeByGitHubAliasAsync(eventId, gitHubAlias);

this._logger.LogInformation("Completed the request to get the access code belongs to the given GitHub alias");

return new OkObjectResult(result);
}
catch (Exception ex)
{
this._logger.LogError(ex, "Failed to get the access code belongs to the given GitHub alias");

return new ObjectResult(ex.Message) { StatusCode = StatusCodes.Status500InternalServerError };
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace AzureOpenAIProxy.ApiApp.Controllers;
/// <param name="logger"><see cref="ILogger{TCategoryName}"/> instance.</param>
[ApiController]
[Route("api/management")]
public class ManagementController(
public partial class ManagementController(
[FromKeyedServices("management")] IAuthService<EventRecord> auth,
IManagementService management,
ILogger<ManagementController> logger) : ControllerBase
Expand All @@ -22,12 +22,18 @@ public class ManagementController(
private readonly IManagementService _management = management ?? throw new ArgumentNullException(nameof(management));
private readonly ILogger<ManagementController> _logger = logger ?? throw new ArgumentNullException(nameof(logger));

/// <summary>
/// Gets the list of events.
/// </summary>
/// <param name="apiKey">API key.</param>
/// <param name="page">Page number.</param>
/// <param name="size">Page size.</param>
/// <returns>Returns the <see cref="EventResponseCollection"/> instance.</returns>
[HttpGet("events", Name = "GetListOfEvents")]
public async Task<IActionResult> GetEventsAsync(
[FromHeader(Name = "Authorization")] string apiKey,
[FromQuery(Name = "page")] int? page = 0,
[FromQuery(Name = "size")] int? size = 20
)
[FromQuery(Name = "size")] int? size = 20)
{
this._logger.LogInformation("Received a request to get all events");

Expand Down Expand Up @@ -55,8 +61,14 @@ public async Task<IActionResult> GetEventsAsync(
}
}

/// <summary>
/// Creates the event.
/// </summary>
/// <param name="apiKey">API key.</param>
/// <param name="req"><see cref="EventRequest"/> instance.</param>
/// <returns>Returns the <see cref="EventResponse"/> instance.</returns>
[HttpPost("events", Name = "CreateEvent")]
public async Task<IActionResult> CreateEvent(
public async Task<IActionResult> CreateEventAsync(
[FromHeader(Name = "Authorization")] string apiKey,
[FromBody] EventRequest req)
{
Expand Down Expand Up @@ -93,6 +105,12 @@ public async Task<IActionResult> CreateEvent(
}
}

/// <summary>
/// Gets the event by ID.
/// </summary>
/// <param name="apiKey">API key.</param>
/// <param name="eventId">Event ID.</param>
/// <returns>Returns the <see cref="EventResponse"/> instance.</returns>
[HttpGet("events/{eventId}", Name = "GetEventById")]
public async Task<IActionResult> GetEventByEventIdAsync(
[FromHeader(Name = "Authorization")] string apiKey,
Expand Down Expand Up @@ -130,72 +148,4 @@ public async Task<IActionResult> GetEventByEventIdAsync(
return new ObjectResult(ex.Message) { StatusCode = StatusCodes.Status500InternalServerError };
}
}

[HttpGet("events/{eventId}/access-codes", Name = "GetListOfEventAccessCodes")]
public async Task<IActionResult> GetAccessCodesByEventIdAsync(
[FromHeader(Name = "Authorization")] string apiKey,
[FromRoute] string eventId)
{
var result = new OkObjectResult("Pong");

return await Task.FromResult(result);
}

[HttpPost("events/{eventId}/access-codes", Name = "CreateEventAccessCode")]
public async Task<IActionResult> CreateEvent(
[FromHeader(Name = "Authorization")] string apiKey,
[FromRoute] string eventId,
[FromBody] AccessCodeRequest req)
{
this._logger.LogInformation("Received a request to generate an access code");

var record = await this._auth.ValidateAsync(apiKey);
if (record == null)
{
this._logger.LogError("Invalid API key");

return new UnauthorizedResult();
}

if (string.IsNullOrWhiteSpace(eventId))
{
this._logger.LogError("No event ID");

return new NotFoundResult();
}

if (req == null)
{
this._logger.LogError("No request payload");

return new BadRequestResult();
}

try
{
req.EventId = eventId;
var result = await this._management.CreateAccessCodeAsync(req);

this._logger.LogInformation("Completed the request to generate the access code");

return new OkObjectResult(result);
}
catch (Exception ex)
{
this._logger.LogError(ex, "Failed to generate the access code");

return new ObjectResult(ex.Message) { StatusCode = StatusCodes.Status500InternalServerError };
}
}

[HttpGet("events/{eventId}/access-codes/{gitHubAlias}", Name = "GetEventAccessCodeByGitHubAlias")]
public async Task<IActionResult> GetAccessCodesByEventIdAsync(
[FromHeader(Name = "Authorization")] string apiKey,
[FromRoute] string eventId,
[FromRoute] string gitHubAlias)
{
var result = new OkObjectResult("Pong");

return await Task.FromResult(result);
}
}
4 changes: 2 additions & 2 deletions src/AzureOpenAIProxy.ApiApp/Models/AccessCodeResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace AzureOpenAIProxy.ApiApp.Models;
/// <summary>
/// This represents the response entity for access code.
/// </summary>
public class AccessCodeResponse : AccessCodeRequest
public class AccessCodeResponse : AccessCodeRequest, IEntityResponse
{
/// <summary>
/// Initializes a new instance of the <see cref="AccessCodeResponse"/> class.
Expand Down Expand Up @@ -48,4 +48,4 @@ public AccessCodeResponse(AccessCodeRecord record)
/// </summary>
[JsonPropertyName("maxTokens")]
public int? MaxTokens { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace AzureOpenAIProxy.ApiApp.Models;

/// <summary>
/// This represents the response entity collection for access code.
/// </summary>
public class AccessCodeResponseCollection : EntityResponseCollection<AccessCodeResponse>
{
}
39 changes: 39 additions & 0 deletions src/AzureOpenAIProxy.ApiApp/Models/EntityResponseCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
namespace AzureOpenAIProxy.ApiApp.Models;

/// <summary>
/// This provides interfaces to the response entity classes.
/// </summary>
public interface IEntityResponse
{
/// <summary>
/// Gets or sets the entity ID.
/// </summary>
string? Id { get; set; }
}

/// <summary>
/// This represents the response entity collection. This MUST be inherited.
/// </summary>
/// <typeparam name="T">Type of response</typeparam>
public abstract class EntityResponseCollection<T> where T : IEntityResponse
{
/// <summary>
/// Gets or sets the current page number.
/// </summary>
public int? CurrentPage { get; set; }

/// <summary>
/// Gets or sets the page size.
/// </summary>
public int? PageSize { get; set; }

/// <summary>
/// Gets or sets the total number of items.
/// </summary>
public int? Total { get; set; }

/// <summary>
/// Gets or sets the list of <see cref="T"/> instances.
/// </summary>
public List<T> Items { get; set; } = [];
}
5 changes: 5 additions & 0 deletions src/AzureOpenAIProxy.ApiApp/Models/EventRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public class EventRecord : ITableEntity
/// </summary>
public string? ApiKey { get; set; }

/// <summary>
/// Gets or sets the maximum number of tokens for the event. Defaults to 4096.
/// </summary>
public int? MaxTokens { get; set; } = 4096;

/// <inheritdoc />
public DateTimeOffset? Timestamp { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion src/AzureOpenAIProxy.ApiApp/Models/EventResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace AzureOpenAIProxy.ApiApp.Models;
/// <summary>
/// This represents the response entity for event.
/// </summary>
public class EventResponse : EventRequest
public class EventResponse : EventRequest, IEntityResponse
{
/// <summary>
/// Initializes a new instance of the <see cref="EventResponse"/> class.
Expand Down
Loading