쿼리
API 쿼리를 사용하면 Telemetry 데이터에 대해 SQL을 실행할 수 있습니다.
포스트 https://api.telemetry.sh/query
헤더
| 이름 | 유형 | 설명 |
|---|---|---|
| 콘텐츠 유형 | 문자열 | 애플리케이션/json |
| 승인 | 문자열 | API 키(원본 키 또는 Bearer <key>) |
본문
| 이름 | 유형 | 필수 | 설명 |
|---|---|---|---|
| 쿼리 | 문자열 | 예 | 실행할 SQL 쿼리입니다. |
| 실시간 | 부울 | 아니요 | 기본값은 true입니다. 쿼리 서비스로 전달되었습니다. |
| JSON | 부울 | 아니요 | 기본값은 true입니다. 쿼리 서비스로 전달되었습니다. |
성공 응답, 200 OK
{
"status": "success",
"data": [
{
"city": "paris",
"average_price": 42.0
}
],
"key_order": ["city", "average_price"]
}
data에는 결과 행이 포함되어 있습니다. key_order는 쿼리 결과의 열 순서를 유지합니다.
cURL의 사용 예
이 cURL 요청은 uber_rides에서 도시별 평균 요금을 조회합니다.
QUERY=$(cat <<'SQL'
SELECT
city,
AVG(price) AS average_price
FROM
uber_rides
GROUP BY
city
LIMIT
10000;
SQL
)
curl -X POST https://api.telemetry.sh/query \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d "$(jq -n --arg query "$QUERY" '{query: $query, realtime: true, json: true}')"
JavaScript SDK 사용
더 나은 개발자 경험을 위해 SDK를 사용하는 것이 좋습니다.
import telemetry from "telemetry-sh";
telemetry.init("YOUR_API_KEY");
const results =
await telemetry.query(`
SELECT
city,
AVG(price)
FROM
uber_rides
GROUP BY
city
`);
비동기 쿼리
작은 JSON 결과는 result의 data와 key_order로 직접 반환됩니다. 큰 JSON 결과와 Parquet 내보내기는 download_url을 사용합니다. 완료 응답에는 둘 중 하나만 있으면 됩니다. 직접 반환되는 결과에는 다운로드 URL이나 URL 만료 필드가 필요하지 않습니다. download_url_expired가 true이면 새 쿼리를 시작하세요. 만료 필드는 선택 사항입니다.
이는 전체 테이블을 내보내거나, 대규모 집계를 실행하거나, 결과를 JSON 또는 Parquet 파일로 다운로드하는 데 특히 유용합니다.
작동 원리
- 시작 —
POST/query/async에 대한 쿼리입니다. 서버는job_id및status_url를 반환합니다. - 설문조사 — 진행 상황을 확인하려면
GETstatus_url를 사용하세요. result에서 결과를 읽거나download_url에서 파일을 다운로드합니다.
API 참조
비동기 쿼리 시작
포스트 https://api.telemetry.sh/query/async
헤더
| 이름 | 유형 | 설명 |
|---|---|---|
| 콘텐츠 유형 | 문자열 | 애플리케이션/json |
| 승인 | 문자열 | API 키(원본 키 또는 Bearer <key>) |
본문
| 이름 | 유형 | 필수 | 설명 |
|---|---|---|---|
| 쿼리 | 문자열 | 예 | 실행할 SQL 쿼리입니다. |
| 실시간 | 부울 | 아니요 | 기본값은 true입니다. 쿼리 서비스로 전달되었습니다. |
| JSON | 부울 | 아니요 | 기본값은 true입니다. 쿼리 서비스로 전달되었습니다. |
| 형식 | 문자열 | 아니요 | 결과 형식: "json"(기본값) 또는 "parquet". |
응답(202 승인)
{
"status": "accepted",
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"format": "json",
"status_url": "/query/async/550e8400-e29b-41d4-a716-446655440000"
}
폴링 쿼리 상태
GET https://api.telemetry.sh/query/async/{job_id}
헤더
| 이름 | 유형 | 설명 |
|---|---|---|
| 승인 | 문자열 | API 키(원본 키 또는 Bearer <key>) |
응답(200 OK)
직접 반환된 JSON 결과
{
"status": "success",
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"query_status": "completed",
"format": "json",
"progress_pct": 100,
"result": {
"data": [{ "events": 7 }],
"key_order": ["events"]
}
}
다운로드 가능한 결과
{
"status": "success",
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"query_status": "completed",
"format": "json",
"progress_pct": 100,
"message": "Query completed",
"created_at": "2025-02-24T12:00:00Z",
"completed_at": "2025-02-24T12:00:05Z",
"download_url": "https://storage.example.com/results/...",
"download_url_expires_in_seconds": 3600
}
format가 "json"인 경우 다운로드한 파일에는 쿼리 메타데이터와 result 아래의 표준 쿼리 결과 형태가 포함됩니다.
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"format": "json",
"result": {
"data": [
{
"city": "paris",
"average_price": 42.0
}
],
"key_order": ["city", "average_price"]
}
}
query_status 필드는 다음 중 하나입니다.
| 상태 | 설명 |
|---|---|
queued |
쿼리가 실행되기를 기다리고 있습니다. |
running |
쿼리가 현재 실행 중입니다. |
completed |
결과는 result 또는 download_url로 제공됩니다. |
failed |
쿼리가 실패했습니다. error 필드를 확인하세요. |
cancelled |
쿼리가 취소되었습니다. |
cURL을 사용한 비동기 쿼리
# 1. Start the async query
QUERY='SELECT * FROM uber_rides'
RESPONSE=$(curl --fail-with-body -sS --max-time 30 https://api.telemetry.sh/query/async \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d "$(jq -n --arg query "$QUERY" '{query: $query, format: "json", realtime: true, json: true}')") || exit 1
STATUS_URL="https://api.telemetry.sh$(echo "$RESPONSE" | jq -r '.status_url')"
# 2. Poll for at most ten minutes
DEADLINE=$((SECONDS + 600))
while [ "$SECONDS" -lt "$DEADLINE" ]; do
STATUS=$(curl --fail-with-body -sS --max-time 30 -H "Authorization: $API_KEY" "$STATUS_URL") || exit 1
QUERY_STATUS=$(echo "$STATUS" | jq -r '.query_status')
if [ "$QUERY_STATUS" = "completed" ]; then
if echo "$STATUS" | jq -e '.download_url_expired == true' >/dev/null; then
echo "Result expired. Start a new query."
exit 1
elif echo "$STATUS" | jq -e '.result | type == "object"' >/dev/null; then
echo "$STATUS" | jq '{result: .result}' > results.json
else
DOWNLOAD_URL=$(echo "$STATUS" | jq -r '.download_url // empty')
if [ -z "$DOWNLOAD_URL" ]; then
echo "Completed response has neither a result nor an active download URL."
exit 1
fi
curl --fail-with-body -sS --max-time 300 -o results.json "$DOWNLOAD_URL" || exit 1
fi
# Both branches have the same result shape, including an empty data array.
jq '.result' results.json
exit 0
elif [ "$QUERY_STATUS" = "failed" ] || [ "$QUERY_STATUS" = "cancelled" ]; then
echo "Query $QUERY_STATUS: $(echo "$STATUS" | jq -r '.error // .message')"
exit 1
elif [ "$QUERY_STATUS" != "queued" ] && [ "$QUERY_STATUS" != "running" ]; then
echo "Unexpected query status: $QUERY_STATUS"
exit 1
fi
sleep 5
done
echo "Query polling timed out."
exit 1
예: 전체 테이블 내보내기
비동기 쿼리 API는 전체 테이블 내보내기에 이상적입니다. 비동기 쿼리에는 행 제한이 없으므로 모든 항목을 내보내고 결과를 단일 파일로 다운로드할 수 있습니다.
# Start the export as Parquet
QUERY='SELECT * FROM uber_rides'
RESPONSE=$(curl -s -X POST https://api.telemetry.sh/query/async \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d "$(jq -n --arg query "$QUERY" '{query: $query, format: "parquet", realtime: true, json: true}')")
STATUS_URL="https://api.telemetry.sh$(echo "$RESPONSE" | jq -r '.status_url')"
# Poll until complete
while true; do
STATUS=$(curl -s -H "Authorization: $API_KEY" "$STATUS_URL")
QUERY_STATUS=$(echo "$STATUS" | jq -r '.query_status')
if [ "$QUERY_STATUS" = "completed" ]; then
DOWNLOAD_URL=$(echo "$STATUS" | jq -r '.download_url // empty')
if [ -z "$DOWNLOAD_URL" ]; then
echo "Export completed, but no active download URL is available."
exit 1
fi
curl -o uber_rides_export.parquet "$DOWNLOAD_URL"
echo "Export complete: uber_rides_export.parquet"
break
elif [ "$QUERY_STATUS" = "failed" ]; then
echo "Export failed: $(echo "$STATUS" | jq -r '.error // .message')"
exit 1
fi
sleep 5
done
SDK 경계
현재 JavaScript SDK의 query 메서드는 대화형 /query를 호출합니다.
끝점. /query/async를 시작하지 않고, status_url를 폴링하고, 실행합니다.
비동기 작업 시간 초과를 선택하거나 완료된 아티팩트를 다운로드하세요.
대규모 JSON 또는 Parquet의 경우 위의 HTTP 시작, 폴링 및 다운로드 흐름을 사용하세요.
수출. 애플리케이션 래퍼는 이 세 가지 작업을 캡슐화할 수 있지만
여전히 총 폴링 기한을 적용하고 failed에서 중지하고
이전 다운로드를 다시 시도하는 대신 새 내보내기로 download_url가 만료되었습니다.
무기한.
일반적인 오류
- JSON 본문이 유효하지 않은 경우
400 Bad Request query가 없거나 비어 있는 경우400 Bad Request- API 키가 없거나 잘못된 경우
401 Unauthorized 402 Payment Required페이월 확인으로 인해 계정이 차단된 경우- API 키가 게이트웨이 속도 제한을 초과하는 경우
429 Too Many Requests