@@ -587,99 +587,115 @@ async def get_pin_thread(self) -> int:
587587 # Namespace
588588 #
589589
590- def set_namespace (self , namespace : str , writeback : str = "safe" , persist : bool = True ) -> None :
591- """Set the current namespace of the app
590+ def set_namespace (
591+ self ,
592+ namespace : str ,
593+ writeback : Literal ["safe" , "hybrid" ] | utils .ADWritebackType = "safe" ,
594+ persist : bool = True ,
595+ ) -> None :
596+ """Set the current namespace of the app.
597+
598+ This will create a new namespace if it doesn't already exist. By default, this will be a persistent namespace
599+ with ``safe`` writeback, which means that all state changes will be stored to disk as they happen.
592600
593- See the `namespace documentation <APPGUIDE.html#namespaces>`__ for more information.
601+ See the :py:ref:`app_namespaces` for more information.
594602
595603 Args:
596604 namespace (str): Name of the new namespace
597605 writeback (str, optional): The writeback to be used if a new namespace gets created. Will be ``safe`` by
598606 default.
599607 persist (bool, optional): Whether to make the namespace persistent if a new one is created. Defaults to
600- `` True` `.
608+ `True`.
601609
602610 Returns:
603611 None.
604612
605613 Examples:
606- >>> self.set_namespace("hass1")
614+ Create a namespace that buffers state changes in memory and periodically writes them to disk.
607615
616+ >>> self.set_namespace("on_disk", writeback="hybrid", persist=True)
617+
618+ Create an in-memory namespace that won't survive AppDaemon restarts.
619+
620+ >>> self.set_namespace("in_memory", persist=False)
608621 """
609- # Keeping namespace get/set functions for legacy compatibility
610622 if not self .namespace_exists (namespace ):
611- self .add_namespace (namespace = namespace , writeback = writeback , persist = persist )
623+ self .add_namespace (
624+ namespace = namespace ,
625+ writeback = utils .ADWritebackType (writeback ),
626+ persist = persist
627+ )
612628 self .namespace = namespace
613629
614630 def get_namespace (self ) -> str :
615631 """Get the app's current namespace.
616632
617- See the `namespace documentation <APPGUIDE.html#namespaces>`__ for more information.
633+ See :py:ref:`app_namespaces` for more information.
618634 """
619635 # Keeping namespace get/set functions for legacy compatibility
620636 return self .namespace
621637
622638 @utils .sync_decorator
623639 async def namespace_exists (self , namespace : str ) -> bool :
624- """Check the existence of a namespace in AppDaemon .
640+ """Check for the existence of a namespace.
625641
626- See the `namespace documentation <APPGUIDE.html#namespaces>`__ for more information.
642+ See :py:ref:`app_namespaces` for more information.
627643
628644 Args:
629- namespace (str): The namespace to be checked .
645+ namespace (str): The namespace to check for .
630646
631647 Returns:
632- bool: ``True`` if the namespace exists, otherwise ``False``.
633-
634- Examples:
635- Check if the namespace ``storage`` exists within AD
636-
637- >>> if self.namespace_exists("storage"):
638- >>> #do something like create it
639-
648+ bool: `True` if the namespace exists, otherwise `False`.
640649 """
641650 return self .AD .state .namespace_exists (namespace )
642651
643652 @utils .sync_decorator
644- async def add_namespace (self , namespace : str , writeback : str = "safe" , persist : bool = True ) -> str | None :
645- """Add a user-defined namespace, which has a database file associated with it.
646-
647- When AppDaemon restarts these entities will be loaded into the namespace with all their previous states. This
648- can be used as a basic form of non-volatile storage of entity data. Depending on the configuration of the
649- namespace, this function can be setup to constantly be running automatically
650- or only when AD shutdown .
653+ async def add_namespace (
654+ self ,
655+ namespace : str ,
656+ writeback : Literal [ "safe" , "hybrid" ] | utils . ADWritebackType = "safe" ,
657+ persist : bool = True ,
658+ ) -> str | None :
659+ """Add a user-defined namespace .
651660
652- See the `namespace documentation <APPGUIDE.html#namespaces>`__ for more information.
661+ See the :py:ref:`app_namespaces` for more information.
653662
654663 Args:
655664 namespace (str): The name of the new namespace to create
656- writeback (optional): The writeback to be used. Will be ``safe`` by default
665+ writeback (optional): The writeback to be used. Defaults to ``safe``, which writes every state change to
666+ disk. This can be problematic for namespaces that have a lot of state changes. `Safe` in this case
667+ refers data loss, rather than performance. The other option is ``hybrid``, which buffers state changes.
657668 persist (bool, optional): Whether to make the namespace persistent. Persistent namespaces are stored in a
658- database file and are reloaded when AppDaemon restarts. Defaults to `` True``
669+ database file and are reloaded when AppDaemon restarts. Defaults to `True`.
659670
660671 Returns:
661- The file path to the newly created namespace. Will be ``None`` if not persistent
672+ The file path to the newly created namespace. Will be ``None`` if not persistent.
662673
663674 Examples:
664- Add a new namespace called `storage`.
675+ Create a namespace that buffers state changes in memory and periodically writes them to disk.
676+
677+ >>> self.add_namespace("on_disk", writeback="hybrid", persist=True)
665678
666- >>> self.add_namespace("storage")
679+ Create an in-memory namespace that won't survive AppDaemon restarts.
667680
681+ >>> self.add_namespace("in_memory", persist=False)
668682 """
669- new_namespace = await self .AD .state .add_namespace (namespace , writeback , persist , self .name )
670- match new_namespace :
671- case Path () | str ():
672- new_namespace = str (new_namespace )
673- self .AD .state .app_added_namespaces .add (new_namespace )
674- return new_namespace
675- case _:
676- self .logger .warning ("Namespace %s already exists or was not created" , namespace )
683+ match await self .AD .state .add_namespace (
684+ namespace ,
685+ utils .ADWritebackType (writeback ),
686+ persist ,
687+ self .name
688+ ):
689+ case Path () as ns_path :
690+ return str (ns_path )
691+ case False | None :
692+ return None
677693
678694 @utils .sync_decorator
679695 async def remove_namespace (self , namespace : str ) -> dict [str , Any ] | None :
680696 """Remove a user-defined namespace, which has a database file associated with it.
681697
682- See the `namespace documentation <APPGUIDE.html#namespaces>`__ for more information.
698+ See :py:ref:`app_namespaces` for more information.
683699
684700 Args:
685701 namespace (str): The namespace to be removed, which must not be the current namespace.
@@ -709,32 +725,22 @@ async def list_namespaces(self) -> list[str]:
709725 return self .AD .state .list_namespaces ()
710726
711727 @utils .sync_decorator
712- async def save_namespace (self , namespace : str | None = None ) -> None :
713- """Saves entities created in user-defined namespaces into a file.
728+ async def save_namespace (self , namespace : str | None = None ) -> bool :
729+ """Saves the given state namespace to its corresponding file.
714730
715- This way, when AD restarts these entities will be reloaded into AD with its
716- previous states within the namespace. This can be used as a basic form of
717- non-volatile storage of entity data. Depending on the configuration of the
718- namespace, this function can be setup to constantly be running automatically
719- or only when AD shutdown. This function also allows for users to manually
720- execute the command as when needed.
731+ This is only relevant for persistent namespaces, which if not set to ``safe`` buffers changes in memory and only
732+ periodically writes them to disk. This function manually forces a write of all the changes since the last save
733+ to disk. See the :py:ref:`app_namespaces` docs section for more information.
721734
722735 Args:
723- namespace (str, optional): Namespace to use for the call. See the section on
724- `namespaces <APPGUIDE.html#namespaces>`__ for a detailed description.
725- In most cases it is safe to ignore this parameter.
736+ namespace (str, optional): Namespace to save. If not specified, the current app namespace will be used.
726737
727738 Returns:
728- None.
729-
730- Examples:
731- Save all entities of the default namespace.
732-
733- >>> self.save_namespace()
739+ bool: `True` if the namespace was saved successfully, `False` otherwise.
734740
735741 """
736742 namespace = namespace if namespace is not None else self .namespace
737- await self .AD .state .save_namespace (namespace )
743+ return await self .AD .state .save_namespace (namespace )
738744
739745 #
740746 # Utility
0 commit comments