🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

boto3로 첫 API 호출 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 17. · 5 Views

boto3로 첫 API 호출 완벽 가이드

AWS Bedrock을 활용하여 boto3로 첫 API 호출을 수행하는 방법을 단계별로 배웁니다. 설치부터 에러 처리까지 실무에 바로 적용할 수 있는 완벽 가이드입니다.


목차

  1. boto3_라이브러리_설치
  2. Bedrock_클라이언트_생성
  3. InvokeModel_API_이해
  4. 첫_번째_텍스트_생성_요청
  5. 응답_파싱하기
  6. 에러_처리_기초

1. boto3 라이브러리 설치

신입 개발자 김개발 씨는 오늘 처음으로 AWS 서비스를 Python에서 사용하는 업무를 맡았습니다. "AWS랑 연결하려면 뭐가 필요한가요?" 선배 박시니어 씨가 웃으며 답했습니다.

"boto3부터 설치해봐요."

boto3는 Python에서 AWS 서비스를 제어할 수 있게 해주는 공식 SDK입니다. 마치 리모컨이 TV를 조작하듯이, boto3는 Python 코드로 AWS의 모든 서비스를 조작할 수 있게 해줍니다.

설치는 pip 명령어 한 줄이면 끝납니다.

다음 코드를 살펴봅시다.

# boto3 설치 명령어
pip install boto3

# 설치 확인
import boto3
print(boto3.__version__)

# 추가로 필요한 패키지도 함께 설치
pip install boto3 python-dotenv

김개발 씨는 새 프로젝트를 시작하면서 처음으로 AWS와 통신하는 코드를 작성해야 했습니다. "AWS 콘솔에서는 클릭 몇 번으로 되던데, Python에서는 어떻게 하는 거지?" 박시니어 씨가 설명을 시작했습니다.

"AWS를 코드로 제어하려면 boto3라는 라이브러리가 필요해요." boto3는 Amazon Web Services의 공식 Python SDK입니다. SDK는 Software Development Kit의 약자로, 쉽게 말하면 개발을 편하게 해주는 도구 모음입니다.

리모컨을 생각해보세요. TV를 끄거나 켜려면 리모컨이 필요합니다.

boto3는 바로 AWS를 조작하는 리모컨과 같습니다. Python 코드를 통해 AWS의 수백 가지 서비스를 제어할 수 있게 해줍니다.

boto3가 없던 시절에는 어땠을까요? 개발자들은 HTTP 요청을 직접 만들어야 했습니다.

AWS의 복잡한 인증 방식을 일일이 구현해야 했고, 서명 알고리즘도 직접 작성해야 했습니다. 실수하기 쉬웠고, 코드도 길어졌습니다.

boto3의 등장으로 모든 것이 바뀌었습니다. 이제는 몇 줄의 코드만으로 S3에 파일을 업로드하거나, EC2 인스턴스를 생성하거나, Bedrock AI 모델을 호출할 수 있습니다.

복잡한 인증과 서명은 boto3가 알아서 처리해줍니다. 설치는 정말 간단합니다.

터미널을 열고 pip install boto3 명령어를 입력하면 끝입니다. pip는 Python 패키지 관리자로, Python을 설치하면 자동으로 함께 설치됩니다.

설치가 완료되면 확인해봅시다. Python 인터프리터를 열고 boto3를 import해봅니다.

버전이 출력되면 성공입니다. 실무에서는 보통 가상환경을 만들어서 작업합니다.

프로젝트마다 독립적인 환경을 유지하기 위해서입니다. python -m venv venv 명령으로 가상환경을 만들고, 활성화한 후에 boto3를 설치하는 것이 좋습니다.

또한 python-dotenv 패키지도 함께 설치하면 편리합니다. 이 패키지는 AWS 자격증명 같은 민감한 정보를 .env 파일에 저장하고 불러올 수 있게 해줍니다.

주의할 점이 하나 있습니다. boto3는 AWS CLI가 설정되어 있어야 제대로 작동합니다.

AWS 자격증명(Access Key, Secret Key)이 필요하기 때문입니다. 이 부분은 다음 카드에서 자세히 다루겠습니다.

김개발 씨는 명령어를 입력하고 설치가 완료되는 것을 확인했습니다. "생각보다 간단하네요!" 박시니어 씨가 미소 지으며 말했습니다.

