Skip to content

Paths

Usage

When Python code executes from the command line, the working directory is a known location - the location where the application was started. However, when executing GUI apps, the working directory varies between platforms. As a result, when specifying file paths, relative paths cannot be used, as there is no location to which they can be considered relative.

Complicating matters further, operating systems have conventions (and in some cases, hard restrictions) over where certain file types should be stored. For example, macOS provides the ~/Library/Application Support folder; Linux encourages use of the ~/.config folder (amongst others), and Windows provides the AppData/Local folder in the user's home directory. Application sandbox and security policies will sometimes prevent reading or writing files in any location other than these pre-approved locations.

To assist with finding an appropriate location to store application files, every Toga application instance has a paths attribute that returns an instance of Paths. This object provides known file system locations that are appropriate for storing files of given types, such as configuration files, log files, cache files, or user data.

Each location provided by the Paths object is a [pathlib.Path][] that can be used to construct a full file path. If required, additional subdirectories can be created under these locations. Toga will guarantee that the path provided by Toga will exist, but it is up you to create any desired subdirectory - if you want to create a credentials/user.toml configuration file, Toga will guarantee that the apps.path.config will exist, but you must take responsibility for creating the credentials subdirectory before saving user.toml.

Reference

Source code in core/src/toga/paths.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class Paths:
    def __init__(self):
        self.factory = get_factory()
        self._impl = self.factory.Paths(self)

    # cached_property isn't read-only; this alternative is. With multiple instances,
    # this would cause a memory leak because it would hold onto all the "self"s in the
    # arguments cache, but for a singleton like this it's fine.
    @property
    @functools.cache  # noqa: B019
    def toga(self) -> Path:
        """The path that contains the core Toga resources.

        This path should be considered read-only. You should not attempt to write
        files into this path.
        """
        return Path(toga.__file__).parent

    @property
    @functools.cache  # noqa: B019
    def app(self) -> Path:
        """The path of the folder that contains the definition of the app class.

        This path should be considered read-only. You should not attempt to write
        files into this path.
        """
        app_module = sys.modules[toga.App.app.__module__]
        try:
            app_file = app_module.__file__
        except AttributeError:
            # At an interactive prompt, return the current working directory.
            return Path.cwd()
        else:
            return Path(app_file).parent

    @property
    @functools.cache  # noqa: B019
    def config(self) -> Path:
        """The platform-appropriate location for storing user configuration
        files associated with this app.
        """
        path = self._impl.get_config_path()
        path.mkdir(parents=True, exist_ok=True)
        return path

    @property
    @functools.cache  # noqa: B019
    def data(self) -> Path:
        """The platform-appropriate location for storing user data associated
        with this app.
        """
        path = self._impl.get_data_path()
        path.mkdir(parents=True, exist_ok=True)
        return path

    @property
    @functools.cache  # noqa: B019
    def cache(self) -> Path:
        """The platform-appropriate location for storing cache files associated
        with this app.

        It should be assumed that the operating system will purge the contents
        of this directory without warning if it needs to recover disk space.
        """
        path = self._impl.get_cache_path()
        path.mkdir(parents=True, exist_ok=True)
        return path

    @property
    @functools.cache  # noqa: B019
    def logs(self) -> Path:
        """The platform-appropriate location for storing log files associated
        with this app.
        """
        path = self._impl.get_logs_path()
        path.mkdir(parents=True, exist_ok=True)
        return path

app cached property

The path of the folder that contains the definition of the app class.

This path should be considered read-only. You should not attempt to write files into this path.

cache cached property

The platform-appropriate location for storing cache files associated with this app.

It should be assumed that the operating system will purge the contents of this directory without warning if it needs to recover disk space.

config cached property

The platform-appropriate location for storing user configuration files associated with this app.

data cached property

The platform-appropriate location for storing user data associated with this app.

logs cached property

The platform-appropriate location for storing log files associated with this app.

toga cached property

The path that contains the core Toga resources.

This path should be considered read-only. You should not attempt to write files into this path.