snap¶
Opinionated library for performing snap operations, targeted at use in charm code.
Use ensure_installed to ensure that a snap is installed, optionally on a specific
channel or revision.
Manually manage snap installation with install, refresh, and remove.
Use list_one to query the current state of an installed snap.
Also manage:
Connections between snaps with
connectanddisconnect.
Exceptions¶
All errors raised due to interactions with the snapd API are subclasses of Error.
Callers may trigger regular Python exceptions (e.g. ValueError) when passing
invalid arguments to library functions.
All functions will raise a APIError (or a subclass) if snapd returns an error response.
Functions will raise specific subclasses where possible to allow callers to handle logical errors.
Check the documentation for each function for details on which exceptions it may raise. A
function’s documented errors are the ones it can report specifically: a plain APIError,
or one of the transport errors below, is possible for any call.
Separately from the APIError hierarchy (but inheriting from Error),
the library may also raise the following exceptions:
A TimeoutError indicates that snapd did not respond to a request in time. The library
does not retry a request that timed out: the timeout is generous, and already covers the retries
snapd itself makes against the store within a single request. The failure may still be transient,
due to the snap store infrastructure being under load, so callers may catch this error to layer
their own retry logic on top, or report a transient failure to the user.
A ConnectionError indicates that snapd could not be reached at all, and may require user
action. The library briefly retries read-only requests, since snapd may be restarting as part of
a snap operation, but not requests that change state, since it cannot tell whether snapd received
them. SocketNotFoundError, a subclass raised when the snapd socket does not exist, is
never retried: it usually means snapd is not installed on the system.
A BadResponseError is raised if the snapd API returns a response the library does not
understand. Callers will not be able to resolve this error directly, and should report it to the
library maintainers. Its message includes what snapd sent that the library could not read, so an
uncaught traceback carries everything the report needs.
- exception APIError(
- message: str,
- *,
- kind: str,
- value: object,
- status_code: int | None = None,
- status: str | None = None,
Bases:
ErrorRaised when the snapd API returns an error response.
- exception AppNotFoundError(
- message: str,
- *,
- kind: str,
- value: object,
- status_code: int | None = None,
- status: str | None = None,
Bases:
APIErrorRaised via the API when a specified app is not found within an installed snap.
- exception BadResponseError(message: str, *, response: object = None)¶
Bases:
ErrorRaised manually when the snapd API returns a response we don’t understand.
Callers will not be able to resolve this error directly. It means the library and snapd disagree about the shape of a response, so it should be reported to the library maintainers. The error message includes what snapd sent that the library could not read, so an uncaught traceback carries everything the report needs.
Use
messagerather thanstr(error)for a charm’s status, which is truncated for display and has no room for a response body.
- exception ChangeError(
- message: str,
- *,
- kind: str,
- value: object,
- status_code: int | None = None,
- status: str | None = None,
Bases:
APIErrorRaised when a snap change results in an error or has an unexpected status.
- exception ChannelNotAvailableError(
- message: str,
- *,
- kind: str,
- value: object,
- status_code: int | None = None,
- status: str | None = None,
Bases:
APIErrorRaised via the API when no snap revision is available on the specified channel.
- exception ConnectionError(message: str)¶
Bases:
Error,ConnectionErrorRaised when a connection to the snapd socket fails.
This typically indicates that snapd isn’t running – for example, it may be restarting as part of a snap operation. The library briefly retries read-only requests before giving up, so a caller that sees this error is looking at a system where snapd stayed unreachable. Requests that change state aren’t retried, since the library can’t tell whether snapd received them.
See
SocketNotFoundErrorfor the case where the socket doesn’t exist at all.
- exception Error(message: str)¶
Bases:
ExceptionBase class for all library errors, not raised directly.
- class InstalledInfo(
- name: str,
- classic: bool,
- tracking: str,
- revision: int | str,
- version: str,
- hold: datetime | str | None,
Bases:
objectInformation about an installed snap.
- property tracking: str¶
The channel the snap tracks, for example
latest/stable.This is the channel a refresh follows, shown as
Trackingbysnap list. It isn’t necessarily the channel the installed revision came from: installing a specific revision without a channel trackslatest/stable, whichever channel that revision was found on.Empty for a snap installed from a local file, which tracks no channel.
- property revision: str¶
The snap’s revision, as a string.
Note that locally installed snaps have revisions in the form ‘x<N>’.
- property hold: datetime | None¶
The date the snap is held until, or None if it is not held.
A held snap is not automatically refreshed, but can be manually refreshed.
For an indefinite hold, snapd reports a timestamp roughly 292 years after the hold was placed (Go’s maximum duration), which is hopefully sufficient.
- class LogEntry(timestamp: datetime.datetime, sid: str, pid: int, message: str)¶
Bases:
objectA single snap log entry.
- property timestamp: datetime.datetime¶
The timestamp of the log entry as a datetime object.
- exception NeedsClassicError(
- message: str,
- *,
- kind: str,
- value: object,
- status_code: int | None = None,
- status: str | None = None,
Bases:
APIErrorRaised via the API if classic is not specified for a classic confinement snap.
This can occur for a snap install or refresh.
- exception NotInStoreError(
- message: str,
- *,
- kind: str,
- value: object,
- status_code: int | None = None,
- status: str | None = None,
Bases:
_NotFoundErrorRaised when the snap store has no snap by that name.
Distinct from
ChannelNotAvailableErrorandRevisionNotAvailableError.
- exception NotInstalledError(
- message: str,
- *,
- kind: str,
- value: object,
- status_code: int | None = None,
- status: str | None = None,
Bases:
_NotFoundErrorRaised when a snap is not installed on the system.
- exception OptionNotFoundError(
- message: str,
- *,
- kind: str,
- value: object,
- status_code: int | None = None,
- status: str | None = None,
Bases:
APIErrorRaised via the API when the specified snap config option is not found.
- exception RevisionNotAvailableError(
- message: str,
- *,
- kind: str,
- value: object,
- status_code: int | None = None,
- status: str | None = None,
Bases:
APIErrorRaised via the API when the specified snap revision is not available.
- exception SocketNotFoundError(message: str)¶
Bases:
ConnectionErrorRaised when the snapd socket does not exist.
This typically indicates that snapd is not installed on the system. Unlike other connection failures, this is not retried: a socket that isn’t there won’t appear moments later.
- exception TimeoutError(message: str)¶
Bases:
Error,TimeoutErrorRaised when snapd does not respond to a request in time.
This typically indicates that snapd is waiting on the snap store, which may indicate a transient issue with the store or a problem with the system’s network connection. Callers may want to catch this for retry logic or to surface a user-friendly message.
- alias(snap: str, app: str, alias: str) None¶
Create an alias for a snap app.
If the alias already exists for the same snap, this call succeeds silently, reassigning the alias to the new app if it differs.
- Parameters:
snap – The name of the snap that owns the app.
app – The name of the app within the snap to alias.
alias – The alias (command name) to create for the app.
- Raises:
ValueError – if the snap name, app name, or alias is empty or blank.
NotInstalledError – if the snap is not installed.
ChangeError – if the alias name is already claimed by a different snap, conflicts with the command namespace of an installed snap, or if the specified app does not exist within the snap.
- connect( ) None¶
Connect a snap’s plug to a slot.
Connecting an already-connected plug and slot succeeds silently.
- Parameters:
plug – The plug to connect, as a
(snap, plug)pair. Both parts are required: snapd cannot resolve a plug from the snap name alone, and treats a missing snap name as an error.slot –
The slot to connect to. May be given as:
a
(snap, slot)pair. Either part may be""to have snapd resolve it. An empty slot resolves to the matching slot on the plug snap. AnAPIErroris raised if the slot cannot be resolved unambiguously. An empty snap means the system snap.a bare snap name, shorthand for
(snap, '').None(the default), shorthand for('', '').
- Raises:
ValueError – if any part of
plugorslotis blank (whitespace only).NotInstalledError – if the plug snap or slot snap is not installed. Never raised for the system snap.
APIError – if the plug is not fully specified (empty snap or plug name), if the named plug or slot does not exist, if the plug and slot interfaces do not match, or if the slot cannot be resolved unambiguously.
ChangeError – if the operation fails after starting (for example, an interface hook errors).
# Connect a plug to its auto-resolved system slot. connect(('mysnap', 'home')) # Connect a plug to the matching slot on a named snap. connect(('mysnap', 'network'), 'other-snap') # Connect a plug to an explicitly named slot. connect(('mysnap', 'content'), ('other-snap', 'content-slot'))
- disconnect( ) None¶
Disconnect a plug from a slot.
At least one of
plugorslotmust be specified. Each is a(snap, name)pair; unlikeconnect, a bare snap name is not accepted, because snapd requires the plug or slot name to identify what to disconnect.An
APIErroris raised if neither side is specified or if a specified side does not specify the plug or slot name.An empty snap on either side means the system snap (mirroring
connect’s slot): for example('', 'mount-observe')refers tomount-observeonsnapd/core.Three forms are supported:
both
plugandslot: disconnect that specific plug-slot connection. AnAPIErroris raised if they are not connected.plugonly: disconnect everything connected to that plug. No-op if nothing is connected.slotonly: disconnect everything connected to that slot. No-op if nothing is connected.
- Parameters:
plug – The plug side, as a
(snap, plug)pair. Omit to disconnect by slot only.slot – The slot side, as a
(snap, slot)pair. Omit to disconnect by plug only.forget – If
True, also clear snapd’s stored preference for this interface. snapd normally remembers manual changes and replays them across snap refreshes. An auto-connected interface you disconnect stays disconnected on refresh, while a manualconnectis preserved.forget=Trueerases that stored preference so the interface reverts to snapd’s default auto-connection policy on the next refresh.
- Raises:
ValueError – if any part of
plugorslotis blank (whitespace only).NotInstalledError – if the plug snap or slot snap is not installed. Never raised for the system snap.
APIError – if neither
plugnorslotnames anything to disconnect, if the named plug or slot does not exist, or if the fully-specified plug and slot are not connected.ChangeError – if the operation fails after starting (for example, an interface hook errors).
# Disconnect everything from a plug (no-op if nothing is connected). disconnect(('mysnap', 'home')) # Disconnect everything from a slot. disconnect(slot=('other-snap', 'content-slot')) # Disconnect one specific connection (raises if not connected). disconnect(('mysnap', 'content'), ('other-snap', 'content-slot'))
- ensure_installed(
- snap: str,
- channel: str | None = None,
- *,
- revision: int | str | None = None,
- classic: bool = False,
- update: bool = True,
Ensure the snap is installed, on the specified channel and revision.
The action taken depends on the current state of the snap:
If the snap is not installed, it will be installed on the specified channel and revision (defaulting to the latest revision on
latest/stable).If the snap is installed on a different channel or revision, it will be refreshed to the specified channel and revision.
If the snap already matches what was specified, it will be refreshed only if a revision wasn’t specified and update =
True(default).
- Parameters:
snap – The name of the snap to install or update.
channel –
The channel to track, for example
latest/edge. IfNone(default), the snap is installed fromlatest/stablewhen not already installed, and an already-installed snap’s channel is left unchanged.A channel that starts with a risk inherits the track an installed snap is on, so ensuring
edgefor a snap that tracks3.6/stablegives3.6/edge.revision –
The revision to install, as an int or string. If
None(default), the latest revision on the channel is used.A revision isn’t a pin: the next refresh of this snap, including an automatic one, will move it to the current revision of the channel it tracks. Use
holdto prevent automatic refreshes. Passchannelas well asrevisionto control which channel the snap tracks – otherwise a newly installed snap trackslatest/stable, whichever channel the revision was found on.classic – Permission to install or refresh a revision that requires classic confinement. If a snap revision requires classic confinement and
classicis not true, aNeedsClassicErroris raised.update –
If
True(default), refresh the snap when it is already installed on the requested channel. IfFalse, leave an already-correct snap untouched.Ignored when
revisionis specified, since that fully determines which revision the snap should be on, leaving nothing to update to.
- Returns:
A truthy value if the snap was installed or updated, or a falsy value otherwise. Not guaranteed to be an actual
bool.- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment.
NotInStoreError – If the store has no snap by that name.
RevisionNotAvailableError – If the revision is not available on any channel.
NeedsClassicError – If the snap requires
classic=True.ChannelNotAvailableError – If the channel is invalid or unavailable, or if the revision is not available on it.
ChangeError – If the install or refresh fails after starting (for example, a hook errors).
Error – (or a subtype) if the snap could not be installed or refreshed for another reason.
- get(snap: str, keys: str | Iterable[str] | None = None) dict[str, Any]¶
Get snap configuration.
- Parameters:
snap – The name of the snap to read configuration from.
keys – Configuration keys to read, as a single key or an iterable of keys. Nested options may be accessed with dotted notation, for example
'server.port'. IfNone, the full config is returned as a nested dict. If an empty iterable, an empty dict is returned if the snap is installed.
- Returns:
A dict mapping each requested key to its configured value. If all keys are requested (keys=None), the entire config is returned as a nested dict (empty if the snap has no configuration). If no keys are requested (keys=[]), an empty dict is returned if the snap is installed. Each dotted key queried is returned as a top-level entry. A single key passed as a bare string is no different from passing it in a list: the result is still a dict, so use
get_oneto read one value without unwrapping it yourself.- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment, or if a key is empty, blank, or contains a comma or surrounding whitespace.
NotInstalledError – if the snap is not installed. Never raised for
systemorcore, whose configuration is served whether or not the core snap is installed.OptionNotFoundError – if a requested key has no value stored in the snap’s configuration. Snap configuration is schemaless, so snapd does not distinguish between a key the snap doesn’t recognise, a key that was never set, and a key that was unset. Any defaults a snap applies internally are invisible here unless its configure hook has stored them with
snapctl set.BadResponseError – if snapd answers with something other than a configuration mapping.
# Full config. get('foo') # {'server': {'port': 8080}, 'client': {'timeout': 30}} get('foo', keys=None) # {'server': {'port': 8080}, 'client': {'timeout': 30}} # Querying specific keys. get('foo', 'client') # {'client': {'timeout': 30}} get('foo', ['client.timeout']) # {'client.timeout': 30} get('foo', ['server', 'server.port']) # {'server': {'port': 8080}, 'server.port': 8080} # Querying no keys. get('foo', keys=[]) # {}
- get_one(snap: str, key: str) Any¶
Get the value of a single snap configuration key.
get_one(snap, key)returnsvalue, whileget(snap, key)returns{key: value}.- Parameters:
snap – The name of the snap to read configuration from.
key – The configuration key to read. Nested options may be accessed with dotted notation, for example
'server.port'.
- Returns:
The configured value, which may be any JSON type, including a nested dict for a key that names a subtree.
- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment, or if the key is empty, blank, or contains a comma or surrounding whitespace.
NotInstalledError – if the snap is not installed. Never raised for
systemorcore, whose configuration is served whether or not the core snap is installed.OptionNotFoundError – if the key has no value stored in the snap’s configuration. See
getfor why snapd cannot distinguish an unrecognised key from an unset one.BadResponseError – if snapd answers with something other than a configuration mapping.
get_one('foo', 'client') # {'timeout': 30} get_one('foo', 'client.timeout') # 30
- hold( ) None¶
Hold a snap to prevent it from being automatically refreshed.
Does not prevent manual refreshes.
- Parameters:
snap – The name of the snap to hold.
duration – How long to hold automatic refreshes for, measured from now. May be a
datetime.timedelta, or a number of seconds as an int or float. IfNone(default), the snap is held indefinitely.
- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment.
NotInstalledError – If the snap is not installed.
ChangeError – If the hold change fails after starting.
- install( ) object¶
Install a snap.
- Parameters:
snap – The name of the snap to install.
channel – The channel to track, for example
latest/edge. Ifrevisionis also given, the revision must be available on this channel. If neither is given, snapd installs fromlatest/stable.revision –
The revision to install, as an int or string. Installing a revision doesn’t pin the snap to it – the next refresh will move the snap to the current revision of the channel it tracks. Use
holdto prevent automatic refreshes.Without
channel, snapd finds the revision on whichever channel it’s available on, but the snap trackslatest/stableregardless, so a later refresh may move the snap to a different channel’s revision. Passchannelas well to control which channel the snap tracks.classic – Permission to install a snap that requires classic confinement. If a snap requires classic confinement and
classicis not true, aNeedsClassicErroris raised.
- Returns:
A truthy value if the snap was installed, or a falsy value if it was already installed. Not guaranteed to be an actual
bool. Note that a falsy result doesn’t mean the snap is installed on the requested channel or revision, just that it was already installed at all.- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment.
NotInStoreError – if the store has no snap by that name.
RevisionNotAvailableError – if the specified revision is not available on any channel.
ChannelNotAvailableError – if the specified channel is not available, or if the specified revision is not available on it.
NeedsClassicError – if the snap requires classic confinement and
classicis not set.ChangeError – if the install fails after starting (for example, an install hook errors).
Error – (or a subtype) if the snap could not be installed for another reason.
- list_one(snap: str) InstalledInfo¶
Get information about a single installed snap.
This function implements the semantics of the
snap listcommand, restricted to a single snap: it reports the local state of an installed snap and never queries the snap store. It is named for that command rather thansnap info, which reports what the store offers for a snap – the channels available and their revisions – and is not implemented here.- Parameters:
snap – the name of the snap.
- Returns:
An
InstalledInfoobject with information about the snap.- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment.
NotInstalledError – if the snap is not installed.
BadResponseError – if snapd’s description of the snap isn’t one we can read.
Error – (or a subtype) if the information could not be retrieved for another reason.
- logs( ) list[LogEntry]¶
Retrieve recent log entries for one or more snaps.
Log entries are returned in chronological order: oldest first, newest last.
- Parameters:
snaps – Snap names to retrieve logs for, as a single name or an iterable of names. If
None(the default), system-wide snap logs are returned. If an empty iterable, no snaps are queried: an empty list is returned without making a request.limit – Maximum number of log entries to return. Must be a positive integer, or
Noneto retrieve all available log entries (equivalent tosnap logs -n all).
- Returns:
A list of
LogEntryobjects, ordered oldest first. The list may contain fewer entries thanlimitif fewer are available. Malformed entries returned by snapd are skipped (and logged as warnings) rather than raising.- Raises:
ValueError – If any snap name is empty, blank, has leading or trailing whitespace, or contains a comma; or if
limitis notNoneand is not a positive integer.NotInstalledError – If a specified snap is not installed.
AppNotFoundError – If a specified snap has no services.
# System-wide snap logs. logs() # Logs for one snap. logs('lxd') # Logs for several. logs(['lxd', 'kube-proxy']) # Logs for no snaps at all: [], without a request. logs([])
- refresh( ) object¶
Refresh a snap.
- Parameters:
snap – The name of the snap to refresh.
channel –
The channel to track, for example
latest/edge. Ifrevisionis also given, the revision must be available on this channel. If neither is given, the snap is refreshed on its current channel.A channel that starts with a risk inherits the track the snap is on, so refreshing a snap that tracks
3.6/stabletoedgegives3.6/edge.revision –
The revision to refresh to, as an int or string. Refreshing to a revision doesn’t pin the snap to it – the next refresh will move the snap to the current revision of the channel it tracks. Use
holdto prevent automatic refreshes.Without
channel, the snap keeps tracking its current channel, even if the revision was found on another one.classic – Permission to refresh to a revision that requires classic confinement from a revision that does not.
- Returns:
A truthy value if the snap was refreshed, or a falsy value if no updates were available. Not guaranteed to be an actual
bool. Note that snapd always refreshes when a revision is specified, even if that revision is already installed.- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment.
NotInstalledError – if the snap is not installed.
NotInStoreError – if the snap is installed but the store no longer offers it.
RevisionNotAvailableError – if the specified revision is not available on any channel.
ChannelNotAvailableError – if the specified channel is not available, or if the specified revision is not available on it.
NeedsClassicError – if the target revision requires classic confinement, the installed revision does not, and
classicis not set.ChangeError – if the refresh fails after starting (for example, a refresh hook errors).
Error – (or a subtype) if the snap could not be refreshed for another reason.
- remove(snap: str, *, purge: bool = False) object¶
Remove a snap.
- Parameters:
snap – The name of the snap to remove.
purge – If True, remove the snap without saving a snapshot of its data.
- Returns:
A truthy value if the snap was removed, or a falsy value if it was not installed. Not guaranteed to be an actual
bool.- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment.
ChangeError – if the removal fails after starting (for example, a remove hook errors).
Error – (or a subtype) if the snap could not be removed as requested.
- restart(snap: str, services: str | Iterable[str] | None = None) None¶
Restart snap services.
- Parameters:
snap – The name of the snap whose services to restart.
services – Names of services within the snap to restart, as a single name or an iterable of names. If
None(the default), all of the snap’s services are restarted. If an empty iterable, no services are restarted and no request is made – but the snap must still be installed.
- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment, or if a service name is empty or blank.
NotInstalledError – if the snap is not installed.
AppNotFoundError – if the snap is installed but has no service with a given name, or if all services were requested and the snap has no services at all.
ChangeError – if the change fails (for example, the service fails to restart).
- set(snap: str, config: dict[str, Any]) None¶
Set snap configuration.
- Parameters:
snap – The name of the snap to configure.
config – A mapping of configuration keys to values. Values may be any JSON-serialisable type, including nested dicts and lists. Setting a key to
Noneunsets it. Nested options may be addressed with dotted keys, for exampleserver.port. An empty mapping is accepted as a no-op.
- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment, or if a key in
configis empty or blank.NotInstalledError – if the snap is not installed.
ChangeError – if the snap’s configure hook fails. This includes setting any configuration on a snap that does not define a configure hook, and configuration rejected by a validating configure hook. A failed change is rolled back: no key from the request is applied.
- start( ) None¶
Start snap services.
- Parameters:
snap – The name of the snap whose services to start.
services – Names of services within the snap to start, as a single name or an iterable of names. If
None(the default), all of the snap’s services are started. If an empty iterable, no services are started and no request is made – but the snap must still be installed.enable – If
True, also enable the services to start automatically at boot.
- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment, or if a service name is empty or blank.
NotInstalledError – if the snap is not installed.
AppNotFoundError – if the snap is installed but has no service with a given name, or if all services were requested and the snap has no services at all.
ChangeError – if the change fails (for example, the service fails to start).
# Start every service the snap has. start('lxd') # Start one service. start('lxd', 'daemon') # Start several. start('lxd', ['daemon', 'user-daemon']) # Start none of them -- a no-op, but still an error if lxd isn't installed. start('lxd', [])
- stop( ) None¶
Stop snap services.
- Parameters:
snap – The name of the snap whose services to stop.
services – Names of services within the snap to stop, as a single name or an iterable of names. If
None(the default), all of the snap’s services are stopped. If an empty iterable, no services are stopped and no request is made – but the snap must still be installed.disable – If
True, also disable the services from starting automatically at boot.
- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment, or if a service name is empty or blank.
NotInstalledError – if the snap is not installed.
AppNotFoundError – if the snap is installed but has no service with a given name, or if all services were requested and the snap has no services at all.
ChangeError – if the change fails (for example, the service fails to stop).
- unalias(alias: str) None¶
Remove an alias.
- Parameters:
alias – The alias to remove.
- Raises:
ValueError – if the alias is empty or blank.
ChangeError – if the alias removal fails after starting.
APIError – if the alias does not exist (for example, was never created, or the snap it belonged to was removed – aliases do not survive snap removal).
- unhold(snap: str) None¶
Unhold a snap to allow it to be refreshed.
Does not raise if the snap is not held, or if it is not installed (an absent snap is not held).
- Parameters:
snap – The name of the snap to unhold.
- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment.
ChangeError – If the unhold change fails after starting.
- unset(snap: str, keys: str | Iterable[str]) None¶
Unset snap configuration keys.
Unsetting a key that is not currently set is a no-op and does not raise.
- Parameters:
snap – The name of the snap to unset configuration on.
keys –
Configuration keys to unset, as a single key or an iterable of keys. Nested options may be addressed with dotted notation, for example
'server.port'. An empty iterable is still passed to snapd, and may trigger the snap’s config hook.Unlike
get, there is noNonemeaning “all keys”: snapd has no request for it, and building one out of the keysgetreports would unset keys the caller never named.
- Raises:
ValueError – if the snap name is empty, blank, or is not a single path segment, or if a key is empty or blank.
NotInstalledError – if the snap is not installed.
ChangeError – if the snap’s configure hook fails. This includes unsetting any configuration on a snap that does not define a configure hook. A failed change is rolled back: no key from the request is unset.