{"id":13510703,"url":"https://github.com/neuml/tldrstory","last_synced_at":"2025-03-30T16:34:53.423Z","repository":{"id":57475913,"uuid":"301469435","full_name":"neuml/tldrstory","owner":"neuml","description":"📊 Semantic search for headlines and story text","archived":false,"fork":false,"pushed_at":"2023-09-23T13:08:32.000Z","size":25762,"stargazers_count":355,"open_issues_count":7,"forks_count":27,"subscribers_count":16,"default_branch":"master","last_synced_at":"2024-09-24T01:14:16.417Z","etag":null,"topics":["machine-learning","nlp","python","search","txtai"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neuml.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-10-05T16:19:44.000Z","updated_at":"2024-09-12T11:44:19.000Z","dependencies_parsed_at":"2024-01-13T19:35:53.623Z","dependency_job_id":"5fa0c214-add1-46c8-84fd-49b9c0a9ab19","html_url":"https://github.com/neuml/tldrstory","commit_stats":{"total_commits":43,"total_committers":1,"mean_commits":43.0,"dds":0.0,"last_synced_commit":"130b6ffe00a324ba8adc04c51ba72f24417fe666"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuml%2Ftldrstory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuml%2Ftldrstory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuml%2Ftldrstory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuml%2Ftldrstory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neuml","download_url":"https://codeload.github.com/neuml/tldrstory/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222566739,"owners_count":17004237,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["machine-learning","nlp","python","search","txtai"],"created_at":"2024-08-01T02:01:50.698Z","updated_at":"2025-03-30T16:34:53.408Z","avatar_url":"https://github.com/neuml.png","language":"Python","funding_links":[],"categories":["Python","python"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/neuml/tldrstory/master/logo.png\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cb\u003eSemantic search for headlines and story text\u003c/b\u003e\n\u003c/p\u003e\n\n-------------------------------------------------------------------------------------------------------------------------------------------------------\n\ntldrstory is a semantic search application for headlines and text content related to stories. tldrstory applies zero-shot labeling over text, which allows dynamically categorizing content. This framework also builds a txtai index that enables text similarity search. A customizable Streamlit application and FastAPI backend service allows users to review and analyze the data processed.\n\ntldrstory has a corresponding [Medium article](https://towardsdatascience.com/tldrstory-ai-powered-understanding-of-headlines-and-story-text-fc86abd702fc) that covers the concepts in this README and more. Check it out!\n\n## Examples\n\nThe following links are example applications built with tldrstory.\n\n- [Mobile Tech News](https://github.com/neuml/tldrstory/tree/master/apps/devices)\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/neuml/tldrstory/master/apps/devices/demo.gif\"/\u003e\n\u003c/p\u003e\n\n- [Sports News](https://github.com/neuml/tldrstory/tree/master/apps/sports)\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/neuml/tldrstory/master/apps/sports/demo.gif\"/\u003e\n\u003c/p\u003e\n\n## Installation\n\nThe easiest way to install is via pip and PyPI\n\n    pip install tldrstory\n\nYou can also install tldrstory directly from GitHub. Using a Python Virtual Environment is recommended.\n\n    pip install git+https://github.com/neuml/tldrstory\n\nPython 3.8+ is supported\n\nSee [this link](https://github.com/neuml/txtai#installation) to help resolve environment-specific install issues.\n\n## Configurating an application\n\nOnce installed, an application must be configured to run. A tldrstory application consists of three separate processes:\n\n- Indexing\n- API backend\n- Streamlit application\n\nThis section will show how to start the \"Sports News\" application.\n\n1. Download the “Sports News” application configuration.\n\n```bash\nmkdir sports\n\nwget https://raw.githubusercontent.com/neuml/tldrstory/master/apps/sports/app.yml -O sports/app.yml\n\nwget https://raw.githubusercontent.com/neuml/tldrstory/master/apps/sports/api.yml -O sports/api.yml\n\nwget https://raw.githubusercontent.com/neuml/tldrstory/master/apps/sports/index-simple.yml -O sports/index.yml\n\nwget https://raw.githubusercontent.com/neuml/tldrstory/master/src/python/tldrstory/app.py -O sports/app.py\n```\n\n2. Start the indexing process.\n\n```bash\npython -m tldrstory.index sports/index.yml\n```\n\n3. Start the API process.\n\n```bash\nCONFIG=sports/api.yml API_CLASS=tldrstory.api.API uvicorn \"txtai.api:app\" \u0026\n```\n\n4. Start Streamlit.\n\n```bash\nstreamlit run sports/app.py sports/app.yml \"Sports\" \"🏆\"\n```\n\n5. Open a web browser and go to http://localhost:8501\n\n## Custom Sources\n\nOut of the box, tldrstory supports reading data from RSS and the Reddit API. Additional data sources can be defined and configured.\n\nThe following shows an example custom data source definition. [neuspo](https://neuspo.com) is a real-time sports event and news application.\nThis data source loads 4 pre-defined entries into the articles database.\n\n```python\nfrom tldrstory.source.source import Source\n\nclass Neuspo(Source):\n    \"\"\"\n    Articles have the following schema:\n        uid - unique id\n        source - source name\n        date - article date\n        title - article title\n        url - reference url for data\n        entry - entry date\n    \"\"\"\n\n    def run(self):\n        # List of articles created\n        articles = []\n\n        articles.append(self.article(\"0\", \"Neuspo\", self.now(), \"Eagles defeat the Giants 22 - 21\", \n                                     \"https://neuspo.com/stream/34952e3919d685982c17735018b0197f\", self.now()))\n\n        articles.append(self.article(\"1\", \"Neuspo\", self.now(), \"Giants lose to the Eagles 22 - 21\", \n                                     \"https://t.co/e9FFgo0wgR?amp=1\", self.now()))\n\n        articles.append(self.article(\"2\", \"Neuspo\", self.now(), \"Rays beat Dodgers 6 to 4\", \n                                     \"https://neuspo.com/stream/6cb820b3ebadc086aa36b5cc4a0f575d\", self.now()))\n\n        articles.append(self.article(\"3\", \"Neuspo\", self.now(), \"Dodgers drop Game 2, 6-4\", \n                                     \"https://t.co/1hEQAShVnP?amp=1\", self.now()))\n\n        return articles\n```\n\nLet’s re-run the steps above using neuspo as the data source. First remove the sports/data directory, to ensure we create a fresh database. We can then download the gist above into the sports directory.\n\n```bash\n# Delete the sports/data directory before running\n\nwget https://gist.githubusercontent.com/davidmezzetti/9a6064d9a741acb89bd46eba9f906c26/raw/7058e97da82571005b2654b4ab908f25b9a04fe2/neuspo.py -O sports/neuspo.py\n```\n\nEdit sports/index.yml and remove the rss section. Replace it with the following.\n\n```yaml\n# Custom data source for neuspo\nsource: sports.neuspo.Neuspo\n```\n\nNow re-run steps 2–4 from the [instructions above](#configurating-an-application).\n\n## Parameter Reference\n\nThe following sections define configuration parameters for each process that is part of a tldrstory application.\n\n## Indexing\n\nConfigures the indexing of content. Currently supports pulling data via the Reddit API, RSS and custom user-defined sources.\n\n### name\n```yaml\nname: string\n```\n\nApplication name\n\n### schedule\n```yaml\nschedule: string\n```\n\nCron-style string that enables scheduled running of the indexing job. See [this link](https://en.wikipedia.org/wiki/Cron) for more information on cron strings.\n\n### sources\n\nData source configuration.\n\n#### reddit\n```yaml\nreddit.subreddit: name of subreddit to pull from \nreddit.sort: sort type\nreddit.time: time range\nreddit.queries: list of text queries to run\n```\n\nRuns a series of Reddit API queries. A Reddit API key will need to be created and configured for this method to work. Authentication parameters can be set within the enviroment or in a praw.ini file. See [this link](https://praw.readthedocs.io/en/latest/getting_started/quick_start.html) for more information on setting up a Reddit API account, read-only access is all that is needed.\n\nSee [PRAW documentation](https://praw.readthedocs.io/en/latest/code_overview/models/subreddit.html) for more details on how to configure the query settings.\n\n#### rss\n```yaml\nrss: list of RSS urls\n```\n\nReads a series of RSS feeds and builds articles for each article link found.\n\n#### source\n```yaml\nsource: string\n```\n\nConfigures a custom source. This parameter takes a full class path as a string, for example \"tldrstory.source.rss.RSS\"\n\nCustom sources can be use any data that has a date, text string and reference url. See the documentation in [source.py](https://github.com/neuml/tldrstory/blob/master/src/python/tldrstory/source/source.py) for information on how to create a custom source. [rss.py](https://github.com/neuml/tldrstory/blob/master/src/python/tldrstory/source/rss.py) and [reddit.py](https://github.com/neuml/tldrstory/blob/master/src/python/tldrstory/source/reddit.py) are example implementations.\n\n### ignore\n```yaml\nignore: list of url patterns\n```\n\nList of url patterns to ignore. Supports strings and regular expressions.\n\n### labels\n```yaml\nlabels: dict\n```\n\nLabel configuration for zero-shot classifier. This configuration sets a category along with a list of topic values.\n\nExample:\n\n```yaml\nlabels:\n  topic:\n    values: [Label 1, Label 2]\n```\n\nThe example above configures the category \"Topic\" with two possible labels, \"Label 1\" and \"Label 2\". Any label can be set here and a large-scale\nNLP model will be used to categorize input text into those labels.\n\n### path\n```yaml\npath: string\n```\n\nWhere to store model output, path will be created if it doesn't already exist. \n\n### embeddings\n```yaml\nembeddings: dict\n```\n\nConfigures a txtai index used for searching topics. See [txtai configuration](https://github.com/neuml/txtai#configuration) for more details on this. \n\n## API\n\nConfigures a FastAPI backed interface for pulling indexed data.\n\n### path\n```yaml\npath: string\n```\n\nPath to a model index.\n\n## Application\n\nThe default application is powered by Streamlit and driven by a YAML configuration file. The configuration file sets the application name, API endpoint for pulling content, and component configuration. A custom Streamlit application or any other application can be used in place of this to pull content from the API endpoint directly.\n\n### name\n```yaml\nname: string\n```\n\nApplication name\n\n### api\n```yaml\napi: url\n```\n\nAPI endpoint for pulling content. \n\n### layout\n```yaml\ndescription: string\n```\n\nMarkdown string that is used to build a sidebar description.\n\n#### queries\n```yaml\nqueries.name: Queries drop down header\nqueries.values: List of values to use for queries drop down\n```\n\nConfigures the query drop down box. This should be a list of pre-canned queries to use. If a value of \"Latest\" is present, it will query for the last N\narticles. If a value of \"--Search--\" is present, it will present another text box to allow entering custom queries.\n\n#### filters\n```yaml\nfilters: list\n```\n\nList of slider filters. This should map to the zero-shot labels configured in the indexing section.\n\n#### chart\n```yaml\nchart.name: Chart name\nchart.x: Chart x-axis column\nchart.y: Chart y-axis column\nchart.scale: Color scale for list of colors\nchart.colors: List of colors\n```\n\nAllows configuration of a scatter plot that graphs two label points. This chart can be used to plot and apply coloring to applied labels.\n\n#### table\n```yaml\n\"column name\": dynamic range of coloring\n```\n\nData table that shows result details. In addition to default columns, this section allows adding additional columns based on the zero-shot\nlabels applied. The default mode is to show the numeric value of the label but a range of text labels can also be applied.\n\nFor example:\n  - [0, 5.0, Label 1, \"color: #F00\"]\n  - [5.0, 10.0, Label 2, \"color: #0F0\"]\n\nThe above would output the text \"Label 1\" in red for values between 0 and 5. Values between 5 and 10 would output the text \"Label 2\" in green. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneuml%2Ftldrstory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneuml%2Ftldrstory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneuml%2Ftldrstory/lists"}