Mikber
Mikber

Reputation: 43

How to Upload a File to OpenAI API and Get a Summary Using .NET Core?

I'm trying to upload a file to the OpenAI API and get a summary of its content using .NET Core. I have written the following code, but I'm encountering issues with empty file content and extracting text properly.

Here's my current code for uploading the file and getting a summary:

private readonly string apiUrl = "https://api.openai.com/v1/files";

private readonly string apiKey = "sk-dfsdfsdgsdg";

\[HttpPost\]
\[Route("sendFile")\]
public async Task\<IActionResult\> UploadFile(\[FromForm\] ChatRequestV2 request)
{
    if (request.File == null || request.File.Length == 0)
    return BadRequest("No file uploaded.");
    
    using (var memoryStream = new MemoryStream())
    {
        await request.File.CopyToAsync(memoryStream);
        var fileBytes = memoryStream.ToArray();
    
        var fileContent = Encoding.UTF8.GetString(fileBytes);
        if (string.IsNullOrWhiteSpace(fileContent))
        {
            return BadRequest("The file content is empty or only contains whitespace.");
        }
    
        var fileId = await UploadFileToAPI(fileBytes, request.File.FileName);
    
        if (!string.IsNullOrEmpty(fileId))
        {
            var assistantId = await CreateAssistantAsync();
            if (string.IsNullOrEmpty(assistantId))
                return BadRequest("Assistant creation failed.");
    
            var attachmentId = await AttachFileToAssistantAsync(assistantId, fileId);
            if (string.IsNullOrEmpty(attachmentId))
                return BadRequest("File attachment to assistant failed.");
    
            var summary = await GetSummaryFromAPI(assistantId, fileId);
            return Ok(new { FileId = fileId, Summary = summary });
        }
        else
        {
            return BadRequest("File upload failed.");
        }
    }
    
    }
    
    private async Task\<string\> UploadFileToAPI(byte\[\] fileBytes, string fileName)

    {
    try
    {
    using (var client = new HttpClient())
    {
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
    client.DefaultRequestHeaders.Add("OpenAI-Beta", "assistants=v2");

            using (var content = new MultipartFormDataContent())
            {
                var fileContent = new ByteArrayContent(fileBytes);
                fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/form-data");
                content.Add(fileContent, "file", fileName);
    
                content.Add(new StringContent("assistants"), "purpose");
    
                var response = await client.PostAsync(apiUrl, content);
                if (response.IsSuccessStatusCode)
                {
                    var jsonResponse = await response.Content.ReadAsStringAsync();
                    var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonResponse);
                    return result["id"].ToString();
                }
                else
                {
                    var errorResponse = await response.Content.ReadAsStringAsync();
                    throw new Exception($"API call failed with status code {response.StatusCode}: {errorResponse}");
                }
            }
        }
    }
    catch (HttpRequestException httpEx)
    {
        Console.WriteLine($"HttpRequestException: {httpEx.Message}");
        return null;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception: {ex.Message}");
        return null;
    }
    
    }
    
    private async Task\<string\> CreateAssistantAsync()
    {
    try
    {
    using (var client = new HttpClient())
    {
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
    client.DefaultRequestHeaders.Add("OpenAI-Beta", "assistants=v2");
    
            var requestBody = new
            {
                model = "gpt-4-turbo",
                instructions = "You are an assistant that summarizes text.",
                name = "Text Summarizer",
                tools = new[]
                {
                    new { type = "code_interpreter" },
                    new { type = "file_search" }
                }
            };
    
            var jsonRequestBody = JsonConvert.SerializeObject(requestBody);
            var requestContent = new StringContent(jsonRequestBody, Encoding.UTF8, "application/json");
    
            var response = await client.PostAsync("https://api.openai.com/v1/assistants", requestContent);
            if (response.IsSuccessStatusCode)
            {
                var jsonResponse = await response.Content.ReadAsStringAsync();
                var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonResponse);
                return result["id"].ToString();
            }
            else
            {
                var errorResponse = await response.Content.ReadAsStringAsync();
                throw new Exception($"API call failed with status code {response.StatusCode}: {errorResponse}");
            }
        }
    }
    catch (HttpRequestException httpEx)
    {
        Console.WriteLine($"HttpRequestException: {httpEx.Message}");
        return null;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception: {ex.Message}");
        return null;
    }
    
    }
    
    private async Task\<string\> AttachFileToAssistantAsync(string assistantId, string fileId)
    {
    try
    {
    using (var client = new HttpClient())
    {
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
    client.DefaultRequestHeaders.Add("OpenAI-Beta", "assistants=v2");
    
            var requestBody = new
            {
                tool_resources = new
                {
                    code_interpreter = new { file_ids = new[] { fileId } }
                }
            };
    
            var jsonRequestBody = JsonConvert.SerializeObject(requestBody);
            var requestContent = new StringContent(jsonRequestBody, Encoding.UTF8, "application/json");
    
            var response = await client.PostAsync($"https://api.openai.com/v1/assistants/{assistantId}/files", requestContent);
            if (response.IsSuccessStatusCode)
            {
                var jsonResponse = await response.Content.ReadAsStringAsync();
                var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonResponse);
                return result["id"].ToString();
            }
            else
            {
                var errorResponse = await response.Content.ReadAsStringAsync();
                throw new Exception($"API call failed with status code {response.StatusCode}: {errorResponse}");
            }
        }
    }
    catch (HttpRequestException httpEx)
    {
        Console.WriteLine($"HttpRequestException: {httpEx.Message}");
        return null;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception: {ex.Message}");
        return null;
    }
    
    }
    
    private async Task\<string\> GetSummaryFromAPI(string assistantId, string fileId)
    {
    try
    {
    using (var client = new HttpClient())
    {
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
    client.DefaultRequestHeaders.Add("OpenAI-Beta", "assistants=v2");
    
            var requestBody = new
            {
                messages = new object[]
                {
                    new { role = "user", content = $"Please summarize the content of the file with ID: {fileId}" }
                }
            };
    
            var jsonRequestBody = JsonConvert.SerializeObject(requestBody);
            var requestContent = new StringContent(jsonRequestBody, Encoding.UTF8, "application/json");
    
            var response = await client.PostAsync($"https://api.openai.com/v1/assistants/{assistantId}/messages", requestContent);
            if (response.IsSuccessStatusCode)
            {
                var jsonResponse = await response.Content.ReadAsStringAsync();
                var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonResponse);
                var choices = (JArray)result["choices"];
                var summary = choices[0]["message"]["content"].ToString();
                return summary;
            }
            else
            {
                var errorResponse = await response.Content.ReadAsStringAsync();
                throw new Exception($"API call failed with status code {response.StatusCode}: {errorResponse}");
            }
        }
    }
    catch (HttpRequestException httpEx)
    {
        Console.WriteLine($"HttpRequestException: {httpEx.Message}");
        return "Error summarizing the content.";
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception: {ex.Message}");
        return "Error summarizing the content.";
    }
}

I keep encountering the following error:

{
   "error":{
      "message":"Failed to index file: Error extracting text from file...",
      "type":"invalid_request_error",
      "param":null,
      "code":null
   }
}

What am I missing or doing wrong in my implementation? Are there alternative ways to properly upload a file and get a summary of its content using the OpenAI API?

Alternative Approaches If there's a better approach to achieve this, please provide examples or references. For instance, is there a way to directly read and summarize file content without uploading it first?

Upvotes: 0

Views: 294

Answers (0)

Related Questions