A web application that provides LLM-based text web page summarization for bookmarking services using Flask, subprocesses, and custom scripts.
Summarizer Service is a bare-bones sample Flask web application using Flask, using subprocesses and custom scripts. The application provides text web page summarization for bookmarking services, accepting both GET and POST requests with or without a custom prompt.
Copyright 2024-2025 Leigh Klotz
The app uses <a href="https://github.com/leighklotz/answer>answer, but is easily adapted to use other mechanisms for LLM access.
Install the answer and edit config.py:
cp config.py.example config.py
emacs config.pyClone this repository, Install dependencies and create Python virtualenv, and install systemd service:
$ git clone https://github.com/leighklotz/summarizer-service.git
$ cd summarizer-service/scripts
$ ./install.sh
$ cd ../systemd
$ ./install.sh/: Home card/scuttle?url=: Scuttle bookmarking service card/summarize?url=&prompt=: Text summarization with optional prompt card/ask?question=&context=: Q and A with optional context card/via-api-model?model_name=: List models and select current; POST to load.
Cards are implemented in app.py and with templates in templates/cards/cardname.
Use these bookmarklets from your desktop browser to send pages and text to the summarizer.
Replace host.example.com with your hostname and add to your browser toolbar.
Summarize current web page with keywords and open a window to post to Scuttle.
javascript:( function() %7B var x = document; var a = encodeURIComponent(x.location.href); var d = encodeURIComponent(window.getSelection()); open('https://host.example.com/card/scuttle?url=%27%20+%20a%20+%20%27&prompt=%27%20+%20d,%20%27SemanticScuttle%20-%20example.com%27,%20%27modal=1,status=0,scrollbars=1,toolbar=0,resizable=1,width=790,height=465,left=%27%20+%20(screen.width-790)/2%20+%20%27,top=%27%20+%20(screen.height-425)/2);%20%20%7D)();Summarize current web page and open a window with the summary. Current selectin is optional additional prompt.
javascript:( function() %7B var x = document; var a = encodeURIComponent(x.location.href); var d = encodeURIComponent(window.getSelection()); open('https://host.example.com/card/summarize?url=%27%20+%20a%20+%20%27&prompt=%27%20+%20d,%20%27Summarize20-%20example.com%27,%20%27modal=1,status=0,scrollbars=1,toolbar=0,resizable=1,width=790,height=465,left=%27%20+%20(screen.width-790)/2%20+%20%27,top=%27%20+%20(screen.height-425)/2);%20%20%7D)();Ask a question with optional context (defaults to current selection) and open a window with the answer.
javascript:( function() %7B var x = document; var d = encodeURIComponent(window.getSelection()).replace(/%20/g, '+'); open('https://host.example.com/card/ask?question=context=%27%20+%20d,%20%27Ask20-%20example.com%27,%20%27modal=1,status=0,scrollbars=1,toolbar=0,resizable=1,width=790,height=465,left=%27%20+%20(screen.width-790)/2%20+%20%27,top=%27%20+%20(screen.height-425)/2);%20%20%7D)();See recent service and software update status. See docs/summarizer-status.png.
See flask_sessions/ for session data, which will accumulate files, some containtining the contents of form fields. You will need to protect the files and delete them periodically.
This project is licensed under the MIT License - see the LICENSE.md file for details.

