diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index 4456a0bbf455ade1e3f72ca16f7f28e0daef8d80..e7638d94bea9193bdb7153e1aa23273611e40f78 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -56,6 +56,7 @@ typedef unsigned int size_t;
 #define API_FILE_FLUSH         0x35
 #define API_FILE_SEEK          0x36 //NYI
 #define API_FILE_TELL          0x37 //NYI
+#define API_FILE_STAT          0x38
 /* clang-format on */
 
 typedef uint32_t api_int_id_t;
@@ -463,4 +464,29 @@ API(API_FILE_READ,  int32_t epic_read(int32_t fd, void* buf, uint32_t nbytes));
 API(API_FILE_WRITE, int32_t epic_write(int32_t fd, const void* buf, uint32_t nbytes));
 API(API_FILE_FLUSH, int32_t epic_flush(int32_t fd));
 
+enum epic_stat_type {
+    EPICSTAT_FILE,
+    EPICSTAT_DIR,
+};
+
+typedef struct epic_stat_t {
+    enum epic_stat_type type;
+} epic_stat_t;
+
+/**
+ * stat path
+ *
+ * This does not follow posix convention, but rather takes
+ * a path as parameter. This aligns more with libff's API and
+ * also this has been implemented for python import support, which
+ * passes the filename as well.
+ *
+ * :param const char* filename: path to stat
+ * :param epic_stat_t* stat: pointer to result
+ *
+ * :return: `0` on success, negative on error
+ *      if an error occured.
+ */
+API(API_FILE_STAT,  int32_t epic_stat(const char* path, epic_stat_t* stat));
+
 #endif /* _EPICARDIUM_H */
diff --git a/epicardium/modules/fatfs.c b/epicardium/modules/fatfs.c
index 84622d264287b872b793ca432b6c8e63a2f94755..254f9a0a4fb459bd858ecec8c0cee51935919671 100644
--- a/epicardium/modules/fatfs.c
+++ b/epicardium/modules/fatfs.c
@@ -14,6 +14,7 @@
 #include <semphr.h>
 
 #include "modules.h"
+#include "epicardium.h"
 
 #ifndef EPIC_FAT_STATIC_SEMAPHORE
 #define EPIC_FAT_STATIC_SEMAPHORE 0
@@ -326,3 +327,21 @@ int32_t epic_flush(int32_t fd) {
     return 0;
 }
 
+int32_t epic_stat(const char* filename, epic_stat_t* stat) {
+
+    int res;
+    FILINFO finfo;
+    res = f_stat(filename, &finfo);
+    if (res != FR_OK) {
+        return -fresult_to_errno_table[res];
+    }
+
+    if(finfo.fattrib & AM_DIR) {
+        stat->type = EPICSTAT_DIR;
+    } else {
+        stat->type = EPICSTAT_FILE;
+    }
+
+    return 0;
+}
+
diff --git a/pycardium/meson.build b/pycardium/meson.build
index 453fc752e9c4bbe403b117c65d1c4cf992faded1..42fa849d1da7d63cae02f260495f61dd9875eec3 100644
--- a/pycardium/meson.build
+++ b/pycardium/meson.build
@@ -6,8 +6,9 @@ modsrc = files(
   'modules/sys_display.c',
   'modules/utime.c',
   'modules/vibra.c',
-  'modules/light_sensor.c'
+  'modules/light_sensor.c',
   'modules/fat_file.c',
+  'modules/fat_reader_import.c',
 )
 
 #################################
diff --git a/pycardium/modules/fat_file.c b/pycardium/modules/fat_file.c
index 711217b4dfd0ace444d08ab6a6f03d5676fcc5d5..70f019950915a24e84ae2b19092be1a057e9abf6 100644
--- a/pycardium/modules/fat_file.c
+++ b/pycardium/modules/fat_file.c
@@ -31,6 +31,7 @@
 #include "py/builtin.h"
 #include "py/stream.h"
 #include "py/mperrno.h"
+
 #include "epicardium.h"
 
 extern const mp_obj_type_t mp_type_fat_textio;
