# 파이썬 스크립트를 n8n에서 사용하는 방법 (GCP Cloud Run Function)

## 언제 사용하나요? 비용이 발생하나요?

- n8n에서 완성된 파이썬 스크립트를 파라미터값을 입력받아 결과를 받아야 하는 경우.

- Make를 비롯한 노코드 자동화툴에서 파이썬 코드를 직접 실행하는 것을 제한적으로 지원합니다. 외부 파이썬 패키지(라이브러리)를 설치해야할 경우 본 가이드를 통해 비용없이 파이썬 코드를 실행해서 만들 수 있습니다.

## Cloud Run Function이란?

- (ChatGPT) GCP의 **Cloud Run**은 Google Cloud에서 제공하는 **완전 관리형 서버리스 플랫폼**으로, 컨테이너화된 애플리케이션을 실행할 수 있는 환경입니다. Cloud Run Function은 일반적으로 **Cloud Run에서 실행되는 특정 기능이나 역할을 수행하는 서버리스 애플리케이션**을 의미합니다. 

- **Cloud Run 비용 구조 **

    - **무료 제공량 (Free Tier) **매월 다음 양은 무료로 제공됩니다:

        - CPU: **180,000 vCPU-초** (약 50시간)

        - 메모리: **360,000 GiB-초** (약 100시간 @ 3GiB)

        - 요청: **200만 개**

        - 아웃바운드 네트워크: **1GB**

    - 트래픽이 적은 경우 무료 한도를 넘지 않아 비용이 들지 않을 수 있습니다.

## 단계 설명

> 주의! 난이도가 어느정도 있습니다. Google Cloud에 대한 사전지식을 갖고 있으시면 도움이 됩니다.

사전에 미리 Google Cloud 계정 및 프로젝트를 생성해주세요.

