{"id":37085901,"url":"https://github.com/mediatechlab/aida-lib","last_synced_at":"2026-01-14T10:34:10.709Z","repository":{"id":57408665,"uuid":"240532253","full_name":"mediatechlab/aida-lib","owner":"mediatechlab","description":"Aida is a language agnostic library for text generation.","archived":true,"fork":false,"pushed_at":"2020-09-08T04:41:10.000Z","size":51,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-12-22T00:54:13.457Z","etag":null,"topics":["library","natural-language-generation","nlg","python","python-library","text-generation"],"latest_commit_sha":null,"homepage":null,"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/mediatechlab.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}},"created_at":"2020-02-14T14:55:45.000Z","updated_at":"2024-05-05T23:53:19.000Z","dependencies_parsed_at":"2022-09-26T22:30:22.112Z","dependency_job_id":null,"html_url":"https://github.com/mediatechlab/aida-lib","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mediatechlab/aida-lib","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediatechlab%2Faida-lib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediatechlab%2Faida-lib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediatechlab%2Faida-lib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediatechlab%2Faida-lib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mediatechlab","download_url":"https://codeload.github.com/mediatechlab/aida-lib/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mediatechlab%2Faida-lib/sbom","scorecard":{"id":634227,"data":{"date":"2025-08-11","repo":{"name":"github.com/mediatechlab/aida-lib","commit":"8ec94e3843945937b63503a2e5a69ef52520cfef"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pythonpackage.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/mediatechlab/aida-lib/pythonpackage.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pythonpackage.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/mediatechlab/aida-lib/pythonpackage.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/pythonpackage.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/pythonpackage.yml:22","Warn: pipCommand not pinned by hash: .github/workflows/pythonpackage.yml:25","Warn: pipCommand not pinned by hash: .github/workflows/pythonpackage.yml:32","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/pythonpackage.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-21T08:41:13.654Z","repository_id":57408665,"created_at":"2025-08-21T08:41:13.654Z","updated_at":"2025-08-21T08:41:13.654Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28417643,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:25:19.714Z","status":"ssl_error","status_checked_at":"2026-01-14T10:22:49.371Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["library","natural-language-generation","nlg","python","python-library","text-generation"],"created_at":"2026-01-14T10:34:10.079Z","updated_at":"2026-01-14T10:34:10.702Z","avatar_url":"https://github.com/mediatechlab.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Aida Lib\n\n![](https://github.com/mediatechlab/aida-lib/workflows/Python%20package/badge.svg)\n\nAida is a language agnostic library for text generation.\n\n## Usage\n\nA simple hello world script would look like this:\n\n```Python\nfrom aida import render, Empty, Var\n\n# create a variable to hold a name\nname_var = Var('name')\n\n# create a simple phrase\nnode = (Empty + 'hello,' | name_var).to_phrase()\n\n# assign a value to the variable\nname_var.assign('World')\n\n# render the node\nprint(render(node))  # 'Hello, World.'\n```\n\n## Install\n\nDownload and install with pip:\n\n```bash\npip install aidalib\n```\n\n## Core Concepts\n\nWhen using Aida, first you compose a tree of operations on your text that include conditions via branches and other control flow. Later, you fill the tree with data and render the text.\n\nA building block is the variable class: `Var`. Use it to represent a value that you want to control later. A variable can hold numbers (e.g. `float`, `int`) or strings.\n\nYou can create branches and complex logic with `Branch`. In the example below, if `x` is greater than 1, it will render `many`, otherwise `single`.\n\n```Python\nx = Var('x')\nBranch(x \u003e 1, 'many', 'single')\n```\n\n### Context\n\nThe context, represented by the class `Ctx`, is useful to create rules that depends on what has been written before. Each object or literal that is passed to Aida is remembered by the context.\n\n```Python\nname = Const('Bob')\nalt_name = Const('He')\nbob = Branch(~name.in_ctx(), name, alt_name)\nctx = Ctx()\n\nrender(bob | 'is a cool guy.' | bob | 'doesn\\'t mind.', ctx)\n# Bob is a cool guy. He doesn't mind.\n```\n\nCreating a reference expression is a common use-case, so we have a helper function called `create_ref`.\n\n```Python\nbob = create_ref('Bob', 'He')\n```\n\n### Operators\n\nYou can compose operations on your text with some handy operators.\n\n#### Concatenation (`+` and `|`)\n\n```Python\n'the' | 'quick' | 'brown' | 'fox'  # 'the quick brown fox'\n\n'the' + 'quick' + 'brown' + 'fox'  # 'thequickbrownfox'\n```\n\n#### Check context (`in_ctx`)\n\nCheck if the current node is in the context.\n\n```Python\nConst('something').in_ctx()\n```\n\n#### Create a sentence (`sentence`)\n\nFormats a line into a sentence, capitalizing the first word and adding a period.\n\n```Python\nConst('hello world').sentence()  # 'Hello world.'\n```\n\n#### Logical and numeric operators\n\n| operator              | example  |\n| --------------------- | -------- |\n| negation              | `!x`     |\n| greater than          | `x \u003e y`  |\n| greater or equal than | `x \u003e= y` |\n| less than             | `x \u003c y`  |\n| less or equal than    | `x \u003c= y` |\n| equal                 | `x == y` |\n| not equal             | `x != y` |\n| or                    | `x | y`  |\n| and                   | `x \u0026 y`  |\n| plus                  | `x + y`  |\n\n### Random choice\n\nRandomly draws one node from a list of possibilities.\n\n```Python\nChoice('Alice', 'Bob', 'Chris')  # either 'Alice', 'Bob', or 'Chris'\n```\n\n### Injector\n\nThe `Injector` class assigns values to variables from a list each time it is rendered. Very useful to automatically fill values based on data.\n\n```Python\nanimal = Var('animal')\nsound = Var('sound')\nnode = animal | 'makes' | sound\nnode = Injector([animal, sound], node)\n\n# assign multiple values\nnode.assign([\n  {'animal': 'cat', 'sound': 'meaw'},\n  {'animal': 'dog', 'sound': 'roof'},\n])\n\nrender(node) # 'cat makes meaw'\n\nrender(node) # 'dog makes roof'\n```\n\n### For-loops with `Repeat`\n\nUse `Repeat` to render a node multiple times. At the simplest level, you have this:\n\n```Python\nrender(Repeat('buffalo').assign(8))\n# 'buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo'\n```\n\n`Repeat` is very useful when used with `Injector`, like this:\n\n```Python\nanimal = Var('animal')\nsound = Var('sound')\nnode = animal | 'makes' | sound\nnode = Injector([animal, sound], node)\nrepeat = Repeat(node)\n\n# assign multiple values\ndata = [\n  {'animal': 'cat', 'sound': 'meaw'},\n  {'animal': 'dog', 'sound': 'roof'},\n]\nnode.assign(data)\nrepeat.assign(len(data))\n\n# renders text based on data\nrender(node)  # cat makes meaw dog makes roof\n```\n\n## Language Concepts\n\nThere are some experimental features that allows you to create text that adapts to common language features, like grammatical _number_ and _person_.\n\n### Enumerate items\n\nUse `LangConfig` to setup language features and then call `create_enumeration()`.\n\n```Python\nfrom aida import create_enumeration, LangConfig, Lang, render\n\nrender(create_enumeration(LangConfig(lang=Lang.ENGLISH), 'Alice', 'Bob', 'Chris'))\n# 'Alice, Bob, and Chris'\n\nrender(create_enumeration(LangConfig(lang=Lang.PORTUGUESE), 'Alice', 'Bob', 'Chris'))\n# 'Alice, Bob e Chris'\n```\n\n### Sentence Structure\n\nYou can compose sentences using special structures: `NP` (noun phrase) and `VP` (verb phrase) along with `LangConfig`.\n\n```Python\nfrom aida import NP, VP, LangConfig\n\nsubj = NP('the dog')\nverb = VP('barked')\n\ns = (subj | verb).sentence()\n\nrender(LangConfig(s))  # The dog barked.\n```\n\nWhat really makes this different from just using `Const` is that we can create rules that change the output of `NP` and `VP` based on various language features. The system will try to use the rule that matches most features from the given `LangConfig`.\n\n```Python\nfrom aida import NP, VP, LangConfig, GNumber, GPerson\n\nsubj = (NP('I')\n        .add_mapping('I', GNumber.SINGULAR, GPerson.FIRST)\n        .add_mapping('he', GNumber.SINGULAR, GPerson.THIRD))\n        .add_mapping('we', GNumber.PLURAL, GPerson.FIRST))\nverb = (VP('drive')\n        .add_mapping('drive', GPerson.FIRST)\n        .add_mapping('drives', GPerson.THIRD))\n\ns = (subj | verb | 'a nice car').sentence()\n\nrender(LangConfig(s, number=GNumber.SINGULAR, person=GPerson.FIRST))  # I drive a nice car.\nrender(LangConfig(s, number=GNumber.SINGULAR, person=GPerson.THIRD))  # He drives a nice car.\nrender(LangConfig(s, number=GNumber.PLURAL, person=GPerson.FIRST))  # We drive a nice car.\n```\n\n## Examples\n\nCheck more complex uses at the [examples folder](examples).\n\n## License\n\nLicensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmediatechlab%2Faida-lib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmediatechlab%2Faida-lib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmediatechlab%2Faida-lib/lists"}