Skip to content

Commit

Permalink
fix: removed autopopulated input, and workflow improved
Browse files Browse the repository at this point in the history
- resolves #16 by removing the spoof_metadata; now the user should enter
  data
- some strange behaviour with the time coming from the file metadata,
  see #21.

- workflow changed so that now:
  1. the user must fill all fields before the validate button is activated
  2. the user must click validate before the classifier button is activated

- implementation for (1) is handled by adding unique keys to all the
  input elements, and adding `check_inputs_are_set -> bool` to ease
  checking the whole group.
  • Loading branch information
rmm-ch committed Jan 17, 2025
1 parent 16fcc83 commit bd70dda
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 10 deletions.
56 changes: 50 additions & 6 deletions src/input_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,38 @@ def get_image_latlon(image_file: UploadedFile) -> tuple[float, float] | None:
"time": None,
}

def check_inputs_are_set(debug:bool=False) -> bool:
"""
Checks if all expected inputs have been entered
Implementation: via the Streamlit session state.
Args:
debug (bool): If True, prints and logs the status of each expected input key. Default is False.
Returns:
bool: True if all expected input keys are set, False otherwise.
"""

exp_input_keys = ["input_latitude", "input_longitude", "input_author_email", "input_date", "input_time", "input_image_selector"]
vals = []
for k in exp_input_keys:
val = None
if k in st.session_state:
val = st.session_state[k]

vals.append(val)

if debug:
msg = f"{k:15}, {(val is not None):8}, {val}"
m_logger.debug(msg)
print(msg)

return all([v is not None for v in vals])





#def display_whale(whale_classes:List[str], i:int, viewcontainer=None):
def setup_input(
viewcontainer: DeltaGenerator=None,
Expand Down Expand Up @@ -269,7 +301,7 @@ def setup_input(
viewcontainer.title("Input image and data")

# 1. Image Selector
uploaded_filename = viewcontainer.file_uploader("Upload an image", type=allowed_image_types)
uploaded_filename = viewcontainer.file_uploader("Upload an image", type=allowed_image_types, key="input_image_selector")
image_datetime = None # For storing date-time from image

if uploaded_filename is not None:
Expand All @@ -292,18 +324,18 @@ def setup_input(


# 2. Latitude Entry Box
latitude = viewcontainer.text_input("Latitude", spoof_metadata.get('latitude', ""))
latitude = viewcontainer.text_input("Latitude", placeholder="from image metadata if present", key="input_latitude")
if latitude and not is_valid_number(latitude):
viewcontainer.error("Please enter a valid latitude (numerical only).")
m_logger.error(f"Invalid latitude entered: {latitude}.")
# 3. Longitude Entry Box
longitude = viewcontainer.text_input("Longitude", spoof_metadata.get('longitude', ""))
longitude = viewcontainer.text_input("Longitude", placeholder="from image metadata if present", key="input_longitude")
if longitude and not is_valid_number(longitude):
viewcontainer.error("Please enter a valid longitude (numerical only).")
m_logger.error(f"Invalid latitude entered: {latitude}.")

# 4. Author Box with Email Address Validator
author_email = viewcontainer.text_input("Author Email", spoof_metadata.get('author_email', ""))
author_email = viewcontainer.text_input("Author Email", placeholder="[email protected]", key="input_author_email")

if author_email and not is_valid_email(author_email):
viewcontainer.error("Please enter a valid email address.")
Expand All @@ -318,11 +350,23 @@ def setup_input(
date_value = datetime.datetime.now().date()

## if not, give user the option to enter manually
date_option = st.sidebar.date_input("Date", value=date_value)
time_option = st.sidebar.time_input("Time", time_value)
date_option = st.sidebar.date_input("Date", value=date_value, key="input_date")
time_option = st.sidebar.time_input("Time", value=time_value, key="input_time")

observation = InputObservation(image=uploaded_filename, latitude=latitude, longitude=longitude,
author_email=author_email, date=image_datetime, time=None,
date_option=date_option, time_option=time_option)

# add a label to say if inputs are all entered yet. use the func check_inputs_are_set
# all_set = check_inputs_are_set(True)
# if all_set:
# clr = 'gray'
# else:
# clr = 'red'
# viewcontainer.markdown(f":{clr}[Inputs are all set? {all_set}]")




return observation

12 changes: 8 additions & 4 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,11 @@ def main() -> None:


# Display submitted data
if st.sidebar.button("Validate"):
all_inputs_entered = sw_inp.check_inputs_are_set()
if not all_inputs_entered:
st.sidebar.button("Validate", disabled=True, help="Please fill in all fields.")

elif st.sidebar.button("**Validate**"):
# create a dictionary with the submitted data
submitted_data = observation.to_dict()
#print(submitted_data)
Expand All @@ -252,16 +256,16 @@ def main() -> None:
st.table(df)




# inside the inference tab, on button press we call the model (on huggingface hub)
# which will be run locally.
# - the model predicts the top 3 most likely species from the input image
# - these species are shown
# - the user can override the species prediction using the dropdown
# - an observation is uploaded if the user chooses.
if st.session_state.full_data == {}:
tab_inference.button("Identify with cetacean classifier", disabled=True, help="Please validate inputs before proceeding", key="button_infer_ceteans")

if tab_inference.button("Identify with cetacean classifier"):
elif tab_inference.button("Identify with cetacean classifier", key="button_infer_ceteans"):
#pipe = pipeline("image-classification", model="Saving-Willy/cetacean-classifier", trust_remote_code=True)
cetacean_classifier = AutoModelForImageClassification.from_pretrained("Saving-Willy/cetacean-classifier",
revision=classifier_revision,
Expand Down

0 comments on commit bd70dda

Please sign in to comment.