Repository: NatLibFi/Annif (language: python)

Issue:
Use Python type hints
Since Python 3.5 it has been possible to add type hints for variables and function/method signatures ([PEP 484](https://peps.python.org/pep-0484/)).

We should do this within the Annif codebase as well. [Here](https://towardsdatascience.com/12-beginner-concepts-about-type-hints-to-improve-your-python-code-90f1ba0ac49) is a good basic tutorial about the available types and how to use them. Quoting from the post:

> Type hints bring an additional layer of abstraction on top of your code: they help to document it, clarify the assumptions about inputs/outputs and prevent insidious and silent mistakes when static code analysis (👋 mypy) is performed on top.

Eventually we should also enforce the type hints with [mypy](https://mypy-lang.org/), but let's leave that out of scope for this issue so that it can be closed once we have the hints in place at least for a reasonable proportion of the codebase.


Discussion / hints:
[A few tools have been mentioned](https://stackoverflow.com/a/50416746) that can help by (semi)automatically generating the type annotations:

> Sure, there are some projects out there that can help out.
> 
>>   Instagram developed the MonkeyType tool to pick up runtime type information. These are output as stubs files, but you can use the tools included to apply those to your source files as inline annotations, or use the retype project to do the same.
>>   Dropbox has a similar tool called pyannotate; this tool can generate either Python 2 type hint comments or annotations.
> 
> Neither project will produce perfect type hints; always take their output as a starting point, not the authoritative final annotations.

Fix patch:
diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml
index f415ebc91..fd28a25c0 100644
--- a/.github/workflows/cicd.yml
+++ b/.github/workflows/cicd.yml
@@ -36,6 +36,24 @@ jobs:
       run: |
         poetry run flake8
 
+  time-startup:
+    runs-on: ubuntu-22.04
+    name: check CLI startup time
+    steps:
+    - uses: actions/checkout@v3
+    - name: "Prepare: restore caches, install Poetry, set up Python"
+      id: prepare
+      uses: ./.github/actions/prepare
+      with:
+        python-version: "3.9"
+        poetry-version: ${{ env.POETRY_VERSION }}
+    - name: Install Python dependencies
+      run: |
+        poetry install
+    - name: Check startup time
+      run: |
+        poetry run tests/time-startup.sh
+
   test:
     runs-on: ubuntu-22.04
     timeout-minutes: 15


Test patch:
diff --git a/tests/time-startup.sh b/tests/time-startup.sh
new file mode 100755
index 000000000..dabb56134
--- /dev/null
+++ b/tests/time-startup.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Function to measure startup time
+measure_startup_time() {
+    startup_time=$( { time -p annif --help >/dev/null; } 2>&1 | awk '/^user/{u=$2}/^sys/{s=$2} END{print u+s}' )
+    echo "$startup_time"
+}
+
+startup_time1=$(measure_startup_time)
+startup_time2=$(measure_startup_time)
+startup_time3=$(measure_startup_time)
+startup_time4=$(measure_startup_time)
+
+# Calculate the average startup time
+average_startup_time=$(echo "scale=3; ($startup_time1 + $startup_time2 + $startup_time3 + $startup_time4) / 4" | bc)
+
+# Print the average startup time
+echo "Average Startup time: $average_startup_time seconds"
+
+# Set the threshold for acceptable startup time in seconds
+threshold=0.300
+
+# Compare the average startup time with the threshold
+if (( $(echo "$average_startup_time > $threshold" | bc -l) )); then
+    echo "Startup time (user + sys time) exceeds the threshold of $threshold s. Test failed."
+    exit 1
+fi