728x90
이 부분은 기존에 python으로 작성한 코드를 chatGPT를 활용해서 kotlin으로 바꾸고, 약간의 수작업을 추가해서 완성시킬 수 있었다.
timeout 이슈
timeout 에러가 났었는데, 처리 시간이 기본 세팅된 timeout보다 오래 걸려서 발생한 에러이다. 이미지를 다루다보니 처리 시간이 길어져서 생긴 것이다. 나는 timeout의 길이를 늘려줘서 처리를 했다.
다음 코드를 적용하면 timeout 문제를 해결할 수 있다.
...
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES) // 연결 타임아웃을 1분으로 설정
.readTimeout(1, TimeUnit.MINUTES) // 읽기 타임아웃을 1분으로 설정
.writeTimeout(1, TimeUnit.MINUTES) // 쓰기 타임아웃을 1분으로 설정
.build()
val service = Retrofit.Builder()
.baseUrl("<https://api.openai.com/>")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(OpenAIApiService::class.java)
...
완성 코드
class ImageProcess(private val context: Context) {
// OPENAI 인증키
private val openAiApiKey = BuildConfig.OPENAI_API_KEY
fun imageProcess(base64Image: String, imageUri: Uri) {
// 코루틴을 사용해서 비동기 작업을 진행. Dispatchers.IO는 I/O 작업을 위한 스레드 풀을 사용
CoroutineScope(Dispatchers.IO).launch {
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES) // 연결 타임아웃을 1분으로 설정
.readTimeout(1, TimeUnit.MINUTES) // 읽기 타임아웃을 1분으로 설정
.writeTimeout(1, TimeUnit.MINUTES) // 쓰기 타임아웃을 1분으로 설정
.build()
// Retrofit을 사용해서 HTTP API를 자바 인터페이스로 변환
// GsonConverterFactory를 사용하여 JSON을 자바 객체로 변환
val service = Retrofit.Builder()
.baseUrl("<https://api.openai.com/>")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(OpenAIApiService::class.java)
val prompt = """
이 포스터의 내용을 제목과 요약으로 정리해서 json 형태로 적어줘.
요약은 이 포스터의 목적과 내용 구성에 대해서 줄글 형태로 적어줘.
please write in Korean.
<예시>
{
"제목": "이벤트 포스터",
"요약": "이벤트 포스터입니다. 이벤트 내용을 확인하고 싶으신 분은 이미지를 참고해주세요."
}
""".trimIndent()
// OPENAI API에 전달될 데이터를 담는다. 이미지와 함께 prompt를 전달
// 사용할 모델 이름, 메시지 리스트를 포함한다.
val payload = ImageProcessPayload(
model = "gpt-4-vision-preview",
messages = listOf(
ImageProcessMessage(
role = "user",
content = listOf(
ImageProcessContentText(
type = "text",
text = prompt
),
ImageProcessContentImageUrl(
type = "image_url",
image_url = ImageUrl("data:image/jpeg;base64,$base64Image")
)
)
)
),
)
// service를 사용해 OpenAI API에 이미지 처리 요청을 보낸다. 요청 헤더에는 인증키를 포함
val response = service.processImage("Bearer $openAiApiKey", payload)
// Log.d("test", response.toString())
if (response.isSuccessful) {
// 메인 스레드로 데이터 처리를 전환하거나 UI 업데이트
Log.d("test", response.body().toString())
// OkHttp를 사용하여 HTTP 요청을 수행하고 응답을 받는 가정하에
val responseBodyString = response.body().toString() // 응답 본문을 문자열로 직접 얻기
// 응답 문자열에서 불필요한 부분을 제거하고, 그 결과를 JSONObject로 변환
val modifiedString = responseBodyString
.replace("```json", "") // 시작 부분 제거
.replace("```", "") // 종료 부분 제거
val jsonObject = JSONObject(modifiedString)
// println(jsonObject.toString())
// JSON 객체에서 필요한 부분을 추출
val contentString = jsonObject
.getJSONArray("choices")
.getJSONObject(0)
.getJSONObject("message")
.getString("content")
// 백틱(```) 제거하고, 필요한 부분만 추출
val content = if (contentString.startsWith("```") && contentString.endsWith("```")) {
contentString.substring(3, contentString.length - 3)
} else {
contentString
}
// response 문자열을 Event 객체로 변환한다.
val gson = Gson()
val event = gson.fromJson(content, Event::class.java)
// 네이버 카페 포스팅 수행
NaverCafePosting(context).post(imageUri, event.제목, event.요약)
}
}
}
interface OpenAIApiService {
@POST("v1/chat/completions")
@Headers("Content-Type: application/json")
suspend fun processImage(
@retrofit2.http.Header("Authorization") authHeader: String,
@Body payload: ImageProcessPayload
): retrofit2.Response
}
}
data class ImageProcessPayload(
val model: String,
val messages: List,
)
data class ImageProcessMessage(
val role: String,
val content: List
)
data class ImageProcessContentText(
val type: String,
val text: String
)
data class ImageProcessContentImageUrl(
val type: String,
val image_url: ImageUrl
)
data class ImageUrl(
val url: String
)
// Response 예시
data class Event(
val 제목: String,
val 요약: String
)
728x90
'진행중' 카테고리의 다른 글
[프로젝트] 지역 공공 포스터를 포스팅해보자. 6) 기타 이슈 및 추가 작업 사항 (0) | 2024.04.09 |
---|---|
[프로젝트] 지역 공공 포스터를 포스팅해보자. 5) 네이버 카페에 글 올리기 (4) | 2024.04.09 |
[프로젝트] 지역 공공 포스터를 포스팅해보자. 3) 갤러리에서 이미지를 불러오기 (0) | 2024.04.09 |
[프로젝트] 지역 공공 포스터를 포스팅해보자. 2) 네이버 아이디로 로그인(네아로) 구현 (0) | 2024.04.08 |
[프로젝트] 지역 공공 포스터를 포스팅해보자. 1) 프로젝트 동기 및 초기 실험 과정 (5) | 2024.04.07 |