streamlit-nightly 1.53.2.dev20260203__py3-none-any.whl → 1.54.1.dev20260204__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/elements/arrow.py +66 -26
- streamlit/elements/lib/built_in_chart_utils.py +1 -1
- streamlit/elements/lib/column_config_utils.py +4 -4
- streamlit/elements/lib/options_selector_utils.py +4 -0
- streamlit/elements/lib/pandas_styler_utils.py +22 -22
- streamlit/elements/widgets/button_group.py +221 -86
- streamlit/elements/widgets/data_editor.py +9 -9
- streamlit/elements/widgets/radio.py +8 -4
- streamlit/hello/dataframe_demo.py +1 -1
- streamlit/proto/ArrowData_pb2.py +5 -3
- streamlit/proto/ArrowData_pb2.pyi +44 -4
- streamlit/proto/ArrowNamedDataSet_pb2.py +4 -4
- streamlit/proto/ArrowNamedDataSet_pb2.pyi +3 -3
- streamlit/proto/ArrowVegaLiteChart_pb2.py +4 -4
- streamlit/proto/ArrowVegaLiteChart_pb2.pyi +3 -3
- streamlit/proto/ButtonGroup_pb2.py +8 -8
- streamlit/proto/ButtonGroup_pb2.pyi +9 -7
- streamlit/proto/Dataframe_pb2.py +31 -0
- streamlit/proto/{Arrow_pb2.pyi → Dataframe_pb2.pyi} +39 -102
- streamlit/proto/Element_pb2.py +5 -4
- streamlit/proto/Element_pb2.pyi +11 -10
- streamlit/proto/Table_pb2.py +29 -0
- streamlit/proto/Table_pb2.pyi +83 -0
- streamlit/static/index.html +1 -1
- streamlit/static/manifest.json +308 -308
- streamlit/static/static/js/{ErrorOutline.esm.C9uHPmIj.js → ErrorOutline.esm.DWBqsdHn.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.D-YPxF3t.js → FileDownload.esm.D5koxJhf.js} +1 -1
- streamlit/static/static/js/{FileHelper.DQSH0zYW.js → FileHelper.kJKftfu4.js} +5 -5
- streamlit/static/static/js/{FormClearHelper.DQoXcOWo.js → FormClearHelper.CyGGPn10.js} +1 -1
- streamlit/static/static/js/{InputInstructions.C7VMyGT7.js → InputInstructions.oezYb8Lm.js} +1 -1
- streamlit/static/static/js/{Particles.BdQSRZde.js → Particles.BIpBmEwi.js} +1 -1
- streamlit/static/static/js/{ProgressBar.DNF_pWKr.js → ProgressBar.BRAS_FJc.js} +1 -1
- streamlit/static/static/js/{StreamlitSyntaxHighlighter.Cys9Bt18.js → StreamlitSyntaxHighlighter.c2qcx-xG.js} +1 -1
- streamlit/static/static/js/{TableChart.esm.B9SMgSK4.js → TableChart.esm.BuemQLVW.js} +1 -1
- streamlit/static/static/js/{Toolbar.BXfC9Z-W.js → Toolbar.mUe2Nmta.js} +1 -1
- streamlit/static/static/js/{WidgetLabelHelpIconInline.gkreC55g.js → WidgetLabelHelpIconInline.if89y2mu.js} +1 -1
- streamlit/static/static/js/{base-input.iB32RS3w.js → base-input.AJ4KxBTh.js} +1 -1
- streamlit/static/static/js/{checkbox.Bqz68SYq.js → checkbox.GY4JoJkM.js} +1 -1
- streamlit/static/static/js/{createDownloadLinkElement.YxVC9Qur.js → createDownloadLinkElement.BWJh90jh.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.sBsdk5Xg.js → data-grid-overlay-editor.C9AINtRf.js} +1 -1
- streamlit/static/static/js/{downloader.Bzxqt3AW.js → downloader.BZY8OE4f.js} +1 -1
- streamlit/static/static/js/{embed.CDzakah3.js → embed.BjO7Ez0y.js} +1 -1
- streamlit/static/static/js/{es6.CxCc4bfn.js → es6.eb5oR8iN.js} +2 -2
- streamlit/static/static/js/{formatNumber.L8T7D36k.js → formatNumber.CCeQsvJQ.js} +1 -1
- streamlit/static/static/js/{iconPosition.C47DkA-1.js → iconPosition.D6eEnKvO.js} +1 -1
- streamlit/static/static/js/{iframeResizer.contentWindow.uEFLXEg3.js → iframeResizer.contentWindow.DTsWJRTo.js} +1 -1
- streamlit/static/static/js/{index.C6dhwBSe.js → index.B6l4FdUv.js} +1 -1
- streamlit/static/static/js/{index.BV_YgIHe.js → index.B7H2q9vo.js} +2 -2
- streamlit/static/static/js/{index.DjgdCvlK.js → index.BDdmrM58.js} +1 -1
- streamlit/static/static/js/{index.CAbQaUvi.js → index.BMbQnwRD.js} +1 -1
- streamlit/static/static/js/{index.CCLteRW6.js → index.BQ5MOzHu.js} +1 -1
- streamlit/static/static/js/{index.CzwJzgQs.js → index.BSgo_bkv.js} +1 -1
- streamlit/static/static/js/{index.B60AZFRh.js → index.BU5M9DsN.js} +1 -1
- streamlit/static/static/js/{index.BVTW_o-a.js → index.BYIxnU34.js} +1 -1
- streamlit/static/static/js/{index.DqhZqWYB.js → index.BZL2hIBz.js} +1 -1
- streamlit/static/static/js/{index.CAbafj7s.js → index.BZVrJlnq.js} +1 -1
- streamlit/static/static/js/{index.Ck0ZkOfK.js → index.Bd7QK46M.js} +1 -1
- streamlit/static/static/js/{index.BzdcdLDK.js → index.BfHA_i34.js} +1 -1
- streamlit/static/static/js/{index.kBgXO7Vv.js → index.Bgry-Ek_.js} +1 -1
- streamlit/static/static/js/{index.aZRhdEuX.js → index.Bi25zaXA.js} +1 -1
- streamlit/static/static/js/{index.QXukCzoh.js → index.Bj3M1xBC.js} +1 -1
- streamlit/static/static/js/{index.Bnwh8oZr.js → index.Bjrvlqx5.js} +6 -6
- streamlit/static/static/js/{index.h2N-W51I.js → index.BnOSeM5K.js} +1 -1
- streamlit/static/static/js/index.BoL6J1jK.js +2 -0
- streamlit/static/static/js/{index.BwvxzVOo.js → index.BoORyxOa.js} +1 -1
- streamlit/static/static/js/{index.Ba8L-ulI.js → index.Bpd7GPeH.js} +1 -1
- streamlit/static/static/js/{index.BG4RxMOI.js → index.BpeJX018.js} +1 -1
- streamlit/static/static/js/index.BriH7JVk.js +2 -0
- streamlit/static/static/js/{index.DO55kRo5.js → index.BwkeObMo.js} +1 -1
- streamlit/static/static/js/{index.C1d2QjTR.js → index.C0o85qmd.js} +1 -1
- streamlit/static/static/js/{index.D7L9gHlE.js → index.C7_wNJTH.js} +1 -1
- streamlit/static/static/js/{index.BwTkGOAy.js → index.CGZP_w9b.js} +1 -1
- streamlit/static/static/js/{index.CjBDVb1a.js → index.CGw52-0-.js} +1 -1
- streamlit/static/static/js/{index.D_cvtSlg.js → index.CUvtJj0a.js} +1 -1
- streamlit/static/static/js/{index.Dtbj_oyb.js → index.Cfx1ZHWt.js} +1 -1
- streamlit/static/static/js/{index.BvHsyiyy.js → index.Chl2kALe.js} +1 -1
- streamlit/static/static/js/index.Crlx_wdE.js +1 -0
- streamlit/static/static/js/{index.B_LfkwqU.js → index.D9A-8ebQ.js} +1 -1
- streamlit/static/static/js/{index.BHyzKS4e.js → index.DBIoNOen.js} +7 -7
- streamlit/static/static/js/{index.DgqmsDCJ.js → index.DMKTAe4F.js} +1 -1
- streamlit/static/static/js/{index.DEKnCsY-.js → index.DNrpqKVt.js} +1 -1
- streamlit/static/static/js/{index.BsrhCS7f.js → index.DSRvF_8e.js} +1 -1
- streamlit/static/static/js/{index.DN_oudQl.js → index.DhB1m_xG.js} +1 -1
- streamlit/static/static/js/{index.XJY9qZ6a.js → index.DiES30vM.js} +1 -1
- streamlit/static/static/js/{index.DHrByikW.js → index.DlJ4Y1xc.js} +1 -1
- streamlit/static/static/js/{index.C5-TpWis.js → index.J61yByUR.js} +1 -1
- streamlit/static/static/js/{index.iUHLeAvv.js → index.JxDTXE8N.js} +1 -1
- streamlit/static/static/js/{index.C1uZrWog.js → index.KGr28TP8.js} +1 -1
- streamlit/static/static/js/{index.BuJPJSD7.js → index.Pgm3rRpH.js} +1 -1
- streamlit/static/static/js/{index.fUsWkW8E.js → index.XzcYOc9I.js} +1 -1
- streamlit/static/static/js/{index.CQ713nQM.js → index.Z_u7ZS4h.js} +1 -1
- streamlit/static/static/js/{index.D-9VyyiA.js → index.hDg7x0Tp.js} +1 -1
- streamlit/static/static/js/{index.D2R3Co5f.js → index.k7p0hmaU.js} +1 -1
- streamlit/static/static/js/{index.Bh5BZaHG.js → index.syoxWolF.js} +1 -1
- streamlit/static/static/js/{index.kEL0HsUR.js → index.xZ651bTg.js} +1 -1
- streamlit/static/static/js/{input.BCHJn1Cw.js → input.C-PwAMG6.js} +1 -1
- streamlit/static/static/js/{main.23ZP6f1E.js → main.fMmyxXOf.js} +1 -1
- streamlit/static/static/js/{memory.D8f8Q4mO.js → memory.BG__eDEj.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.ZWvSpjJ5.js → number-overlay-editor.C0n-91sR.js} +1 -1
- streamlit/static/static/js/{pandasStylerUtils.DlZ2GBs_.js → pandasStylerUtils.BqWaUzvh.js} +1 -1
- streamlit/static/static/js/{sandbox.BH6D3KL9.js → sandbox.CHhc-txg.js} +1 -1
- streamlit/static/static/js/{sprintfjs.CtrdaGLQ.js → sprintfjs.BlFBKfMf.js} +1 -1
- streamlit/static/static/js/{styled-components.iD1HRMLc.js → styled-components.D5uOQqN2.js} +1 -1
- streamlit/static/static/js/{throttle.DR7d9vp_.js → throttle.DlZC3xNA.js} +1 -1
- streamlit/static/static/js/{timepicker.Bd34xjcG.js → timepicker._TfRUaDL.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.BDTTq1c5.js → toConsumableArray.CZW4AmuW.js} +1 -1
- streamlit/static/static/js/uniqueId.CTTDAAaF.js +1 -0
- streamlit/static/static/js/{useBasicWidgetState.BXKaD8DQ.js → useBasicWidgetState.Bx27912z.js} +1 -1
- streamlit/static/static/js/{useIntlLocale.CysOvegI.js → useIntlLocale.DsOvysl7.js} +1 -1
- streamlit/static/static/js/{useTextInputAutoExpand.CVd5Hf2S.js → useTextInputAutoExpand.C9g8px1W.js} +1 -1
- streamlit/static/static/js/{useUpdateUiValue.CIUgfO8X.js → useUpdateUiValue.fF-Cntkp.js} +1 -1
- streamlit/static/static/js/{useWaveformController.CDLqlnLv.js → useWaveformController.C5EtFoJE.js} +1 -1
- streamlit/static/static/js/{withCalculatedWidth.Ce1Zblb2.js → withCalculatedWidth.CcvaXQb0.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.DBm7N75M.js → withFullScreenWrapper.DP61hzLF.js} +1 -1
- streamlit/testing/v1/element_tree.py +20 -15
- streamlit/web/server/routes.py +14 -0
- streamlit/web/server/server.py +4 -0
- {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/RECORD +122 -120
- streamlit/proto/Arrow_pb2.py +0 -34
- streamlit/static/static/js/index.B3zULhHv.js +0 -1
- streamlit/static/static/js/index.BrZtYm2A.js +0 -2
- streamlit/static/static/js/index.CcBYyLfq.js +0 -2
- streamlit/static/static/js/uniqueId.Bd_Iuzvc.js +0 -1
- {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/top_level.txt +0 -0
streamlit/static/static/js/{useWaveformController.CDLqlnLv.js → useWaveformController.C5EtFoJE.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{l as Z,r as i,aR as M,ac as $,aS as O}from"./index.BHyzKS4e.js";async function q(l,e=16e3){if(!l||l.size===0)throw new Error("Invalid or empty blob provided");if(!window.AudioContext)throw new Error("AudioContext not supported in this browser");const o=new AudioContext;try{const n=await l.arrayBuffer(),r=await o.decodeAudioData(n),d=e??r.sampleRate,s=await J(r,d);return K(s,d)}finally{o.close()}}async function J(l,e){const{duration:o,numberOfChannels:n,sampleRate:r}=l,d=Math.ceil(o*e);if(!window.OfflineAudioContext)throw new Error("OfflineAudioContext not supported");const s=new OfflineAudioContext(1,d,e),p=s.createBufferSource();if(p.buffer=l,n>1){const h=s.createChannelSplitter(n),m=s.createChannelMerger(1);p.connect(h);for(let c=0;c<n;c++){const u=s.createGain();u.gain.value=1/n,h.connect(u,c),u.connect(m,0,0)}m.connect(s.destination)}else p.connect(s.destination);p.start(0);try{return await s.startRendering()}catch(h){throw new Error(`Failed to resample audio from ${r}Hz to ${e}Hz: ${h instanceof Error?h.message:String(h)}`)}}function K(l,e){const n=l.length,r=n*2+44,d=new ArrayBuffer(r),s=new DataView(d),p=l.getChannelData(0),h=(c,u)=>{for(let y=0;y<u.length;y++)s.setUint8(c+y,u.charCodeAt(y))};h(0,"RIFF"),s.setUint32(4,r-8,!0),h(8,"WAVE"),h(12,"fmt "),s.setUint32(16,16,!0),s.setUint16(20,1,!0),s.setUint16(22,1,!0),s.setUint32(24,e,!0),s.setUint32(28,e*2,!0),s.setUint16(32,2,!0),s.setUint16(34,16,!0),h(36,"data"),s.setUint32(40,n*2,!0);let m=44;for(let c=0;c<n;c++){const u=Math.max(-1,Math.min(1,p[c]));s.setInt16(m,u*32767,!0),m+=2}return new Blob([d],{type:"audio/wav"})}class W{constructor(){this.wavesurfer=null,this.currentBlobUrl=null,this.events={},this.isPlaying=!1}initialize(e){this.wavesurfer=e,this.setupEventListeners()}setupEventListeners(){this.wavesurfer&&(this.teardownEventListeners(),this.handleTimeUpdate=e=>{this.events.onTimeUpdate?.(e*1e3)},this.handlePause=()=>{this.isPlaying=!1,this.events.onPause?.()},this.handlePlay=()=>{this.isPlaying=!0,this.events.onPlay?.()},this.handleFinish=()=>{this.isPlaying=!1,this.events.onFinish?.()},this.handleReady=()=>{this.events.onReady?.()},this.handleError=e=>{const o=e instanceof Error?e:new Error(String(e));this.events.onError?.(o)},this.wavesurfer.on("timeupdate",this.handleTimeUpdate),this.wavesurfer.on("pause",this.handlePause),this.wavesurfer.on("play",this.handlePlay),this.wavesurfer.on("finish",this.handleFinish),this.wavesurfer.on("ready",this.handleReady),this.wavesurfer.on("error",this.handleError))}setEventHandlers(e){this.events=e}async load(e){if(!this.wavesurfer)throw new Error("WaveSurfer not initialized");this.cleanupPreviousUrl();let o,n=null;try{if(e instanceof Blob)n=URL.createObjectURL(e),o=n;else if(e instanceof ArrayBuffer){const r=new Blob([e]);n=URL.createObjectURL(r),o=n}else o=e;this.currentBlobUrl=n,await this.wavesurfer.load(o)}catch(r){throw this.cleanupPreviousUrl(),r}}async play(){if(!this.wavesurfer)throw new Error("WaveSurfer not initialized");await this.wavesurfer.play()}pause(){this.wavesurfer&&this.wavesurfer.pause()}getDuration(){return this.wavesurfer?this.wavesurfer.getDuration()*1e3:0}getCurrentTime(){return this.wavesurfer?this.wavesurfer.getCurrentTime()*1e3:0}getIsPlaying(){return this.isPlaying}seekToStart(){this.wavesurfer&&this.wavesurfer.seekTo(0)}cleanupPreviousUrl(){this.currentBlobUrl&&(URL.revokeObjectURL(this.currentBlobUrl),this.currentBlobUrl=null)}destroy(){this.pause(),this.cleanupPreviousUrl(),this.wavesurfer&&(this.teardownEventListeners(),this.wavesurfer.empty(),this.wavesurfer=null),this.events={},this.isPlaying=!1,this.handleTimeUpdate=void 0,this.handlePause=void 0,this.handlePlay=void 0,this.handleFinish=void 0,this.handleReady=void 0,this.handleError=void 0}teardownEventListeners(){this.wavesurfer&&(this.handleTimeUpdate&&(this.wavesurfer.un("timeupdate",this.handleTimeUpdate),this.handleTimeUpdate=void 0),this.handlePause&&(this.wavesurfer.un("pause",this.handlePause),this.handlePause=void 0),this.handlePlay&&(this.wavesurfer.un("play",this.handlePlay),this.handlePlay=void 0),this.handleFinish&&(this.wavesurfer.un("finish",this.handleFinish),this.handleFinish=void 0),this.handleReady&&(this.wavesurfer.un("ready",this.handleReady),this.handleReady=void 0),this.handleError&&(this.wavesurfer.un("error",this.handleError),this.handleError=void 0))}}function I(l){return l.name==="NotAllowedError"||l.name==="PermissionDeniedError"||l.message?.toLowerCase().includes("permission denied")}class Q{constructor(e={}){this.wavesurfer=null,this.recordPlugin=null,this.isRecording=!1,this.recordEndResolve=null,this.recordEndReject=null,this.events={},this.options=e}initialize(e,o){this.wavesurfer=e;try{const n={renderRecordedAudio:!1,mimeType:"audio/webm"};this.recordPlugin=e.registerPlugin(o.create(n)),this.setupEventListeners()}catch(n){const r=n instanceof Error?n:new Error(String(n));throw I(r)?(this.events.onPermissionDenied?.(),new Error("Microphone permission denied")):(this.events.onError?.(r),r)}}setupEventListeners(){this.recordPlugin&&(this.recordPlugin.on("record-start",()=>{this.isRecording=!0,this.events.onRecordStart?.()}),this.recordPlugin.on("record-end",e=>{this.isRecording=!1,this.events.onRecordEnd?.(e),this.recordEndResolve&&e&&e.size>0?(this.recordEndResolve(e),this.recordEndResolve=null,this.recordEndReject=null):this.recordEndReject?(this.recordEndReject(new Error("Invalid or empty recording")),this.recordEndResolve=null,this.recordEndReject=null):(this.recordEndResolve=null,this.recordEndReject=null)}),this.recordPlugin.on("record-progress",e=>{this.events.onRecordProgress?.(e)}))}setEventHandlers(e){this.events=e}async startRecording(){if(!this.recordPlugin)throw new Error("Record plugin not initialized");if(this.isRecording)return;const e=typeof this.options.sampleRate=="number"?this.options.sampleRate:void 0,o={};e!==void 0&&(o.sampleRate={ideal:e}),await this.startRecordingWithConstraints(o,e!==void 0)}async startRecordingWithConstraints(e,o){if(!this.recordPlugin)throw new Error("Record plugin not initialized");try{const n=Object.keys(e).length?e:void 0;await this.recordPlugin.startRecording(n)}catch(n){const r=n instanceof Error?n:new Error(String(n));if(I(r))throw this.events.onPermissionDenied?.(),new Error("Microphone permission denied");if(o&&(r.name==="OverconstrainedError"||r.name==="NotReadableError")){this.options.sampleRate=void 0,await this.startRecordingWithConstraints({},!1);return}throw this.events.onError?.(r),r}}async stopRecording(){if(!this.recordPlugin||!this.isRecording)throw new Error("Not currently recording");try{return await new Promise((e,o)=>{this.recordEndResolve=e,this.recordEndReject=o,this.recordPlugin?.stopRecording()})}catch(e){const o=e instanceof Error?e:new Error(String(e));throw this.events.onError?.(o),o}}cancelRecording(){this.recordPlugin&&this.isRecording&&(this.recordPlugin.stopRecording(),this.isRecording=!1,this.recordEndResolve=null,this.recordEndReject=null)}destroy(){this.cancelRecording(),this.recordPlugin&&(this.recordPlugin.destroy(),this.recordPlugin=null),this.wavesurfer=null,this.events={}}}const X=4,Y=4,ee=8,re=0,te=16e3;function se({containerRef:l,sampleRate:e,events:o,waveformPadding:n=0}){const r=Z(),[d,s]=i.useState("idle"),[p,h]=i.useState(null),[m,c]=i.useState(!1),u=i.useRef(null),y=i.useRef(null),a=i.useRef(null),f=i.useRef(o),U=i.useRef(!1),D=i.useRef(!1),E=i.useRef(new Set),P=i.useRef(!1),b=e===void 0?te:e,A=i.useCallback(()=>{E.current.clear(),c(!1),y.current&&(y.current.destroy(),y.current=null),a.current&&(a.current.destroy(),a.current=null),u.current&&(u.current.destroy(),u.current=null),U.current=!1,P.current=!1,s("idle"),h(null)},[]),x=i.useCallback(()=>{const t=Array.from(E.current);E.current.clear(),t.forEach(w=>{w.resolve()})},[]),_=i.useCallback(t=>{c(!1);const w=Array.from(E.current);E.current.clear(),w.forEach(v=>{v.reject(t)})},[]),T=i.useCallback(t=>{const w={onPlay:()=>{c(!0),f.current.onPlaybackPlay?.()},onPause:()=>{c(!1),f.current.onPlaybackPause?.()},onFinish:()=>{c(!1),f.current.onPlaybackFinish?.()},onReady:()=>{x()},onError:v=>{c(!1),_(v),f.current.onError?.(v)}};t.setEventHandlers(w)},[x,_]);i.useEffect(()=>{f.current=o,a.current&&T(a.current)},[o,T]);const S=i.useCallback(async()=>{if(!(U.current||D.current||!l.current)){D.current=!0;try{const[t,w]=await Promise.all([M(()=>import("./wavesurfer.esm.D1Sty35j.js"),[],import.meta.url),M(()=>import("./record.DytFsBUt.js"),[],import.meta.url)]),v=t.default,B=w.default,k=v.create({container:l.current,waveColor:r.colors.primary,progressColor:r.colors.bodyText,height:n>0?$(r.sizes.largestElementHeight)-2*n:"auto",barWidth:X,barGap:Y,barRadius:ee,cursorWidth:re,interact:!0});u.current=k,P.current=!1;const C=new Q({sampleRate:b});C.initialize(k,B),C.setEventHandlers({onRecordProgress:R=>{f.current.onProgressMs?.(R)},onPermissionDenied:()=>{f.current.onPermissionDenied(),s("idle")},onError:R=>{f.current.onError(R),s("idle")}}),y.current=C;const g=new W;g.initialize(k),a.current=g,T(g),U.current=!0}catch(t){const w=t instanceof Error?t:new Error(String(t));f.current.onError?.(w)}finally{D.current=!1}}},[l,r,b,T,n]);i.useEffect(()=>(S(),()=>{A()}),[A,S]),i.useEffect(()=>{const t=u.current;if(t){if(d==="recording"){t.setOptions({waveColor:r.colors.primary,progressColor:r.colors.primary});return}if(P.current){t.setOptions({interact:!0,waveColor:O(r.colors.fadedText40,r.colors.secondaryBg),progressColor:r.colors.bodyText});return}t.setOptions({waveColor:r.colors.primary,progressColor:r.colors.bodyText})}},[d,r.colors.bodyText,r.colors.fadedText40,r.colors.primary,r.colors.secondaryBg]);const F=i.useCallback(async()=>{if(d!=="recording"){if(U.current||await S(),!y.current)throw new Error("Record backend not initialized");u.current&&u.current.setOptions({waveColor:r.colors.primary,progressColor:r.colors.primary}),P.current=!1,await y.current.startRecording(),s("recording"),h(null),c(!1),f.current.onRecordStart?.()}},[d,S,r.colors.primary]),L=i.useCallback(()=>{a.current&&u.current&&(a.current.destroy(),a.current=new W,a.current.initialize(u.current),E.current.clear(),c(!1),T(a.current)),P.current=!1},[T]),z=i.useCallback(()=>{a.current?.seekToStart(),c(!1),P.current=!0,u.current&&u.current.setOptions({interact:!0,waveColor:O(r.colors.fadedText40,r.colors.secondaryBg),progressColor:r.colors.bodyText})},[r.colors.bodyText,r.colors.fadedText40,r.colors.secondaryBg]),H=i.useCallback(async()=>{if(d!=="recording")throw new Error("Not currently recording");if(!y.current||!a.current)throw new Error("Backends not initialized");try{const t=await y.current.stopRecording();h(t),await new Promise((k,C)=>{if(!a.current){C(new Error("Player not initialized"));return}const g={resolve:()=>{E.current.delete(g),k()},reject:R=>{E.current.delete(g),C(R)}};E.current.add(g),a.current.load(t).catch(R=>{E.current.delete(g),C(R instanceof Error?R:new Error(String(R)))})}),s("idle"),c(!1),z();const v={durationMs:a.current?.getDuration()??0,sampleRate:typeof b=="number"?b:null,mimeType:t.type||"audio/webm",size:t.size},B={blob:t,meta:v};return f.current.onRecordReady?.(t),B}catch(t){const w=t instanceof Error?t:new Error(String(t));return c(!1),s("idle"),f.current.onError(w),{blob:new Blob,meta:{durationMs:0,sampleRate:null,mimeType:"audio/webm",size:0}}}},[d,z,b]),j=i.useCallback(async t=>{const w=t??p;if(!w){const v=new Error("No recorded audio to approve");f.current.onError(v);return}try{const v=await q(w,b);await f.current.onApprove?.(v),h(null),s("idle")}catch(v){const B=v instanceof Error?v:new Error(String(v));f.current.onError(B)}},[p,b]),N=i.useCallback(()=>{d==="recording"&&y.current?.cancelRecording(),L(),h(null),s("idle"),c(!1),P.current=!1,f.current.onCancel?.()},[d,L]),V=i.useMemo(()=>({isPlaying:()=>a.current?.getIsPlaying()??!1,play:async()=>{if(!a.current)throw new Error("Player not initialized");await a.current.play()},pause:()=>{a.current?.pause()},load:async t=>{if(U.current||await S(),!a.current)throw new Error("Player not initialized");await a.current.load(t),z()},getCurrentTimeMs:()=>a.current?.getCurrentTime()??0,getDurationMs:()=>a.current?.getDuration()??0}),[z,S]),G=i.useCallback(t=>{f.current=t},[]);return i.useEffect(()=>()=>{A()},[A]),{state:d,isPlaybackPlaying:m,mountRef:l,start:F,stop:H,approve:j,cancel:N,destroy:A,playback:V,setEventHandlers:G}}export{se as u};
|
|
1
|
+
import{l as Z,r as i,aR as M,ac as $,aS as O}from"./index.DBIoNOen.js";async function q(l,e=16e3){if(!l||l.size===0)throw new Error("Invalid or empty blob provided");if(!window.AudioContext)throw new Error("AudioContext not supported in this browser");const o=new AudioContext;try{const n=await l.arrayBuffer(),r=await o.decodeAudioData(n),d=e??r.sampleRate,s=await J(r,d);return K(s,d)}finally{o.close()}}async function J(l,e){const{duration:o,numberOfChannels:n,sampleRate:r}=l,d=Math.ceil(o*e);if(!window.OfflineAudioContext)throw new Error("OfflineAudioContext not supported");const s=new OfflineAudioContext(1,d,e),p=s.createBufferSource();if(p.buffer=l,n>1){const h=s.createChannelSplitter(n),m=s.createChannelMerger(1);p.connect(h);for(let c=0;c<n;c++){const u=s.createGain();u.gain.value=1/n,h.connect(u,c),u.connect(m,0,0)}m.connect(s.destination)}else p.connect(s.destination);p.start(0);try{return await s.startRendering()}catch(h){throw new Error(`Failed to resample audio from ${r}Hz to ${e}Hz: ${h instanceof Error?h.message:String(h)}`)}}function K(l,e){const n=l.length,r=n*2+44,d=new ArrayBuffer(r),s=new DataView(d),p=l.getChannelData(0),h=(c,u)=>{for(let y=0;y<u.length;y++)s.setUint8(c+y,u.charCodeAt(y))};h(0,"RIFF"),s.setUint32(4,r-8,!0),h(8,"WAVE"),h(12,"fmt "),s.setUint32(16,16,!0),s.setUint16(20,1,!0),s.setUint16(22,1,!0),s.setUint32(24,e,!0),s.setUint32(28,e*2,!0),s.setUint16(32,2,!0),s.setUint16(34,16,!0),h(36,"data"),s.setUint32(40,n*2,!0);let m=44;for(let c=0;c<n;c++){const u=Math.max(-1,Math.min(1,p[c]));s.setInt16(m,u*32767,!0),m+=2}return new Blob([d],{type:"audio/wav"})}class W{constructor(){this.wavesurfer=null,this.currentBlobUrl=null,this.events={},this.isPlaying=!1}initialize(e){this.wavesurfer=e,this.setupEventListeners()}setupEventListeners(){this.wavesurfer&&(this.teardownEventListeners(),this.handleTimeUpdate=e=>{this.events.onTimeUpdate?.(e*1e3)},this.handlePause=()=>{this.isPlaying=!1,this.events.onPause?.()},this.handlePlay=()=>{this.isPlaying=!0,this.events.onPlay?.()},this.handleFinish=()=>{this.isPlaying=!1,this.events.onFinish?.()},this.handleReady=()=>{this.events.onReady?.()},this.handleError=e=>{const o=e instanceof Error?e:new Error(String(e));this.events.onError?.(o)},this.wavesurfer.on("timeupdate",this.handleTimeUpdate),this.wavesurfer.on("pause",this.handlePause),this.wavesurfer.on("play",this.handlePlay),this.wavesurfer.on("finish",this.handleFinish),this.wavesurfer.on("ready",this.handleReady),this.wavesurfer.on("error",this.handleError))}setEventHandlers(e){this.events=e}async load(e){if(!this.wavesurfer)throw new Error("WaveSurfer not initialized");this.cleanupPreviousUrl();let o,n=null;try{if(e instanceof Blob)n=URL.createObjectURL(e),o=n;else if(e instanceof ArrayBuffer){const r=new Blob([e]);n=URL.createObjectURL(r),o=n}else o=e;this.currentBlobUrl=n,await this.wavesurfer.load(o)}catch(r){throw this.cleanupPreviousUrl(),r}}async play(){if(!this.wavesurfer)throw new Error("WaveSurfer not initialized");await this.wavesurfer.play()}pause(){this.wavesurfer&&this.wavesurfer.pause()}getDuration(){return this.wavesurfer?this.wavesurfer.getDuration()*1e3:0}getCurrentTime(){return this.wavesurfer?this.wavesurfer.getCurrentTime()*1e3:0}getIsPlaying(){return this.isPlaying}seekToStart(){this.wavesurfer&&this.wavesurfer.seekTo(0)}cleanupPreviousUrl(){this.currentBlobUrl&&(URL.revokeObjectURL(this.currentBlobUrl),this.currentBlobUrl=null)}destroy(){this.pause(),this.cleanupPreviousUrl(),this.wavesurfer&&(this.teardownEventListeners(),this.wavesurfer.empty(),this.wavesurfer=null),this.events={},this.isPlaying=!1,this.handleTimeUpdate=void 0,this.handlePause=void 0,this.handlePlay=void 0,this.handleFinish=void 0,this.handleReady=void 0,this.handleError=void 0}teardownEventListeners(){this.wavesurfer&&(this.handleTimeUpdate&&(this.wavesurfer.un("timeupdate",this.handleTimeUpdate),this.handleTimeUpdate=void 0),this.handlePause&&(this.wavesurfer.un("pause",this.handlePause),this.handlePause=void 0),this.handlePlay&&(this.wavesurfer.un("play",this.handlePlay),this.handlePlay=void 0),this.handleFinish&&(this.wavesurfer.un("finish",this.handleFinish),this.handleFinish=void 0),this.handleReady&&(this.wavesurfer.un("ready",this.handleReady),this.handleReady=void 0),this.handleError&&(this.wavesurfer.un("error",this.handleError),this.handleError=void 0))}}function I(l){return l.name==="NotAllowedError"||l.name==="PermissionDeniedError"||l.message?.toLowerCase().includes("permission denied")}class Q{constructor(e={}){this.wavesurfer=null,this.recordPlugin=null,this.isRecording=!1,this.recordEndResolve=null,this.recordEndReject=null,this.events={},this.options=e}initialize(e,o){this.wavesurfer=e;try{const n={renderRecordedAudio:!1,mimeType:"audio/webm"};this.recordPlugin=e.registerPlugin(o.create(n)),this.setupEventListeners()}catch(n){const r=n instanceof Error?n:new Error(String(n));throw I(r)?(this.events.onPermissionDenied?.(),new Error("Microphone permission denied")):(this.events.onError?.(r),r)}}setupEventListeners(){this.recordPlugin&&(this.recordPlugin.on("record-start",()=>{this.isRecording=!0,this.events.onRecordStart?.()}),this.recordPlugin.on("record-end",e=>{this.isRecording=!1,this.events.onRecordEnd?.(e),this.recordEndResolve&&e&&e.size>0?(this.recordEndResolve(e),this.recordEndResolve=null,this.recordEndReject=null):this.recordEndReject?(this.recordEndReject(new Error("Invalid or empty recording")),this.recordEndResolve=null,this.recordEndReject=null):(this.recordEndResolve=null,this.recordEndReject=null)}),this.recordPlugin.on("record-progress",e=>{this.events.onRecordProgress?.(e)}))}setEventHandlers(e){this.events=e}async startRecording(){if(!this.recordPlugin)throw new Error("Record plugin not initialized");if(this.isRecording)return;const e=typeof this.options.sampleRate=="number"?this.options.sampleRate:void 0,o={};e!==void 0&&(o.sampleRate={ideal:e}),await this.startRecordingWithConstraints(o,e!==void 0)}async startRecordingWithConstraints(e,o){if(!this.recordPlugin)throw new Error("Record plugin not initialized");try{const n=Object.keys(e).length?e:void 0;await this.recordPlugin.startRecording(n)}catch(n){const r=n instanceof Error?n:new Error(String(n));if(I(r))throw this.events.onPermissionDenied?.(),new Error("Microphone permission denied");if(o&&(r.name==="OverconstrainedError"||r.name==="NotReadableError")){this.options.sampleRate=void 0,await this.startRecordingWithConstraints({},!1);return}throw this.events.onError?.(r),r}}async stopRecording(){if(!this.recordPlugin||!this.isRecording)throw new Error("Not currently recording");try{return await new Promise((e,o)=>{this.recordEndResolve=e,this.recordEndReject=o,this.recordPlugin?.stopRecording()})}catch(e){const o=e instanceof Error?e:new Error(String(e));throw this.events.onError?.(o),o}}cancelRecording(){this.recordPlugin&&this.isRecording&&(this.recordPlugin.stopRecording(),this.isRecording=!1,this.recordEndResolve=null,this.recordEndReject=null)}destroy(){this.cancelRecording(),this.recordPlugin&&(this.recordPlugin.destroy(),this.recordPlugin=null),this.wavesurfer=null,this.events={}}}const X=4,Y=4,ee=8,re=0,te=16e3;function se({containerRef:l,sampleRate:e,events:o,waveformPadding:n=0}){const r=Z(),[d,s]=i.useState("idle"),[p,h]=i.useState(null),[m,c]=i.useState(!1),u=i.useRef(null),y=i.useRef(null),a=i.useRef(null),f=i.useRef(o),U=i.useRef(!1),D=i.useRef(!1),E=i.useRef(new Set),P=i.useRef(!1),b=e===void 0?te:e,A=i.useCallback(()=>{E.current.clear(),c(!1),y.current&&(y.current.destroy(),y.current=null),a.current&&(a.current.destroy(),a.current=null),u.current&&(u.current.destroy(),u.current=null),U.current=!1,P.current=!1,s("idle"),h(null)},[]),x=i.useCallback(()=>{const t=Array.from(E.current);E.current.clear(),t.forEach(w=>{w.resolve()})},[]),_=i.useCallback(t=>{c(!1);const w=Array.from(E.current);E.current.clear(),w.forEach(v=>{v.reject(t)})},[]),T=i.useCallback(t=>{const w={onPlay:()=>{c(!0),f.current.onPlaybackPlay?.()},onPause:()=>{c(!1),f.current.onPlaybackPause?.()},onFinish:()=>{c(!1),f.current.onPlaybackFinish?.()},onReady:()=>{x()},onError:v=>{c(!1),_(v),f.current.onError?.(v)}};t.setEventHandlers(w)},[x,_]);i.useEffect(()=>{f.current=o,a.current&&T(a.current)},[o,T]);const S=i.useCallback(async()=>{if(!(U.current||D.current||!l.current)){D.current=!0;try{const[t,w]=await Promise.all([M(()=>import("./wavesurfer.esm.D1Sty35j.js"),[],import.meta.url),M(()=>import("./record.DytFsBUt.js"),[],import.meta.url)]),v=t.default,B=w.default,k=v.create({container:l.current,waveColor:r.colors.primary,progressColor:r.colors.bodyText,height:n>0?$(r.sizes.largestElementHeight)-2*n:"auto",barWidth:X,barGap:Y,barRadius:ee,cursorWidth:re,interact:!0});u.current=k,P.current=!1;const C=new Q({sampleRate:b});C.initialize(k,B),C.setEventHandlers({onRecordProgress:R=>{f.current.onProgressMs?.(R)},onPermissionDenied:()=>{f.current.onPermissionDenied(),s("idle")},onError:R=>{f.current.onError(R),s("idle")}}),y.current=C;const g=new W;g.initialize(k),a.current=g,T(g),U.current=!0}catch(t){const w=t instanceof Error?t:new Error(String(t));f.current.onError?.(w)}finally{D.current=!1}}},[l,r,b,T,n]);i.useEffect(()=>(S(),()=>{A()}),[A,S]),i.useEffect(()=>{const t=u.current;if(t){if(d==="recording"){t.setOptions({waveColor:r.colors.primary,progressColor:r.colors.primary});return}if(P.current){t.setOptions({interact:!0,waveColor:O(r.colors.fadedText40,r.colors.secondaryBg),progressColor:r.colors.bodyText});return}t.setOptions({waveColor:r.colors.primary,progressColor:r.colors.bodyText})}},[d,r.colors.bodyText,r.colors.fadedText40,r.colors.primary,r.colors.secondaryBg]);const F=i.useCallback(async()=>{if(d!=="recording"){if(U.current||await S(),!y.current)throw new Error("Record backend not initialized");u.current&&u.current.setOptions({waveColor:r.colors.primary,progressColor:r.colors.primary}),P.current=!1,await y.current.startRecording(),s("recording"),h(null),c(!1),f.current.onRecordStart?.()}},[d,S,r.colors.primary]),L=i.useCallback(()=>{a.current&&u.current&&(a.current.destroy(),a.current=new W,a.current.initialize(u.current),E.current.clear(),c(!1),T(a.current)),P.current=!1},[T]),z=i.useCallback(()=>{a.current?.seekToStart(),c(!1),P.current=!0,u.current&&u.current.setOptions({interact:!0,waveColor:O(r.colors.fadedText40,r.colors.secondaryBg),progressColor:r.colors.bodyText})},[r.colors.bodyText,r.colors.fadedText40,r.colors.secondaryBg]),H=i.useCallback(async()=>{if(d!=="recording")throw new Error("Not currently recording");if(!y.current||!a.current)throw new Error("Backends not initialized");try{const t=await y.current.stopRecording();h(t),await new Promise((k,C)=>{if(!a.current){C(new Error("Player not initialized"));return}const g={resolve:()=>{E.current.delete(g),k()},reject:R=>{E.current.delete(g),C(R)}};E.current.add(g),a.current.load(t).catch(R=>{E.current.delete(g),C(R instanceof Error?R:new Error(String(R)))})}),s("idle"),c(!1),z();const v={durationMs:a.current?.getDuration()??0,sampleRate:typeof b=="number"?b:null,mimeType:t.type||"audio/webm",size:t.size},B={blob:t,meta:v};return f.current.onRecordReady?.(t),B}catch(t){const w=t instanceof Error?t:new Error(String(t));return c(!1),s("idle"),f.current.onError(w),{blob:new Blob,meta:{durationMs:0,sampleRate:null,mimeType:"audio/webm",size:0}}}},[d,z,b]),j=i.useCallback(async t=>{const w=t??p;if(!w){const v=new Error("No recorded audio to approve");f.current.onError(v);return}try{const v=await q(w,b);await f.current.onApprove?.(v),h(null),s("idle")}catch(v){const B=v instanceof Error?v:new Error(String(v));f.current.onError(B)}},[p,b]),N=i.useCallback(()=>{d==="recording"&&y.current?.cancelRecording(),L(),h(null),s("idle"),c(!1),P.current=!1,f.current.onCancel?.()},[d,L]),V=i.useMemo(()=>({isPlaying:()=>a.current?.getIsPlaying()??!1,play:async()=>{if(!a.current)throw new Error("Player not initialized");await a.current.play()},pause:()=>{a.current?.pause()},load:async t=>{if(U.current||await S(),!a.current)throw new Error("Player not initialized");await a.current.load(t),z()},getCurrentTimeMs:()=>a.current?.getCurrentTime()??0,getDurationMs:()=>a.current?.getDuration()??0}),[z,S]),G=i.useCallback(t=>{f.current=t},[]);return i.useEffect(()=>()=>{A()},[A]),{state:d,isPlaybackPlaying:m,mountRef:l,start:F,stop:H,approve:j,cancel:N,destroy:A,playback:V,setEventHandlers:G}}export{se as u};
|
streamlit/static/static/js/{withCalculatedWidth.Ce1Zblb2.js → withCalculatedWidth.CcvaXQb0.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{h as l,k as h,j as s,d as n}from"./index.
|
|
1
|
+
import{h as l,k as h,j as s,d as n}from"./index.DBIoNOen.js";const o=t=>{const a=e=>{const{width:i,elementRef:c}=h();return s(n,{ref:c,children:s(t,{...e,width:i})})};return a.displayName=`withCalculatedWidth(${t.displayName||t.name})`,l(a,t)};export{o as w};
|
streamlit/static/static/js/{withFullScreenWrapper.DBm7N75M.js → withFullScreenWrapper.DP61hzLF.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as n,z as m,be as p,bf as h,l as x,k as y,j as i,h as g}from"./index.
|
|
1
|
+
import{r as n,z as m,be as p,bf as h,l as x,k as y,j as i,h as g}from"./index.DBIoNOen.js";const f=n.createContext(null);f.displayName="ElementFullscreenContext";const w=m("div",{target:"e5bcvgj0"})(({theme:e,isExpanded:t})=>({width:"100%",height:"100%",...t?{position:"fixed",top:0,left:0,bottom:0,right:0,background:e.colors.bgColor,zIndex:e.zIndices.fullscreenWrapper,padding:e.spacing.md,paddingTop:e.sizes.fullScreenHeaderHeight,overflow:"auto",display:"flex",alignItems:"center",justifyContent:"center"}:{}})),C=()=>{const{setFullScreen:e}=n.useContext(p),[t,s]=n.useState(!1),{fullHeight:a,fullWidth:c}=h(),l=n.useCallback(r=>{s(r),e(r)},[e]),u=n.useCallback(()=>{document.body.style.overflow="hidden",l(!0)},[l]),o=n.useCallback(()=>{document.body.style.overflow="unset",l(!1)},[l]),d=n.useCallback(r=>{r.keyCode===27&&t&&o()},[o,t]);return n.useEffect(()=>(document.addEventListener("keydown",d,!1),()=>{document.removeEventListener("keydown",d,!1)}),[d]),n.useMemo(()=>({expanded:t,zoomIn:u,zoomOut:o,fullHeight:a,fullWidth:c}),[t,u,o,a,c])},b=({children:e})=>{const t=x(),{expanded:s,fullHeight:a,fullWidth:c,zoomIn:l,zoomOut:u}=C(),{width:o,elementRef:d}=y(),r=n.useMemo(()=>({width:s?c:o,height:s?a:void 0,expanded:s,expand:l,collapse:u}),[s,a,c,o,l,u]);return i(f.Provider,{value:r,children:i(w,{ref:d,isExpanded:s,"data-testid":"stFullScreenFrame",theme:t,children:e})})};function S(e){const t=s=>i(b,{children:i(e,{...s})});return t.displayName=`withFullScreenWrapper(${e.displayName||e.name})`,g(t,e)}export{f as E,S as w};
|
|
@@ -57,13 +57,13 @@ from streamlit.runtime.state.common import TESTING_KEY, user_key_from_element_id
|
|
|
57
57
|
if TYPE_CHECKING:
|
|
58
58
|
from pandas import DataFrame as PandasDataframe
|
|
59
59
|
|
|
60
|
-
from streamlit.proto.Arrow_pb2 import Arrow as ArrowProto
|
|
61
60
|
from streamlit.proto.Block_pb2 import Block as BlockProto
|
|
62
61
|
from streamlit.proto.Button_pb2 import Button as ButtonProto
|
|
63
62
|
from streamlit.proto.ButtonGroup_pb2 import ButtonGroup as ButtonGroupProto
|
|
64
63
|
from streamlit.proto.ChatInput_pb2 import ChatInput as ChatInputProto
|
|
65
64
|
from streamlit.proto.Code_pb2 import Code as CodeProto
|
|
66
65
|
from streamlit.proto.ColorPicker_pb2 import ColorPicker as ColorPickerProto
|
|
66
|
+
from streamlit.proto.Dataframe_pb2 import Dataframe as DataframeProto
|
|
67
67
|
from streamlit.proto.DateInput_pb2 import DateInput as DateInputProto
|
|
68
68
|
from streamlit.proto.DateTimeInput_pb2 import DateTimeInput as DateTimeInputProto
|
|
69
69
|
from streamlit.proto.Element_pb2 import Element as ElementProto
|
|
@@ -78,6 +78,7 @@ if TYPE_CHECKING:
|
|
|
78
78
|
from streamlit.proto.Radio_pb2 import Radio as RadioProto
|
|
79
79
|
from streamlit.proto.Selectbox_pb2 import Selectbox as SelectboxProto
|
|
80
80
|
from streamlit.proto.Space_pb2 import Space as SpaceProto
|
|
81
|
+
from streamlit.proto.Table_pb2 import Table as TableProto
|
|
81
82
|
from streamlit.proto.Text_pb2 import Text as TextProto
|
|
82
83
|
from streamlit.proto.TextArea_pb2 import TextArea as TextAreaProto
|
|
83
84
|
from streamlit.proto.TextInput_pb2 import TextInput as TextInputProto
|
|
@@ -495,17 +496,19 @@ class ColorPicker(Widget):
|
|
|
495
496
|
|
|
496
497
|
@dataclass(repr=False)
|
|
497
498
|
class Dataframe(Element):
|
|
498
|
-
proto:
|
|
499
|
+
proto: DataframeProto = field(repr=False)
|
|
499
500
|
|
|
500
|
-
def __init__(self, proto:
|
|
501
|
+
def __init__(self, proto: DataframeProto, root: ElementTree) -> None:
|
|
501
502
|
self.key = None
|
|
502
503
|
self.proto = proto
|
|
503
504
|
self.root = root
|
|
504
|
-
self.type = "
|
|
505
|
+
self.type = "dataframe"
|
|
505
506
|
|
|
506
507
|
@property
|
|
507
508
|
def value(self) -> PandasDataframe:
|
|
508
|
-
return dataframe_util.convert_arrow_bytes_to_pandas_df(
|
|
509
|
+
return dataframe_util.convert_arrow_bytes_to_pandas_df(
|
|
510
|
+
self.proto.arrow_data.data
|
|
511
|
+
)
|
|
509
512
|
|
|
510
513
|
|
|
511
514
|
SingleDateValue: TypeAlias = date | datetime
|
|
@@ -1262,17 +1265,19 @@ class Slider(Widget, Generic[SliderValueT]):
|
|
|
1262
1265
|
|
|
1263
1266
|
@dataclass(repr=False)
|
|
1264
1267
|
class Table(Element):
|
|
1265
|
-
proto:
|
|
1268
|
+
proto: TableProto = field(repr=False)
|
|
1266
1269
|
|
|
1267
|
-
def __init__(self, proto:
|
|
1270
|
+
def __init__(self, proto: TableProto, root: ElementTree) -> None:
|
|
1268
1271
|
self.key = None
|
|
1269
1272
|
self.proto = proto
|
|
1270
1273
|
self.root = root
|
|
1271
|
-
self.type = "
|
|
1274
|
+
self.type = "table"
|
|
1272
1275
|
|
|
1273
1276
|
@property
|
|
1274
1277
|
def value(self) -> PandasDataframe:
|
|
1275
|
-
return dataframe_util.convert_arrow_bytes_to_pandas_df(
|
|
1278
|
+
return dataframe_util.convert_arrow_bytes_to_pandas_df(
|
|
1279
|
+
self.proto.arrow_data.data
|
|
1280
|
+
)
|
|
1276
1281
|
|
|
1277
1282
|
|
|
1278
1283
|
@dataclass(repr=False)
|
|
@@ -1654,7 +1659,7 @@ class Block:
|
|
|
1654
1659
|
|
|
1655
1660
|
@property
|
|
1656
1661
|
def dataframe(self) -> ElementList[Dataframe]:
|
|
1657
|
-
return ElementList(self.get("
|
|
1662
|
+
return ElementList(self.get("dataframe")) # type: ignore
|
|
1658
1663
|
|
|
1659
1664
|
@property
|
|
1660
1665
|
def date_input(self) -> WidgetList[DateInput]:
|
|
@@ -1746,7 +1751,7 @@ class Block:
|
|
|
1746
1751
|
|
|
1747
1752
|
@property
|
|
1748
1753
|
def table(self) -> ElementList[Table]:
|
|
1749
|
-
return ElementList(self.get("
|
|
1754
|
+
return ElementList(self.get("table")) # type: ignore
|
|
1750
1755
|
|
|
1751
1756
|
@property
|
|
1752
1757
|
def tabs(self) -> Sequence[Tab]:
|
|
@@ -2112,10 +2117,10 @@ def parse_tree_from_messages(messages: list[ForwardMsg]) -> ElementTree:
|
|
|
2112
2117
|
raise ValueError(
|
|
2113
2118
|
f"Unknown alert type with format {elt.alert.format}"
|
|
2114
2119
|
)
|
|
2115
|
-
elif ty == "
|
|
2116
|
-
new_node = Dataframe(elt.
|
|
2117
|
-
elif ty == "
|
|
2118
|
-
new_node = Table(elt.
|
|
2120
|
+
elif ty == "dataframe":
|
|
2121
|
+
new_node = Dataframe(elt.dataframe, root=root)
|
|
2122
|
+
elif ty == "table":
|
|
2123
|
+
new_node = Table(elt.table, root=root)
|
|
2119
2124
|
elif ty == "button":
|
|
2120
2125
|
new_node = Button(elt.button, root=root)
|
|
2121
2126
|
elif ty == "button_group":
|
streamlit/web/server/routes.py
CHANGED
|
@@ -121,6 +121,20 @@ class AddSlashHandler(tornado.web.RequestHandler):
|
|
|
121
121
|
pass
|
|
122
122
|
|
|
123
123
|
|
|
124
|
+
class UnsafePathBlockHandler(tornado.web.RequestHandler):
|
|
125
|
+
"""Block requests with unsafe path patterns for security.
|
|
126
|
+
|
|
127
|
+
This is the Tornado equivalent of the Starlette PathSecurityMiddleware.
|
|
128
|
+
It blocks double-slash paths (protocol-relative URL attacks) and other
|
|
129
|
+
unsafe patterns like UNC paths and path traversal attempts.
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
def prepare(self) -> None:
|
|
133
|
+
self.set_status(400)
|
|
134
|
+
self.write("Bad Request")
|
|
135
|
+
self.finish()
|
|
136
|
+
|
|
137
|
+
|
|
124
138
|
class RemoveSlashHandler(tornado.web.RequestHandler):
|
|
125
139
|
@tornado.web.removeslash
|
|
126
140
|
def get(self) -> None:
|
streamlit/web/server/server.py
CHANGED
|
@@ -49,6 +49,7 @@ from streamlit.web.server.routes import (
|
|
|
49
49
|
HostConfigHandler,
|
|
50
50
|
RemoveSlashHandler,
|
|
51
51
|
StaticFileHandler,
|
|
52
|
+
UnsafePathBlockHandler,
|
|
52
53
|
)
|
|
53
54
|
from streamlit.web.server.server_util import (
|
|
54
55
|
get_cookie_secret,
|
|
@@ -369,6 +370,9 @@ class Server:
|
|
|
369
370
|
base = config.get_option("server.baseUrlPath")
|
|
370
371
|
|
|
371
372
|
routes: list[Any] = [
|
|
373
|
+
# SECURITY: Block unsafe paths (double-slash, UNC paths, etc.)
|
|
374
|
+
# before any other handler. Matches PathSecurityMiddleware in Starlette.
|
|
375
|
+
(r"^//.*$", UnsafePathBlockHandler),
|
|
372
376
|
(
|
|
373
377
|
make_url_path_regex(base, STREAM_ENDPOINT),
|
|
374
378
|
BrowserWebSocketHandler,
|