"이제 본격적으로 AWS를 코드로 제어할 준비가 됐어요." 첫 단계는 항상 간단합니다. boto3 설치는 단 한 줄이지만, 이것이 AWS의 거대한 생태계로 들어가는 첫 관문입니다.

실전 팁

💡 - 가상환경(venv)을 만들어서 프로젝트별로 독립적인 환경 유지

  • python-dotenv를 함께 설치하여 환경변수 관리 편리하게 하기

2. Bedrock 클라이언트 생성

boto3를 설치한 김개발 씨는 이제 실제로 AWS Bedrock 서비스에 연결해야 합니다. "클라이언트를 만들어야 해요." 박시니어 씨의 말에 김개발 씨는 고개를 갸우뚱했습니다.

"클라이언트요?"

Bedrock 클라이언트는 AWS Bedrock 서비스와 통신하는 연결 객체입니다. 마치 전화기가 상대방과 통화를 연결하듯이, 클라이언트는 우리 코드와 AWS 서비스를 연결해줍니다.

boto3.client() 함수로 생성하며, 지역(region)과 자격증명이 필요합니다.

다음 코드를 살펴봅시다.

import boto3
from botocore.exceptions import ClientError

# Bedrock Runtime 클라이언트 생성
bedrock_runtime = boto3.client(
    service_name='bedrock-runtime',
    region_name='us-east-1',  # 사용 가능한 리전 선택
    # aws_access_key_id='YOUR_ACCESS_KEY',  # 선택사항
    # aws_secret_access_key='YOUR_SECRET_KEY'  # 선택사항
)

# 클라이언트가 정상적으로 생성되었는지 확인
print(f"클라이언트 생성 완료: {bedrock_runtime}")

김개발 씨는 boto3를 설치한 후 다음 단계를 물었습니다. "이제 뭘 해야 하나요?" 박시니어 씨가 화면을 가리키며 설명했습니다.

"클라이언트를 만들어야 해요. AWS 서비스와 대화하려면 연결 통로가 필요하거든요." 클라이언트는 무엇일까요?

카페를 떠올려봅시다. 카페에 들어가서 커피를 주문하려면 직원과 대화해야 합니다.

직원은 우리의 주문을 받아서 바리스타에게 전달하고, 완성된 커피를 다시 가져다줍니다. boto3의 클라이언트도 이와 똑같습니다.

우리의 Python 코드가 고객이라면, 클라이언트는 카페 직원이고, AWS Bedrock 서비스는 바리스타입니다. 클라이언트가 우리의 요청을 Bedrock에 전달하고, 결과를 다시 가져다줍니다.

클라이언트를 생성하려면 boto3.client() 함수를 사용합니다. 첫 번째 파라미터는 service_name입니다.

AWS에는 수백 가지 서비스가 있습니다. S3, EC2, Lambda, Bedrock 등등.

우리는 Bedrock의 AI 모델을 실행할 것이므로 'bedrock-runtime'을 지정합니다. 두 번째로 중요한 것은 region_name입니다.

AWS는 전 세계 여러 지역에 데이터센터를 운영합니다. 서울(ap-northeast-2), 버지니아(us-east-1), 도쿄(ap-northeast-1) 등이 있습니다.

Bedrock은 모든 리전에서 사용 가능한 것은 아니므로, 지원하는 리전을 선택해야 합니다. 자격증명은 어떻게 처리할까요?

AWS를 사용하려면 누구인지 증명해야 합니다. 이를 위해 Access KeySecret Key가 필요합니다.

하지만 코드에 직접 적는 것은 위험합니다. 코드가 GitHub에 올라가면 누구나 볼 수 있기 때문입니다.

boto3는 똑똑하게도 여러 곳에서 자격증명을 찾습니다. ~/.aws/credentials 파일, 환경변수, IAM 역할 등에서 자동으로 찾아줍니다.

따라서 코드에 직접 적지 않아도 됩니다. 실무에서는 보통 AWS CLI로 aws configure 명령을 실행하여 자격증명을 설정합니다.

그러면 boto3가 자동으로 이를 사용합니다. 코드를 살펴봅시다.

boto3.client() 함수를 호출하면 클라이언트 객체가 반환됩니다. 이 객체를 통해 Bedrock의 모든 기능을 사용할 수 있습니다.

주의할 점은 bedrock-runtimebedrock은 다릅니다. bedrock-runtime은 모델을 실행하는 서비스이고, bedrock은 모델을 관리하는 서비스입니다.

