Sigma IDE现在支持Python无服务器Lambda函数!
想想無(wú)服務(wù)器,使用Pythonic –全部在您的瀏覽器中!
(好吧,這則新聞已經(jīng)過(guò)了幾周了,但是仍然……)
如果您沉迷于整個(gè)無(wú)服務(wù)器的“事物”中 ,您可能已經(jīng)注意到我們,一個(gè)在SLAppForge臭名昭著的人 ,對(duì)“無(wú)服務(wù)器的IDE”感到困惑。 是的,我們已經(jīng)運(yùn)行了很長(zhǎng)一段時(shí)間的Sigma IDE (這是同類(lèi)產(chǎn)品中的第一個(gè)),已經(jīng)得到了全世界用戶(hù)的反饋。
我們的標(biāo)準(zhǔn)反饋表中有一個(gè)問(wèn)題: “開(kāi)發(fā)無(wú)服務(wù)器應(yīng)用程序時(shí)首選的語(yǔ)言是什么?” ; 帶有選項(xiàng)Node , Java , Go , C#和一個(gè)建議框。 令人驚訝的是(或可能不是),建議框是最受歡迎的選項(xiàng)。 除了兩個(gè)以外,其他所有“替代”選項(xiàng)都是一個(gè)-Python 。
是Python!
我們甚至有一些用戶(hù)想要取消他們的全新訂閱,因?yàn)镾igma不像他們期望的那樣支持Python。
因此,在我們的路線(xiàn)圖會(huì)議之一中,整個(gè)Python的故事問(wèn)世了; 我們決定試一試。
在故事發(fā)生之前,一些積分要整理好。
Hasangi是我們以前的開(kāi)發(fā)人員之一,最初負(fù)責(zé)評(píng)估在Sigma中支持Python的可行性。 她離開(kāi)后,我接手了。 現(xiàn)在,在這一勝利的時(shí)刻,我要感謝哈桑吉(Hasangi)率領(lǐng)整個(gè)Python行動(dòng)。 👏
Chathura ,我們以前的另一個(gè)向?qū)?#xff0c;已經(jīng)使用Babel解決了IDE的整個(gè)NodeJS代碼分析部分。 盡管在我的編譯器理論講座中有關(guān)于抽象語(yǔ)法樹(shù)(AST)的課程,但經(jīng)過(guò)他的代碼后,我才真正“感受到”了AST的力量。 Chathura,這就是您的生命,它賦予了我們IDE的核心–并使我們的Python旅程大大加快了! 🖖
謝謝你
Chathura的工作很棒。 然而,這就像“水在水里”(哎呀,這是什么樣的比喻?)。 換句話(huà)說(shuō),我們基本上是在ReactJS(yeah,JS)應(yīng)用程序內(nèi)解析(Node)JS代碼。
因此,自然而然,我們的第一個(gè)問(wèn)題(當(dāng)時(shí)的百萬(wàn)美元問(wèn)題)是:我們可以在JS應(yīng)用程序中解析Python嗎? 以及我們所有的魔術(shù)–為API調(diào)用呈現(xiàn)漂亮的彈出窗口,自動(dòng)檢測(cè)資源使用情況,自動(dòng)生成IAM權(quán)限等嗎?
Hasangi已經(jīng)找到了filbert.js ,這是acorn的衍生版本,可以解析Python。 不幸的是,不久之后,我和她了解到它無(wú)法理解AWS SDK API調(diào)用的標(biāo)準(zhǔn)(也是最受歡迎的)格式,即命名為params :
s3.put_object( Bucket= "foo" , Key= "bar" , Body=our_data )如果我們改為使用“流利的”格式,請(qǐng)執(zhí)行以下操作:
boto.connect_s3() \ .get_bucket( "foo" ) \ .new_key( "bar" ) \ .set_contents_from_string(our_data)我們將不得不重寫(xiě)整個(gè)lotta AST解析邏輯; 也許是用于基于Python的用戶(hù)區(qū)代碼的全新AST解釋器。 我們不想要那么多冒險(xiǎn)-至少現(xiàn)在還沒(méi)有。
(有用!!)
一個(gè)好的夜晚,我繼續(xù)玩filbert.js 。 瀏覽解析路徑時(shí),我注意到:
... } else if (!noCalls && eat(_parenL)) { if (scope.isUserFunction(base.name)) { // Unpack parameters into JavaScript-friendly parameters, further processed at runtime var pl = parseParamsList(); ... node.arguments = args; } else node.arguments = parseExprList(_parenR, false ); ...等等...他們故意跳過(guò)命名參數(shù)嗎?
如果我注釋掉該狀況檢查該怎么辦?
... } else if (!noCalls && eat(_parenL)) { // if (scope.isUserFunction(base.name)) { // Unpack parameters into JavaScript-friendly parameters, further processed at runtime var pl = parseParamsList(); ... node.arguments = args; // } else node.arguments = parseExprList(_parenR, false); ...然后……嗯,我簡(jiǎn)直不敢相信自己的眼睛。
注釋了兩行,它已經(jīng)開(kāi)始工作!
那是我的關(guān)鍵時(shí)刻。 我要把Python引入Sigma。 無(wú)論。
我不能放棄。 不追隨我剛剛看到的。
大重構(gòu)
當(dāng)我們誕生Sigma時(shí) ,它應(yīng)該更像是PoC –證明我們無(wú)需本地開(kāi)發(fā)人員設(shè)置,儀表板和文檔往返以及大量配置即可進(jìn)行無(wú)服務(wù)器開(kāi)發(fā)。
結(jié)果,那時(shí)的可擴(kuò)展性和可定制性還不太成熟。 事情幾乎與AWS和NodeJS綁定在一起。 (并認(rèn)為我們?nèi)匀环Q(chēng)它們?yōu)椤?JavaScript”文件…😁)
因此,從解析器開(kāi)始,一大堆重構(gòu)都在等待著我急切的手指。 從Language抽象開(kāi)始,我逐步完成了編輯器和彈出式渲染,代碼段生成,構(gòu)建工件,部署等工作。
( 在為Sigma提供Google Cloud支持時(shí),我已經(jīng)解決了類(lèi)似的挑戰(zhàn)-因此我對(duì)如何處理整個(gè)問(wèn)題有一些了解。)
測(cè)試環(huán)境
自從Chathura(我們的前Adroit向?qū)?#xff09;一手實(shí)現(xiàn)它以來(lái), 測(cè)試環(huán)境就成為Sigma功能集中最重要的一個(gè)。 如果Python產(chǎn)生了影響,我們還將需要一個(gè)Python測(cè)試環(huán)境。
這里的事情開(kāi)始變得有些時(shí)髦。 由于它的歷史有些尷尬 ,Python具有兩個(gè)明顯的“特色”:2.7和3.x。 因此,實(shí)際上,我們需要維護(hù)兩個(gè)不同的環(huán)境-每個(gè)版本一個(gè)-并根據(jù)當(dāng)前函數(shù)的運(yùn)行時(shí)設(shè)置調(diào)用正確的環(huán)境。
(好吧,實(shí)際上,NodeJS也確實(shí)有同樣的問(wèn)題(6.x,8.x,10.x,...);但是顯然我們沒(méi)有考慮太多,也沒(méi)有造成任何問(wèn)題。也是主要問(wèn)題!!)
pip install
我們還需要一種處理Python( pip )依賴(lài)項(xiàng)的新方法。 幸運(yùn)的是,Lambda容器上已經(jīng)提供了pip ,因此安裝不是主要問(wèn)題。 真正的問(wèn)題是必須將它們直接提取到測(cè)試環(huán)境中的項(xiàng)目根目錄中。 (與npm相反,這里的所有內(nèi)容都進(jìn)入一個(gè)漂亮且易于管理的node_modules目錄中,以便我們可以一次性提取和清理內(nèi)容。)幸運(yùn)的是,一點(diǎn)點(diǎn)(希望很穩(wěn)定!)代碼帶領(lǐng)我們完成了工作。
沒(méi)有
一切運(yùn)行順利,直到…
from subdirectory.util_file import util_func , in <module> File "/tmp/pypy/ding.py" , line 1 , line from subdirectory.util_file import util_func ImportError: No module named subdirectory.util_file僅在Python 2.7中發(fā)生過(guò),因此這一點(diǎn)很容易弄清楚–我們需要在subdirectory內(nèi)部有一個(gè)__init__.py來(lái)將其標(biāo)記為可導(dǎo)入模塊 。
我們決定不自己依靠用戶(hù)來(lái)創(chuàng)建它,而是決定自己做。 每當(dāng)創(chuàng)建Python文件時(shí),我們現(xiàn)在都確保__init__.py在其父目錄中也存在; 如果沒(méi)有文件,則創(chuàng)建一個(gè)空文件。
該死的原木–它們功能異常!
SigmaTrail是我們Sigma IDE的另一個(gè)瑰寶。 逐段編寫(xiě)Lambda時(shí),在代碼窗口旁邊放置一個(gè)日志窗格確實(shí)有幫助。 此外,如果您看不到剛運(yùn)行的日志,那么測(cè)試環(huán)境有什么用?
Chathura再次成為SigmaTrail的策劃者。 (是的,畢竟,他編寫(xiě)了一半以上的IDE!)他的代碼是謙虛地解析CloudWatch日志,并將它們與Lambda調(diào)用返回的LogResult合并; 所以我想我可以將其插入Python運(yùn)行時(shí),坐下來(lái)欣賞一下視圖。
我錯(cuò)了。
舉起手來(lái),那些使用Python
在Node中,您要從控制臺(tái)中獲得某種東西的唯一(顯而易見(jiàn)的)方法(或從技術(shù)上來(lái)說(shuō)是stdout )是通過(guò)其中一個(gè)console.{level}()調(diào)用。
但是Python提供了一些選擇 –例如內(nèi)置的print和logging模塊。
如果要進(jìn)行l(wèi)ogging ,則必須:
是的,在Lambda上,您還可以
context.log( "your log message\n" )如果您的context仍然存在-仍然需要在末尾添加\n ,以便將其記錄到自己的行中。
但是,僅print("your log message")更容易-哎呀,如果您使用的是2.x,則甚至不需要那些花括號(hào)!
對(duì)你有益。
但這對(duì)SigmaTrail造成了嚴(yán)重的問(wèn)題。
uck
對(duì)于Node中的console.log ,Lambda自動(dòng)為每個(gè)日志添加當(dāng)前時(shí)間戳和請(qǐng)求ID( context.awsRequestId )。 Chathura利用這些數(shù)據(jù)來(lái)分離出日志行,并在SigmaTrail中將它們顯示為不錯(cuò)的線(xiàn)索。
但是現(xiàn)在,有了print ,就沒(méi)有前綴了。 什么都沒(méi)撿到。
解決這個(gè)問(wèn)題可能是工作中最困難的部分。 我花了大約一個(gè)星期的時(shí)間來(lái)嘗試?yán)斫獯a(由于使用了基于工人的模式); 然后又一個(gè)星期嘗試在不破壞NodeJS流程的情況下對(duì)其進(jìn)行修復(fù)。
到現(xiàn)在為止,它應(yīng)該相當(dāng)穩(wěn)定-并且能夠處理隨著時(shí)間的流逝可能拋出的任何其他語(yǔ)言。
“真正的”運(yùn)行時(shí):與
測(cè)試環(huán)境復(fù)活后,我以為所有麻煩都結(jié)束了。 “傳統(tǒng)”構(gòu)建(由CodeBuild驅(qū)動(dòng))和部署非常易于重構(gòu),因此我很高興–甚至為初始版本提高了環(huán)保標(biāo)志。
但是我犯了一個(gè)嚴(yán)重的錯(cuò)誤。
直到我實(shí)際上通過(guò)API網(wǎng)關(guān)觸發(fā)器調(diào)用已部署的Lambda時(shí),我才意識(shí)到這一點(diǎn)。
{ "errorMessage" : "Unable to import module 'project-name/func'" }什么...
Unable to import module 'project-name/func' : No module named 'subdirectory' : No module namedma模塊在哪里?
測(cè)試工作正常! 那么為什么不生產(chǎn)呢?
經(jīng)過(guò)幾次隨機(jī)實(shí)驗(yàn),并檢查了其他框架生成的Python捆綁軟件,我意識(shí)到罪魁禍?zhǔn)资俏覀兊牟渴饳n案(zipfile)結(jié)構(gòu)。
所有其他捆綁軟件都具有頂層功能,但我們的捆綁軟件將它們包含在目錄(我們的“項(xiàng)目根目錄”)中。 到目前為止,這對(duì)于NodeJS來(lái)說(shuō)不是問(wèn)題。 但是現(xiàn)在,無(wú)論我如何定義處理程序路徑,AWS的Python運(yùn)行時(shí)都找不到它!
改變項(xiàng)目結(jié)構(gòu)將是一場(chǎng)災(zāi)難。 破壞幾乎所有其他事物的風(fēng)險(xiǎn)太大。 一個(gè)更安全的想法是重寫(xiě)可用設(shè)置之一(例如特定于Python的環(huán)境變量),以某種方式將我們的根目錄添加到PYTHONPATH 。
一個(gè)簡(jiǎn)單的技巧
是的,答案就在那里, PYTHONPATH ; 但我不想像這樣覆蓋掉來(lái)自AWS Gods的幫助。
因此,我開(kāi)始深入研究Lambda運(yùn)行時(shí)( 是的,再次 )以查找是否可以使用某些東西:
import os def handler(event, context): print(os.environ)給出:
{ 'PATH' : '/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin' , 'LD_LIBRARY_PATH' : '/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib' , ... 'LAMBDA_TASK_ROOT' : '/var/task' , 'LAMBDA_RUNTIME_DIR' : '/var/runtime' , ... 'AWS_EXECUTION_ENV' : 'AWS_Lambda_python3.6' , '_HANDLER' : 'runner_python36.handler' , ... 'PYTHONPATH' : '/var/runtime' , 'SIGMA_AWS_ACC_ID' : 'nnnnnnnnnnnn' }LAMBDA_RUNTIME_DIR看起來(lái)是一個(gè)很有前途的選擇; 但不幸的是,AWS拒絕了它。 每次部署均失敗,并出現(xiàn)長(zhǎng)期平均錯(cuò)誤:
Lambda was unable to configure your environment variables because the environment variables you have provided contains reserved keys that are currently not supported for modification. this request: LAMBDA_RUNTIME_DIR Reserved keys used in request: LAMBDA_RUNTIME_DIR但是,該調(diào)查顯示出一些重要的信息:Lambda中的PYTHONPATH并不像我想象的那樣復(fù)雜或擁擠。
'PYTHONPATH' : '/var/runtime'顯然,Lambda的內(nèi)部代理商對(duì)此并沒(méi)有太在意。 只需拉出并閱讀/var/runtime/awslambda/bootstrap.py然后自己看看。 😎
ew
因此,我最終重寫(xiě)了PYTHONPATH ,以包含項(xiàng)目的根目錄/var/task/project-name (除了/var/runtime )。 如果您希望在其中顯示其他內(nèi)容,請(qǐng)隨時(shí)修改環(huán)境變量 -但不要把我們的片段留在后面!
從好的方面來(lái)說(shuō),這應(yīng)該意味著我的功能也應(yīng)該在其他平臺(tái)上工作,因?yàn)镻YTHONPATH應(yīng)該是跨平臺(tái)的。
Google Cloud for Python –即將推出!
經(jīng)過(guò)一些調(diào)整,我們也可以使Python在Google Cloud Functions上運(yùn)行。 它已經(jīng)在我們的暫存環(huán)境中; 只要GCP上線(xiàn),它就會(huì)很幸運(yùn)! 🎉
還有很長(zhǎng)的路要走……但是Python已經(jīng)存在并且正在不斷發(fā)展!
您可以在當(dāng)前版本的IDE中編寫(xiě)Python函數(shù)。 只需單擊“ 項(xiàng)目”窗格右上方的加號(hào)(+)按鈕,選擇“ 新建Python函數(shù)文件” (或“ 新建Python文件” ),然后開(kāi)始魔術(shù)吧!
當(dāng)然, 讓我們-世界-知道事情的發(fā)展!
翻譯自: https://www.javacodegeeks.com/2019/09/sigma-ide-now-supports-python-serverless-lambda-functions.html
總結(jié)
以上是生活随笔為你收集整理的Sigma IDE现在支持Python无服务器Lambda函数!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在AWS第1部分中使用Terraform
- 下一篇: 一斤是多少两 一斤是几两