@@ -271,3 +272,4 @@ mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs)
 	return file_open(&mp_type_fat_textio, arg_vals);
 }
 MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
+
diff --git a/pycardium/modules/fat_reader_import.c b/pycardium/modules/fat_reader_import.c
new file mode 100644
index 0000000000000000000000000000000000000000..a035754e761f8ff29e8db19baf2fa1cd9e1769a9
--- /dev/null
+++ b/pycardium/modules/fat_reader_import.c
@@ -0,0 +1,79 @@
+#include "epicardium.h"
+
+#include <py/runtime.h>
+#include <py/reader.h>
+#include <py/lexer.h>
+
+/** ported from picropython's posic implementation */
+
+typedef struct _mp_reader_epicfat_t {
+    bool close_fd;
+    int fd;
+    size_t len;
+    size_t pos;
+    byte buf[20];
+} mp_reader_epicfat_t;
+
+STATIC mp_uint_t mp_reader_epicfat_readbyte(void *data) {
+    mp_reader_epicfat_t *reader = (mp_reader_epicfat_t*)data;
+    if (reader->pos >= reader->len) {
+        if (reader->len == 0) {
+            return MP_READER_EOF;
+        } else {
+            int n = epic_read(reader->fd, reader->buf, sizeof(reader->buf));
+            if (n <= 0) {
+                reader->len = 0;
+                return MP_READER_EOF;
+            }
+            reader->len = n;
+            reader->pos = 0;
+        }
+    }
+    return reader->buf[reader->pos++];
+}
+
+STATIC void mp_reader_epicfat_close(void *data) {
+    mp_reader_epicfat_t *reader = (mp_reader_epicfat_t*)data;
+    epic_close(reader->fd);
+    m_del_obj(mp_reader_epicfat_t, reader);
+}
+
+void mp_reader_new_file(mp_reader_t* reader, const char *filename)
+{
+    int fd = epic_open(filename, "r");
+    if (fd < 0) {
+        mp_raise_OSError(-fd);
+    }
+    mp_reader_epicfat_t *rp = m_new_obj(mp_reader_epicfat_t);
+    rp->fd = fd;
+    int n = epic_read(rp->fd, rp->buf, sizeof(rp->buf));
+    if (n < 0) {
+        epic_close(fd);
+    }
+    rp->len = n;
+    rp->pos = 0;
+    reader->data = rp;
+    reader->readbyte = mp_reader_epicfat_readbyte;
+    reader->close = mp_reader_epicfat_close;
+}
+
+mp_lexer_t *mp_lexer_new_from_file(const char *filename)
+{
+    mp_reader_t reader;
+    mp_reader_new_file(&reader, filename);
+    return mp_lexer_new(qstr_from_str(filename), reader);
+}
+
+mp_import_stat_t mp_import_stat(const char *path)
+{
+    struct epic_stat_t stat;
+
+    if(epic_stat(path, &stat) == 0) {
+        if (stat.type == EPICSTAT_FILE) {
+            return MP_IMPORT_STAT_FILE;
+        } else {
+            return MP_IMPORT_STAT_DIR;
+        }
+    }
+	return MP_IMPORT_STAT_NO_EXIST;
+}
diff --git a/pycardium/mphalport.c b/pycardium/mphalport.c
index 7c14df44e3ef09bbc6972b1a442cae8240fe7b36..29784be54638f22eeac9215697eb11f7fd19dd93 100644
--- a/pycardium/mphalport.c
+++ b/pycardium/mphalport.c
@@ -121,14 +121,3 @@ void NORETURN nlr_jump_fail(void *val)
  * Stubs
  */
 
-mp_lexer_t *mp_lexer_new_from_file(const char *filename)
-{
-	/* TODO: Do we need an implementation for this? */
-	mp_raise_OSError(MP_ENOENT);
-}
-
-mp_import_stat_t mp_import_stat(const char *path)
-{
-	return MP_IMPORT_STAT_NO_EXIST;
-}
-