AI 모델을 호출하려면 bedrock-runtime을 사용해야 합니다. 클라이언트를 생성한 후에는 꼭 확인해보세요.

print 문으로 출력하면 객체가 제대로 생성되었는지 볼 수 있습니다. 에러가 발생할 수도 있습니다.

가장 흔한 에러는 자격증명이 없거나, 리전이 잘못되었거나, 권한이 부족한 경우입니다. 이럴 때는 에러 메시지를 잘 읽어보세요.

김개발 씨는 코드를 실행하고 클라이언트가 생성되는 것을 확인했습니다. "오, 이제 Bedrock이랑 대화할 준비가 됐네요!" 박시니어 씨가 고개를 끄덕였습니다.

"맞아요. 이제 진짜 재미있는 부분이 시작돼요."

실전 팁

💡 - AWS CLI로 aws configure를 먼저 실행하여 자격증명 설정하기

  • Bedrock을 사용 가능한 리전인지 확인하기 (모든 리전에서 지원하지 않음)

3. InvokeModel API 이해

클라이언트를 만든 김개발 씨는 드디어 AI 모델을 호출할 준비가 되었습니다. "어떤 API를 사용하면 되나요?" 박시니어 씨가 화이트보드에 "InvokeModel"이라고 적었습니다.

"이게 핵심이에요."

InvokeModel API는 Bedrock의 AI 모델을 실행하는 핵심 메서드입니다. 모델 ID, 요청 본문, 응답 형식을 지정하여 AI 모델에게 작업을 요청합니다.

마치 함수를 호출하듯이 모델을 호출할 수 있으며, JSON 형식으로 데이터를 주고받습니다.

다음 코드를 살펴봅시다.

import json

# InvokeModel API의 기본 구조
response = bedrock_runtime.invoke_model(
    modelId='anthropic.claude-3-haiku-20240307-v1:0',  # 사용할 모델 ID
    contentType='application/json',  # 요청 데이터 형식
    accept='application/json',  # 응답 데이터 형식
    body=json.dumps({  # 요청 본문 (JSON을 문자열로 변환)
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 1000,
        "messages": [
            {"role": "user", "content": "안녕하세요"}
        ]
    })
)

# response는 딕셔너리 형태로 반환됨
print(type(response))

김개발 씨는 궁금했습니다. "클라이언트를 만들었으니 이제 뭘 하면 되나요?" 박시니어 씨가 설명을 시작했습니다.

"InvokeModel이라는 메서드를 사용해요. 이게 실제로 AI 모델을 실행하는 함수예요." InvokeModel은 무엇일까요?

식당을 떠올려봅시다. 메뉴판을 보고 주문서에 원하는 음식을 적습니다.

주문서를 주방에 전달하면, 요리사가 음식을 만들어서 다시 내어줍니다. InvokeModel도 정확히 이와 같습니다.

우리가 원하는 작업을 주문서(요청)에 적어서 AI 모델(요리사)에게 전달하면, 모델이 작업을 수행하고 결과(음식)를 돌려줍니다. InvokeModel API는 네 가지 핵심 파라미터가 필요합니다.

첫 번째는 modelId입니다. Bedrock에는 여러 AI 모델이 있습니다.

Claude, Llama, Titan 등등. 어떤 모델을 사용할지 정확히 지정해야 합니다.

모델 ID는 AWS 콘솔에서 확인할 수 있습니다. 두 번째는 contentType입니다.

우리가 보내는 데이터가 어떤 형식인지 알려줍니다. 보통 'application/json'을 사용합니다.

JSON은 데이터를 구조화하여 전달하는 표준 형식입니다. 세 번째는 accept입니다.

우리가 받고 싶은 응답의 형식입니다. 역시 'application/json'을 사용합니다.

같은 형식으로 주고받는 것이 편리합니다. 네 번째이자 가장 중요한 것은 body입니다.

이것이 바로 주문서입니다. AI 모델에게 무엇을 해달라고 요청할지 담는 곳입니다.

body는 JSON 형식이어야 하는데, Python에서는 딕셔너리로 만든 후 **json.dumps()**로 문자열로 변환합니다. 왜 문자열로 변환할까요?

HTTP 통신은 텍스트 기반이기 때문입니다. body 안의 구조를 살펴봅시다.

