@@ -553,6 +553,8 @@ def generate_files(engine, crypto_factory, min_dt=None, max_dt=None):
553
553
"""
554
554
Create a generator of decrypted files.
555
555
556
+ Files are yielded in ascending order of their timestamp.
557
+
556
558
This function selects all current notebooks (optionally, falling within a
557
559
datetime range), decrypts them, and returns a generator yielding dicts,
558
560
each containing a decoded notebook and metadata including the user,
@@ -571,12 +573,8 @@ def generate_files(engine, crypto_factory, min_dt=None, max_dt=None):
571
573
max_dt : datetime.datetime, optional
572
574
Last modified datetime at and after which a file will be excluded.
573
575
"""
574
- where_conds = []
575
- if min_dt is not None :
576
- where_conds .append (files .c .created_at >= min_dt )
577
- if max_dt is not None :
578
- where_conds .append (files .c .created_at < max_dt )
579
- return _generate_notebooks (files , engine , where_conds , crypto_factory )
576
+ return _generate_notebooks (files , files .c .created_at ,
577
+ engine , crypto_factory , min_dt , max_dt )
580
578
581
579
582
580
# =======================================
@@ -736,6 +734,8 @@ def generate_checkpoints(engine, crypto_factory, min_dt=None, max_dt=None):
736
734
"""
737
735
Create a generator of decrypted remote checkpoints.
738
736
737
+ Checkpoints are yielded in ascending order of their timestamp.
738
+
739
739
This function selects all notebook checkpoints (optionally, falling within
740
740
a datetime range), decrypts them, and returns a generator yielding dicts,
741
741
each containing a decoded notebook and metadata including the user,
@@ -754,38 +754,53 @@ def generate_checkpoints(engine, crypto_factory, min_dt=None, max_dt=None):
754
754
max_dt : datetime.datetime, optional
755
755
Last modified datetime at and after which a file will be excluded.
756
756
"""
757
- where_conds = []
758
- if min_dt is not None :
759
- where_conds .append (remote_checkpoints .c .last_modified >= min_dt )
760
- if max_dt is not None :
761
- where_conds .append (remote_checkpoints .c .last_modified < max_dt )
762
757
return _generate_notebooks (remote_checkpoints ,
763
- engine , where_conds , crypto_factory )
758
+ remote_checkpoints .c .last_modified ,
759
+ engine , crypto_factory , min_dt , max_dt )
764
760
765
761
766
762
# ====================
767
763
# Files or Checkpoints
768
764
# ====================
769
- def _generate_notebooks (table , engine , where_conds , crypto_factory ):
765
+ def _generate_notebooks (table , timestamp_column ,
766
+ engine , crypto_factory , min_dt , max_dt ):
770
767
"""
771
768
See docstrings for `generate_files` and `generate_checkpoints`.
772
- `where_conds` should be a list of SQLAlchemy expressions, which are used as
773
- the conditions for WHERE clauses on the SELECT queries to the database.
769
+
770
+ Parameters
771
+ ----------
772
+ table : SQLAlchemy.Table
773
+ Table to fetch notebooks from, `files` or `remote_checkpoints.
774
+ timestamp_column : SQLAlchemy.Column
775
+ `table`'s column storing timestamps, `created_at` or `last_modified`.
776
+ engine : SQLAlchemy.engine
777
+ Engine encapsulating database connections.
778
+ crypto_factory : function[str -> Any]
779
+ A function from user_id to an object providing the interface required
780
+ by PostgresContentsManager.crypto. Results of this will be used for
781
+ decryption of the selected notebooks.
782
+ min_dt : datetime.datetime, optional
783
+ Minimum last modified datetime at which a file will be included.
784
+ max_dt : datetime.datetime, optional
785
+ Last modified datetime at and after which a file will be excluded.
774
786
"""
787
+ where_conds = []
788
+ if min_dt is not None :
789
+ where_conds .append (timestamp_column >= min_dt )
790
+ if max_dt is not None :
791
+ where_conds .append (timestamp_column < max_dt )
792
+
775
793
# Query for notebooks satisfying the conditions.
776
- query = select ([table ]).order_by (table . c . user_id )
794
+ query = select ([table ]).order_by (timestamp_column )
777
795
for cond in where_conds :
778
796
query = query .where (cond )
779
797
result = engine .execute (query )
780
798
781
799
# Decrypt each notebook and yield the result.
782
- last_user_id = None
783
800
for nb_row in result :
784
- # The decrypt function depends on the user, so if the user is the same
785
- # then the decrypt function carries over.
786
- if nb_row ['user_id' ] != last_user_id :
787
- decrypt_func = crypto_factory (nb_row ['user_id' ]).decrypt
788
- last_user_id = nb_row ['user_id' ]
801
+ # The decrypt function depends on the user
802
+ user_id = nb_row ['user_id' ]
803
+ decrypt_func = crypto_factory (user_id ).decrypt
789
804
790
805
nb_dict = to_dict_with_content (table .c , nb_row , decrypt_func )
791
806
if table is files :
@@ -798,7 +813,7 @@ def _generate_notebooks(table, engine, where_conds, crypto_factory):
798
813
# here as well.
799
814
yield {
800
815
'id' : nb_dict ['id' ],
801
- 'user_id' : nb_dict [ ' user_id' ] ,
816
+ 'user_id' : user_id ,
802
817
'path' : to_api_path (nb_dict ['path' ]),
803
818
'last_modified' : nb_dict ['last_modified' ],
804
819
'content' : reads_base64 (nb_dict ['content' ]),
0 commit comments