Hi Ibrahim,
Welcome to the community! And thank you for your question. If I understand you correctly, you would like to have a dynamic list of options based on the uploaded csv file. To achieve this, some things need to be understood first:
- Callback functions
One of the ways to create a dynamic option field is by defining a function that produces a list of options based on certain input and logic. These functions need to be defined in a certain format before they can be added to the options
argument of the OptionField
object. The format is as follows:
def name_of_callback_function(params, **kwargs):
...
return [...]
The input that can be passed on in the key word arguments are:
- params: the parameters defined in the parametrization
- entity_id
- entity_name
For your example, only the params
will be necessary.
- The
FileField
The FileField
is used to if a developer wants to upload a file of sorts. To be able to retrieve the uploaded file, this can be retrieved from the name of the variable on which the FileField
is defined. In your case, the name file
. The object that is obtained, however, is not a File
object, but rather a FileResource
object. A FileResource
object holds both the properties file
(which returns a File
object) and filename
.
- Combining both
Knowing about this, to achieve your case, let us first rewrite your callback function:
import StringIO
import pandas as pd
from viktor import File
from viktor.api_v1 import FileResource
def extract_data(params, **kwargs):
my_csv_file_resource: FileResource = params.file
if not my_csv_file_resource:
# in the case of no file uploaded, return an empty list of options
return []
my_csv_file: File = my_csv_file_resource.file
# convert `File` to `StringIO`
csv_stringio = StringIO(my_csv_file.getvalue())
# convert `StringIO` to `DataFrame`
df = pd.read_csv(csv_stringio, sep=‘;’)
options = df.columns.values.tolist()
return options
(For more information on converting a string to a pandas DataFrame
object, refer to this link.)
And then, the parametrization:
from viktor.parametrization import ViktorParametrization, FileField, OptionField
class Parametrization(ViktorParametrization):
#uploading file
file = FileField(‘Upload a CSV’, file_types=[‘.csv’])
#optionfields
main_column = OptionField('Choose main property', options=extract_data)
count_column = OptionField('Choose property to analyse', options=extract_data)
For more information, refer to the following link, which also describes how callback functions can be used to make an OptionField
dynamic.
I hope this answers your question.