anthropic_version은 API 버전을 지정합니다. Claude 모델을 사용할 때 필요합니다.

max_tokens는 AI가 생성할 최대 텍스트 길이입니다. 토큰은 단어보다 작은 단위로, 대략 한글 1글자가 2-3토큰 정도입니다.

messages는 대화 내용입니다. 배열 형태로, 각 메시지는 role(역할)과 content(내용)를 가집니다.

user는 우리의 질문이고, assistant는 AI의 답변입니다. 첫 요청에서는 user 메시지만 보냅니다.

invoke_model을 호출하면 무엇이 반환될까요? response라는 딕셔너리가 반환됩니다.

이 안에 AI 모델의 답변이 들어있습니다. 하지만 직접 사용할 수는 없고, 파싱(해석)하는 과정이 필요합니다.

이는 다음 카드에서 다루겠습니다. 실무에서 주의할 점이 있습니다.

모델마다 body의 구조가 다릅니다. Claude는 messages 배열을 사용하지만, 다른 모델은 prompt 필드를 사용할 수도 있습니다.

반드시 해당 모델의 문서를 확인하세요. 또한 max_tokens를 너무 크게 설정하면 비용이 많이 나갑니다.

Bedrock은 사용한 토큰 수만큼 과금되기 때문입니다. 필요한 만큼만 설정하는 것이 좋습니다.

김개발 씨는 코드를 보며 고개를 끄덕였습니다. "아, 이렇게 모델을 호출하는 거군요!" 박시니어 씨가 미소 지었습니다.

"맞아요. 이제 실제로 텍스트를 생성해볼까요?"

실전 팁

💡 - 모델 ID는 AWS Bedrock 콘솔에서 확인 가능

  • max_tokens는 필요한 만큼만 설정하여 비용 절약하기

4. 첫 번째 텍스트 생성 요청

이제 드디어 AI에게 질문을 보낼 차례입니다. 김개발 씨는 설레는 마음으로 키보드에 손을 올렸습니다.

"진짜 AI가 답변을 해주는 건가요?" 박시니어 씨가 웃으며 답했습니다. "직접 해보면 알 수 있어요."

텍스트 생성 요청은 AI 모델에게 질문이나 작업을 요청하여 답변을 받는 과정입니다. messages 배열에 사용자의 메시지를 담아 전송하면, AI가 이를 읽고 답변을 생성합니다.

간단한 인사부터 복잡한 코드 생성까지 다양한 작업이 가능합니다.

다음 코드를 살펴봅시다.

import boto3
import json

# Bedrock Runtime 클라이언트 생성
bedrock_runtime = boto3.client(
    service_name='bedrock-runtime',
    region_name='us-east-1'
)

# 첫 번째 텍스트 생성 요청
prompt = "Python에서 리스트를 정렬하는 방법을 알려주세요."

response = bedrock_runtime.invoke_model(
    modelId='anthropic.claude-3-haiku-20240307-v1:0',
    contentType='application/json',
    accept='application/json',
    body=json.dumps({
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 500,
        "messages": [
            {"role": "user", "content": prompt}
        ]
    })
)

print("요청 성공!")

김개발 씨는 드디어 실전입니다. "이제 AI에게 진짜 질문을 해볼까요?" 박시니어 씨가 제안했습니다.

"간단한 프로그래밍 질문으로 시작해봐요. Python 리스트 정렬 방법을 물어보는 건 어때요?" 첫 번째 AI 요청을 보내는 것은 특별한 순간입니다.

마치 처음으로 이메일을 보내거나, 첫 전화를 걸던 순간처럼요. 떨리지만 설레는 마음으로 코드를 작성합니다.

prompt라는 변수에 질문을 담았습니다. prompt는 AI에게 보내는 지시문이나 질문을 의미합니다.

"Python에서 리스트를 정렬하는 방법을 알려주세요."라는 명확한 질문입니다. 이 prompt를 messages 배열에 넣습니다.

role은 "user"로 지정합니다. 우리가 사용자이고, AI에게 질문하는 것이기 때문입니다.

invoke_model을 호출하면 어떤 일이 벌어질까요? 우리의 요청이 인터넷을 타고 AWS 데이터센터로 전송됩니다.

그곳에서 Claude 모델이 실행되고, 우리의 질문을 읽고, 생각하고, 답변을 생성합니다. 그리고 그 답변이 다시 우리에게 돌아옵니다.

