File tree Expand file tree Collapse file tree 3 files changed +48
-0
lines changed
Expand file tree Collapse file tree 3 files changed +48
-0
lines changed Original file line number Diff line number Diff line change @@ -272,6 +272,17 @@ def metric(self, metrics: List[str]):
272272 metrics .ParseFromString (response .metrics )
273273 return metrics
274274
275+ def export_to_arrow (self , output_path : str ):
276+ """Export all intrinsic tables as a TAR archive of Arrow IPC files.
277+
278+ The archive is streamed directly to disk without materializing in memory.
279+
280+ Args:
281+ output_path: Path to write the TAR archive to.
282+ """
283+ with open (output_path , 'wb' ) as f :
284+ self .http .export_to_arrow (f )
285+
275286 @property
276287 def metadata (self ) -> Dict [str , str ]:
277288 """Returns metadata associated with this trace.
Original file line number Diff line number Diff line change @@ -106,3 +106,13 @@ def disable_and_read_metatrace(self):
106106 result = self .protos .DisableAndReadMetatraceResult ()
107107 result .ParseFromString (f .read ())
108108 return result
109+
110+ def export_to_arrow (self , output_file ):
111+ """Streams the arrow TAR archive directly to an open file object."""
112+ self .conn .request ('POST' , '/export_to_arrow' )
113+ with self .conn .getresponse () as f :
114+ while True :
115+ chunk = f .read (65536 )
116+ if not chunk :
117+ break
118+ output_file .write (chunk )
Original file line number Diff line number Diff line change @@ -646,3 +646,30 @@ def resolve(self):
646646 '_path' : example_android_trace_path ()
647647 }
648648 self .assertEqual (tp .metadata , expected_metadata )
649+
650+ def test_export_to_arrow (self ):
651+ import tarfile
652+ with create_tp (trace = example_android_trace_path ()) as tp :
653+ with tempfile .NamedTemporaryFile (suffix = '.tar' , delete = False ) as f :
654+ output_path = f .name
655+ try :
656+ tp .export_to_arrow (output_path )
657+
658+ # Verify the output is a valid TAR archive.
659+ self .assertTrue (tarfile .is_tarfile (output_path ))
660+
661+ with tarfile .open (output_path ) as tf :
662+ names = tf .getnames ()
663+ # Should contain metadata.json and at least one .arrow file.
664+ self .assertIn ('metadata.json' , names )
665+ arrow_files = [n for n in names if n .endswith ('.arrow' )]
666+ self .assertGreater (len (arrow_files ), 0 )
667+
668+ # Verify arrow files have ARROW1 magic bytes.
669+ for name in arrow_files :
670+ member = tf .extractfile (name )
671+ self .assertIsNotNone (member )
672+ data = member .read ()
673+ self .assertTrue (data [:6 ] == b'ARROW1' , f'{ name } missing ARROW1 header' )
674+ finally :
675+ os .unlink (output_path )
You can’t perform that action at this time.
0 commit comments