피터의 Deta 사용기 (2) Deta Micros

Pt J·2021년 6월 27일
0

Story Of My Life

목록 보기
25/31
post-thumbnail

Deta Micros (beta)
Deploy scalable Node & Python apps in seconds.
― 수 초 내로 확장 가능한 Node 및 Python 앱 배포

공식문서 Home에서는 Micros가 먼저고 문서 내용 자체는 Drive가 먼저라, 어느 것을 먼저 할지 살짝 고민했지만 전자를 따르기로 했다.
그런데 Drive는 beta가 아니라 soon 상태인데 문서가 있다?
이에 대해선 일단 Micros 이후에 생각하자.

Deta Micros는 Microserver로, HTTP 엔드포인트에 연결된 가볍고 확장 가능한 클라우드 런타임이다.

기술 사양

  • 지원하는 프로그래밍 언어 버전: Python 3.7, Node.js 12.x
  • Micro별 자체 샌드박스 Linux VM 존재
  • Micro에 고유한 키와 비밀 키가 환경에 설정되어 있음 (외부 공유 금지)
  • 실행 시간이 만료되는 건 10초 후 (관리자 문의로 최대 30초까지 확장 가능)
  • 각 실행 당 최대 128MB의 RAM 사용 (관리자 문의로 최대 1GB까지 확장 가능)
  • /tmp 만 작성 가능한, 512MB의 읽기 전용 시스템
  • 실행 프로세스/스레드 제한은 1024
  • HTTP 페이로드 크기 제한은 5.5MB
  • 수명주기 관리 및 SSH 접속 불필요
  • 데이터베이스는 Deta Base 사용 (읽기 전용 SQLite 가능)
  • 소스코드와 에셋의 총 업로드 크기는 최대 250MB
  • 의존성(npm, pip)도 총 크기 최대 250MB
  • 알 수 없는 이유로(...) Python용 Google & Firebase 패키지 사용 불가...?

Deta CLI

Deta Micros는 Deta CLI를 통해 관리한다.
Deta CLI는 공식 문서 Deta CLI에서도 사용 방법을 확인할 수 있다.

Deta CLI는 다음과 같은 명령어로 설치할 수 있다

$ curl -fsSL https://get.deta.dev/cli.sh | sh

는 Mac과 Linux의 경우고, Windows에서는 다음 명령어를 사용해야 한다.

$ iwr https://get.deta.dev/cli.ps1 -useb | iex

설치가 완료되었다면 인증 후 Deta CLI 명령어를 사용할 수 있다.
deta login 명령어와 웹 브라우저를 통한 인증, 그리고 Access Token을 통한 인증, 이렇게 두 가지 방식의 인증이 가능하다.

전자의 경우 터미널에서 deta login 명령어를 입력하여 웹 브라우저에서 로그인을 하면 인증되며, 후자의 경우, Deta HomeSetting 에서 Access Token을 생성하고 그것을 $HOME/.deta/tokens"deta_access_token"라는 key에 대한 value로 작성한다.
이렇게 생성한 Access Token은 1년 동안 유효하다.

Deta Micros

Deta CLI를 설치했다면 Deta Micros를 사용할 준비가 되었다.
본격적으로 Deta Micros를 사용해보자.

생성하기

명령어를 통해 클라우드에 새 Micro를 생성하고 로컬에 동명의 디렉토리로 복사본을 만들 수 있다.
Micro는 --project PROJECT_NAME 으로 명시해주지 않는다면 Default 프로젝트 내에 생성된다.
Micro는 왠일인지 해당 Micro의 Settings 에서 삭제 가능하다.

JavaScript를 사용할 경우,

$ deta new --node first_micro

Python을 사용할 경우

$ deta new --python first_micro

를 통해 first_micro 라는 이름의 Micro를 생성할 수 있다.
여기선 Python을 기준으로 이야기하겠다.

명령어 실행 시 다음과 같이 출력되며,