이 모든 과정이 몇 초 안에 일어납니다. 놀랍지 않나요?

max_tokens를 500으로 설정했습니다. 리스트 정렬 방법을 설명하는 데는 500토큰이면 충분합니다.

너무 길게 설정할 필요가 없습니다. 실무에서는 prompt를 신중하게 작성해야 합니다.

명확하고 구체적일수록 좋은 답변을 받습니다. "리스트 정렬"이라고만 하는 것보다 "Python에서 리스트를 정렬하는 방법"이라고 하는 것이 더 좋습니다.

AI도 맥락이 필요합니다. 또한 예시를 포함하면 더 좋습니다.

"숫자 리스트 [3, 1, 2]를 오름차순으로 정렬하는 코드를 보여주세요"처럼 구체적으로 요청할 수 있습니다. 요청이 성공하면 "요청 성공!"이라는 메시지가 출력됩니다.

하지만 아직 답변을 보지는 못했습니다. response 안에 답변이 들어있는데, 이를 파싱해야 합니다.

에러가 발생할 수도 있습니다. 가장 흔한 에러는 다음과 같습니다.

모델 ID가 잘못되었거나, 리전에서 해당 모델을 사용할 수 없거나, 권한이 부족하거나, 네트워크 문제가 있을 때입니다. invoke_model의 응답 시간은 보통 2-5초 정도입니다.

프롬프트가 길거나 답변이 길면 더 걸릴 수 있습니다. 실시간 채팅처럼 빠르지는 않지만, 충분히 실용적입니다.

김개발 씨는 코드를 실행하고 "요청 성공!" 메시지를 확인했습니다. "와!

정말 되네요!" 박시니어 씨가 고개를 끄덕였습니다. "이제 답변을 파싱해서 읽어볼까요?" 실제 프로젝트에서는 이렇게 간단한 질문뿐 아니라 복잡한 작업도 요청할 수 있습니다.

코드 리뷰, 문서 요약, 번역, 데이터 분석 등 AI의 능력을 다양하게 활용할 수 있습니다.

실전 팁

💡 - prompt는 명확하고 구체적으로 작성하기

  • max_tokens는 작업에 맞게 적절히 설정하여 비용과 시간 절약하기

5. 응답 파싱하기

요청은 성공했지만, 답변을 아직 보지 못했습니다. 김개발 씨는 response 변수를 출력해봤지만 복잡한 데이터만 보였습니다.

"이걸 어떻게 읽어야 하나요?" 박시니어 씨가 화면을 가리켰습니다. "파싱이 필요해요."

응답 파싱은 InvokeModel이 반환한 raw 데이터에서 실제 답변 텍스트를 추출하는 과정입니다. response 딕셔너리의 body를 읽고, JSON으로 변환한 후, content 배열에서 텍스트를 꺼냅니다.

여러 단계를 거쳐야 하지만, 패턴을 익히면 간단합니다.

다음 코드를 살펴봅시다.

import boto3
import json

bedrock_runtime = boto3.client(
    service_name='bedrock-runtime',
    region_name='us-east-1'
)

response = bedrock_runtime.invoke_model(
    modelId='anthropic.claude-3-haiku-20240307-v1:0',
    contentType='application/json',
    accept='application/json',
    body=json.dumps({
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 500,
        "messages": [{"role": "user", "content": "안녕하세요!"}]
    })
)

# 1단계: body를 읽기
response_body = response['body'].read()

# 2단계: JSON 문자열을 Python 딕셔너리로 변환
response_json = json.loads(response_body)

# 3단계: content 배열에서 텍스트 추출
answer = response_json['content'][0]['text']

print(f"AI의 답변: {answer}")

김개발 씨는 response를 출력해봤습니다. 화면에는 복잡한 딕셔너리가 나타났습니다.

"이게 뭐죠?" 박시니어 씨가 설명했습니다. "답변이 그 안에 들어있어요.

하지만 바로 꺼내 쓸 수는 없어요. 파싱이 필요합니다." 파싱이란 무엇일까요?

택배 상자를 떠올려봅시다. 물건을 주문하면 택배로 도착합니다.

하지만 상자 안에는 포장지, 완충재, 에어캡이 겹겹이 싸여 있습니다. 실제 물건을 꺼내려면 포장을 벗겨내야 합니다.

