04_第一個(gè)固體潮模型服務(wù)接口

內(nèi)容簡(jiǎn)介:前面兩篇文章分別介紹了JKG和Streamlit兩種方法杠纵,將python代碼發(fā)布成服務(wù)荠耽,今天我們體會(huì)一下第三種,采用Flask框架來實(shí)現(xiàn)比藻。正所謂條條大路通羅馬铝量,技術(shù)沒有什么絕對(duì)的好壞,小哥想說的是只要適合那就是最好银亲,怎么選完全看你自己慢叨,而多知道一種實(shí)現(xiàn)方法,沒壞處群凶。

1插爹、什么是Flask?

Flask是一個(gè)用Python編寫的Web應(yīng)用程序框架。什么是Web應(yīng)用程序框架赠尾?

Web Application Framework(Web應(yīng)用程序框架)或簡(jiǎn)單的Web Framework(Web框架)表示一個(gè)庫(kù)和模塊的集合力穗,使Web應(yīng)用程序開發(fā)人員能夠編寫應(yīng)用程序,而不必?fù)?dān)心協(xié)議气嫁,線程管理等低級(jí)細(xì)節(jié)当窗。

在Python生態(tài)中,F(xiàn)lask和Django是主流的兩種Web解決方案寸宵。兩者都很有名崖面,社區(qū)活躍程度差不多。

兩者可以實(shí)現(xiàn)的功能也相似梯影,如果非要對(duì)比巫员,那么Flask可以看成是毛坯房,Django是精裝修交付甲棍。但這不是說Flask不好或簡(jiǎn)陋简识,而是Flask給用戶更多靈活的配置空間,整個(gè)框架也更加輕量級(jí)感猛。

2七扰、固體潮模型計(jì)算

固體潮是啥?那我們首先科普一下陪白,在日颈走、月引潮力的作用下,固體地球產(chǎn)生的周期性形變的現(xiàn)象就叫固體潮咱士。啥地球也能變形立由,你聽的沒錯(cuò),當(dāng)太陽和月亮相對(duì)地球的位置發(fā)生改變司致,萬有引力也會(huì)發(fā)生變化拆吆,這個(gè)力能讓地球表面產(chǎn)生10cm左右量級(jí)的變化。

固體潮不像海潮那樣肉眼可見脂矫,但是確實(shí)是真實(shí)存在的,現(xiàn)代化的高精度GPS和重力儀器都可以妥妥地測(cè)量到霉晕。就拿重力固體潮來說庭再,可以好不夸張地說這是人類迄今為止能預(yù)測(cè)到的最準(zhǔn)確的地球物理現(xiàn)象,沒有之一牺堰。

在很多的現(xiàn)代化精密地球科學(xué)觀測(cè)中拄轻,固體潮的影響都需要定量扣除,這時(shí)候需要計(jì)算每個(gè)時(shí)間和地點(diǎn)上的理論固體潮伟葫,然后從儀器觀測(cè)結(jié)果中扣除這部分信號(hào)恨搓,才能得到要研究的數(shù)據(jù)對(duì)象。

今天我們以重力固體潮為例,談?wù)勗趺从?jì)算固體潮模型斧抱,并發(fā)布成一個(gè)服務(wù)常拓。固體潮模型計(jì)算方法有很多,有封閉公式型的辉浦,球諧系數(shù)方法等弄抬,這里面我們不想去深究,總之很成熟了宪郊,但是算起來還挺麻煩掂恕,代碼至少也得有個(gè)百十來行吧,公式一堆一堆的弛槐,哪如果我們用一個(gè)微服務(wù)的形式是否可以呢懊亡?

讓我們想想,輸入/輸出應(yīng)該是什么乎串?

輸入與位置相關(guān)店枣,那就是經(jīng)度/緯度/高度唄;還有時(shí)間灌闺,那就用北京時(shí)間吧艰争;

輸入解決了,那就是輸出桂对,輸出很簡(jiǎn)單就是重力固體潮理論值甩卓,有個(gè)單位用mGal吧

計(jì)算環(huán)境

計(jì)算方法有很多,我們推薦使用Geoist工具包蕉斜,怎么獲得和安裝逾柿,首先弄個(gè)開發(fā)環(huán)境,然后直接從我們的github倉(cāng)庫(kù)安裝一下宅此,命令如下:

pip install git+git://github.com/igp-gravity/geoist.git

函數(shù)用法

