Images remaining after closing app

Hi,

For the tool we are developing we upload many images, to be used in a report. The intention is for a user to use this app multiple times a month.

Currently we have an issue were the uploaded images remain in the apps ‘memory’, even after the user has closed the app. Ideally, we would like this data to be cleared once the user has created the report, as the next time they use the app they won’t need to use those images.

The current workaround is to create another entity for the app and delete the old one, however we are unsure of what happens to those old images in the deleted entity. Do those images remain on the server? Is there a time limit for how long they are stored there? If not, what happens when multiple users are uploading 100+ images multiple times a month? How does this effect the storage of the app?

Is there a way we can force the app to clear this data when the process is complete?

Thanks,
Charlie

Hi Charlie,

It is possible to create entities by uploading a file.
These entities can later be deleted through the Viktor API.
In your case you could either write a for-loop that deletes all pictures for a report, e.g. after the user presses a button, or you could write some logic to delete a parent entity that contains multiple pictures.

Hope this helps!

Ideally, we would like this data to be cleared once the user has created the report, as the next time they use the app they won’t need to use those images.

I am quite curious as to why it is a problem that old entities are persisted. One of the key features of VIKTOR is the revision system and being able view / revert to earlier created revisions. For example, if a user has created a report a few months ago and he needs one of the figures that is used, he can simply navigate to that entity and retrieve it. Or if an old report has to be revised, you can open the old entity, update the image, and regenerate the report.

Hi @khameeteman
You can see the report tool as a template to organize and create quick reports in .doc or .ppt
The creation is once required and the outputs are files that can eventually be modified; there is no point in coming back after 3 weeks and making a new report with the same pictures.
This is why we don’t need to keep the uploading persistence and because @charlie.mottmac was asking in another post to use an external directory to avoid ‘saturating’ the app storage with pictures.
The pictures will be archived on our servers and there is no point of store them in the app for future use.

Hi @ymacken,

Would you be able to show me an example of this?

Hi @charlie.mottmac.

Perhaps good to elaborate first.
As I understand, you are now using the app to generate reports. The user uploads images and in the same session generates the report. After generating the report, the user has no need to access the images anymore. Is this correct?

If your problem is the manual act of adding and deleting an entity, this can be solved by deleting the entity through the api as described above. If you are worried about storage of deleted files, there is currently no limit on storage. The amount of stored files should not impact your apps performance.

Good to know is that we are working on a single-editor application. In this ‘stateless’ type of application, you would for example be able to upload the images on a FileField and download the report without storing any data on an entity. Would this feature be of use for you?

1 Like

@ymacken you are correct.

  1. Good to know there is not limiting of space.
  2. The single editor is perfect for this application. When it will release it?
  3. The point of removing the images is because if I run the app, generate the report and after some times I re-use the same entity of the app and upload other images I will end up having the ones I have previously uploaded and the new one creating confusion.

If you could provide an example of how upload multiple files to an entity it will be beneficial for the work Charlie is doing.

Thanks.

Hi sonomirco,

The release of the single-editor entity is planned for next month (but we can’t make any promises), so until then it should be fine to have the deleted files living on storage.

I think in your case it boils down to the structure of the app. I would suggest a tree type app with the following entity types:

reports-folder
     └── report-editor
          └── image

The controller of your reports-folder would look like this:

from viktor import ViktorController

class ReportFolderController(ViktorController):
    label = "Report Folder"
    children = ["ReportEditor"]
    show_children_as = "Table"

The controller of your report-editor would look like this:

from viktor import ViktorController
from viktor.api_v1 import API

class ReportEditorController(ViktorController):
    label = "Report Editor"
    children = ["Image"]
    show_children_as = "Table"

   def someMethod(self, params, entity_id, **kwargs):
      # Loop through all child entities (of type 'Image')
      for child in API().get_entity(entity_id).children():
         # Get image File object from child entity
         image_file = child.get_file()

The controller of your ‘image’ entity-type would look like this:

from viktor import ViktorController, File, ParamsFromFile

class ImageController(ViktorController):

    @ParamsFromFile()
    def process_file(self, file: File, **kwargs):
        return {}

Now it is possible for each user to create a new ‘report-editor’ entity, upload multiple files simultaneously as children of this entity, generate a report in this entities editor, and delete the report entity afterwards.

Hope this helps!

1 Like

Hi @ymacken,

I want to populate a table in my app after the images are uploaded. Currently my code looks like;

def get_images(self, entity_id, **kwargs):
        image_table = []
        global image_files
        image_files = {}

        for child in API().get_entity(entity_id).children():
            image_files[child.name] = child.get_file()
            image_dict = {}
            image_dict['image_name'] = child.name
            image_dict['description'] = ''
            image_table.append(Munch(image_dict))

I would like to move this into the class’ def __init__ so the table is populated as the user opens the controller. However, I’m not sure how to pass the entity_id through to this function.

Thanks,
Charlie

Hi Charlie,

Interesting case. Can you please elaborate what you want to achieve specifically (i.e. faster response time, less code to type, …)?

Every time a view is rendered the __init__ method is called again, and I therefore can imagine that that is not the solution you would like to have. The entity_id parameter will be known once the specific function is called.

Your current implementation of calling get_images every time a function is evaluated looks like the way to do it, even though you have to call the function for every view. If you would like to speed up the application, you can see if you can memoize this function: https://docs.viktor.ai/docs/create-apps/results-and-visualizations/storing-results?_highlight=memo#memoize

Hope this helps! Sylvain

Hi @Sylvain ,

Thanks for the response. I’ll run you through the process so you can better understand how we have it working currently. This workflow is for creating a report containing site photos with captions.

First users make a new report.

Next they upload the site images

From here they enter the app. Ideally the uploaded images pre-populate this table, which is used to fill in descriptions for the images.

Currently we have a button that checks for child entities and populates the table, which makes the table look like this

Having the table pre-populated would be a nicer/simplier user experience. Is there a way to call a function without user interaction?

Or can we iterate over the child entities in the app when it opens? I think the best way to do this is to get the entity id, but I don’t know how to get this without the user interacting with something.

Thanks

@charlie.mottmac , thanks for the extra clarification! The way you have implemented it now is indeed how the platform is meant to be used. As a user you fill in everything on the parametrization side, which also makes it more intuitive that the user has to press a button to change something for them on the parametrization side.

Other options I can think of which might easen the user experience:

  • Use a DynamicArray instead of a table. This enables fields such as EntityOptionField, which gives the user the option to select an image and attach a caption.
  • Make an editor for the image entity itself, such that captions can be edited at that entity
  • Generate a UserException if not all images have captions attached

Apart from that, you currently use child entities to hold files. Perhaps a MultiFileField does what you want it to do as well while keeping the user in the same editor.

Hope this information helps you to decide what would be best with respect to user interaction!

The solution I went with was to follow @ymacken suggestion and make a tree structure app in the suggested format. After making the report, a function iterates over the image entities (child entities) and deletes them.