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