파싱도 이와 같습니다. InvokeModel의 응답은 여러 겹으로 포장되어 있습니다.

우리가 원하는 텍스트 답변을 꺼내려면 단계별로 포장을 벗겨야 합니다. 첫 번째 단계는 body를 읽는 것입니다.

response는 딕셔너리인데, 'body'라는 키에 답변 데이터가 들어있습니다. 하지만 이것은 StreamingBody라는 특수한 객체입니다.

파일처럼 읽어야 합니다. .read() 메서드를 호출하면 바이트 문자열이 나옵니다.

두 번째 단계는 JSON으로 변환하는 것입니다. 바이트 문자열은 JSON 형식입니다.

하지만 문자열 상태로는 사용하기 불편합니다. json.loads() 함수로 Python 딕셔너리로 변환합니다.

loads는 "load string"의 약자입니다. 변환 후의 딕셔너리 구조를 살펴봅시다.

'content'라는 키가 있고, 그 안에 배열이 있습니다. 배열의 첫 번째 요소에 'text'라는 키가 있고, 여기에 드디어 우리가 원하는 답변이 들어있습니다.

세 번째 단계는 텍스트를 추출하는 것입니다. **response_json['content'][0]['text']**로 접근합니다.

content 배열의 첫 번째 요소의 text 필드입니다. 이것이 AI가 생성한 답변입니다.

왜 이렇게 복잡할까요? Claude 모델은 여러 종류의 콘텐츠를 반환할 수 있습니다.

텍스트뿐 아니라 도구 사용 요청, 중간 생각 과정 등이 포함될 수 있습니다. 따라서 배열 형태로 반환되고, 각 요소가 type을 가집니다.

대부분의 경우 첫 번째 요소가 텍스트 답변입니다. 하지만 안전하게 코딩하려면 type을 확인하는 것이 좋습니다.

type이 'text'인지 체크하는 로직을 추가할 수 있습니다. 실무에서는 이 파싱 로직을 함수로 만들어 재사용합니다.

매번 세 단계를 반복하는 것은 번거롭습니다. **parse_response(response)**같은 함수를 만들어서 호출하면 편리합니다.

주의할 점은 에러 처리입니다. 만약 content 배열이 비어있거나, text 필드가 없다면 에러가 발생합니다.

try-except로 감싸서 안전하게 처리하는 것이 좋습니다. 김개발 씨는 코드를 실행하고 "AI의 답변: 안녕하세요!

무엇을 도와드릴까요?"라는 메시지를 확인했습니다. "드디어 제대로 된 답변을 받았어요!" 박시니어 씨가 미소 지었습니다.

"이제 진짜 AI와 대화할 수 있게 됐어요." 파싱 패턴을 한 번 익히면 계속 사용할 수 있습니다. 모든 InvokeModel 호출에서 같은 방식으로 파싱하면 됩니다.

실전 팁

💡 - 파싱 로직을 별도 함수로 분리하여 재사용하기

  • content 배열이 비어있을 수 있으니 에러 처리 추가하기

6. 에러 처리 기초

모든 것이 순조롭게 진행되던 중, 김개발 씨는 갑자기 에러를 만났습니다. "ModelNotFoundError가 뭐죠?" 박시니어 씨가 화면을 보며 말했습니다.

"AWS 작업에서는 에러 처리가 필수예요."

에러 처리는 API 호출이 실패했을 때 프로그램이 중단되지 않도록 대비하는 것입니다. boto3는 다양한 예외를 발생시키며, try-except로 잡아서 적절히 처리해야 합니다.

에러 메시지를 읽고 원인을 파악하여 사용자에게 알려주는 것이 중요합니다.

다음 코드를 살펴봅시다.

import boto3
import json
from botocore.exceptions import ClientError, BotoCoreError

bedrock_runtime = boto3.client(
    service_name='bedrock-runtime',
    region_name='us-east-1'
)

try:
    response = bedrock_runtime.invoke_model(
        modelId='anthropic.claude-3-haiku-20240307-v1:0',
        contentType='application/json',
        accept='application/json',
        body=json.dumps({
            "anthropic_version": "bedrock-2023-05-31",
            "max_tokens": 500,
            "messages": [{"role": "user", "content": "안녕하세요"}]
        })
    )

    # 파싱
    response_body = response['body'].read()
    response_json = json.loads(response_body)
    answer = response_json['content'][0]['text']
    print(f"답변: {answer}")

