Apps
Contents
Apps¶
Heedy’s apps are used as logical entities that interact with external services.
In most cases, a plugin defines an app in its heedy.conf
, which a user can then add to their account. The plugin then handles the app’s features and synchronization with external data sources.
Apps can also be used directly without associated plugins if they have a access token defined. An access token enables an external service/script to query the Heedy API with the permissions defined in the app’s scope string. This allows an external service to sync with Heedy using an Oauth2 flow (not yet implemented), or explicitly by asking the user to manually create an app with certain permissions and provide it the associated access token.
Once an auth token is obtained, logging into Heedy can be done by initializing the App
object:
app = heedy.App("my_access_token",url="http://localhost:1324")
app = heedy.App("my_access_token",url="http://localhost:1324",session="async")
Listing & Accessing¶
While an app can be obtained directly from its access token, apps are also frequently accessed
and used by plugins. Apps can be listed given a set of constraints using the apps
attribute of the Plugin
object:
# Returns all enabled apps with the given plugin key (usually defined in heedy.conf)
apps = p.apps(plugin="myplugin:myapptype",enabled=True)
# Returns all enabled apps with the given plugin key (usually defined in heedy.conf)
apps = await p.apps(plugin="myplugin:myapptype",enabled=True)
To list the apps beloning to a specific user, the constraint owner="myuser"
can be used,
or the list can be generated from the apps
attribute of the User
object, which automatically adds the owner constraint.
If an app’s ID is known, the corresponding App
object can be retrieved with:
app = p.apps["appid123"]
print(app.read())
app = p.apps["appid123"]
print(await app.read())
Note
Only plugins can list or read apps - when accessing heedy using an app’s access token, the app can only access itself, and cannot see any other apps.
Creating & Deleting¶
A Heedy plugin can create/delete apps, but an app logged in with an app token cannot. An app can be added with the create()
method:
app = p.apps.create("My App Name",
owner="myusername"
plugin=f"{p.name}:myapp"
)
app = await p.apps.create("My App Name",
owner="myusername"
plugin=f"{p.name}:myapp"
)
The above is equivalent to:
app = p.users["myusername"].apps.create("My App Name",
plugin=f"{p.name}:myapp"
)
app = await p.users["myusername"].apps.create("My App Name",
plugin=f"{p.name}:myapp"
)
Once the App
object is retrieved, it can be deleted with the delete()
method:
app.delete()
await app.delete()
Reading & Updating Properties¶
Just like with user
and Object
, an App
’s properties can be accessed directly as properties or as attributes:
# Does not use a server query - but it might say "self" before read() is called
# if logged in using the app token.
print(app.id)
# Reads the app's display name from the server
print(app.name)
# Uses the previously read cached data, avoiding a server query
print(app["name"])
# Does not use a server query - but it might say "self" before read() is called
# if logged in using the app token.
print(app.id)
# Reads the app's display name from the server
print(await app.name)
# Uses the previously read cached data, avoiding a server query
print(app["name"])
To update the corresponding properties, the update function can be used, or if in a sync session, the properties can also be directly set:
app.name = "My App" # Sets the app's display name
# The update function allows setting multiple properties in a single query
app.update(description="Syncs with a cool service")
# The update function allows setting properties for the app:
await app.update(name="My App", description="Syncs with a cool service")
Updating Access Token¶
An app access token cannot be directly modified. Instead, an update request is sent, and the server generates a new key itself. The newly generated key is returned as part of the query result.
If accessing Heedy using an App token, and the token is updated, the session must be re-created with the new token, since the old token is no longer valid for requests.
result = app.update(access_token=True)
# The old app object is no longer valid if it was logged in with the old access token
newapp = heedy.App(result["access_token"],url=app.session.url)
result = await app.update(access_token=True)
# The old app object is no longer valid if it was logged in with the old access token
newapp = heedy.App(result["access_token"],url=app.session.url)
If the app has its access token set to False
or ""
, the app will lose login capabilities,
and will only be accessible from plugins.
API¶
Apps¶
- class heedy.Apps(constraints, session)[source]¶
Bases:
heedy.base.APIList
Apps is a class implementing a list of apps. It is accessed as a property of users to allow querying apps belonging to a user, or as a property of a plugin object, to allow generic querying of apps. Listing apps is currently only possible when authenticated as a plugin, because an app only has access to itself, and cannot read any other apps.
myuser.apps() # list of apps belonging to myuser plugin.apps() # list of all apps in heedy
await myuser.apps() # list of apps belonging to myuser await plugin.apps() # list of all apps in heedy
- __call__(**kwargs)[source]¶
Gets the apps matching the given constraints. If used as a property of a user, the apps are those belonging to the user. Otherwise, if used as a property of a plugin, apps for all users are returned.
# Get all plugins handled by myplugin, with myapptype subkey. # Include each app's access tokens in the response. applist = p.apps(plugin="myplugin:myapptype",token=True)
# Get all plugins handled by myplugin, with myapptype subkey. # Include each app's access tokens in the response. applist = await p.apps(plugin="myplugin:myapptype",token=True)
- Parameters
owner (str) – The username of the apps’ owner. Set automatically when accessed using the apps property of a user.
plugin (str) – The plugin key of the apps. Allows querying for apps related to specific plugins.
enabled (bool,null) – Include only enabled/disabled apps (true/false)
icon (bool,False) – Whether to include the icons of the apps in the response.
token (bool,False) – Whether to include the access tokens of the apps in the response.
- Returns
A list of
App
matching the given constraints.
- Throws:
HeedyException: If the request fails.
- __getitem__(appId)[source]¶
Gets an app by its ID. Each app in heedy has a unique string ID, which can then be used to access the app. The ID can be seen in the URL of the app’s page in the frontend.
app = p.apps["d233rk43o6kkle43kl"]
app = await p.apps["d233rk43o6kkle43kl"]
- Returns
The
App
with the given ID (or promise for the app)
- Throws:
HeedyException: If the app does not exist, or insufficient permissions
- create(name='', **kwargs)[source]¶
Creates a new app. Only the first argument, the app name, is required.
app = p.apps.create("My App", description="This is my plugin's app", icon="fas fa-chart-line", owner="myuser", # set automatically when accessed using the apps property of a user plugin="myplugin:myapptype" )
app = await p.apps.create("My App", description="This is my plugin's app", icon="fas fa-chart-line", owner="myuser", # set automatically when accessed using the apps property of a user plugin="myplugin:myapptype" )
When creating an app for a plugin, it is useful to set the
plugin
property in the formatplugin_name:app_type
. The plugin property allows a plugin to recover which apps are associated with it, and the subkey allows the plugin to distinguish between multiple apps with different functionality that are handled by the same plugin.- Parameters
name (str,"") – The name of the app.
description (str,"") – A description of the app.
icon (str,"") – The app’s icon, either a base64 urlencoded image or fontawesome/material icon id.
owner (str) – The username of the app’s owner. Set automatically when accessed using the apps property of a user.
plugin (str) – The plugin key of the app. Usually in the format
plugin_name:app_type
.enabled (bool,True) – Whether the app is enabled.
scope (str,"") – space-separated access scopes that are given to the app. Only relevant if the app will be accessed using its access token.
settings (dict,{}) – A dictionary of settings for the app.
settings_schema (dict,{}) – A JSON Schema describing the settings.
access_token (bool,True) – Whether the app should be given an access token.
- Returns
The newly created
App
, with its data cached.
- Throws:
HeedyException: If the request fails.
App¶
- class heedy.App(access_token, url='http://localhost:1324', session='sync', cached_data=None)[source]¶
Bases:
heedy.base.APIObject
App is a class representing a Heedy app. Using an access token, you can log into heedy using the App object:
.. tab:: Sync
access_token = "..." app = heedy.App(access_token,url="http://localhost:1324")
access_token = "..." app = heedy.App(access_token,url="http://localhost:1324",session="async")
access_token = “…” app = heedy.App(access_token,url=”http://localhost:1324”)
Pre-initialized app objects are also returned when querying for apps from a plugin.
- props = {'access_token', 'description', 'icon', 'name', 'settings', 'settings_schema'}¶
Each element has the above properties available as attributes. In synchronous sessions, they allow you to update the properties directly:
o.name = "My new name" assert o.name == "My new name"
The above is equivalent to:
o.update(name="My new name") assert o["name"] == "My new name"
Note that each time you access the properties, they are fetched from the server. In non-interactive scripts it is useful to avoid redundant querying, so each read of data is cached. To use this cached data, you can access the property as a key. Instead of
o.name
, useo["name"]
, and callo.read()
to create/update the cache. Accessingo["name"]
will only work after the data was initially read, otherwise it will lead to aKeyError
.
- copy(session=None)[source]¶
Creates a copy of the app object. This function is usually used to switch between sync and async sessions:
app_sync = heedy.App(access_token,url="http://localhost:1324",session="sync") app_async = app_sync.copy("async")
This function will fail if used on an app object returned from a plugin session. Only App login sessions can be copied.
- Parameters
session (str) – The session type to use for the copy (either “sync” or “async”). If not specified, the session type of the current app is used.
- Returns
A new
App
object.
- delete(**kwargs)¶
Calls the element’s URI with the DELETE method. This is a method available for all subclasses of APIObject (objects, apps, users, etc), and removes all associated data from Heedy.
o.delete() o.read() # Throws error - it longer exists!
await o.delete() await o.read() # Throws error - it no longer exists!
- Parameters
**kwargs – Arguments to pass as query parameters to the server (usually empty)
- Raises
HeedyException – If the server returns an error, or when the app does not have permission to delete.
- property id¶
The app’s unique ID. This is directly available, so does not need to be awaited in async sessions:
print(myapp.id)
- property kv¶
The key-value store associated with this app. For details of usage, see KV.
- Returns
A
heedy.kv.KV
object for the element.
- notifications¶
A
Notifications
object that allows you to access the notifications associated with this element. See Notifications for details.
- notify(*args, **kwargs)¶
Shorthand for
self.notifications.notify
(see Notifications).
- objects¶
An
Objects
instance associated with the app, allowing to interact with the objects of the app. For example, listing the objects that are managed by the app can be done withapp.objects()
.
- property owner¶
The user which owns this app:
print(app.owner.username) # Queries the server for the owner, and prints username print(app["owner"].username) # Uses cached query data to get the owner
print((await app.owner).username) # Queries the server for the owner, and prints username print(app["owner"].username) # Uses cached query data to get the owner
- Returns
The
User
object of the user which owns this object. The returned user does not have any cached data other than its username.
- read(**kwargs)¶
Sends a GET request to the element’s URI with function arguments as query parameters. This method is available for all subclasses of APIObject (objects, apps, users, etc), and is used to read element’s properties in heedy.
data = o.read(icon=True)
data = await o.read(icon=True)
Caches the result of the read accessible as dict keys:
assert data["name"] == o["name"]
The read or update functions both update the cached data automatically.
- Parameters
**kwargs – The url parameters to send with the request.
- Returns
The server’s response dict, namely a dict of the element’s properties.
- Raises
HeedyException – If the server returns an error.
- update(**kwargs)[source]¶
Sends a PATCH request to element’s URI with arguments as a json object. This method is available for all subclasses of APIObject (objects, apps, users, etc), and is used to update the element’s properties in heedy.
o.update(name="My new name",description="my new description") assert o["name"] == "My new name"
await o.update(name="My new name",description="my new description") assert o["name"] == "My new name"
- Parameters
**kwargs – The properties to update, sent as the json body of the request.
- Returns
The server’s response as a dict, namely the updated element’s properties.
- Raises
HeedyException – If the server returns an error, such as when there are insufficient permissions.