Modules

The Modules-class provides access to the database-modules. In scriptor, there’s a preconfigured instance under the name modules (all lowercase) connected to your viur backend. Accessing a module is simply done by calling get_module.

Here’s an example to retrieve all users and print them:

#### scriptor ####
from viur.scriptor import *

async def main():
    users = await modules.get_module("user")
    async for user in users.list():
        print(user)

Depending on the type of module, the result of get_module differs. It can return a ListModule, a TreeModule or a SingletonModule.

The methods available in all of them are view, edit, structure and preview.

TreeModule and ListModule additionaly have list, add, delete and for_each.

In addition to that, TreeModule also has list_root_nodes and move.

TreeModule and ListModule also need an extra parameter for methods, that interact with the database. For ListModule, this is group. The group parameter filters only records that belong to that group and also potentially modifies the returned model (i.e. if you’re selling kitchen supplies, pans might have a diameter, which would be unused for knives). For TreeModule, the extra parameter is skel_type. It can have one of two values: node or leaf. This determines what parts of the tree will be returned (i.e. for scriptor-scripts, scripts are leaves and the folders are nodes).

Since examples are specific to the database and its configuration, the first ones assume you have a module called “example” that has at least the fields “name” and “sortindex”.

Here’s how you’d create five new records with the name test and sortindex ranging from 1 to 5.

#### scriptor ####
from viur.scriptor import *

async def main():
    example_entries_to_add = 5
    example = await modules.get_module("example")
    for i in range(example_entries_to_add):
        ProgressBar.set(i/example_entries_to_add*100, i, example_entries_to_add, str(i))
        await example.add({"name": "test", "sortindex": i+1})
    ProgressBar.unset()

The next example shows, how to get all records with the name “test” and rename one of them. It also shows the number of records named “test” before and after the edit.

#### scriptor ####
from viur.scriptor import *

async def main():
    example = await modules.get_module("example")
    test = await gather_async_iterator(example.list(params={"name": "test"}))
    print(f"""Number of records with name "test": {len(test)}""")
    try:
        print(f"""The record we'll edit:\n{test[0]}""")
        test_key = test[0]["key"]
    except IndexError:
        print("""Nothing to do, there are not records with the name "test" left.""")
        return
    print(f"""Key of the record we'll edit: {test_key}""")
    await example.edit(key=test_key, params={"name": "test_edited"})
    test_after_edit = await gather_async_iterator(example.list(params={"name": "test"}))
    print(f"""Number of records with name "test" after editing: {len(test_after_edit)}""")
    edited_test = await example.view(key=test_key)
    print(f"""The edited record:\n{edited_test}""")

After creating and renaming test records, you might want to delete them from the database. This example shows how to delete all records with the name “test_edited”:

#### scriptor ####
from viur.scriptor import *

async def main():

    example = await modules.get_module("example")
    test = await gather_async_iterator(example.list(params={"name": "test_edited"}))
    print(f"""Number of records with name "test_edited": {len(test)}""")
    for t in test:
        print(f"""deleting record with id {t["key"]}""")
        res = await example.delete(key=t["key"])
    test_after_deletes = await gather_async_iterator(
        example.list(params={"name": "test_edited"})
    )
    print(f"""Number of records with name "test_edited" after deletion:"""
          f"""{len(test_after_deletes)}""")

As a final example, here’s how to export all scriptor-scripts to a compressed zip-file. We won’t demonstrate how to modify or delete scripts here.

#### scriptor ####
from viur.scriptor import *
from io import BytesIO
from zipfile import ZipFile, ZIP_DEFLATED


async def main():
    script = await modules.get_module("script")
    scriptleaves = await gather_async_iterator(script.list(params={"skelType": "leaf"}))
    bio = BytesIO()
    script_count = len(scriptleaves)
    with ZipFile(bio, "w", compression=ZIP_DEFLATED, compresslevel=9) as z:
        for n, s in enumerate(scriptleaves):
            name = s["name"]
            ProgressBar.set(n/script_count*100, n, script_count, name)
            try:
                z.writestr(s["path"], s["script"])
            except KeyError:
                z.writestr(name, s["script"])
        ProgressBar.unset()
    bio.seek(0)
    zip_bytes = bio.read()
    bio.close()
    zipname = f"""ScriptorScripts.zip"""
    print(f"""downloading "{zipname}" ({len(zip_bytes):_} b)""")
    out_file = File.from_bytes(zip_bytes, zipname)
    out_file.download()
    print("...done")