安裝完geoist后机错,可以直接調(diào)用tide模塊,計(jì)算與太陽相關(guān)的重力固體潮gs父腕,與月亮相關(guān)的gm和兩者之和g弱匪。

from datetime import date, datetime, timedelta
import geoist.pfm.tide as tide
gdate = datetime(int(year), int(month), int(day), 
                                 int(hour), int(min), int(sec))
gdate = gdate - timedelta(hours=8)  #北京為UTC時(shí)間+8
g1 = tide.TideModel()
gm, gs, g =g1.solve_longman(slat,slon,selev,gdate)

好了,算一個(gè)點(diǎn)沒問題了璧亮,那我要算幾天的怎么搞萧诫,代碼改一下,結(jié)果見圖1:

from datetime import datetime
import geoist.pfm.tide as tide
g1= tide.TideModel()
gdate = datetime(2020, 3, 19, 10, 00, 00)
g1.duration = 5
g1.increment = 60
g1.start_time = gdate
g1.latitude = 45.0
g1.longitude = 105.0
g1.altitude = 0.0
g1.run_model()
g1.plot()
圖1 5天連續(xù)固體潮計(jì)算結(jié)果

算法請(qǐng)參考:I.M. Longman "Forumlas for Computing the Tidal Accelerations Due to the Moon and the Sun" Journal of Geophysical Research, vol. 64, no. 12, 1959, pp. 2351-2355

3枝嘶、Flask封裝接口

那好了計(jì)算固體潮沒問題了帘饶,怎么能編程一個(gè)服務(wù)大家都能happy呢?好群扶,這就要Flask登場(chǎng)啦及刻,還是先安裝:

pip install Flask

然后編寫代碼镀裤,如下:

from flask import Flask,jsonify

app  = Flask(__name__)

@app.route('/')
def hello():
    return 'GEOIST restful API demo! Powered by Flask from Python ecosystem...'

@app.route('/user/<username>')
def profile(username):
    result = {username : ['{}\'s profile'.format(username)]}
    return jsonify(result)

if __name__ == '__main__':
    app.run(debug = True)

將上述代碼保存成一個(gè)py文件,例如flaskdemo1.py缴饭,然后暑劝,在虛擬環(huán)境中,運(yùn)行

python flaskdemo1.py

運(yùn)行后茴扁,會(huì)提示開啟了一個(gè)本地web服務(wù)铃岔,這就是一個(gè)web的應(yīng)用啦,如圖2:

圖2a flask應(yīng)用開啟窗口

圖2b 封裝的接口1

圖2c 封裝的接口2

簡(jiǎn)單接口這樣就成了峭火,但是我們還想再專業(yè)一點(diǎn)毁习,別急,用flask下的專用restful插件卖丸,沒有就再安裝一下(這就是毛坯房纺且,想要啥自己裝):

pip install flask_restful

上面的代碼改造成下面樣式:

from flask import Flask,jsonify
from flask_restful import reqparse, abort, Api, Resource
from datetime import datetime
import geoist.pfm.tide as tide

app  = Flask(__name__)
api = Api(app)

@app.route('/')
def hello():
    return 'GEOIST restful API for Earthtide using longman method...'

class longmantide(Resource):
    def post(self):
        parser = reqparse.RequestParser(bundle_errors=True)
        parser.add_argument('lon', type=float,  required=True, help='經(jīng)度d.ddd')
        parser.add_argument('lat', type=float,  required=True, help='緯度d.ddd')
        args = parser.parse_args()
        slon = float(args["lon"])
        slat = float(args["lat"])
        t1 = datetime.now()
        g1 = tide.TideModel()
        gm, gs, g = g1.solve_longman(slat,slon,0.0,t1)
        return {'gm': gm, 'gs': gs, 'g':g, 't': str(t1)}
   
api.add_resource(longmantide, '/tide')

if __name__ == '__main__':
    app.run(debug = True)

注意這次里面用了post接口,而且增加了對(duì)request參數(shù)的解析(開啟了bundle_errors設(shè)置稍浆,輸入錯(cuò)誤會(huì)提示)载碌,POST方式在運(yùn)行簡(jiǎn)單瀏覽器就不行了,這里我們用Postman演示一下提交方法衅枫,如圖3所示嫁艇。

圖3 通過POST接口計(jì)算指定位置固體潮

4、生成專業(yè)API接口及OpenAPI規(guī)范文檔

