11# datamanager/__main__.py
2+ import re
23import subprocess
3- from datetime import datetime , timezone
44import tempfile
5- import re
6- from dateutil . parser import isoparse
5+ from collections . abc import Callable
6+ from datetime import UTC , datetime
77from pathlib import Path
8+ from typing import Any
89
910import questionary
1011import typer
12+ from dateutil .parser import isoparse
1113from rich .console import Console
1214from rich .table import Table
1315
14- from typing import Callable , Optional , Any
15-
16- from datamanager .config import settings
1716from datamanager import core , manifest
18-
17+ from datamanager . config import settings
1918
2019# Common options for all commands
2120COMMON_OPTIONS = dict (
3130def _ask_confirm (ctx : typer .Context , prompt : str , default : bool = False ) -> bool :
3231 if ctx .obj .get ("no_prompt" ):
3332 return True
34- result : Optional [ bool ] = questionary .confirm (prompt , default = default ).ask ()
33+ result : bool | None = questionary .confirm (prompt , default = default ).ask ()
3534 return bool (result ) # Cast to bool to avoid NoneType issues
3635
3736
3837def _rel (iso : str ) -> str :
3938 dt = isoparse (iso )
40- delta = datetime .now (timezone . utc ) - dt
39+ delta = datetime .now (UTC ) - dt
4140 hours = int (delta .total_seconds () // 3600 )
4241 return f"{ hours } h ago"
4342
@@ -138,7 +137,7 @@ def list_datasets(ctx: typer.Context) -> None:
138137 console .print (table )
139138
140139
141- def _run_pull_logic (name : str , version : str , output : Optional [ Path ] ) -> None :
140+ def _run_pull_logic (name : str , version : str , output : Path | None ) -> None :
142141 """The core logic for pulling and verifying a dataset."""
143142 console .print (f"🔎 Locating version '{ version } ' for dataset '{ name } '..." )
144143 version_entry = manifest .get_version_entry (name , version )
@@ -188,7 +187,7 @@ def pull(
188187 "-v" ,
189188 help = "Version to pull (e.g., 'v1'). Defaults to latest." ,
190189 ),
191- output : Optional [ Path ] = typer .Option (
190+ output : Path | None = typer .Option (
192191 None ,
193192 "--output" ,
194193 "-o" ,
@@ -330,7 +329,7 @@ def _run_prepare_logic(ctx: typer.Context, name: str, file: Path) -> None:
330329 console .print (f"Change detected! Preparing new version: { new_version } " )
331330
332331 console .print ("Downloading previous version to generate diff..." )
333- diff_git_path : Optional [ Path ] = None
332+ diff_git_path : Path | None = None
334333 with tempfile .TemporaryDirectory () as tempdir :
335334 old_path = Path (tempdir ) / "prev.sqlite"
336335 # Download from the PRODUCTION bucket
@@ -355,7 +354,7 @@ def _run_prepare_logic(ctx: typer.Context, name: str, file: Path) -> None:
355354
356355 new_entry = {
357356 "version" : new_version ,
358- "timestamp" : datetime .now (timezone . utc ).isoformat ().replace ("+00:00" , "Z" ),
357+ "timestamp" : datetime .now (UTC ).isoformat ().replace ("+00:00" , "Z" ),
359358 "sha256" : new_hash ,
360359 "r2_object_key" : final_r2_key ,
361360 "staging_key" : staging_key ,
@@ -376,9 +375,7 @@ def _run_prepare_logic(ctx: typer.Context, name: str, file: Path) -> None:
376375 "history" : [
377376 {
378377 "version" : "v1" ,
379- "timestamp" : datetime .now (timezone .utc )
380- .isoformat ()
381- .replace ("+00:00" , "Z" ),
378+ "timestamp" : datetime .now (UTC ).isoformat ().replace ("+00:00" , "Z" ),
382379 "sha256" : new_hash ,
383380 "r2_object_key" : f"{ Path (Path (name ).stem )} /v1-{ new_hash } .sqlite" ,
384381 "staging_key" : staging_key ,
@@ -492,7 +489,7 @@ def _run_rollback_logic(ctx: typer.Context, name: str, to_version: str) -> None:
492489
493490 rollback_entry = {
494491 "version" : new_version ,
495- "timestamp" : datetime .now (timezone . utc ).isoformat ().replace ("+00:00" , "Z" ),
492+ "timestamp" : datetime .now (UTC ).isoformat ().replace ("+00:00" , "Z" ),
496493 "sha256" : target_entry ["sha256" ],
497494 "r2_object_key" : target_entry ["r2_object_key" ],
498495 "diffFromPrevious" : None ,
0 commit comments