$ deta new --python first_micro
Successfully created a new micro
{
        "name": "first_micro",
        "runtime": "python3.7",
        "endpoint": "https://eqtjah.deta.dev",
        "visor": "enabled",
        "http_auth": "disabled"
}

다음과 같은 구조가 생성된다.

first_micro/
├── .deta
│   ├── prog_info
│   └── state
└── main.py

엔드포인트의 eqtjah 에 해당하는 부분은 Micro를 고유하게 식별한다.
즉, Micro를 생성할 때마다 서로 다른 문자열이 들어간다.

.deta 디렉토리는 Deta CLI에 의해 관리되는 설정 파일들이 들어있고, main.py 는 다음과 같이 생성된다.

main.py

def app(event):
    return "Hello, world!"

이 상태에서 엔드포인트로 접속해보면 다음과 같이 뜨는 것을 확인할 수 있다.

만약 다음과 같은 오류가 발생한다면,

{
    "errors":["Unauthorized"]
}

다음 명령어를 통해 Deta Auth의 미승인 접근 차단을 해제함으로써 접근할 수 있다.

$ deta auth disable

업로드

공식문서 예제에서는 Flask를 사용하지만 FastAPI를 통해 작성해보도록 하겠다.
사실 공식문서에도 FastAPI를 이용하는 예제가 나와있긴 하다.
조금 전에 생성된 first_micro 디렉토리 내에 requirements.txt 파일을 생성하고 다음과 같이 작성한다.

requirements.txt

fastapi

그리고 main.py 를 다음과 같이 수정한다.

main.py

from fastapi import FastAPI

app = FastAPI(
    title='DETA Micros Test',
    description='Deta Micros test with FastAPI')

@app.get('/')
def hello_world():
    return 'Hello World'

수정된 내용을 클라우드에 반영하기 위해 다음 명령어를 사용한다.

first_micro$ deta deploy

requirements.txt 에 적혀 있는 fastapi 라는 의존성이 설치되며 다음과 같은 로그가 뜨는 것을 확인할 수 있다.

first_micro$ deta deploy
Deploying...
Successfully deployed changes
Updating dependencies...
Collecting fastapi
  Downloading fastapi-0.65.2-py3-none-any.whl (51 kB)
Collecting pydantic!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<2.0.0,>=1.6.2
  Downloading pydantic-1.8.2-cp37-cp37m-manylinux2014_x86_64.whl (10.1 MB)
Collecting starlette==0.14.2
  Downloading starlette-0.14.2-py3-none-any.whl (60 kB)
Collecting typing-extensions>=3.7.4.3
  Downloading typing_extensions-3.10.0.0-py3-none-any.whl (26 kB)
Installing collected packages: typing-extensions, starlette, pydantic, fastapi
Successfully installed fastapi-0.65.2 pydantic-1.8.2 starlette-0.14.2 typing-extensions-3.10.0.0

그리고 엔드포인트에 다시 접속해보면,

default 출력이었던 Hello, World!Hello World 로 변경된 것을 확인할 수 있다.

Run

Deta Micro는 deta run 명령어를 통해 Deta CLI로 직접 코드를 실행할 수 있다.

새 Micro micro_run을 생성하여 다음과 같은 코드를 작성하고 배포하면

main.py

from deta import app

@app.lib.run()
def welcome(event):
    return "Welcome to Deta!"

deta run 명령어를 통해 welcome 함수를 호출할 수 있다.

micro_run$ deta run
Running micro...

Response:
"Welcome to Deta!"

event 인자

Deta CLI를 통해 실행되는 모든 함수는 event 라는 하나의 인자를 갖는다.
이것은 함수에 입력을 전달하는 데 사용되며, 네 개의 속성을 갖는다.

  • event.json ― JSON 페이로드를 담고 있는 object
  • event.body ― JSON 페이로드의 raw 데이터를 담고 있는 string
  • event.type ― 이벤트 타입을 담고 있는 string
  • event.action ― CLI로부터 제공된 action을 담고 있는 string (default는 빈 문자열)

