STEP 0. 백엔드 준비 (이전 글 참조)
https://doraemin.tistory.com/120
[Docker] FastAPI container 설치 및 실행 with llama
도커 이미지 빌드 & 테스트# 0. 먼저, Docker Desktop 앱 실행하자.# Docker Desktop이 설치 안 되어있다면, https://www.docker.com/get-started/ 에서 설치.# 1. FestAPI.zip 압축파일의 압축 풀고 vsCode 실행# 2. 터미널을
doraemin.tistory.com
STEP 1. FastAPI 수정
PS C:\Users\032\SKT_AI\FastAPI> docker exec -it fastapi bash
>>
root@c40a0e51c864:/usr/src# pip install httpx
main.py 변경하기
플러터 앱과 통신을 위해 몇 가지 코드를 추가 했습니다.
from fastapi import FastAPI, Form
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware
import httpx
import json
app = FastAPI()
# CORS 설정
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
class RequestModel(BaseModel):
model: str
prompt: str
class Message(BaseModel):
message: str
@app.post("/chat")
async def chat(message: Message):
prompt = message.message
# 요청할 URL
url = "http://host.docker.internal:11434/api/generate"
# 요청에 포함할 데이터
data = {
"model": "llama3.1:8b",
"prompt": prompt
}
# 요청 헤더
headers = {
"Content-Type": "application/json"
}
async with httpx.AsyncClient() as client:
response = await client.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
# 개별 JSON 객체로 분할
json_objects = response.content.decode().strip().split("\n")
# 각 JSON 객체를 Python 사전으로 변환
data = [json.loads(obj) for obj in json_objects]
res_text = ''
# 변환된 데이터 출력
for item in data:
print(item)
res_text += item['response']
else:
res_text = f"Error Code : {response.status_code}"
return {"reply": res_text}
STEP 2.플러터 프로젝트 시작
플러터 설치 및 환경변수 설정은 아래 글 참고...
https://cafe.naver.com/aiclubcafe/673
Flutter - 개발환경 구축하기
1. Windows에서 설치 https://flutter-ko.dev/docs/get-started/install/windows 위 주소로 이동 합니다. "Flutter_wi...
cafe.naver.com
Android Studio를 실행하여, 몇가지 코드를 추가하자.
# pubspec.yaml > 37번째 줄에 아래 코드 추가
http: ^0.13.3 # 추가하자
# 이후 Pub get 클릭!
# Androidmanifest.xml > 2번째줄과 16번째 줄에 추가
<uses-permission android:name="android.permission.INTERNET" />
android:usesCleartextTraffic="true" > # 15번째 줄의 '>'닫는 괄호는 삭제
main.dart
먼저 최종 코드로 변경하기
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Chatbot',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ChatScreen(),
);
}
}
class ChatScreen extends StatefulWidget {
@override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final TextEditingController _controller = TextEditingController();
final List<Map<String, String>> _messages = [];
Future<void> _sendMessage(String message) async {
if (message.isEmpty) return;
setState(() {
_messages.add({'sender': 'user', 'text': message});
});
_controller.clear();
final response = await http.post(
Uri.parse('http://127.0.0.1:88/chat'), // 여러분의 FastAPI IP와 Port 에 맞게 수정해 주세요!
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{'message': message}),
);
if (response.statusCode == 200) {
final data = jsonDecode(utf8.decode(response.bodyBytes));
setState(() {
_messages.add({'sender': 'bot', 'text': data['reply']});
});
} else {
setState(() {
_messages.add({'sender': 'bot', 'text': '서버와의 통신 오류가 있습니다.'});
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Chatbot'),
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: _messages.length,
itemBuilder: (context, index) {
final message = _messages[index];
final isUser = message['sender'] == 'user';
return ListTile(
title: Align(
alignment: isUser ? Alignment.centerRight : Alignment.centerLeft,
child: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: isUser ? Colors.blue : Colors.grey,
borderRadius: BorderRadius.circular(10),
),
child: Text(
message['text']!,
style: TextStyle(color: Colors.white),
),
),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _controller,
decoration: InputDecoration(
hintText: 'Enter your message...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
),
SizedBox(width: 8),
ElevatedButton(
onPressed: () => _sendMessage(_controller.text),
child: Text('Send'),
),
],
),
),
],
),
);
}
}
Chrome(web)으로, main.dart를 실행(초록색 버튼) !
자동으로 크롬 웹페이지가 뜨면서, Chatbot을 사용할 수 있다!
// 포트 번호는 이전에 설정한 포트 번호로 변경 ex.8000
참고 문서 ; 이경용 대표님 강의자료
OpenAI - ChatGPT
Llama 모델 챗봇 앱 만들기
라마 모델 사용하기 https://cafe.naver.com/aiclubcafe/823
라마 모델과 FastAPI와 연동하기 https://cafe.naver.com/aiclubcafe/943
라마 연동 플러터 챗봇 앱 만들기 https://cafe.naver.com/aiclubcafe/945
플러터 STT, TTS 라이브러리 활용해서 음성 챗봇 만들기 https://cafe.naver.com/aiclubcafe/946
'웹 개발' 카테고리의 다른 글
[Docker] FastAPI container 설치 및 실행 with llama (0) | 2025.02.03 |
---|---|
[GitHub] Organization 관리하기 (0) | 2025.02.03 |
[공모전] README.md (1) | 2025.01.24 |
[GitHub] Organization vs. Repositories (collaborator, contributor) (0) | 2025.01.21 |
[GitHub] 사용법 (fork, commit, PR) (0) | 2024.10.22 |