diff --git a/.gitignore b/.gitignore
index c7d958b..cc9af04 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
node_modules
data/*
+.env
\ No newline at end of file
diff --git a/default.env b/default.env
new file mode 100644
index 0000000..2db7f32
--- /dev/null
+++ b/default.env
@@ -0,0 +1,2 @@
+YOLO_WEB_URL=http://localhost:3333
+YOLOv5=../yolo_train/
\ No newline at end of file
diff --git a/dist/index.js b/dist/index.js
index 0c61e53..5e0a94f 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -38,7 +38,8 @@ function fileFilter(req, file, cb) {
cb(new Error("Dataset is not of type zip"), false);
}
}
-const upload = (0, multer_1.default)({ storage, fileFilter });
+const uploadZip = (0, multer_1.default)({ storage, fileFilter });
+const uploadOnnx = (0, multer_1.default)({ storage });
app.use(body_parser_1.default.json());
app.use(body_parser_1.default.urlencoded({ extended: true }));
function hash(path) {
@@ -80,6 +81,10 @@ async function status(id) {
return db.all(query, [id], (err, rows) => {
if (err)
return reject(err);
+ if (rows.length !== 1) {
+ return resolve(jobStatus);
+ }
+ const obj = rows[0];
if (rows[0].started === null) {
jobStatus = `Has not started`;
}
@@ -89,6 +94,9 @@ async function status(id) {
else if (rows[0].completed !== null) {
jobStatus = `Completed ${rows[0].completed} Download`;
}
+ else if (rows[0].started !== null) {
+ jobStatus = `Started ${rows[0].started}`;
+ }
console.log(`Got status for job ${id}: ${jobStatus}`);
return resolve(jobStatus);
});
@@ -132,9 +140,64 @@ async function job() {
if (err)
return reject(err);
if (rows.length < 1) {
- return resolve(null);
+ return resolve([]);
}
- return resolve(rows[0].id);
+ return resolve([rows[0].id]);
+ });
+ });
+}
+async function jobs() {
+ const query = `SELECT id FROM queue WHERE
+ started IS NULL
+ AND completed IS NULL
+ AND failed IS NULL
+ ORDER BY created ASC;`;
+ return new Promise((resolve, reject) => {
+ return db.all(query, [], (err, rows) => {
+ if (err)
+ return reject(err);
+ return resolve(rows.map((el) => el.id));
+ });
+ });
+}
+async function claim(id) {
+ const query = `SELECT * FROM queue WHERE id = ? LIMIT 1;`;
+ return new Promise((resolve, reject) => {
+ return db.all(query, [id], (err, rows) => {
+ if (err)
+ return reject(err);
+ if (rows.length < 1) {
+ return reject(new Error(`Dataset ${id} does not exist`));
+ }
+ if (rows[0].started !== null) {
+ return reject(new Error(`Job ${id} is already claimed`));
+ }
+ const claimQuery = `UPDATE queue SET started = CURRENT_TIMESTAMP WHERE id = ?;`;
+ return db.run(claimQuery, [id], (err, row) => {
+ if (err)
+ return reject(err);
+ return resolve(rows[0]);
+ });
+ });
+ });
+}
+async function fail(id, meta) {
+ const query = `UPDATE queue SET failed = CURRENT_TIMESTAMP, meta = ? WHERE id = ?;`;
+ return new Promise((resolve, reject) => {
+ return db.run(query, [meta, id], (err, row) => {
+ if (err)
+ return reject(err);
+ return resolve(true);
+ });
+ });
+}
+async function complete(id, meta) {
+ const query = `UPDATE queue SET completed = CURRENT_TIMESTAMP, meta = ? WHERE id = ?;`;
+ return new Promise((resolve, reject) => {
+ return db.run(query, [meta, id], (err, row) => {
+ if (err)
+ return reject(err);
+ return resolve(true);
});
});
}
@@ -149,7 +212,7 @@ app.get('/', async (req, res, next) => {
}
res.send(html);
});
-app.post('/', upload.single('dataset'), async (req, res, next) => {
+app.post('/', uploadZip.single('dataset'), async (req, res, next) => {
let fileHash;
let filePath;
let fileExists;
@@ -175,7 +238,7 @@ app.post('/', upload.single('dataset'), async (req, res, next) => {
}
if (!fileExists) {
try {
- await promises_1.default.rename(req.file.path, filePath);
+ await promises_1.default.copyFile(req.file.path, filePath);
console.log(`Saved dataset with hash ${fileHash}`);
}
catch (err) {
@@ -185,12 +248,12 @@ app.post('/', upload.single('dataset'), async (req, res, next) => {
}
else {
console.warn(`Dataset with hash ${fileHash} already exists...`);
- try {
- await promises_1.default.unlink(req.file.path);
- }
- catch (err) {
- console.error(err);
- }
+ }
+ try {
+ await promises_1.default.unlink(req.file.path);
+ }
+ catch (err) {
+ console.error(err);
}
try {
id = await add(req.body.email, req.body.name, fileHash, req.body.model);
@@ -201,6 +264,42 @@ app.post('/', upload.single('dataset'), async (req, res, next) => {
}
res.send(`
Dataset for job ${req.body.name} has been uploaded successfully. You will be emailed when your job has started and when it has completed training.
Monitor job status here: ${id}`);
});
+app.post('/job/:id', uploadOnnx.single('model'), async (req, res, next) => {
+ let filePath;
+ let meta = null;
+ let id;
+ req.setTimeout(0);
+ if (typeof req.file === 'undefined' && req.file === null) {
+ console.error('No file in upload');
+ return next('ERROR: Please model as ONNX file');
+ }
+ filePath = (0, path_1.join)(data, `${id}.onnx`);
+ if (typeof req.body.meta !== 'undefined') {
+ meta = req.body.meta;
+ }
+ try {
+ await promises_1.default.copyFile(req.file.path, filePath);
+ console.log(`Saved model for job ${id}`);
+ }
+ catch (err) {
+ console.error(err);
+ return next(err);
+ }
+ try {
+ await promises_1.default.unlink(req.file.path);
+ }
+ catch (err) {
+ console.error(err);
+ }
+ try {
+ await complete(id, meta);
+ }
+ catch (err) {
+ console.log(err);
+ return next(`Error completing training job ${id}`);
+ }
+ res.json({ id });
+});
app.get('/job/:id', async (req, res, next) => {
let jobStatus;
if (typeof req.params.id === 'undefined' || req.params.id === null) {
@@ -297,18 +396,72 @@ app.get('/dataset/:id', async (req, res, next) => {
stream.pipe(res);
});
app.get('/job', async (req, res, next) => {
- let jobId;
+ let jobArr;
try {
- jobId = await job();
+ jobArr = await job();
}
catch (err) {
console.error(err);
return next('Error getting job');
}
- res.json([jobId]);
+ res.json(jobArr);
+});
+app.get('/jobs', async (req, res, next) => {
+ let jobArr;
+ try {
+ jobArr = await jobs();
+ }
+ catch (err) {
+ console.error(err);
+ return next('Error getting job');
+ }
+ res.json(jobArr);
+});
+app.post('/job/claim/:id', async (req, res, next) => {
+ let id;
+ let jobObj;
+ let resObj = {};
+ if (typeof req.params.id === 'undefined' || req.params.id === null) {
+ console.error(`No dataset id provided`);
+ return next('Invalid request');
+ }
+ id = req.params.id;
+ try {
+ jobObj = await claim(id);
+ console.log(`Job ${id} was claimed`);
+ }
+ catch (err) {
+ console.error(err);
+ return next('Error claiming job');
+ }
+ resObj.id = id;
+ resObj.path = `/dataset/${id}`;
+ resObj.dataset = jobObj.dataset;
+ resObj.model = jobObj.model;
+ resObj.name = jobObj.name;
+ res.json(resObj);
+});
+app.post('/job/fail/:id', async (req, res, next) => {
+ let id;
+ let meta = null;
+ if (typeof req.params.id === 'undefined' || req.params.id === null) {
+ console.error(`No dataset id provided`);
+ return next('Invalid request');
+ }
+ id = req.params.id;
+ if (typeof req.body.meta !== 'undefined') {
+ meta = req.body.meta;
+ }
+ try {
+ await fail(id, meta);
+ console.log(`Job ${id} failed`);
+ }
+ catch (err) {
+ console.error(err);
+ return next('Error failing job');
+ }
+ res.json(true);
});
-//app.get('/jobs');
-//app.post('/job/started/:id', )
app.listen(port, () => {
console.log(`yolo_web running on port ${port}`);
});
diff --git a/dist/index.js.map b/dist/index.js.map
index ca29a6c..fde43b1 100644
--- a/dist/index.js.map
+++ b/dist/index.js.map
@@ -1 +1 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/docker-compose.yaml b/docker-compose.yaml
new file mode 100644
index 0000000..6f0c730
--- /dev/null
+++ b/docker-compose.yaml
@@ -0,0 +1,9 @@
+services:
+ yolo_web:
+ image: yolo_web
+ container_name: yolo_web
+ volumes:
+ - './views:/code/views'
+ - './data/:/code/data'
+ ports:
+ - '3333:3333'
\ No newline at end of file
diff --git a/scripts/claim.sh b/scripts/claim.sh
new file mode 100644
index 0000000..2a9bf1f
--- /dev/null
+++ b/scripts/claim.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+if [ -f .env ]; then
+ source .env
+fi
+
+if [ -z ${1} ]; then
+ echo "Please provide a job"
+ exit 1
+fi
+
+JOB="${1}"
+
+JSON=$(curl -s -X POST "${YOLO_WEB_URL}/job/claim/${JOB}")
+
+if [[ "${JSON}" != *"{"* ]]; then
+ echo ERROR
+ echo "${JSON}"
+ exit 1
+fi
+
+bash ./scripts/train.sh "${JSON}"
\ No newline at end of file
diff --git a/scripts/job.sh b/scripts/job.sh
new file mode 100644
index 0000000..f608665
--- /dev/null
+++ b/scripts/job.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+set -e
+
+if [ -f .env ]; then
+ source .env
+fi
+
+if [ -z ${YOLO_WEB_URL} ]; then
+ YOLO_WEB_URL=http://localhost:3333
+fi
+
+JOB_JSON=$(curl -s "${YOLO_WEB_URL}/job")
+JOB=$(echo $JOB_JSON | jq -r '.[0]')
+
+if [[ "${JOB}" != "null" ]]; then
+ bash ./scripts/claim.sh "${JOB}"
+else
+ echo "No jobs"
+fi
\ No newline at end of file
diff --git a/scripts/train.sh b/scripts/train.sh
new file mode 100644
index 0000000..4f327ce
--- /dev/null
+++ b/scripts/train.sh
@@ -0,0 +1,47 @@
+set -e
+
+if [ -f .env ]; then
+ source .env
+fi
+
+if [ -z ${1} ]; then
+ echo "Please provide a JSON object"
+ exit 1
+fi
+
+function fail () {
+ ID="${1}"
+ META=${2}
+ URL="${YOLO_WEB_URL}/job/fail/${ID}"
+ echo "${META}"
+ curl -s -X POST \
+ -H 'Content-Type: application/json' \
+ -d "{\"meta\":\"${META}\"}" "${URL}"
+}
+
+JSON="${1}"
+
+ID=$(echo $JSON | jq -r '.id')
+DATASET=$(echo $JSON | jq -r '.dataset')
+MODEL=$(echo $JSON | jq -r '.model')
+NAME=$(echo $JSON | jq -r '.name')
+FILEPATH=$(echo $JSON | jq -r '.path')
+
+DOWNLOAD="${YOLO_WEB_URL}${FILEPATH}"
+DEST="${YOLOv5}${DATASET}.zip"
+UNZIPPED="${YOLOv5}${DATASET}"
+
+echo "Downloading ${DOWNLOAD}"
+
+if [ ! -f "${DEST}" ]; then
+ wget -q -O "${DEST}" "${DOWNLOAD}"
+fi
+
+unzip "${DEST}" -d "${UNZIPPED}"
+
+if [ ! -f "${UNZIPPED}/data.yaml" ]; then
+ fail "${ID}" "Invalid dataset"
+ rm -rf "${UNZIPPED}"
+ rm "${DEST}"
+ exit 1
+fi
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index 069b7b9..592ef3e 100755
--- a/src/index.ts
+++ b/src/index.ts
@@ -38,7 +38,8 @@ function fileFilter (req: any, file: any, cb: any) {
}
}
-const upload : any = multer({ storage, fileFilter });
+const uploadZip : any = multer({ storage, fileFilter });
+const uploadOnnx : any = multer({ storage });
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
@@ -82,12 +83,18 @@ async function status (id : string) : Promise {
return new Promise((resolve : Function, reject : Function) => {
return db.all(query, [id], (err : Error, rows : any) => {
if (err) return reject(err);
+ if (rows.length !== 1) {
+ return resolve(jobStatus);
+ }
+ const obj : any = rows[0];
if (rows[0].started === null) {
jobStatus = `Has not started`
} else if (rows[0].failed !== null) {
jobStatus = `Failed
${rows[0].meta}
`;
} else if (rows[0].completed !== null) {
jobStatus = `Completed ${rows[0].completed} Download`;
+ } else if (rows[0].started !== null) {
+ jobStatus = `Started ${rows[0].started}`;
}
console.log(`Got status for job ${id}: ${jobStatus}`);
return resolve(jobStatus);
@@ -121,7 +128,7 @@ async function dataset (id : string) : Promise {
});
}
-async function job () : Promise {
+async function job () : Promise {
const query : string = `SELECT id FROM queue WHERE
started IS NULL
AND completed IS NULL
@@ -132,9 +139,23 @@ async function job () : Promise {
return db.all(query, [], (err : Error, rows : any) => {
if (err) return reject(err);
if (rows.length < 1) {
- return resolve(null);
+ return resolve([]);
}
- return resolve(rows[0].id);
+ return resolve([rows[0].id]);
+ });
+ });
+}
+
+async function jobs () : Promise {
+ const query : string = `SELECT id FROM queue WHERE
+ started IS NULL
+ AND completed IS NULL
+ AND failed IS NULL
+ ORDER BY created ASC;`;
+ return new Promise((resolve : Function, reject : Function) => {
+ return db.all(query, [], (err : Error, rows : any) => {
+ if (err) return reject(err);
+ return resolve(rows.map((el : any) => el.id));
});
});
}
@@ -150,7 +171,7 @@ async function claim (id : string) : Promise {
if (rows[0].started !== null) {
return reject(new Error(`Job ${id} is already claimed`));
}
- const claimQuery : string = `UPDATE queue SET started = CURRENT_TIMESTAMP WHERE id = ? LIMIT 1;`;
+ const claimQuery : string = `UPDATE queue SET started = CURRENT_TIMESTAMP WHERE id = ?;`;
return db.run(claimQuery, [id], (err : Error, row : any) => {
if (err) return reject(err);
return resolve(rows[0]);
@@ -159,10 +180,20 @@ async function claim (id : string) : Promise {
});
}
-async function fail (id : string, meta : string) : Promise {
- const query : string = `UPDATE queue SET failed = CURRENT_TIMESTAMP WHERE id = ? LIMIT 1;`;
+async function fail (id : string, meta : string | null) : Promise {
+ const query : string = `UPDATE queue SET failed = CURRENT_TIMESTAMP, meta = ? WHERE id = ?;`;
return new Promise((resolve : Function, reject : Function) => {
- return db.run(query, [ id ], (err : Error, row : any) => {
+ return db.run(query, [ meta, id], (err : Error, row : any) => {
+ if (err) return reject(err);
+ return resolve(true);
+ });
+ });
+}
+
+async function complete (id : string, meta : string | null) : Promise {
+ const query : string = `UPDATE queue SET completed = CURRENT_TIMESTAMP, meta = ? WHERE id = ?;`;
+ return new Promise((resolve : Function, reject : Function) => {
+ return db.run(query, [ meta, id ], (err : Error, row : any) => {
if (err) return reject(err);
return resolve(true);
});
@@ -180,7 +211,7 @@ app.get('/', async (req : Request, res : Response, next : NextFunction) => {
res.send(html);
});
-app.post('/', upload.single('dataset'), async (req : Request, res : Response, next : NextFunction) => {
+app.post('/', uploadZip.single('dataset'), async (req : Request, res : Response, next : NextFunction) => {
let fileHash : string;
let filePath : string;
let fileExists : boolean;
@@ -209,20 +240,20 @@ app.post('/', upload.single('dataset'), async (req : Request, res : Response, ne
if (!fileExists) {
try {
- await fs.rename(req.file.path, filePath);
+ await fs.copyFile(req.file.path, filePath);
console.log(`Saved dataset with hash ${fileHash}`);
} catch (err) {
console.error(err);
return next(err);
}
-
} else {
console.warn(`Dataset with hash ${fileHash} already exists...`);
- try {
- await fs.unlink(req.file.path);
- } catch (err) {
- console.error(err);
- }
+ }
+
+ try {
+ await fs.unlink(req.file.path);
+ } catch (err) {
+ console.error(err);
}
try {
@@ -235,6 +266,47 @@ app.post('/', upload.single('dataset'), async (req : Request, res : Response, ne
res.send(`Dataset for job ${req.body.name} has been uploaded successfully. You will be emailed when your job has started and when it has completed training.
Monitor job status here: ${id}`);
});
+app.post('/job/:id', uploadOnnx.single('model'), async (req : Request, res : Response, next : NextFunction) => {
+ let filePath : string;
+ let meta : string = null;
+ let id : string;
+
+ req.setTimeout(0);
+
+ if (typeof req.file === 'undefined' && req.file === null) {
+ console.error('No file in upload');
+ return next('ERROR: Please model as ONNX file');
+ }
+
+ filePath = join(data, `${id}.onnx`);
+ if (typeof req.body.meta !== 'undefined') {
+ meta = req.body.meta;
+ }
+
+ try {
+ await fs.copyFile(req.file.path, filePath);
+ console.log(`Saved model for job ${id}`);
+ } catch (err) {
+ console.error(err);
+ return next(err);
+ }
+
+ try {
+ await fs.unlink(req.file.path);
+ } catch (err) {
+ console.error(err);
+ }
+
+ try {
+ await complete(id, meta);
+ } catch (err) {
+ console.log(err);
+ return next(`Error completing training job ${id}`);
+ }
+
+ res.json({ id });
+});
+
app.get('/job/:id', async (req : Request, res : Response, next : NextFunction) => {
let jobStatus : string;
@@ -344,16 +416,29 @@ app.get('/dataset/:id', async (req : Request, res: Response, next : NextFunction
});
app.get('/job', async (req : Request, res: Response, next : NextFunction) => {
- let jobId : string;
+ let jobArr : string[];
try {
- jobId = await job();
+ jobArr = await job();
} catch (err) {
console.error(err);
return next('Error getting job');
}
- res.json([jobId]);
+ res.json(jobArr);
+});
+
+app.get('/jobs', async (req : Request, res: Response, next : NextFunction) => {
+ let jobArr : string[];
+
+ try {
+ jobArr = await jobs();
+ } catch (err) {
+ console.error(err);
+ return next('Error getting job');
+ }
+
+ res.json(jobArr);
});
app.post('/job/claim/:id', async (req : Request, res: Response, next : NextFunction) => {
@@ -370,22 +455,24 @@ app.post('/job/claim/:id', async (req : Request, res: Response, next : NextFunct
try {
jobObj = await claim(id);
+ console.log(`Job ${id} was claimed`);
} catch (err) {
console.error(err);
return next('Error claiming job');
}
- resJob.id = id;
- resJob.datasetPath = `/dataset/${id}`;
- resJob.model = jobObj.model;
+ resObj.id = id;
+ resObj.path = `/dataset/${id}`;
+ resObj.dataset = jobObj.dataset;
+ resObj.model = jobObj.model;
+ resObj.name = jobObj.name;
- res.json(resJob);
+ res.json(resObj);
});
app.post('/job/fail/:id', async (req : Request, res: Response, next : NextFunction) => {
let id : string;
- let jobObj : any;
- let resObj : any = {};
+ let meta : string = null;
if (typeof req.params.id === 'undefined' || req.params.id === null) {
console.error(`No dataset id provided`);
@@ -393,22 +480,20 @@ app.post('/job/fail/:id', async (req : Request, res: Response, next : NextFuncti
}
id = req.params.id;
-
- try {
- jobObj = await claim(id);
- } catch (err) {
- console.error(err);
- return next('Error claiming job');
+ if (typeof req.body.meta !== 'undefined') {
+ meta = req.body.meta;
}
- resJob.id = id;
- resJob.datasetPath = `/dataset/${id}`;
- resJob.model = jobObj.model;
+ try {
+ await fail(id, meta);
+ console.log(`Job ${id} failed`);
+ } catch (err) {
+ console.error(err);
+ return next('Error failing job');
+ }
- res.json(resJob);
+ res.json(true);
});
-//app.get('/jobs');
-//app.post('/job/started/:id', )
app.listen(port, () => {
console.log(`yolo_web running on port ${port}`);