{"id":50701554,"url":"https://github.com/jfdev001/lingua-loop","last_synced_at":"2026-06-09T09:30:44.210Z","repository":{"id":349534149,"uuid":"1174707720","full_name":"jfdev001/lingua-loop","owner":"jfdev001","description":"Full stack, single-page web app for learning languages via transcription.","archived":false,"fork":false,"pushed_at":"2026-06-07T10:44:12.000Z","size":5714,"stargazers_count":3,"open_issues_count":10,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-07T12:14:18.042Z","etag":null,"topics":["fastapi","language-learning","youtube-api"],"latest_commit_sha":null,"homepage":"https://jfdev001.github.io/lingua-loop/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jfdev001.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,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-06T18:46:05.000Z","updated_at":"2026-06-07T10:43:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jfdev001/lingua-loop","commit_stats":null,"previous_names":["jfdev001/lingua-loop"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jfdev001/lingua-loop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jfdev001%2Flingua-loop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jfdev001%2Flingua-loop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jfdev001%2Flingua-loop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jfdev001%2Flingua-loop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jfdev001","download_url":"https://codeload.github.com/jfdev001/lingua-loop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jfdev001%2Flingua-loop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34101065,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["fastapi","language-learning","youtube-api"],"created_at":"2026-06-09T09:30:43.403Z","updated_at":"2026-06-09T09:30:44.204Z","avatar_url":"https://github.com/jfdev001.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lingua-loop\n\n\u003e Train your listening skills by transcribing real speech from YouTube videos.\n\n`lingua-loop` is a single-page web application designed to improve language\nlistening skills through active transcription. It is based on a\ntranscription-first learning approach where users repeatedly listen to short\naudio segments and attempt to write down what they've heard.\n\n## Installation\n\nTo run the web application on your computer, you need Python version 3.12 or\nhigher installed. It is recommended to create a dedicated virtual environment\nfirst before installing `lingua-loop`.\n\nUsing conda:\n\n```\nconda create --name lingua-loop python=3.12\nconda activate lingua-loop\n```\n\nUsing venv on Windows, if you know your python version is 3.12 or higher,\nopen `Command Prompt`:\n\n```\npython -m venv .venv_lingua_loop\n.\\.venv_lingua_loop\\Scripts\\activate\n```\n\nUsing venv on Linux/macOS, if you know your python version is 3.12 or higher,\nopen a terminal:\n\n```\npython -m venv .venv_lingua_loop\n. .venv_lingua_loop/bin/activate\n```\n\nThen you can install the package:\n\n```\npip install git+https://github.com/jfdev001/lingua-loop.git\n```\n\nFor a faster install for users more familiar with Python packages and virtual\nenvironments, you can use the [uv](https://github.com/astral-sh/uv) package\nmanager, go to section [Installation with uv](#installation-with-uv) for details.\n\n\n## Usage\n\nYou can launch the app, which will automatically open a web browser, with the\nfollowing command in a terminal:\n\n```\nlingua-loop\n```\n\nHere's how you use the app:\n\n1. Select the target language you want to study.\n2. Copy and paste a YouTube video URL corresponding to that target language.\n   Ideally, the video should have **official** transcripts since those will be\n   used as the reference for scoring your transcription attempt.\n3. Listen to short segments of the video (e.g., 10 seconds) and type what you\n   hear. You may replay each segment as many times as needed.\n4. Once you have made an honest attempt, you can submit your transcription\n   attempt and will receive a score from 0 to 1. A score of 1 indicates a\n   perfect transcription and a score of 0 indicates a complete mismatch.\n5. Repeat as long as desired.\n\nThe scoring algorithm uses [Gestalt pattern\nmatching](https://en.wikipedia.org/wiki/Gestalt_pattern_matching), which\ncompares your input to the reference transcript by finding the longest common\nsubsequences of characters. For example, if you type\n\n$$\n\\text{wikim}\\textcolor{red}{an}\\text{ia}\n$$\n\nbut the official transcript has\n\n\n$$\n\\text{wikim}\\textcolor{red}{ed}\\text{ia}\n$$\n\nyou would receive a score of 0.70 because, despite the error, there are common\ncharacters that you correctly typed.\n\nNote that this package is an alpha state and subject to breaking changes and\nbug fixes. Please open a GitHub issue if you encounter problems!\n\n# Future Work\n\nSome possible extension ideas:\n\n1. Significantly improve the styling/UX.\n2. Integrate Anki-style flash cards for selected words. A word should be added\n   to a flash card deck in addition to the context in which it occurred (e.g.,\n   sentence or phrase). The user *should* write additional context to keep them\n   actively engaged in the learning process.\n3. Support more languages. Currently only Indo-European languages are\n   supported, though support for languages such as Mandarin would be extremely\n   valuable. For Mandarin, I think text normalization would require\n   [pinyin](https://en.wikipedia.org/wiki/Pinyin).\n4. More sophisticated scoring algorithms.\n5. Integrate an AI chat bot that is given the full transcript as context and\n   subsequently asks the user comprehension questions or engages in\n   conversation about the video topic. Could be executed using local models\n   or combined with API keys.\n\n# Developers\n\nThe directory structure is inspired by a number of projects, so it is\nintended to be as standard and intuitive as possible:\n\n```\nlingua-loop\n├── src\n│   └── lingua_loop\n│       ├── api\n│       │   └── routers\n│       │       └── transcript.py\n│       ├── constants.py\n│       ├── db\n│       │   ├── models.py\n│       │   ├── session.py\n│       │   └── transcript.py\n│       ├── exceptions.py\n│       ├── integrations\n│       │   └── youtube\n│       │       ├── types.py\n│       │       └── wrapper.py\n│       ├── main.py\n│       ├── schemas\n│       │   └── transcript.py\n│       ├── scripts\n│       │   └── run.py\n│       ├── services\n│       │   ├── text_normalization.py\n│       │   └── transcript.py\n│       ├── static\n│       │   ├── app.js\n│       │   └── style.css\n│       └── templates\n│           └── index.html\n└── tests\n    ├── boundary\n    │   ├── conftest.py\n    │   └── test_youtube_transcript_api.py\n    ├── conftest.py\n    ├── constants.py\n    ├── integration\n    │   └── test_integration.py\n    └── unit\n        ├── api\n        │   └── test_api.py\n        ├── db\n        │   └── test_db.py\n        └── services\n            └── test_services.py\n```\n\nThe fast package manger `uv` was used in the development of this project.\nYou can install `lingua-loop` in development mode by doing the following:\n\n```shell\ngit clone git@github.com:jfdev001/lingua-loop.git\ncd lingua-loop\nuv sync\n```\n\nAs a sanity check, you should verify the FastAPI backend tests pass:\n\n```shell\npytest -v tests/\n```\n\nThere are tests to verify the outputs of the `youtube_transcript_api`\ndependency, however, these make requests to YouTube, and are therefore *not*\nrun by default. You can run those tests if you want by including the `--slow`\nflag like:\n\n```shell\npytest -v --slow tests/\n```\n\nYou should also make sure that your files are formatted according to\nthe conventions defined in `.pre-commit-config.yaml`. To that end, use\nthe fast git hook runner framework [prek](https://github.com/j178/prek):\n\n```\nprek install\n```\n\nIf you'd like to contribute, consider opening an issue first and/or addressing\none of the issues already available. AI contributions will **not** be accepted.\nYou should fork the project first before contributing. Pull requests should\ncome from branches with the following structure:\n\n```\n\u003cname\u003e/\u003cissue-number-if-applicable\u003e-\u003cfeature-description\u003e\n```\n\nThe frontend is vanilla JS/HTML/CSS, so using `npm` is not strictly necessary,\nbut if you'd like type hints for the Youtube iframe API, you can install\nthe frontend dependencies with:\n\n```\nnpm install\n```\n\n# Extras\n\n## Installation with uv\n\nIf you do not already have the `uv` package manager installed, you can go to\nAstral's official documentation and follow the [installation\ninstructions](https://docs.astral.sh/uv/getting-started/installation/).\n\nIf you already have a conda base environment and are okay installing\n`lingua-loop` there with `uv`, do the following:\n\n```\nuv pip install git+https://github.com/jfdev001/lingua-loop.git --system\n```\n\nOtherwise, you can follow whichever `uv` workflow you're comfortable with, but\nfor those familiar with `pip`, the following is the easiest (on Linux/macOS):\n\n```\npython -m venv .venv_lingua_loop\n. .venv_lingua_loop/bin/activate\nuv pip install git+https://github.com/jfdev001/lingua-loop.git\n```\n\nFor Windows users, you could execute the above commands using `Command Prompt`:\n\n```\npython -m venv .venv_lingua_loop\n.\\.venv_lingua_loop\\Scripts\\activate\nuv pip install git+https://github.com/jfdev001/lingua-loop.git\n```\n\n### Docker\n\nYou can also run `lingua-loop` with Docker. Build the image:\n\n```\ngit clone --depth 1 https://github.com/jfdev001/lingua-loop.git\ncd lingua-loop\ndocker build -t lingua-loop .\n```\n\nThen run the container:\n\n```\ndocker run -p 49152:49152 lingua-loop\n```\n\n\u003e **Note:** The browser auto-open feature does not work inside a container. Manually open http://localhost:49152 in your browser.\n\n# References\n\nBelow are a series of references, in no particular order, that I used to gain\nthe necessary background knowledge for the project:\n\n[1] [Python FastAPI Tutorial (Part 1): Getting Started - Web App + REST\nAPI](https://www.youtube.com/watch?v=7AMjmCTumuo)\n\n[2] [Learn Fast API With This ONE\nProject](https://www.youtube.com/watch?v=SR5NYCdzKkc)\n\n[3] [Anatomy of a Scalable Python Project\n(FastAPI)](https://www.youtube.com/watch?v=Af6Zr0tNNdE)\n\n[4] [Developing and Testing an Asynchronous API with FastAPI and\nPytest](https://testdriven.io/blog/fastapi-crud/) \u0026\n[github.com/fastapi-crud-async](https://github.com/testdrivenio/fastapi-crud-async)\n\n[5] [Netflix/dispatch](https://github.com/Netflix/dispatch)\n\n[6] [polarsource/polar](https://github.com/polarsource/polar)\n\n[7] [FastAPI: Modern Web Development (Lubanovic\n2024)](https://www.oreilly.com/library/view/fastapi/9781098135492/)\n\n[8] [ecmwf/forecast-in-a-box](https://github.com/ecmwf/forecast-in-a-box)\n\n[9] [fastapi-docs: Testing\nDependencies](https://fastapi.tiangolo.com/advanced/testing-dependencies/)\n\n[10] [Build Advanced Youtube Player UI --\nVideo](https://www.youtube.com/watch?v=lsu-g-_6i_A\u0026list=PLzKme01IAXkLBmWBihSwIhLk8Qluli0Jl\u0026index=2)\nand [Build Advanced Youtube Player UI -- Source\nCode](https://codepen.io/PixelPerfectLabs/pen/PwwrJge)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjfdev001%2Flingua-loop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjfdev001%2Flingua-loop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjfdev001%2Flingua-loop/lists"}