except ClientError as e:
    # AWS 서비스 에러
    error_code = e.response['Error']['Code']
    error_message = e.response['Error']['Message']
    print(f"AWS 에러 발생: [{error_code}] {error_message}")

except BotoCoreError as e:
    # boto3 라이브러리 에러
    print(f"boto3 에러 발생: {str(e)}")

except Exception as e:
    # 기타 모든 에러
    print(f"예상치 못한 에러: {str(e)}")

김개발 씨는 코드를 실행하다가 갑자기 빨간 에러 메시지를 만났습니다. "어?

왜 안 되죠?" 박시니어 씨가 화면을 살펴봤습니다. "ModelNotFoundError네요.

모델 ID가 잘못됐거나, 리전에서 사용할 수 없는 모델이에요." 프로그래밍에서 에러는 피할 수 없습니다. 특히 네트워크 통신을 하는 경우 더욱 그렇습니다.

인터넷이 끊기거나, 서버가 응답하지 않거나, 권한이 부족하거나, 데이터 형식이 잘못될 수 있습니다. 에러를 무시하면 어떻게 될까요?

프로그램이 갑자기 멈춥니다. 사용자는 무슨 일이 일어났는지 알 수 없습니다.

로그도 남지 않아 디버깅도 어렵습니다. 실무에서는 절대 용납되지 않습니다.

try-except를 사용하면 에러를 잡을 수 있습니다. try 블록 안에 위험한 코드를 넣습니다.

에러가 발생하면 프로그램이 멈추는 대신 except 블록으로 넘어갑니다. 여기서 에러를 처리하고, 적절한 메시지를 출력하고, 복구 작업을 할 수 있습니다.

boto3에서 발생하는 에러는 크게 두 종류입니다. 첫 번째는 ClientError입니다.

AWS 서비스가 반환하는 에러입니다. 모델을 찾을 수 없거나, 권한이 없거나, 요청 형식이 잘못되었을 때 발생합니다.

ClientError 객체는 response라는 속성을 가집니다. 이 안에 에러 코드와 메시지가 들어있습니다.

**e.response['Error']['Code']**로 에러 코드를, **e.response['Error']['Message']**로 자세한 메시지를 얻을 수 있습니다. 흔한 에러 코드를 알아두면 좋습니다.

ModelNotFoundError는 모델 ID가 잘못되었을 때, AccessDeniedException은 권한이 없을 때, ThrottlingException은 요청이 너무 많을 때 발생합니다. 두 번째는 BotoCoreError입니다.

boto3 라이브러리 자체의 에러입니다. 네트워크 연결이 끊기거나, 자격증명이 없거나, 설정이 잘못되었을 때 발생합니다.

마지막으로 Exception으로 모든 에러를 잡습니다. 예상치 못한 에러도 처리할 수 있도록 안전망을 만드는 것입니다.

실무에서는 에러를 로깅해야 합니다. logging 라이브러리를 사용하여 에러를 파일에 기록합니다.

나중에 문제가 생겼을 때 로그를 보고 원인을 파악할 수 있습니다. 또한 재시도 로직을 추가할 수 있습니다.

네트워크 오류처럼 일시적인 에러는 다시 시도하면 성공할 수 있습니다. tenacity 같은 라이브러리를 사용하면 편리합니다.

사용자에게 친절한 메시지를 보여주는 것도 중요합니다. "에러 발생: ResourceNotFoundException"보다는 "요청하신 모델을 찾을 수 없습니다.

모델 ID를 확인해주세요."가 훨씬 좋습니다. 김개발 씨는 에러 처리 코드를 추가하고 다시 실행했습니다.

이번에는 모델 ID를 올바르게 고쳤고, 성공적으로 답변을 받았습니다. "에러 처리 덕분에 무슨 문제인지 바로 알 수 있었어요!" 박시니어 씨가 고개를 끄덕였습니다.

"그래야 안정적인 서비스를 만들 수 있어요." 에러 처리는 귀찮아 보이지만, 실제로는 시간을 절약해줍니다. 에러 메시지가 명확하면 디버깅이 훨씬 빠릅니다.

실전 팁

💡 - 에러 코드별로 다른 메시지를 보여주어 사용자 경험 개선하기

  • logging 라이브러리로 에러를 파일에 기록하여 나중에 분석하기

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Python#boto3#AWS#Bedrock#API

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.