이 문서는 NHN Cloud의 Cloud Functions 서비스에서 Python을 사용하여 함수를 개발하는 방법을 상세히 설명합니다.
| 항목 | 값 |
|---|---|
| 지원 버전 | 3.11, 3.12, 3.13 |
| 파일명 | user.py |
| Entry Point | user.main |
가장 기본적인 함수 형태입니다.
import sys
import yaml
document = """
a: 1
b:
c: 3
d: 4
"""
def main():
return yaml.dump(yaml.safe_load(document))
Python 함수에서는 Flask의 request 객체를 통해 HTTP 요청 정보에 접근할 수 있습니다.
from flask import request
import json
def main():
# HTTP 요청 정보
method = request.method
headers = dict(request.headers)
args = request.args.to_dict()
# 요청 본문(POST/PUT 등)
data = None
if request.is_json:
data = request.get_json()
elif request.data:
data = request.data.decode('utf-8')
return {
'method': method,
'headers': headers,
'query_params': args,
'body': data
}
Cloud Functions에서 제공하는 Python 템플릿을 다운로드하여 로컬 환경에서 개발할 수 있습니다.
템플릿 다운로드 링크: python.zip
다운로드한 템플릿 파일의 구조는 다음과 같습니다.
python.zip
├── user.py # 메인 함수 파일
└── requirements.txt # 의존성 관리 파일
기본 YAML 처리 함수가 포함되어 있습니다.
import sys
import yaml
document = """
a: 1
b:
c: 3
d: 4
"""
def main():
return yaml.dump(yaml.safe_load(document))
pyyaml
# 압축 해제
unzip python.zip -d my-function
# 작업 디렉터리 이동
cd my-function
user.py 파일을 원하는 로직으로 수정합니다.
# user.py - 간단한 수정 예시
from flask import request
import json
from datetime import datetime
def main():
try:
# 쿼리 파라미터에서 이름 가져오기
name = request.args.get('name', 'World')
# POST 요청인 경우 body에서 메시지 가져오기
custom_message = ''
if request.method == 'POST':
try:
data = request.get_json()
if data:
custom_message = data.get('message', '')
except Exception:
# JSON 파싱 실패 시 무시
pass
result = {
'greeting': f'Hello, {name}!',
'message': custom_message,
'method': request.method,
'timestamp': str(datetime.now())
}
return json.dumps(result, ensure_ascii=False)
except Exception as e:
return json.dumps({
'error': 'Internal Server Error',
'details': str(e)
}, ensure_ascii=False)
수정된 코드를 다시 ZIP 파일로 압축합니다.
# Windows (PowerShell)
Compress-Archive -Path .\user.py, .\requirements.txt -DestinationPath my-function.zip
# Windows (7-Zip 사용 시)
7z a my-function.zip user.py requirements.txt
# macOS/Linux
zip my-function.zip user.py requirements.txt
# 모든 파일 포함(추가 파일이 있는 경우)
zip -r my-function.zip . -x "*.git*" "__pycache__/*" "*.pyc" "test.py"
함수를 생성하거나 수정할 때 사용자 로컬 환경의 파일을 업로드 시 사용. (콘솔 사용 가이드 참고)
.py 파일과 requirements.txt가 위치해야 합니다.올바른 구조:
my-function.zip
├── user.py
├── requirements.txt
└── utils.py (추가 파일이 있는 경우)
잘못된 구조:
my-function.zip
└── my-function/
├── user.py
└── requirements.txt
__pycache__ 폴더는 포함하지 마세요.# .gitignore와 유사하게 다음 파일들은 제외
zip -r my-function.zip . -x \
"__pycache__/*" \
"*.pyc" \
".git/*" \
"*.log" \
"test.py" \
".env" \
"*.zip"
from flask import request
import json
from datetime import datetime
def main():
if request.method != 'GET':
return json.dumps({'error': 'Method Not Allowed'}, ensure_ascii=False), 405
# 쿼리 파라미터 가져오기
name = request.args.get('name', 'World')
greeting = request.args.get('greeting', 'Hello')
result = {
'message': f'{greeting}, {name}!',
'timestamp': datetime.now().isoformat(),
'method': 'GET'
}
return json.dumps(result, ensure_ascii=False)
from flask import request
import json
from datetime import datetime
import uuid
def main():
if request.method != 'POST':
return json.dumps({'error': 'Method Not Allowed'}, ensure_ascii=False), 405
try:
# JSON 형태의 request body 파싱
request_body = request.get_json()
# 필수 필드 검증
if not request_body or 'name' not in request_body:
return json.dumps({
'error': 'Missing required field: name'
}, ensure_ascii=False), 400
name = request_body['name']
email = request_body.get('email', 'not provided')
message = request_body.get('message', 'No message')
# 처리 로직
response = {
'id': str(uuid.uuid4())[:8],
'name': name,
'email': email,
'message': message,
'processed_at': datetime.now().isoformat()
}
return json.dumps(response, ensure_ascii=False)
except Exception as e:
return json.dumps({
'error': 'Invalid JSON format',
'details': str(e)
}, ensure_ascii=False), 400
의존성 관리를 위해 requirements.txt 파일을 작성합니다.
pyyaml
requests>=2.28.0
python-dateutil>=2.8.0
from flask import request
import json
import requests
from datetime import datetime
def main():
try:
user_id = request.args.get('userId')
if not user_id:
return json.dumps({'error': 'userId is required'}, ensure_ascii=False), 400
# 외부 API 호출
response = requests.get(f'https://jsonplaceholder.typicode.com/users/{user_id}')
if response.status_code == 404:
return json.dumps({'error': 'User not found'}, ensure_ascii=False), 404
response.raise_for_status()
user_data = response.json()
result = {
'user': user_data,
'fetched_at': datetime.now().isoformat()
}
return json.dumps(result, ensure_ascii=False)
except requests.RequestException as e:
return json.dumps({
'error': 'External API error',
'details': str(e)
}, ensure_ascii=False), 500
except Exception as e:
return json.dumps({
'error': 'Internal server error',
'details': str(e)
}, ensure_ascii=False), 500
from flask import request
import json
from datetime import datetime
import uuid
import re
def main():
try:
request_body = request.get_json()
data = request_body.get('data', [])
if not isinstance(data, list):
return json.dumps({'error': 'Data must be an array'}, ensure_ascii=False), 400
# 데이터 처리
processed_data = []
for item in data:
if 'name' in item:
processed_item = {
'id': str(uuid.uuid4())[:8],
**item,
'processed_at': datetime.now().isoformat(),
'normalized_name': normalize_name(item['name'])
}
processed_data.append(processed_item)
# 데이터 정렬 및 필터링
valid_data = [item for item in processed_data if item['normalized_name']]
valid_data.sort(key=lambda x: x['normalized_name'])
result = {
'total_processed': len(processed_data),
'valid_items': len(valid_data),
'data': valid_data
}
return json.dumps(result, ensure_ascii=False)
except Exception as e:
return json.dumps({
'error': 'Data processing failed',
'details': str(e)
}, ensure_ascii=False), 400
def normalize_name(name):
"""이름 정규화 함수"""
if not name:
return ''
# 공백 제거 및 첫 글자 대문자화
return name.strip().title()
파일명.함수명을 Entry Point로 사용합니다.
파일명: user.py
함수명: main
Entry Point: user.main
하나의 파일에서 여러 함수를 정의할 수 있습니다.
# handlers.py
from flask import request
import json
def get_user():
# 사용자 조회 로직
return json.dumps({'message': 'Get user'}, ensure_ascii=False)
def create_user():
# 사용자 생성 로직
return json.dumps({'message': 'User created'}, ensure_ascii=False)
def update_user():
# 사용자 수정 로직
return json.dumps({'message': 'User updated'}, ensure_ascii=False)
Entry Point 설정:
- handlers.get_user
- handlers.create_user
- handlers.update_user
현재 아래 특징이 있는 복잡한 패키지는 지원하지 않습니다.
지원하지 않는 패키지 예시:
- numpy, pandas (C/C++ 확장 모듈 필수)
- scipy (시스템 라이브러리 의존성)
- tensorflow, pytorch (복잡한 초기화 과정)
지원 가능한 패키지 예시:
- requests (HTTP 클라이언트)
- pyyaml (YAML 처리)
- python-dateutil (날짜/시간 처리)
- pillow (이미지 처리 - 기본 기능)