deta run 명령어에 인자를 전달할 때는 -- 을 사이에 두고, deta run -- --KEY VALUE 형태로 사용한다.

예를 들어 다음과 같이 코드를 수정하였을 때,

main.py

from deta import app

@app.lib.run()
def welcome(event):
    return {
        # access input to your function with event.json
        "message": f"hello {event.json.get('name')}!"
    }

다음과 같이 실행할 수 있다.

$ deta run -- --name deta
Running micro...

Response:
{
        "message": "hello deta!"
}

이 때, 단지 파일을 수정하기만 하는 게 아니라 deta deploy 명령어를 통한 배포를 수행하여야 수정 사항이 반영된다.

deta run 의 인자는 여러 개 전달할 수 있으며, 동일 Key에 대한 Value가 둘 이상일 경우 리스트 형태로 들어간다.

예를 들어 다음과 같은 명령어는

$ deta run -- --name jimmy --age 33 --emails jimmy@deta.sh --emails jim@deta.sh -active

다음과 같은 입력을 의미한다.

{
    "name": "jimmy",
    "age": "33", // notice '33' here is a string not an int
    "emails": ["jimmy@deta.sh", "jim@deta.sh"],
    "active": true
}

action

deta run 명령어로 실행하는 함수는 action 을 통해 식별할 수 있다.

@app.lib.run(action="ACTION") 라는 어노테이션이 붙은 함수는 다음과 같이 호출할 수 있다.

$ deta run ACTION -- --KEY VALUE

예를 들어, 앞서 작성한 main.py 에 다음과 같은 내용을 추가할 수 있다.

main.py

# 생략
@app.lib.run(action="hello")
def welcome(event):
    return {
        "message": f"hello {event.json.get('name')}!"
    }

@app.lib.run(action="greet")
def greet(event):
    return {
        "message": f"good morning {event.json.get('name')}!"
    }

deta deploy 명령어로 배포한 후 다음과 같이 실행할 수 있다.

micro_run$ deta run hello -- --name deta
Running micro...

Response:
{
        "message": "hello deta!"
}
micro_run$ deta run greet -- --name deta
Running micro...

Response:
{
        "message": "good morning deta!"
}

HTTP Trigger

deta 라이브러리를 통해 앱을 인스턴스화함으로써 deta run 과 HTTP 트리거를 둘 다 사용할 수 있다.
다음과 같이 작성하면 된다.

main.py

from deta import App
from fastapi import FastAPI

app = App(FastAPI())

# HTTP
@app.get("/")
def http():
    return "Hello deta, i am running with HTTP"

# CLI run
@app.lib.run()
def run(event):
    return "Hello deta, i am running from the cli"

cron

Cron 또한 동일 Micro에서 생성할 수 있다.
뿐만 아니라 같은 함수를 deta run 과 Cron 모두 사용할 수 있도록 지정할 수 있다.

main.py

from deta import app
from datetime import datetime

# CLI run
@app.lib.run()
def say_hello(event):
    return "hello deta"

# CLI run & cron
@app.lib.run(action='time') # action 'time'
@app.lib.cron()
def print_time(event):
    return f"it is {datetime.now()}" 

그런데 잠깐... Cron이란?

Cron

리눅스 사용자라면 많이 들어봤을 수 있다.
작업 스케줄링을 통해 일정 간격마다 어떤 명령어를 실행하도록 설정하는 것이다.

deta cron set 명령어를 통해 설정할 수 있으며, 두 가지 방식이 있다.

먼저, deta cron set "VALUE UNIT" 형태로, 0이 아닌 양의 정수 VALUE와 시간의 단위 UNIT 으로 나타내는 방식이다.
UNIT 으로 사용할 수 있는 값은 minute, minutes, hour, hours, day, days 가 있다.
단수형은 VALUE1 인 경우에만 사용하며 나머지는 복수형을 사용한다.

