@@ -263,7 +263,7 @@ def add_and_trim_labels(
263263 )
264264
265265
266- def create_bq_event_callback (publisher ):
266+ def create_bq_event_callback (publisher , cell_execution_count = None ):
267267 event_map = {
268268 google .cloud .bigquery ._job_helpers .QueryFinishedEvent : (
269269 bigframes .core .events .BigQueryFinishedEvent
@@ -286,7 +286,9 @@ def publish_bq_event(event):
286286 bf_event = bf_type .from_bqclient (event ) # type: ignore
287287 break
288288 envelope = bigframes .core .events .EventEnvelope (
289- event = bf_event , progress_bar = bigframes .core .events ._DEFAULT
289+ event = bf_event ,
290+ progress_bar = bigframes .core .events ._DEFAULT ,
291+ cell_execution_count = cell_execution_count ,
290292 )
291293 publisher .publish (envelope )
292294
@@ -309,10 +311,21 @@ def start_query_with_job(
309311 job_retry : google .api_core .retry .Retry = (third_party_gcb_retry .DEFAULT_JOB_RETRY ), # noqa: E501
310312 publisher : bigframes .core .events .Publisher ,
311313 session = None ,
314+ cell_execution_count : Optional [int ] = None ,
312315) -> Tuple [google .cloud .bigquery .table .RowIterator , bigquery .QueryJob ]:
313316 """
314317 Starts query job and waits for results.
315318 """
319+ if cell_execution_count is None :
320+ try :
321+ import IPython
322+
323+ ipy = IPython .get_ipython ()
324+ if ipy is not None and hasattr (ipy , "execution_count" ):
325+ cell_execution_count = ipy .execution_count
326+ except (ImportError , NameError ):
327+ pass
328+
316329 # Note: Ensure no additional labels are added to job_config after this
317330 # point, as `add_and_trim_labels` ensures the label count does not
318331 # exceed MAX_LABELS_COUNT.
@@ -339,6 +352,7 @@ def start_query_with_job(
339352 sql = sql ,
340353 publisher = publisher ,
341354 metrics = metrics ,
355+ cell_execution_count = cell_execution_count ,
342356 )
343357 return results_iterator , query_job
344358
@@ -359,13 +373,24 @@ def start_query_job_optional(
359373 job_retry : google .api_core .retry .Retry = (third_party_gcb_retry .DEFAULT_JOB_RETRY ), # noqa: E501
360374 publisher : bigframes .core .events .Publisher ,
361375 session = None ,
376+ cell_execution_count : Optional [int ] = None ,
362377) -> google .cloud .bigquery .table .RowIterator :
363378 """
364379 Run a bigquery query, with job optional.
365380
366381 See:
367382 https://docs.cloud.google.com/bigquery/docs/running-queries#optional-job-creation
368383 """
384+ if cell_execution_count is None :
385+ try :
386+ import IPython
387+
388+ ipy = IPython .get_ipython ()
389+ if ipy is not None and hasattr (ipy , "execution_count" ):
390+ cell_execution_count = ipy .execution_count
391+ except (ImportError , NameError ):
392+ pass
393+
369394 add_and_trim_labels (job_config , session = session )
370395 try :
371396 results_iterator = bq_client ._query_and_wait_bigframes (
@@ -375,10 +400,14 @@ def start_query_job_optional(
375400 project = project ,
376401 api_timeout = timeout ,
377402 job_retry = job_retry ,
378- callback = create_bq_event_callback (publisher ),
403+ callback = create_bq_event_callback (
404+ publisher , cell_execution_count = cell_execution_count
405+ ),
379406 )
380407 if metrics is not None :
381- metrics .count_job_stats (row_iterator = results_iterator )
408+ metrics .count_job_stats (
409+ row_iterator = results_iterator , cell_execution_count = cell_execution_count
410+ )
382411 return results_iterator
383412 except google .api_core .exceptions .Forbidden as ex :
384413 if "Drive credentials" in ex .message :
@@ -392,35 +421,45 @@ def _publish_events(
392421 total_rows : Optional [int ],
393422 publisher : bigframes .core .events .Publisher ,
394423 metrics : Optional [bigframes .session .metrics .ExecutionMetrics ] = None ,
424+ cell_execution_count : Optional [int ] = None ,
395425):
396426 if not query_job .configuration .dry_run :
397427 publisher .publish (
398- bigframes .core .events .BigQuerySentEvent (
399- sql ,
400- billing_project = query_job .project ,
401- location = query_job .location ,
402- job_id = query_job .job_id ,
403- request_id = None ,
428+ bigframes .core .events .EventEnvelope (
429+ event = bigframes .core .events .BigQuerySentEvent (
430+ sql ,
431+ billing_project = query_job .project ,
432+ location = query_job .location ,
433+ job_id = query_job .job_id ,
434+ request_id = None ,
435+ ),
436+ cell_execution_count = cell_execution_count ,
404437 )
405438 )
406439 if not query_job .configuration .dry_run :
407440 publisher .publish (
408- bigframes .core .events .BigQueryFinishedEvent (
409- billing_project = query_job .project ,
410- location = query_job .location ,
411- job_id = query_job .job_id ,
412- destination = query_job .destination ,
413- total_rows = total_rows ,
414- total_bytes_processed = query_job .total_bytes_processed ,
415- slot_millis = query_job .slot_millis ,
416- created = query_job .created ,
417- started = query_job .started ,
418- ended = query_job .ended ,
441+ bigframes .core .events .EventEnvelope (
442+ event = bigframes .core .events .BigQueryFinishedEvent (
443+ billing_project = query_job .project ,
444+ location = query_job .location ,
445+ query_id = query_job .query_id ,
446+ job_id = query_job .job_id ,
447+ destination = query_job .destination ,
448+ total_rows = total_rows ,
449+ total_bytes_processed = query_job .total_bytes_processed ,
450+ slot_millis = query_job .slot_millis ,
451+ created = query_job .created ,
452+ started = query_job .started ,
453+ ended = query_job .ended ,
454+ ),
455+ cell_execution_count = cell_execution_count ,
419456 )
420457 )
421458
422459 if metrics is not None :
423- metrics .count_job_stats (query_job = query_job )
460+ metrics .count_job_stats (
461+ query_job = query_job , cell_execution_count = cell_execution_count
462+ )
424463
425464
426465def delete_tables_matching_session_id (
0 commit comments