改造CIMISS MUSIC接口的Python SDK
本文仅代表笔者对 2019 年 10 月时 MUSIC 接口发布版本的观点,随着版本更新及对接口进一步研究,笔者后续观点已有变化。
注:CMADaaS 已提供官方 Python 3 的 MUSIC 接口。
2021.04.15
背景
CIMISS 是全国综合气象信息共享平台 (China Integrated Meteorological Information Service System) 的简称。 由国家气象信息中心牵头建设,用于共享气象业务的数据信息。 对于数值预报中心来说,CIMISS 一般用于检索观测资料。
MUSIC 接口是气象数据统一服务接口 (MUSIC:Meteorological Unified Service Interface Community) 的简称,是为访问 CIMISS 库中保存的数据而开发的接口。 该接口提供统一、标准、丰富的数据访问服务和应用编程接口 (API),为应用系统提供唯一权威的数据接入服务。
今年 6 月 30 日开放测试的 气象大数据云平台 看起来像是对 CIMISS 系统的升级,不仅包含数据,提供包括内置算法在内的计算功能。 该平台提供了 MUSIC 2.0 版的接口。
MUSIC接口的版本
当前业务系统正在使用的 MUSIC 接口版本是1.6,从 MUSIC接口内网网址 下载。
2.0 版本与 1.6 版本最大的区别在于使用不同的库实现数据序列化。 1.6 版本使用 ICE,2.0 版本使用 Protobuf。
MUSIC 1.6 版本只提供了 Python 2.6 的 SDK,而没有提供更广泛使用的 Python 2.7 版本。所以我没有使用过这个版本的 SDK。
MUSIC 2.0 版本提供了 Python 2.7 的 SDK,却没有提供 Python 3.x 版本。 Python 2.7 版本将于 2020 年停止维护,所以我觉得现在发布的 Python 库都支持 Python 3.x 版本。
注:CMADaaS 已提供官方 Python 3 的 MUSIC 接口。[2021.04.15]
不过好在 Protobuf 生成的 Python 代码同时支持 Python 2 和 3,我花了一些时间将整个 MUSIC Python SDK 移植到 Python 3。
修改代码过程中,发现 MUSIC Python SDK 库的代码不像是熟悉 Python 的程序员编写的,编码方式有一些 C/C++ 的风格。 从而萌生了重新写一个 MUSIC Python SDK 的想法。
下面介绍经过重新设计的 SDK 库 —— nuwe-cmadaas-python。
起步
重写的第一步就是编写 protobuf 的定义文件。
Python 这类脚本语言的优势在于不容易隐藏源码,可以从 Python SDK 中的 apiinterface_pb2.py
文件反推回 protobuf 定义文件。
MUSIC 的 protobuf 仅使用基础功能,所以很容易就能得到 proto 文件。
syntax = "proto3";
package cma.music.pb;
message RequestInfo{
int32 errorCode = 1;
string errorMessage =2;
string requestElems = 3;
string requestParams = 4;
string requestTime = 5;
string responseTime = 6;
int32 rowCount = 7;
int32 takeTime = 8;
int32 colCount = 9;
}
message RetArray2D{
repeated string data = 1;
RequestInfo request = 2;
repeated string elementNames = 3;
}
message RetGridArray2D{
repeated float data = 1;
RequestInfo request = 2;
float startLat = 3;
float startLon = 4;
float endLat = 5;
float endLon = 6;
int32 latCount = 7;
int32 lonCount = 8;
float lonStep = 9;
float latStep = 10;
repeated float lats = 11;
repeated float lons = 12;
string units = 13;
string userEleName = 14;
}
message FileInfo{
string fileName = 1;
string savePath = 2;
string suffix = 3;
string size = 4;
string fileUrl = 5;
string imgBase64 = 6;
repeated string attributes = 7;
}
message RetFilesInfo{
repeated FileInfo fileInfos = 1;
RequestInfo request = 2;
}
message StoreArray2D{
repeated string data = 1;
int32 row = 2;
int32 col = 3;
int32 fileflag = 4;
repeated string filenames = 5;
int32 is_backstage = 6;
string client_mount_path = 7;
string server_mount_path = 8;
}
message RetDataBlock{
string dataName = 1;
bytes byteArray = 2;
RequestInfo request = 3;
}
message RetGridVector2D{
repeated float u_datas = 1;
repeated float v_data2 = 2;
RequestInfo request = 3;
float startLat = 4;
float startLon = 5;
float endLat = 6;
float endLon = 7;
int32 latCount = 8;
int32 lonCount = 9;
float lonStep = 10;
float latStep = 11;
repeated float lats = 12;
repeated float lons = 13;
string u_EleName = 14;
string v_EleName = 15;
}
message RetGridScalar2D{
repeated float datas = 1;
RequestInfo request = 2;
float startLat = 3;
float startLon = 4;
float endLat = 5;
float endLon = 6;
int32 latCount = 7;
int32 lonCount = 8;
float lonStep = 9;
float latStep = 10;
repeated float lats = 11;
repeated float lons = 12;
string units = 13;
string userEleName = 14;
}
message StoreGridData{
repeated string attributes = 1;
int32 pointflag = 2;
repeated float Lats = 3;
repeated float Lons = 4;
repeated float datas = 5;
}
message StoreBlockData{
repeated string attributes = 1;
bytes data = 2;
}
使用新的 proto 文件编译 python 代码,会发现与之前的代码有所不同。 不过经测试发现,不影响对消息的解析,可以正常使用。
架构
CIMISS MUSIC 接口调用包括下面几个步骤:
- 根据用户提供的参数和接口生成相应的URL
- 访问 URL 获取响应
- 对响应进行解析,包括错误处理和 protobuf 反序列化
- 对响应进行本地操作,可选步骤
整个 API 的架构如下所示:
不过我这里要指出的是,MUSIC 接口在 URL 中使用明文传输密码,即使在内网也充满风险。 不过这不是我能接触到范畴,所以还是当做没看见比较好。
注:2020 年新版 MUSIC 接口已不再使用明文密码传输。 2021.04.15
使用
MUSIC 接口仅适用于气象局内网用户,使用前请先申请账户。
使用 nuwe_cmadaas.CMADaaSClient
类从 CMADaaS 中检索数据。
需要提供 CMADaaS 服务的相关参数,可以保存在当前目录 client.conf
文件中, 或者在创建 nuwe_cmadaas.CMADaaSClient
对象显式指定。
参数包括:
music_server
: MUSIC 接口 ip 地址,必须指定music_port
:MUSIC 接口端口号,必须指定music_connTimeout
:连接超时,秒,可选music_readTimeout
:数据读取超时,秒,可选music_ServiceId
:默认服务节点 id
下面的示例展示如何检索地面观测资料。
from nuwe_cmadaas import CMADaaSClient
client_config_path="path/to/client/config/file"
user="user name"
password="user password"
server_id = "server id"
interface_id = "getSurfEleByTimeRange"
params = {
"dataCode": "SURF_CHN_MUL_HOR",
"elements": "Station_Id_d,Lat,Lon,Alti,Day,Hour,PRS_Sea,TEM,"
"DPT,WIN_D_INST,WIN_S_INST,PRE_1h,PRE_6h,PRE_24h,PRS",
"timeRange": "[20190817000000,20190817020000)",
"orderby": "Station_ID_d:ASC",
"limitCnt": "10",
}
client = CMADaaSClient(
user=user,
password=password,
config_file=client_config_path
)
result = client.callAPI_to_array2D(interface_id, params)
参考
perillaroc/nuwe-cmadaas-python
相关博文: