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