1. 명세서 확인
명세서에서 API 경로·메서드·요청 형식을 확인합니다.
정보공유 › Open API명세서 확인 → 토큰 준비 → 호출까지, 세 단계면 충분합니다.
명세서에서 API 경로·메서드·요청 형식을 확인합니다.
정보공유 › Open API발급을 신청하고, 승인되면 토큰 키를 확인합니다.
정보공유 › Open API › 내 API 토큰Authorization 헤더로 요청하고 응답을 확인합니다.
API 요청 › JSON·RDF 응답명세서에서 제공 범위를 확인하고, 토큰을 준비한 뒤, 인증 헤더로 표준데이터를 조회하는 흐름으로 이용합니다.
제공 API와 요청 형식을 확인합니다.
발급 신청과 승인 이력을 확인합니다.
경로·파라미터·인증 헤더를 구성합니다.
목록은 JSON, 상세는 RDF 로 받고 접근 로그가 남습니다.
서비스·시스템 간에 주고받는 최상위 단위입니다. 필드마다 데이터 프레임이나 데이터 엘리먼트를 가리킵니다.
데이터 엘리먼트나 다른 데이터 프레임을 필드로 묶은 복합 단위입니다.
더 나누지 않는 기본 값 단위입니다. 데이터 유형·제약 표현식·단위를 정의합니다.
표준데이터에 붙는 국제 객체식별자입니다. 점 표기·상위·하위 OID와 연결된 표준데이터를 줍니다.
메시지 → 메시지 필드 → 데이터 프레임 → 데이터 프레임 필드 → 데이터 엘리먼트 순으로 이어집니다. 목록은 JSON, 메시지·데이터 프레임·데이터 엘리먼트 상세는 RDF 로 받습니다. OID 는 목록·상세 모두 JSON 이고, 상세의 instances 에서 연결된 메시지 등의 상세 주소로 이어 부를 수 있습니다.
우리 시스템에 메시지 정의 — 필드·M/O·최대 반복과 그 아래 데이터 프레임·데이터 엘리먼트 — 를 반영합니다.
GET /api/v1/messages/?q=이름 → GET /api/v1/messages/{id}/?depth=full인코딩·디코딩을 개발할 때 데이터 프레임·메시지의 ASN.1 코드와 인코딩 방식(UPER 등)을 받습니다.
GET /api/v1/data-frames/{id}/ → kadif:definitionText · sdo:encodingType점 표기 OID만 알 때 어떤 표준데이터인지 찾아 그 상세로 이어 갑니다.
GET /api/v1/oids/?q=1.2.410.200053.2.1.61 → GET /api/v1/oids/{id}/ → instances[].url데이터 엘리먼트가 바뀔 때 그 엘리먼트를 쓰는 상위 데이터 프레임·메시지를 확인합니다.
GET /api/v1/data-elements/{id}/ → 활용·연결(상위 프레임·메시지)토큰은 사용 목적을 입력해 발급을 신청하고, 검토 후 승인되면 상세 화면에서 키를 확인합니다.
호출 가능한 API의 경로·메서드·요청 예시·파라미터·응답 스키마를 명세서에서 확인합니다.
토큰 인증, 요청 형식 확인, 데이터 조회, 응답 반환, 접근 로그 저장 순서로 처리됩니다.
발급받은 토큰 키를 설정한 뒤 아래 예제를 사용하세요.
/api/v1/messages/
export OPEN_API_TOKEN='발급받은_토큰_키'
따옴표 안을 실제 토큰 키로 바꿔 주세요.
curl -X GET \ https://datamanagement.itskorea.kr/api/v1/messages/ \ -H "Authorization: Token $OPEN_API_TOKEN"
import json
import os
from urllib.request import Request, urlopen
request = Request(
"https://datamanagement.itskorea.kr/api/v1/messages/",
headers={
"Authorization": f"Token {os.environ['OPEN_API_TOKEN']}",
},
)
with urlopen(request, timeout=15) as response:
print(json.load(response))
Python 3 · 추가 패키지 설치 없이 사용할 수 있습니다.
서버 주소는 실제 호출 환경에 맞게 바꿔 주세요.
{
"count": 106,
"next": "https://<SDMS 호스트>/api/v1/messages/?page=2",
"previous": null,
"results": [
{
"id": 3661,
"name": "MSG_PersonalSafetyMessage",
"type": "MSG",
"class_curie": "kadif:Message",
"oid": "1.2.410.200053.2.1.62",
"url": "https://<SDMS 호스트>/api/v1/messages/3661/",
"web_url": "https://<SDMS 호스트>/std-data/dataset/instance/3661"
}
]
}
결과의 url 이 그 항목의 상세 주소입니다. 여러 쪽이면 next 주소를 이어서 호출합니다. 실제 필드와 응답은 명세서를 확인해 주세요.
목록에서 찾은 id 로 한 항목의 내용을 받습니다. 형식과 담는 범위는 아래 표에서 고릅니다.
curl -X GET 'https://<SDMS 호스트>/api/v1/data-frames/3231/' \ -H "Authorization: Token $OPEN_API_TOKEN" \ -H "Accept: text/turtle"
@prefix dct: <http://purl.org/dc/terms/> .
@prefix kadif: <https://<SDMS 호스트>/ns/kadif/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sdo: <https://schema.org/> .
# 이 데이터 프레임
<…/instance/3231> a kadif:DataFrame ;
dct:title "요레이트·가속도·조향각 신뢰도" ;
kadif:objectIdentifier "1.2.410.200053.2.2.3" ;
kadif:dataFrameField <…/instance/3980> ;
kadif:hasRepresentation <…/instance/811> .
# 필드 — 필드명·순서·M/O·최대 반복·가리키는 데이터
<…/instance/3980> a kadif:DataFrameField ;
kadif:fieldName "yawRate" ;
kadif:fieldNumber "1" ;
kadif:maxOccurs "1" ;
kadif:requirement <…/instance/381> ;
kadif:references <…/instance/2681> .
<…/instance/381> a kadif:Requirement ;
kadif:notation "M" .
# 데이터 표현 — ASN.1 코드와 인코딩
<…/instance/811> a kadif:Representation ;
kadif:definitionLanguage "ASN.1" ;
kadif:definitionText """AccelSteerYawRateConfidence ::= SEQUENCE { … }""" ;
sdo:encodingType "UPER" .
# 활용·연결 — 이 데이터 프레임을 쓰는 상위 데이터 프레임
<…/instance/3234> a kadif:DataFrame ;
rdfs:label "DF_ConfidenceSet"@ko ;
kadif:dataFrameField <…/instance/4225> .
…은 https://
| 형식 | Accept | 또는 ?format= |
|---|---|---|
| JSON-LD (기본) | application/ld+json | jsonld |
| Turtle | text/turtle | ttl |
| RDF/XML | application/rdf+xml | rdf |
| ?depth= | 담기는 것 |
|---|---|
| 생략 | 상세 화면에 보이는 내용 — 이 항목의 값, 필드·데이터 표현·값 집합·데이터 유형, 이 항목을 쓰는 상위 프레임·메시지 |
| full | 위 내용 + 필드를 따라 아래 데이터 프레임·데이터 엘리먼트의 내용까지 (응답이 커집니다) |
목록에서 메시지를 이름으로 찾고, 상세 RDF 를 읽어 필드표를 출력합니다. requests·rdflib 를 설치한 뒤(pip install requests rdflib) 호스트와 토큰 키만 바꿔 실행합니다. RDF 안의 메시지 주소는 목록의 web_url 과 같아, 그 주소로 메시지의 필드를 찾습니다.
import requests
from rdflib import RDFS, Graph, URIRef
BASE = "https://<SDMS 호스트>/api/v1"
HEADERS = {"Authorization": "Token <토큰 키>"}
# ① 목록(JSON)에서 이름으로 메시지를 찾는다
found = requests.get(f"{BASE}/messages/", params={"q": "MSG_PersonalSafetyMessage"}, headers=HEADERS)
found.raise_for_status()
message = found.json()["results"][0]
# ② 상세(RDF)를 받아 그래프로 읽는다
detail = requests.get(message["url"], params={"format": "ttl"}, headers=HEADERS)
detail.raise_for_status()
g = Graph().parse(data=detail.text, format="turtle")
kadif = dict(g.namespaces())["kadif"] # 네임스페이스 주소는 응답에 적힌 값을 쓴다
def get(node, name):
return g.value(node, URIRef(kadif + name))
# ③ 필드마다 번호·이름·M/O·최대 반복·가리키는 항목을 뽑는다
rows = []
for field in g.objects(URIRef(message["web_url"]), URIRef(kadif + "messageField")):
rows.append((
int(get(field, "fieldNumber")),
get(field, "fieldName"),
get(get(field, "requirement"), "notation"),
get(field, "maxOccurs"),
g.value(get(field, "references"), RDFS.label),
))
print(f"{message['name']} ({message['oid']}) — 필드 {len(rows)}개")
for number, name, requirement, max_occurs, target in sorted(rows):
print(f"{number:>2} {name:<20} {requirement} {max_occurs:>3} {target}")
MSG_PersonalSafetyMessage (1.2.410.200053.2.1.61) — 필드 26개 1 basicType M 1 DE_PersonalDeviceUserType 2 secMark M 1 DE_DSecond 3 msgCnt M 1 DE_MsgCount 4 id M 1 DE_TemporaryID 5 position M 1 DF_Position3D 6 accuracy M 1 DF_PositionalAccuracy 7 speed M 1 DE_Velocity 8 heading M 1 DE_Heading 9 accelSet O 1 DF_AccelerationSet4Way 10 pathHistory O 1 DF_PathHistory … 26 regional O 4 DF_Reg-PersonalSafetyMessage
M/O 는 필수·선택, 마지막 열은 필드가 가리키는 데이터 엘리먼트(DE_)·데이터 프레임(DF_)입니다. 하위 항목의 필드까지 표로 만들려면 상세에 depth=full 을 붙여 같은 방식으로 따라 내려갑니다.
Authorization: Token <토큰 키>
토큰이 없거나 만료·회수된 경우 401로 거부됩니다. 응답 코드와 메시지로 원인을 먼저 확인하세요.
응답 코드를 선택하면 먼저 확인할 내용을 볼 수 있습니다.
목록·OID 상세는 JSON, 그 밖의 상세는 RDF 를 반환합니다. 목록이 비어 있다면 검색어(q)에 맞는 공개 항목이 있는지 확인해 주세요.
depth 에 full 이 아닌 값을 넣었는지 확인하세요. depth 를 빼거나 full 로 바꿉니다.
Authorization 헤더에 Token 과 토큰 키가 포함되어 있는지 확인하세요. 만료·회수된 토큰이나 비활성 계정으로는 호출할 수 없습니다.
명세서의 경로와 실제 요청 주소를 비교하세요. {id} 자리표시자를 실제 값으로 바꾸었는지, 대상이 공개 항목인지, 관리자가 제공을 중지한 API 인지 확인해 주세요.
상세 조회에 Accept: application/json 처럼 지원하지 않는 형식만 보냈는지 확인하세요. 4단계의 형식 표 값이나 ?format= 을 씁니다.
분당·하루 호출 한도를 넘었습니다. 응답 헤더 Retry-After(초)만큼 기다린 뒤 다시 호출하세요.
화면에서 자주 만나는 다섯 가지입니다.
추가로 확인이 필요한 내용은 Q&A로 남겨 주세요.