Saving local skill information

Is there a standard / best practice for skills that may create a file for storing / retrieving skill related information?
I have a couple skills I am considering but I need to be able to open / read / write a file within my skill for access later if the skill requires it. Can I simply create the file in the skills directory? Do I need the file in a temporary location? What file / directory permissions for the storage location need to be considered?
Thanks

1 Like

There are a couple of approaches here.

The “standard” approach to Skills storing data is to use Skill Settings, where the data is stored in JSON format - see

If you need to store other Skill data in a file, some things to consider are;

  • Each Skill is installed on a Device. If you store the file on the Device, then it is only available on that Device, whereas Skill Settings store Skill data across Devices.

  • if you create a file, does it have the potential to be very large?

The documentation does not include many examples of the use of the this. Are there any core skills that utilize the skill settings?
Thanks,

you can look into using the filesystem utis

from mycroft.filesystem import FileSystemAccess

def load_data_file(self, filename, mode="r"):
    file_system = FileSystemAccess(str(self.skill_id))
    file = file_system.open(filename, mode)
    data = file.read()
    file.close()
    return data

def save_data_file(self, filename, data, mode="w"):
    try:
        file_system = FileSystemAccess(str(self.skill_id))
        file = file_system.open(filename, mode)
        file.write(data)
        file.close()
        return True
    except Exception as e:
        LOG.warning("could not save skill file " + filename)
        LOG.error(e)
        return False

but skill settings are also a good option if you are saving non binary data, skill settings are basically a persistent dict saved as a .json file

skill settings are auto saved on skill shutdown, you can also force a save when you want

2 Likes

Sure - there’s a couple of good examples with;

1 Like

@pcwii @forslund gave me some advice that I found extremely useful for saving data in a file and calling it later. Here. But after speaking with @steve.penrod I realized that it can cause issues on a Mark 1 for example if you try to save a file anywhere other than that particular skill’s own folder. The issue with writing it to the skill folder is it will cause the skill to reload. I even ran into a loop when writing a file during the

Def initialize(self)

It’s all in the post if you are interested in reading about my experience with writing files. I eventually only save a small json file with the ip into the skill folder and figured out another way for the code forslund thought I could try.

I hope you find this helpful.

Cheers!

2 Likes

there is a self.reload_skill flag you can use to disable reloading per skill

self.filesystem.path will point to a safe directory dedicated to the skill and not the skills own directory. It will not cause reloads.

1 Like

@Jarbas_Ai, @forslund is absolutely correct. And for a while, I was using the code he has suggested and avoided the loop. I was unaware the reload feature could be disabled. Although when we tried my skill on a Mark 1, at the Kansas City Maker Faire we were running into issues with the code that if I remember right was caused by using the “sandbox” forslund suggested. Again, I’m not sure I remember exactly what the issue was, but I believe @steve.penrod suggested it could be a write/security issue with the Mark 1’s that doesn’t allow a skill to write anywhere but to it’s own skill directory.

In my case @steve.penrod suggested there was not really a reason I had to write that particular file within my code, and suggested, as @forslund had, that I use self.some_variable to hold the data I needed.

That worked for me until I added to the skill the ability to verbally tell Mycroft the IP address of the mirror. That setting needed to persist until the mirror IP address changes. So in that case, it was actually helpful to me that the skill would automatically reload when the skill writes the json file holding the ip to the skill’s directory. Pretty cool stuff. Thanks for the info on how to disable the reload.

Cheers!

there is also a callback you can override to know when skill settings changed (pulled down from mycroft.home)

self.settings.set_changed_callback(self, callback)

Cool usage of the reload!

I’ll have to checl the filesystem.path thing on my mark-1. I’ve had no issues with the zork-skill so It shouldn’t be any issue but I’ve been wrong before :slight_smile:
Thanks for letting me know of this possible issue! And thanks for sharing your development experience!

2 Likes