上面把一個(gè)固體潮計(jì)算的簡(jiǎn)單API做好啦弦撩,但是我們要給用戶用步咪,還需要一個(gè)文檔說明,最好的方法當(dāng)然是一起發(fā)到web上益楼,要實(shí)現(xiàn)這個(gè)目標(biāo)猾漫,還要再安裝一個(gè)flask的插件——文檔生成器。

安裝方法:

pip install flasgger  #http://localhost:5000/apidocs/

flasgger是將代碼里面的docstrings發(fā)布成swagger UI形式的OpenAPI兼任文檔支持模塊

上面例子中的代碼變?yōu)槿缦滦问剑?/p>

from flask import Flask,jsonify
from flask_restful import reqparse, abort, Api, Resource
from flasgger import Swagger
from datetime import datetime
import geoist.pfm.tide as tide

app  = Flask(__name__)
api = Api(app)
swagger = Swagger(app)

@app.route('/')
def hello():
    '''Earthtide API
    ---
    responses:
      200:
        description: longmentide    
    '''
    return 'GEOIST restful API for Earthtide using longman method...'

class longmantide(Resource):
    def post(self):
        '''計(jì)算重力固體潮API接口說明(基于GEOIST開發(fā)).
        ---
        parameters:
        - name: lon
          type: float
          required: true
        - name: lat
          type: float
          required: true
        responses:
          200:
            description: longmentide
            schema:
             id: dict
             properties:
               results:
                 type: string
                 description: json string
                 default: {'gm': gm, 'gs': gs, 'g': g, 't': time}
        '''
        parser = reqparse.RequestParser(bundle_errors=True)
        parser.add_argument('lon', type=float,  required=True, help='經(jīng)度d.ddd')
        parser.add_argument('lat', type=float,  required=True, help='緯度d.ddd')
        args = parser.parse_args()
        slon = float(args["lon"])
        slat = float(args["lat"])
        t1 = datetime.now()
        g1 = tide.TideModel()
        gm, gs, g = g1.solve_longman(slat,slon,0.0,t1)
        return {'gm': gm, 'gs': gs, 'g':g, 't': str(t1)}
    
api.add_resource(longmantide, '/tide')

if __name__ == '__main__':
    app.run(debug = True)

除了代碼層次更加清晰外感凤,然后你再訪問apidocs目錄下悯周,發(fā)現(xiàn)多了一個(gè)文檔界面

圖3 從docstrings生成API接口文檔

一句話總結(jié):到這里一個(gè)基本的RESTful形式API就完成了,如果你有準(zhǔn)備好的服務(wù)器陪竿,可以將python代碼連同flask環(huán)境打包成一個(gè)docker禽翼,再通過CD方法部署到k8s服務(wù)集群上面,通過云基礎(chǔ)設(shè)施發(fā)布族跛,一套完整的流程走完了捐康,這樣一步步循序漸進(jìn)的來,你是否學(xué)會(huì)了呢庸蔼?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市贮匕,隨后出現(xiàn)的幾起案子姐仅,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掏膏,死亡現(xiàn)場(chǎng)離奇詭異劳翰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)馒疹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門佳簸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颖变,你說我怎么就攤上這事生均。” “怎么了腥刹?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵马胧,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我衔峰,道長(zhǎng)佩脊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任垫卤,我火速辦了婚禮威彰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘穴肘。我一直安慰自己歇盼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布梢褐。 她就那樣靜靜地躺著旺遮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盈咳。 梳的紋絲不亂的頭發(fā)上耿眉,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音鱼响,去河邊找鬼鸣剪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛丈积,可吹牛的內(nèi)容都是我干的筐骇。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼江滨,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼铛纬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起唬滑,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤告唆,失蹤者是張志新(化名)和其女友劉穎棺弊,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體擒悬,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡模她,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了懂牧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侈净。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖僧凤,靈堂內(nèi)的尸體忽然破棺而出畜侦,到底是詐尸還是另有隱情,我是刑警寧澤拼弃,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布夏伊,位于F島的核電站,受9級(jí)特大地震影響吻氧,放射性物質(zhì)發(fā)生泄漏溺忧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一盯孙、第九天 我趴在偏房一處隱蔽的房頂上張望鲁森。 院中可真熱鬧,春花似錦振惰、人聲如沸歌溉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痛垛。三九已至,卻和暖如春桶蛔,著一層夾襖步出監(jiān)牢的瞬間匙头,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工仔雷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蹂析,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓碟婆,卻偏偏與公主長(zhǎng)得像电抚,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子竖共,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容