From 1ee2219b8245bba804c658b887525f70af73e738 Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Wed, 16 Jul 2025 23:35:46 -0700 Subject: [PATCH 1/5] mock printer for dev mode --- printer/mock_printer.py | 49 +++++++++++++++++++++++++++++++++++++++++ printer/server.py | 30 ++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 printer/mock_printer.py diff --git a/printer/mock_printer.py b/printer/mock_printer.py new file mode 100644 index 00000000..ad7b158e --- /dev/null +++ b/printer/mock_printer.py @@ -0,0 +1,49 @@ +import time +import logging + +class MockPrinter(): + _instance = None + _current_print_id_num = 0 + _jobs = {} + _queue = [] + + @classmethod + def instance(cls): + if cls._instance is None: + cls._instance = cls.__new__(cls) + return cls._instance + + def get_job_status(self, id: str) -> str: + if id in self._jobs: + return self._jobs[id] + else: + return "PRINTED" + + def remove_job(self, id: str) -> None: + if id in self._jobs: + self._jobs.pop(id, None) + + def lp(self) -> str: + print_id = "HP_LaserJet_p2015dn_Right-" + str(self._current_print_id_num) + self._current_print_id_num += 1 + self._jobs[print_id] = "PENDING" + self._queue.append(print_id) + return print_id + + def update(self) -> None: + while True: + time.sleep(10) + + if self._queue.__len__() == 0: + continue + + if (self._jobs[self._queue[0]] == "PENDING"): + self._jobs[self._queue[0]] = "PRINTED" + self._queue.pop(0) + + def log(self) -> None: + while True: + time.sleep(3) + logging.info("-----------------") + logging.info(f"jobs: {self._jobs}") + logging.info(f"queue: {self._queue}") diff --git a/printer/server.py b/printer/server.py index 17838312..eeb187dc 100644 --- a/printer/server.py +++ b/printer/server.py @@ -15,9 +15,11 @@ import uvicorn from metrics import MetricsHandler +from mock_printer import MockPrinter metrics_handler = MetricsHandler.instance() +mock_printer = None app = FastAPI() app.add_middleware( @@ -117,7 +119,7 @@ def send_file_to_printer( logging.warning( f"server is in development mode, command would've been `{command}`" ) - return None + return mock_printer.lp() print_job = subprocess.Popen( command, @@ -155,6 +157,17 @@ def maybe_delete_pdf(file_path): pathlib.Path(file_path).unlink() +# test endpoint on clark +@app.post("/status") +def status(print_id: str): + if args.development: + status = mock_printer.get_job_status(print_id) + + if (status == "PRINTED"): + mock_printer.remove_job(print_id) + + return status + @app.get("/healthcheck/printer") def api(): metrics_handler.last_health_check_request.set(int(time.time())) @@ -212,6 +225,21 @@ async def read_item( # the thread interacts with an instance different than the one the # server uses if __name__ == "server": + if args.development: + mock_printer = MockPrinter.instance() + + mock_printer_upd_thread = threading.Thread( + target=mock_printer.update, + daemon=True + ) + mock_printer_upd_thread.start() + + mock_printer_log_thread = threading.Thread( + target=mock_printer.log, + daemon=True + ) + mock_printer_log_thread.start() + if not args.development: # set the last time we opened an ssh tunnel to now because # when the script runs for the first time, we did so in what.sh From fb497be7d93b5ab940591dcf0c53829f571ab6cc Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Fri, 18 Jul 2025 20:05:39 -0700 Subject: [PATCH 2/5] remove unnecessary check --- printer/mock_printer.py | 5 ++--- printer/server.py | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/printer/mock_printer.py b/printer/mock_printer.py index ad7b158e..67bd281b 100644 --- a/printer/mock_printer.py +++ b/printer/mock_printer.py @@ -37,9 +37,8 @@ def update(self) -> None: if self._queue.__len__() == 0: continue - if (self._jobs[self._queue[0]] == "PENDING"): - self._jobs[self._queue[0]] = "PRINTED" - self._queue.pop(0) + self._jobs[self._queue[0]] = "PRINTED" + self._queue.pop(0) def log(self) -> None: while True: diff --git a/printer/server.py b/printer/server.py index eeb187dc..de480a7a 100644 --- a/printer/server.py +++ b/printer/server.py @@ -19,7 +19,7 @@ metrics_handler = MetricsHandler.instance() -mock_printer = None +mock_printer = MockPrinter.instance() app = FastAPI() app.add_middleware( @@ -157,7 +157,7 @@ def maybe_delete_pdf(file_path): pathlib.Path(file_path).unlink() -# test endpoint on clark +# still need to test endpoint on clark @app.post("/status") def status(print_id: str): if args.development: @@ -226,8 +226,6 @@ async def read_item( # server uses if __name__ == "server": if args.development: - mock_printer = MockPrinter.instance() - mock_printer_upd_thread = threading.Thread( target=mock_printer.update, daemon=True From 4079d8a14dd798b8d4b9da4b2ad0304c9a31b692 Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Sat, 19 Jul 2025 00:04:51 -0700 Subject: [PATCH 3/5] /status returns json obj & no more log spam --- printer/mock_printer.py | 8 +++----- printer/server.py | 29 +++++++++++------------------ 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/printer/mock_printer.py b/printer/mock_printer.py index 67bd281b..80296e72 100644 --- a/printer/mock_printer.py +++ b/printer/mock_printer.py @@ -41,8 +41,6 @@ def update(self) -> None: self._queue.pop(0) def log(self) -> None: - while True: - time.sleep(3) - logging.info("-----------------") - logging.info(f"jobs: {self._jobs}") - logging.info(f"queue: {self._queue}") + logging.info("-----------------") + logging.info(f"jobs: {self._jobs}") + logging.info(f"queue: {self._queue}") diff --git a/printer/server.py b/printer/server.py index de480a7a..66b66d41 100644 --- a/printer/server.py +++ b/printer/server.py @@ -8,7 +8,7 @@ import uuid import collector -from fastapi import FastAPI, File, Form, HTTPException, UploadFile +from fastapi import FastAPI, File, Form, HTTPException, UploadFile, Body from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import PlainTextResponse import prometheus_client @@ -157,17 +157,6 @@ def maybe_delete_pdf(file_path): pathlib.Path(file_path).unlink() -# still need to test endpoint on clark -@app.post("/status") -def status(print_id: str): - if args.development: - status = mock_printer.get_job_status(print_id) - - if (status == "PRINTED"): - mock_printer.remove_job(print_id) - - return status - @app.get("/healthcheck/printer") def api(): metrics_handler.last_health_check_request.set(int(time.time())) @@ -215,6 +204,16 @@ async def read_item( detail="printing failed, check logs", ) +@app.post("/status") +async def status(print_id: str = Body(...)): + if args.development: + mock_printer.log() + status = mock_printer.get_job_status(print_id) + + if (status == "PRINTED"): + mock_printer.remove_job(print_id) + + return {"status": status} # we have a separate __name__ check here due to how FastAPI starts # a server. the file is first ran (where __name__ == "__main__") @@ -232,12 +231,6 @@ async def read_item( ) mock_printer_upd_thread.start() - mock_printer_log_thread = threading.Thread( - target=mock_printer.log, - daemon=True - ) - mock_printer_log_thread.start() - if not args.development: # set the last time we opened an ssh tunnel to now because # when the script runs for the first time, we did so in what.sh From 7a99dd486bf3348b3a3d7e8d0d9f7e83c2494eea Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Thu, 28 Aug 2025 16:20:45 -0700 Subject: [PATCH 4/5] mmmmmmmmmmmm --- printer/mock_printer.py | 18 +++++++++--------- printer/server.py | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/printer/mock_printer.py b/printer/mock_printer.py index 80296e72..8fb71819 100644 --- a/printer/mock_printer.py +++ b/printer/mock_printer.py @@ -15,13 +15,13 @@ def instance(cls): def get_job_status(self, id: str) -> str: if id in self._jobs: - return self._jobs[id] + return self._jobs[id] else: - return "PRINTED" + return "PRINTED" def remove_job(self, id: str) -> None: if id in self._jobs: - self._jobs.pop(id, None) + self._jobs.pop(id, None) def lp(self) -> str: print_id = "HP_LaserJet_p2015dn_Right-" + str(self._current_print_id_num) @@ -31,14 +31,14 @@ def lp(self) -> str: return print_id def update(self) -> None: - while True: - time.sleep(10) + while True: + time.sleep(10) - if self._queue.__len__() == 0: - continue + if self._queue.__len__() == 0: + continue - self._jobs[self._queue[0]] = "PRINTED" - self._queue.pop(0) + self._jobs[self._queue[0]] = "PRINTED" + self._queue.pop(0) def log(self) -> None: logging.info("-----------------") diff --git a/printer/server.py b/printer/server.py index 66b66d41..84642a60 100644 --- a/printer/server.py +++ b/printer/server.py @@ -207,13 +207,13 @@ async def read_item( @app.post("/status") async def status(print_id: str = Body(...)): if args.development: - mock_printer.log() - status = mock_printer.get_job_status(print_id) + mock_printer.log() + status = mock_printer.get_job_status(print_id) - if (status == "PRINTED"): - mock_printer.remove_job(print_id) + if (status == "PRINTED"): + mock_printer.remove_job(print_id) - return {"status": status} + return {"status": status} # we have a separate __name__ check here due to how FastAPI starts # a server. the file is first ran (where __name__ == "__main__") From 0f59c325adb989a075e18f9f0ee0c96445a49316 Mon Sep 17 00:00:00 2001 From: Benjamin Nguyen Date: Mon, 8 Sep 2025 00:45:44 -0700 Subject: [PATCH 5/5] /status get --- printer/mock_printer.py | 10 ++++++++-- printer/server.py | 15 ++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/printer/mock_printer.py b/printer/mock_printer.py index 8fb71819..68443ee5 100644 --- a/printer/mock_printer.py +++ b/printer/mock_printer.py @@ -4,6 +4,7 @@ class MockPrinter(): _instance = None _current_print_id_num = 0 + _current_time_left = 10 _jobs = {} _queue = [] @@ -21,7 +22,7 @@ def get_job_status(self, id: str) -> str: def remove_job(self, id: str) -> None: if id in self._jobs: - self._jobs.pop(id, None) + self._jobs.pop(id) def lp(self) -> str: print_id = "HP_LaserJet_p2015dn_Right-" + str(self._current_print_id_num) @@ -32,13 +33,18 @@ def lp(self) -> str: def update(self) -> None: while True: - time.sleep(10) + time.sleep(1) if self._queue.__len__() == 0: continue + if (self._current_time_left > 0): + self._current_time_left -= 1 + continue + self._jobs[self._queue[0]] = "PRINTED" self._queue.pop(0) + self._current_time_left = 10 def log(self) -> None: logging.info("-----------------") diff --git a/printer/server.py b/printer/server.py index 84642a60..431b37e6 100644 --- a/printer/server.py +++ b/printer/server.py @@ -175,9 +175,9 @@ async def read_item( """ incoming request to print looks like { - "file": file data - "copies": integer or whatever, we insert this into the lp command, - "sides": string value from user input on clark frontend; we insert this into the lp command, + "file": file data + "copies": integer or whatever, we insert this into the lp command, + "sides": string value from user input on clark frontend; we insert this into the lp command, } """ try: @@ -204,14 +204,15 @@ async def read_item( detail="printing failed, check logs", ) -@app.post("/status") -async def status(print_id: str = Body(...)): +@app.get("/status/") +async def status(id: str = ''): + logging.info(id) if args.development: mock_printer.log() - status = mock_printer.get_job_status(print_id) + status = mock_printer.get_job_status(id) if (status == "PRINTED"): - mock_printer.remove_job(print_id) + mock_printer.remove_job(id) return {"status": status}