1. [https://console.cloud.google.com/](https://console.cloud.google.com/) 접속 후 검색창에 `Cloud Run` 으로 검색하시면 `Cloud Run 함수` 라고 되어있는 메뉴를 선택합니다. 

![Image](https://upload.cafenono.com/image/slashpageHome/20250422/093726_iIBKTtu8jGldkn72lo?q=80&s=1280x180&t=outside&f=webp)

2. 함수 만들기를 선택합니다. 이 과정에서 API 사용에 대한 팝업창이 뜰 수 있는데 모두 동의 하시면 됩니다.

![Image](https://upload.cafenono.com/image/slashpageHome/20250422/093727_x6LwkrSXYvk1qdjY65?q=80&s=1280x180&t=outside&f=webp)

3. 함수명을 설정하고 트리거를 “인증되지 않은 호출 허용”로 선택하고 다음을 누룹니다.

![Image](https://upload.cafenono.com/image/slashpageHome/20250422/093728_NPMpVJuPkogQmf9o1C?q=80&s=1280x180&t=outside&f=webp)

4. 런타임을 `Python 3.12` 으로 선택합니다. 이제 main.py에 여러분들이 돌리실 파이썬 스크립트를 작성합니다. 필요한 패키지들은 requirements.txt에 넣어둡니다. 진입점 항목에는 최종적으로 실행하실 함수명을 입력합니다. 작성을 모두 완료하시면 하단에 `배포` 를 누릅니다.

![Image](https://upload.cafenono.com/image/slashpageHome/20250422/093729_gf8ocXGnhIVDlZkylT?q=80&s=1280x180&t=outside&f=webp)

5. 잠깐 기다리시면 초로색 체크표시가 뜨며 배포가 완료됩니다. 이제 URL값을 복사해서 브라우저에서 실행하시면 앞서 작성했던 파이썬 스크립트가 실행됩니다.

![Image](https://upload.cafenono.com/image/slashpageHome/20250422/093730_1UmOmCCgM5ijfwNCgh?q=80&s=1280x180&t=outside&f=webp)

![Image](https://upload.cafenono.com/image/slashpageHome/20250422/093731_56Ag3UHi5s3qw7k4Zt?q=80&s=1280x180&t=outside&f=webp)

6. 기본 디폴트값으로 함수를 배포하셨다면 아래와 같이 나오실 겁니다.

![Image](https://upload.cafenono.com/image/slashpageHome/20250422/093731_h6jhGa15LBR1LkWvpD?q=80&s=1280x180&t=outside&f=webp)

7. 잘못 작성하신 경우 `수정` 을 하시거나 사용하지 않는 경우 `삭제`를 해주세요.

---

## 활용 예시 1 - SOLAPI 토큰 생성 (파라미터 GET) 

- 호출 URL : [https://us-west1-datapopcorn.cloudfunctions.net/solapi-getheaders?apiKey=<API_KEY>&apiSecret=](https://us-west1-datapopcorn.cloudfunctions.net/solapi-getheaders?apiKey=abc&apiSecret=abc)<API_SECRET>

[main.py](http://main.py/)  (진입점 : get_token)

```
import time
import datetime
import uuid
import hmac
import hashlib
from flask import jsonify, request

def unique_id():
    return str(uuid.uuid1().hex)

def get_iso_datetime():
    utc_offset_sec = time.altzone if time.localtime().tm_isdst else time.timezone
    utc_offset = datetime.timedelta(seconds=-utc_offset_sec)
    return datetime.datetime.now().replace(tzinfo=datetime.timezone(offset=utc_offset)).isoformat()

def get_signature(key, msg):
    return hmac.new(key.encode(), msg.encode(), hashlib.sha256).hexdigest()

def get_headers(apiKey, apiSecret):
    date = get_iso_datetime()
    salt = unique_id()
    data = date + salt
    return {
        'Authorization': 'HMAC-SHA256 ApiKey=' + apiKey + ', Date=' + date + ', salt=' + salt + ', signature=' +
                         get_signature(apiSecret, data)
    }

def get_token(request):
    apiKey = request.args.get('apiKey')
    apiSecret = request.args.get('apiSecret')

    if not apiKey or not apiSecret:
        return jsonify({'error': 'apiKey and apiSecret are required!'}), 400

    headers = get_headers(apiKey, apiSecret)
    return jsonify(headers)
```

## 활용 예시 2 -  구글 뉴스 URL Decode (헤더, 바디 POST)

- 구글 뉴스 URL :  [https://news.google.com/read/CBMiVEFVX3lxTE9EWGRCanFuVXRfOFEyczkxaG4zT2s1NWVnbEZ2MERHMXFmVERVUE5VSEFMS0lQUVdZdVRoRThHbE90eWdjaWJIMlhVQ2lzaXlNWTdwTw?hl=ko&gl=KR&ceid=KR%3Ako](https://news.google.com/read/CBMiVEFVX3lxTE9EWGRCanFuVXRfOFEyczkxaG4zT2s1NWVnbEZ2MERHMXFmVERVUE5VSEFMS0lQUVdZdVRoRThHbE90eWdjaWJIMlhVQ2lzaXlNWTdwTw?hl=ko&gl=KR&ceid=KR%253Ako) 

- [https://news.google.com/rss/articles/CBMidkFVX3lxTE5rWFdRQXNJX1lTVXR1Uzh0dURROUJXVXh1QnZXaUR0WllUZS1NZzRka3BXcTByeVI3d2N3LVNJRWl5aTJxU0lISUxmVXB0dnRCRmZVbFR3c2R4eWg1UnVjNmZSUU9iRnBKbmpSMUEwMEczVHYyNWc?oc=5](https://news.google.com/rss/articles/CBMidkFVX3lxTE5rWFdRQXNJX1lTVXR1Uzh0dURROUJXVXh1QnZXaUR0WllUZS1NZzRka3BXcTByeVI3d2N3LVNJRWl5aTJxU0lISUxmVXB0dnRCRmZVbFR3c2R4eWg1UnVjNmZSUU9iRnBKbmpSMUEwMEczVHYyNWc?oc=5)

```
curl -X POST https://us-central1-datapopcorn.cloudfunctions.net/googlenewsdecoder \
    -H "Content-Type: application/json" \
    -d '{
        "source_url": "https://news.google.com/rss/articles/CBMidkFVX3lxTE5rWFdRQXNJX1lTVXR1Uzh0dURROUJXVXh1QnZXaUR0WllUZS1NZzRka3BXcTByeVI3d2N3LVNJRWl5aTJxU0lISUxmVXB0dnRCRmZVbFR3c2R4eWg1UnVjNmZSUU9iRnBKbmpSMUEwMEczVHYyNWc?oc=5",
        "interval": 5
    }'
```

- 원본 URL : [https://www.etoday.co.kr/news/view/2430685](https://www.etoday.co.kr/news/view/2430685)

- requirement.txt 

- [main.py](http://main.py/) (진입점 : get_token)

For the site tree, see the [root Markdown](https://slashpage.com/n8n-guide.md).
