Skip to content

Commit

Permalink
Merge pull request #34 from tukcomCD2024/backend/feature/15-gpt-api
Browse files Browse the repository at this point in the history
feat: gpt api 연결 및 응답 생성
  • Loading branch information
yo0oni authored Mar 1, 2024
2 parents f15328b + 75385ec commit 8691eab
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class BackendApplication {

public static void main(String[] args) {
SpringApplication.run(BackendApplication.class, args);
}

@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.isp.backend.domain.gpt.config;

import org.springframework.context.annotation.Configuration;

@Configuration
public class ChatGptConfig {
public static final String AUTHORIZATION = "Authorization";
public static final String BEARER = "Bearer ";
public static final String CHAT_MODEL = "gpt-3.5-turbo";
public static final Integer MAX_TOKEN = 300;
public static final Boolean STREAM = false;
public static final String ROLE = "user";
public static final Double TEMPERATURE = 0.6;
//public static final Double TOP_P = 1.0;
public static final String MEDIA_TYPE = "application/json; charset=UTF-8";
//completions : 질답
public static final String CHAT_URL = "https://api.openai.com/v1/chat/completions";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.isp.backend.domain.gpt.controller;

import com.isp.backend.domain.gpt.dto.ChatGptResponseDTO;
import com.isp.backend.domain.gpt.dto.QuestionRequestDTO;
import com.isp.backend.domain.gpt.entity.ChatGptMessage;
import com.isp.backend.domain.gpt.service.ChatGptService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RequestMapping("/chat-gpt")
@RestController
public class ChatGptController {
private final ChatGptService chatGptService;

@PostMapping("/question")
public ResponseEntity<ChatGptMessage> sendQuestion(@RequestBody QuestionRequestDTO questionRequestDTO) {
String code = "";
ChatGptResponseDTO chatGptResponseDTO = new ChatGptResponseDTO();
try {
chatGptResponseDTO = chatGptService.askQuestion(questionRequestDTO);
} catch (Exception e) {
code = e.getMessage();
}
//return 부분은 자유롭게 수정하시면됩니다. ex)return chatGptResponse;
return ResponseEntity.ok(chatGptResponseDTO.getChoices().get(0).getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.isp.backend.domain.gpt.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.isp.backend.domain.gpt.entity.ChatGptMessage;
import lombok.Builder;

import java.util.List;

public class ChatGptRequestDTO {
private String model;
@JsonProperty("max_tokens")
private Integer maxTokens;
private Double temperature;
private Boolean stream;
private List<ChatGptMessage> messages;

@Builder
public ChatGptRequestDTO(String model, Integer maxTokens, Double temperature,
Boolean stream, List<ChatGptMessage> messages
/*,Double topP*/) {
this.model = model;
this.maxTokens = maxTokens;
this.temperature = temperature;
this.stream = stream;
this.messages = messages;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.isp.backend.domain.gpt.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.isp.backend.domain.gpt.entity.ChatGptMessage;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;

@Getter
@NoArgsConstructor
public class ChatGptResponseDTO {
private String id;
private String object;
private long created;
private String model;
private Usage usage;
private List<Choice> choices;

@Getter
@Setter
public static class Usage {
@JsonProperty("prompt_tokens")
private int promptTokens;
@JsonProperty("completion_tokens")
private int completionTokens;
@JsonProperty("total_tokens")
private int totalTokens;
}

@Getter
@Setter
public static class Choice {
private ChatGptMessage message;
@JsonProperty("finish_reason")
private String finishReason;
private int index;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.isp.backend.domain.gpt.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Getter
@NoArgsConstructor
public class QuestionRequestDTO implements Serializable {
private String question;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.isp.backend.domain.gpt.entity;

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
public class ChatGptMessage implements Serializable {
private String role;
private String content;

@Builder
public ChatGptMessage(String role, String content) {
this.role = role;
this.content = content;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.isp.backend.domain.gpt.service;

import com.isp.backend.domain.gpt.config.ChatGptConfig;
import com.isp.backend.domain.gpt.dto.ChatGptRequestDTO;
import com.isp.backend.domain.gpt.dto.ChatGptResponseDTO;
import com.isp.backend.domain.gpt.dto.QuestionRequestDTO;
import com.isp.backend.domain.gpt.entity.ChatGptMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@Service
public class ChatGptService {
private final RestTemplate restTemplate;

@Value("${api-key.chat-gpt}")
private String apiKey;

public HttpEntity<ChatGptRequestDTO> buildHttpEntity(ChatGptRequestDTO chatGptRequestDTO) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.parseMediaType(ChatGptConfig.MEDIA_TYPE));
httpHeaders.add(ChatGptConfig.AUTHORIZATION, ChatGptConfig.BEARER + apiKey);
return new HttpEntity<>(chatGptRequestDTO, httpHeaders);
}

public ChatGptResponseDTO getResponse(HttpEntity<ChatGptRequestDTO> chatGptRequestHttpEntity){

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(60000);
requestFactory.setReadTimeout(60 * 1000);
restTemplate.setRequestFactory(requestFactory);

ResponseEntity<ChatGptResponseDTO> responseEntity = restTemplate.postForEntity(
ChatGptConfig.CHAT_URL,
chatGptRequestHttpEntity,
ChatGptResponseDTO.class);

return responseEntity.getBody();
}
public ChatGptResponseDTO askQuestion(QuestionRequestDTO questionRequestDTO){
List<ChatGptMessage> messages = new ArrayList<>();
messages.add(ChatGptMessage.builder()
.role(ChatGptConfig.ROLE)
.content(questionRequestDTO.getQuestion())
.build());
System.out.println(messages);
return this.getResponse(
this.buildHttpEntity(
new ChatGptRequestDTO(
ChatGptConfig.CHAT_MODEL,
ChatGptConfig.MAX_TOKEN,
ChatGptConfig.TEMPERATURE,
ChatGptConfig.STREAM,
messages
)
)
);
}
}
5 changes: 4 additions & 1 deletion backend/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ cloud:
region:
static: ${AWS_S3_REGION}
stack:
auto: false
auto: false

api-key:
chat-gpt: ${GPT_API_KEY}

0 comments on commit 8691eab

Please sign in to comment.