그리고 보다 더 정밀하게 스케줄링을 하고 싶다면 띄어쓰기로 구분되는 6개의 값으로 이루어진 Cron 표현식을 사용할 수 있다.
6개의 값은 앞에서부터 분, 시, 일, 월, 요일, 년을 의미한다.
구체적인 사용법은 공식 문서를 참고하도록 하자.

Cron으로 사용하고자 하는 함수는 앞에 @app.lib.cron() 어노테이션을 붙인다.
그리고 배포 후 다음과 같이 스케줄링을 설정할 수 있다.

$ deta cron set "10 minutes"

Cron으로 실행될 때 event.typecron 으로 설정되며, 다음 명령어를 통해 스케줄링을 제거할 수 있다.

$ deta cron remove

프리셋 환경 변수

Micro에는 몇 가지 사전 설정된, 프리셋 환경 변수가 존재한다는 걸 간단히 언급하고 넘어간다.

VariableDescriptionRemark
DETA_PATHMicro를 식별하는 문자열엔드포인트가 {DETA_PATH}.deta.dev 로 설정
DETA_RUNTIME스크립트가 Micro에서 실행 중인지 여부로컬에서만 실행해야 하는 디버깅에 이용

API Key

Deta Micros는 API Key를 이용하여 API를 보호하는 방법을 제공한다.
Micro에서 API Key를 사용하려면 Micro의 루트 디렉토리에서 다음 명령어를 통해 Micro가 Deta Access에 의해 보호되도록 설정하고

$ deta auth enable

다음과 유사하게 API Key를 생성해야 한다.

$ deta auth create-api-key --name first_key --desc "api key for agent 1"

이름과 설명은 자유롭게 설정할 수 있으며 자세한 설명은 문서를 참고하자.
출력되는 결과물 중 "api_key" 에 해당하는 것이 API Key다.

Micro에 어떤 요청을 할 때 --header 'X-API-Key: API_KEY 와 같이 헤더를 추가하여 사용한다.

Visor

Micro의 요청을 모니터링할 땐 Visor를 사용한다.
Visor는 Deta 웹사이트의 Micros 탭에서 모니터링하고자 하는 Micro를 선택하면 Visor 탭을 통해 접근할 수 있다.
Visor 화면에서는 이벤트 로그를 확인할 수 있으며 우측 상단에는 Micro의 엔드포인트 URL이 나와 있고, 좌측 하단에는 HTTP 요청을 보낼 수 있는 클라이언트를 띄우기 위한 버튼이 있다.
각각의 이벤트 로그 상의 요청은 버튼을 눌러 수정하여 재전송 할 수 있다.

Visor는 터미널에서 다음과 같은 명령어를 입력해도 웹 브라우저로 띄울 수 있다.

$ deta visor open

502 Bad Gateway

Micro에서 런타임 에러가 발생하면 502 Bad Gateway 라는 프록시 응답을 받게 된다.
이 경우 Visor를 통해 로그를 확인하여 디버깅할 수 있다.

결론

Node.js 또는 Python으로 백엔드를 구현할 때 상당히 유용할 것으로 보인다.
자기네들은 다른 경로로 돈을 벌 거라면서 완전 무료라고 하기에 "이렇게 좋은 조건일 리 없는데..."
하는 생각도 들었는데, 배포하는데 오래 걸리는 것도 아니고 여러 가지로... 정말 수익 모델을 이해하기 어렵다.

We're working on a big, parallel product that we will be announcing soon. This product will be responsible for generating revenue. Stay tuned!

라고 하며 "이 서비스는 무료지만 우린 괜찮아! 돈 벌 수 있어!"를 주장하는데 솔직히 이 쯤되면 궁금해진다.

플젝할 때 유용하게 써먹겠습니다?ㅎ


작성한 코드는 여기여기에서 확인할 수 있다.


+) 2021.07.06

deta.dev 아래에 사용자 지정 서브도메인을 지정할 수 있게 되었다는 추가사항.
물론 이것도 무료로 제공된다.

profile
Peter J Online Space - since July 2020

0개의 댓글