Building the app skeleton
When we have an empty file, the best starting option is to always use the skeleton we adopted in the two web applications we implemented previously. So, we can import the libraries – in this case, just streamlit – and then define a main function containing the menu. The menu for this chapter’s app is quite light in that it just contains two voices: Dropfiles and About.
In the following figure, we can see how short the skeleton we are using for this specific case is:
Figure 12.2: The skeleton of our app
Here’s a breakdown of the code shown in Figure 12.2:
- On line 1, we import the library (here, streamlit), while on line 4, we define the main function – that is, the function containing the business logic of our app.
- On line 5, we have a list named menu containing the values of the web application menu (the functions this web application can offer).
- On line 6, we create a select box starting from the menu list in the sidebar.
- On lines 8 and 13, we add an if clause that enters the proper code to execute according to the selection that was performed in the selectbox on line 6.
With that, we have the skeleton of our app. Now, we can write the following instruction in the terminal:
pipenv run streamlit run app.py
At this point, we can start the web application and see it in our browser:
Figure 12.3: First execution of our new web app
As we can see, in the sidebar, there is a selectbox offering the two options in the menu.
Let’s focus on the Dropfile voice of the menu.
Creating a radio button for the app menu
We can use a radio button to let the user indicate what kind of file they would like to upload. Let’s add the following code:
file_selection = st.radio(“Select the file type”, [‘TXT’, ‘DOCX’, ‘PDF’])
In this way, the file selection is stored in a variable named file_selection. So far, our app looks as follows:
Figure 12.4: Selecting the file type with radio buttons
Once the user selects an option, we are ready to open file_uploader using the file type as the selected option. The following code can be adopted in this case:
raw_text_file = st.file_uploader(“Upload File”, type=[‘txt’])
if raw_text_file is not None:
try:
raw_text = str(raw_text_file.read(),”utf-8″)
st.info(“Text from TXT file”)
st.write(raw_text)
except:
st.warning(“TXT File Fetching Problem…”)
Quite easily, after uploading the file (with the txt type), we can check that the file is not null, read it using utf-8 encoding, and visualize it on the screen. If the uploaded file is null, we just print a warning on the screen stating TXT File Fetching Problem….
Figure 12.5 shows the code in the IDE:
Figure 12.5: Uploading a .txt file
When we move to the browser, something interesting happens. Even if we have three different files containing text in our directory – that is, ‘txt’, ‘docx’, and ‘pdf’ – since we specify txt as the type, the file uploader just sees and can open the .txt file:
Figure 12.6: In the directory on the left, there are three different files, but we can only open the .txt file
At this point, to manage other file types, we should write more or less the same code we used for the txt type but also specify the different types. So, the code can evolve into something like this:
Figure 12.7: Asking the user for the type of file
The code in Figure 12.7 contains a couple of pass calls for .docx and .pdf files. If you want to complete the related functions, you must import the proper library and read the content of the files.
The real point here is that when approaching file uploading in this way, even if the code works very well technically, we are forced to do a couple of operations we don’t like that much:
- Asking the user about the type of file at the beginning
- Repeating (we just copy and paste) a lot of code that is redundant
Now that we’ve explored this solution, let’s try to implement something much more elegant and cleaner that can automatically read the type of file, without asking the user.