@@ -831,6 +831,19 @@ def run_janitor(self, ignore_ttl: bool) -> bool:
831831
832832 return success
833833
834+ @python_api_analytics
835+ def destroy (self ) -> bool :
836+ success = False
837+
838+ if self .console .start_destroy ():
839+ try :
840+ self ._destroy ()
841+ success = True
842+ finally :
843+ self .console .stop_destroy (success = success )
844+
845+ return success
846+
834847 @t .overload
835848 def get_model (
836849 self , model_or_snapshot : ModelOrSnapshot , raise_if_missing : Literal [True ] = True
@@ -1516,16 +1529,19 @@ def apply(
15161529 )
15171530
15181531 @python_api_analytics
1519- def invalidate_environment (self , name : str , sync : bool = False ) -> None :
1532+ def invalidate_environment (
1533+ self , name : str , sync : bool = False , protect_prod : t .Optional [bool ] = True
1534+ ) -> None :
15201535 """Invalidates the target environment by setting its expiration timestamp to now.
15211536
15221537 Args:
15231538 name: The name of the environment to invalidate.
15241539 sync: If True, the call blocks until the environment is deleted. Otherwise, the environment will
15251540 be deleted asynchronously by the janitor process.
1541+ protect_prod: If True, prevents invalidation of the production environment.
15261542 """
15271543 name = Environment .sanitize_name (name )
1528- self .state_sync .invalidate_environment (name )
1544+ self .state_sync .invalidate_environment (name , protect_prod )
15291545 if sync :
15301546 self ._cleanup_environments ()
15311547 self .console .log_success (f"Environment '{ name } ' deleted." )
@@ -2499,6 +2515,21 @@ def _context_diff(
24992515 gateway_managed_virtual_layer = self .gateway_managed_virtual_layer ,
25002516 )
25012517
2518+ def _destroy (self ) -> None :
2519+ # Invalidate all environments, including prod
2520+ for environment in self .state_reader .get_environments ():
2521+ self .invalidate_environment (name = environment .name , protect_prod = False )
2522+
2523+ # Run janitor to clean up all objects
2524+ self ._run_janitor (ignore_ttl = True )
2525+
2526+ # Remove state tables
2527+ self .state_sync .remove_state ()
2528+ self .console .log_status_update ("State tables removed." )
2529+
2530+ # Finally clear caches
2531+ self .clear_caches ()
2532+
25022533 def _run_janitor (self , ignore_ttl : bool = False ) -> None :
25032534 current_ts = now_timestamp ()
25042535
0 commit comments