diff --git a/task_common.py b/task_common.py
new file mode 100644
index 0000000000000000000000000000000000000000..28624405470dc3647eb866fdbe2529eda5da849a
--- /dev/null
+++ b/task_common.py
@@ -0,0 +1,99 @@
+from typing import Optional
+from pathlib import Path
+import yaml
+import os
+import logging
+LOG_FMT = '%(asctime)s %(message)s'
+logging.basicConfig(format=FORMAT)
+logger = logging.getLogger('JudgeAPI')
+"""
+Task common, the file defining the API that will be used for the C judge system.
+
+This API assumes the following course structure:
+
+
+ course/
+ | task_folder/
+ | | student/
+ | | | [lib_folders]
+ | | | [test files]
+ | | | [build files]
+ | | | template file
+ | | | annex file
+ | | run
+ | | task.yaml
+ | < ... >
+ | course.yaml
+ | run
+ | annex
+
+Where annex files can be any file used by the course/task, and the elements between square brackets are optional
+"""
+@dataclass
+class TaskData:
+ template: Path
+ task: dict #Parsed task.yaml describing the task
+ build_script: Optional[Path] #Used to store the optional scripts that are needed to compile the student's code
+ lib_dirs: Optional[list[Path]] #Used to store the paths of the libraries and includes used by the task
+ annex: Optional[list[Path]] #Used to store a list of paths with annex files
+
+
+
+def task_dir_validate(task_dir_path: Path) -> bool:
+ """
+ @brief: performs various checks ensure the task_dir contains everything needed for further work using this API
+
+ @param task_dir_path: (Path) instance of a path object pointing to the target task directory to check
+
+ @return boolean: True if the task directory can be parsed by this API, False otherwise
+ """
+ if not os.path.exists(task_dir_path):
+ logger.debug(f"task path {str(task_dir_path)} does not exist")
+ return False
+ #list task files
+ dir_content = os.listdir()
+ dir_files = {str(f).lower():f for f in dir_content if os.path.isfile(f)}
+ dir_subdirs = {str(d).lower():d for d in dir_content if os.path.isdir(d)}
+
+ #check for mandatory files and subdirectories
+ if "task.yaml" not in dir_files and "task.yml" not in dir_files:
+ logger.debug(f"Could not find task.yaml in {str(task_dir_path)}")
+ return False
+
+ if "run" not in dir_files:
+ logger.debug(f"Could not find run file in {task_dir_path}")
+ return False
+
+ if "student" not in dir_subdirs:
+ logger.debug(f"Could not find student folder in {task_dir_path}. Maybe the tasks are too simple for using this API ?")
+ return False
+
+ #check the content of the student directory
+
+ student_dir = os.path.join(task_dir_path, dir_subdirs['student'])
+ student_dir_content_splitted = [str(c).to_lower().split('.') for c in os.listdir(student_dir)]
+ student_dir_content_ext = [splitted[1] for c in student_dir_content_splitted if len(splitted) > 1]
+ if 'tpl' not in student_dir_content_ext:
+ logger.debug(f"Could not find template file in {str(student_dir)}")
+ return False
+
+ logger.debug(f"Validated task directory {str(task_dir_path)}")
+ return True
+
+
+
+
+
+
+
+
+
+
+
+
+
+def task_dir_to_obj(task_dir_path: Path) -> TaskData:
+ """
+ @brief: Use a task directory to parse a task into a task dictionary
+ """
+ pass
\ No newline at end of file