Cloud Functions은 AWS의 Lambda와 같은 Serverless 실행 환경이다.
Cloud Functions의 경우 Cloud Storage, Cloud Pub/Sub, HTTP등을 통해 트리거를 걸 수 있다. 예를 들어 Cloud Storage를 통해 트리거 한다고 하면 Storage에 파일이 들어왔을 시 자동으로 Cloud Functions이 실행될 수 있는 것이다.
이는 아래와 같은 코드로 Cloud Storage로 들어온 파일명, 버킷명 등을 확인할 수 있다.
def hello_gcs(data, context):
file_name = data['name']
bucket_name = data['bucket']
여기서 data는 "<버킷명>/<폴더>/<파일명>"와 같이 파일 메타데이터가 텍스트로 들어오는 것이다.
보통 Cloud Functions을 GCP에서 사용한다고 하면 BigQuery나 Cloud Storage로의 데이터 적재를 자동화하기 위한 파이프라인 구성에 사용된다.
그럴 경우 파일 경로만 들어와도 해당 파일을 BigQuery로, Cloud Storage로 보내는 작업을 할 수 있다.
하지만 직접 데이터를 갖고와서 전처리나 어떤 분석을 하고싶다? 그럼 Cloud Functions이 데이터를 저장할 수 있어야 된다.
Cloud Functions 메모리 및 파일 시스템 링크를 통해 보면 아래 사진과 같이 나와있다.
Cloud Functions은 우리가 사용하기에 Serverless인 것이지 내부적으로 사실상 하나의 컨테이너가 빌드되어 띄워지는 것이다. 때문에 당연히 os를 갖고 있고, 배포된 소스 파일 및 디렉터리를 포함하는 인메모리 파일 시스템이 존재한다.
os.listdir() 명렁어로 루트(./)디렉토리의 리스트를 실제로 뽑아본 결과이다.
실제로 main.py와 requirements.txt 파일이 존재하고 Cloud Build를 통해 띄워졌다는 것을 확인할 수 있었다.
그렇다면 해당 경로에 파일을 저장해보자.
client = storage.Client(project=<프로젝트 ID>)
bucket = client.bucket(bucket_name)
img_path = "./test_img.jpg"
blob = bucket.blob(file_name)
blob.download_to_filename(img_path)
이렇게 해당 디렉토리는 Read-only만 가능하고 파일을 다운로드하거나 생성하는 것이 불가능하다.
이를 위해 있는 것이 tmp 디렉토리이다. 경로는 /tmp이고 이는 AWS Lambda에도 있는 기능이다.
위의 코드에서 경로만 /tmp 밑으로 바꿔주고 저장한 후 해당 폴더에 존재하는 파일 리스트를 출력하는 코드를 추가해줬다.
client = storage.Client(project=<프로젝트 ID>)
bucket = client.bucket(bucket_name)
img_path = "/tmp/test_img2.jpg"
blob = bucket.blob(file_name)
blob.download_to_filename(img_path)
file_list = os.listdir('/tmp/image/')
file_list_str = ''.join(file_list)
print(file_list_str + ' 이미지 저장 success!!')
성공!!
이런 식으로 파일을 저장해놓은 다음 사용하면 된다.
+추가 유의사항
위의 사진을 보면 빨간 박스 위의 로그가 있다. 첨에 이걸 제대로 캐치하지 못해서 원하는 작업을 진행하는 데에 있어 애를 먹었었다...
Cloud Storage에 파일을 업로드 하면 인증된 URL이라고 https를 기반으로 웹 브라우저에서 볼 수 있는 URL 링크가 부여된다.
처음에 데이터를 다운받을 때 이 URL을 사용하여 아래 코드 한 줄로 받았었다.. 현재 GCP 프로젝트에 인증된 사용자(구글 계정 기반)만이 접근할 수 있는 거였는데..
물론 잘 받아진다! 하지만 당연히 해당 이미지를 갖고 분석을 하거나 가공을 하려고 했으나 인코딩이나 다른 전처리가 되지 않았다.
os.system("curl " + <인증된 URL> + f" > {img_path}")
VM 하나를 띄워서 한 번은 똑같이 curl로 다운받고 한 번은 gsutil로 다운받아 테스트를 해보니 역시나 승인된 URL을 통해 curl로 받아오면 다운은 받아지지만 아예 데이터가 없고 껍데기만 있는 파일이라는 걸 확인할 수 있었다. 때문에 위에 코드들에서도 Cloud Storage에서 지원되는 객체 다운로드 함수를 써서 다운을 받았었다.