{"id":14972723,"url":"https://github.com/alfanous-team/alfanous","last_synced_at":"2026-04-01T18:06:15.934Z","repository":{"id":3556195,"uuid":"4617289","full_name":"Alfanous-team/alfanous","owner":"Alfanous-team","description":"Alfanous is an Arabic search engine API provides the simple and advanced search in Quran , more features and many interfaces...","archived":false,"fork":false,"pushed_at":"2026-02-28T15:11:31.000Z","size":149692,"stargazers_count":280,"open_issues_count":84,"forks_count":89,"subscribers_count":32,"default_branch":"master","last_synced_at":"2026-02-28T15:41:45.077Z","etag":null,"topics":["api","arabic","django-application","indexing","python","quran","search-engine"],"latest_commit_sha":null,"homepage":"http://www.alfanous.org/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Alfanous-team.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"assem-ch"}},"created_at":"2012-06-10T18:31:51.000Z","updated_at":"2026-02-28T14:04:50.000Z","dependencies_parsed_at":"2023-01-13T13:00:15.342Z","dependency_job_id":null,"html_url":"https://github.com/Alfanous-team/alfanous","commit_stats":{"total_commits":24,"total_committers":2,"mean_commits":12.0,"dds":0.04166666666666663,"last_synced_commit":"594514729473c24efa3908e3107b45a38255de4b"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/Alfanous-team/alfanous","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alfanous-team%2Falfanous","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alfanous-team%2Falfanous/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alfanous-team%2Falfanous/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alfanous-team%2Falfanous/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alfanous-team","download_url":"https://codeload.github.com/Alfanous-team/alfanous/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alfanous-team%2Falfanous/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29941794,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T13:49:17.081Z","status":"ssl_error","status_checked_at":"2026-02-28T13:48:50.396Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["api","arabic","django-application","indexing","python","quran","search-engine"],"created_at":"2024-09-24T13:47:25.769Z","updated_at":"2026-04-01T18:06:15.924Z","avatar_url":"https://github.com/Alfanous-team.png","language":"Python","funding_links":["https://github.com/sponsors/assem-ch"],"categories":[],"sub_categories":[],"readme":"[![Tests](https://github.com/Alfanous-team/alfanous/workflows/tests/badge.svg)](https://github.com/Alfanous-team/alfanous/actions)\n\n\u003c!-- mcp-name: io.github.Alfanous-team/alfanous --\u003e\n\n# Alfanous API\n\n**Alfanous** is a Quranic search engine API that provides simple and advanced search capabilities for the Holy Qur'an. It enables developers to build applications that search through Quranic text in Arabic, with support for Buckwalter transliteration, advanced query syntax, and rich metadata.\n\n## Features\n\n* **Powerful Search**: Search Quranic verses with simple queries or advanced Boolean logic\n* **Arabic Support**: Full support for Arabic text and Buckwalter transliteration\n* **Rich Metadata**: Access verse information, translations, recitations, and linguistic data\n* **Flexible API**: Use as a Python library or RESTful web service\n* **Faceted Search**: Aggregate results by Sura, Juz, topics, and more\n* **Multiple Output Formats**: Customize output with different views and highlight styles\n\n## Quickstart\n\n### Installation\n\nInstall from PyPI using pip:\n\n```sh\n$ pip install alfanous3\n```\n\n### Basic Usage\n\n#### Python Library\n\n```python\n\u003e\u003e\u003e from alfanous import api\n\n# Simple search for a word\n\u003e\u003e\u003e api.search(u\"الله\")\n\n# Advanced search with options\n\u003e\u003e\u003e api.do({\"action\": \"search\", \"query\": u\"الله\", \"page\": 1, \"perpage\": 10})\n\n# Search using Buckwalter transliteration\n\u003e\u003e\u003e api.do({\"action\": \"search\", \"query\": u\"Allh\"})\n\n# Get suggestions\n\u003e\u003e\u003e api.do({\"action\": \"suggest\", \"query\": u\"الح\"})\n\n# Correct a query\n\u003e\u003e\u003e api.correct_query(u\"الكتاب\")\n\n# Get metadata information\n\u003e\u003e\u003e api.do({\"action\": \"show\", \"query\": \"translations\"})\n```\n\n#### Web Service\n\nYou can also use the public web service:\n\n* Search: http://alfanous.org/api/search?query=الله\n* With transliteration: http://alfanous.org/api/search?query=Allh\n\nOr run your own web service locally (see [alfanous_webapi](src/alfanous_webapi/README.md)).\n\n#### Quick Examples\n\nSearch for phrases:\n\n```python\n\u003e\u003e\u003e api.search(u'\"الحمد لله\"')\n```\n\nBoolean search (AND, OR, NOT):\n\n```python\n\u003e\u003e\u003e api.search(u'الصلاة + الزكاة')    # AND\n\u003e\u003e\u003e api.search(u'الصلاة | الزكاة')    # OR\n\u003e\u003e\u003e api.search(u'الصلاة - الزكاة')    # NOT\n```\n\nFielded search:\n\n```python\n\u003e\u003e\u003e api.search(u'سورة:يس')           # Search in Sura Yasin\n\u003e\u003e\u003e api.search(u'سجدة:نعم')          # Search verses with sajda\n```\n\nWildcard search:\n\n```python\n\u003e\u003e\u003e api.search(u'*نبي*')             # Words containing \"نبي\"\n```\n\nFaceted search (aggregate by fields):\n\n```python\n\u003e\u003e\u003e api.do({\n...     \"action\": \"search\",\n...     \"query\": u\"الله\",\n...     \"facets\": \"sura_id,juz\"\n... })\n```\n\n## Documentation\n\n### API Reference\n\n#### Core Functions\n\n* `api.search(query, **options)` - Search Quran verses\n* `api.do(params)` - Unified interface for all actions (search, suggest, show, list_values, correct_query)\n* `api.correct_query(query, unit, flags)` - Get a spelling-corrected version of a query\n* `api.get_info(category)` - Get metadata information\n\nThe underlying `Raw` output engine is exposed as `Engine` in `alfanous.api` (and re-exported from `alfanous` directly). Use it as a context manager to ensure index resources are properly released:\n\n```python\nfrom alfanous.api import Engine\n# or equivalently:\n# from alfanous import Engine\n\nwith Engine() as engine:\n    result = engine.do({\"action\": \"search\", \"query\": u\"الله\"})\n```\n\n#### Search Parameters\n\nCommon parameters for `api.do()` with `action=\"search\"`:\n\n* `query` (str): Search query (required)\n* `unit` (str): Search unit - \"aya\", \"word\", or \"translation\" (default: \"aya\")\n* `page` (int): Page number (default: 1)\n* `perpage` (int): Results per page, 1-100 (default: 10)\n* `sortedby` (str): Sort order - \"score\", \"relevance\", \"mushaf\", \"tanzil\", \"ayalength\" (default: \"score\")\n* `reverse` (bool): Reverse the sort order (default: False)\n* `view` (str): Output view - \"minimal\", \"normal\", \"full\", \"statistic\", \"linguistic\" (default: \"normal\")\n* `highlight` (str): Highlight style - \"css\", \"html\", \"bold\", \"bbcode\" (default: \"css\")\n* `script` (str): Text script - \"standard\" or \"uthmani\" (default: \"standard\")\n* `vocalized` (bool): Include Arabic vocalization (default: True)\n* `translation` (str): Translation ID to include\n* `recitation` (str): Recitation ID to include (1-30, default: \"1\")\n* `fuzzy` (bool): Enable fuzzy search — searches both `aya_` (exact) and `aya` (normalised/stemmed) fields, plus Levenshtein distance matching (default: False). See [Exact Search vs Fuzzy Search](#exact-search-vs-fuzzy-search).\n* `fuzzy_maxdist` (int): Maximum Levenshtein edit distance for fuzzy term matching — `1`, `2`, or `3` (default: `1`, only used when `fuzzy=True`).\n* `facets` (str): Comma-separated list of fields for faceted search\n* `filter` (dict): Filter results by field values\n\nFor a complete list of parameters and options, see the [detailed documentation](#advanced-features).\n\n### Advanced Features\n\n#### Exact Search vs Fuzzy Search\n\nAlfanous provides two complementary search modes that control which index fields are queried.\n\n##### Exact Search (default — `fuzzy=False`)\n\nWhen fuzzy search is **off** (the default), queries run against the **`aya_`** field, which stores the fully-vocalized Quranic text with diacritical marks (tashkeel) preserved. This mode is designed for precise, statistical matching:\n\n* Diacritics in the query are significant — `مَلِكِ` and `مَالِكِ` are treated as different words.\n* No stop-word removal, synonym expansion, or stemming is applied to the query.\n* Ideal when you need exact phrase matches, reproducible result counts, or statistical analysis.\n\n```python\n# Default exact search — only the vocalized aya_ field is used\n\u003e\u003e\u003e api.search(u\"الله\")\n\u003e\u003e\u003e api.search(u\"الله\", fuzzy=False)\n\n# Phrase match with full diacritics\n\u003e\u003e\u003e api.search(u'\"الْحَمْدُ لِلَّهِ\"')\n```\n\n##### Fuzzy Search (`fuzzy=True`)\n\nWhen fuzzy search is **on**, queries run against **both** the `aya_` field (exact matches) **and** the `aya` field (a separate index built for broad, forgiving search). At index time the `aya` field is processed through a richer pipeline:\n\n1. **Normalisation** — shaped letters, tatweel, hamza variants and common spelling errors are unified.\n2. **Stop-word removal** — high-frequency function words (e.g. مِنْ، فِي، مَا) are filtered out so they do not dilute result relevance.\n3. **Synonym expansion** — each token is stored together with its synonyms, so a query for one word automatically matches equivalent words.\n4. **Arabic stemming** — words are reduced to their stem using the [Snowball Arabic stemmer](https://snowballstem.org/) (via `pystemmer`), so different morphological forms of the same root match each other.\n\nNo heavy operations are performed on the query string at search time; all the linguistic enrichment lives in the index.\n\nAdditionally, for each Arabic term in the query, a **Levenshtein distance** search is performed against the `aya_ac` field (unvocalized, non-stemmed). This catches spelling variants and typos within a configurable edit-distance budget controlled by `fuzzy_maxdist`.\n\n```python\n# Fuzzy search — aya_ (exact) + aya (normalised/stemmed) + Levenshtein distance on aya_ac\n\u003e\u003e\u003e api.search(u\"الكتاب\", fuzzy=True)\n\n# Increase edit distance to 2 to tolerate more spelling variation\n\u003e\u003e\u003e api.search(u\"الكتاب\", fuzzy=True, fuzzy_maxdist=2)\n\n# Via the unified interface\n\u003e\u003e\u003e api.do({\n...     \"action\": \"search\",\n...     \"query\": u\"مؤمن\",\n...     \"fuzzy\": True,\n...     \"fuzzy_maxdist\": 1,\n...     \"page\": 1,\n...     \"perpage\": 10\n... })\n```\n\n| `fuzzy_maxdist` | Behaviour |\n|---|---|\n| `1` (default) | Catches single-character insertions, deletions, or substitutions |\n| `2` | Broader tolerance — useful for longer words or noisy input |\n| `3` | Maximum supported — use with care as recall increases significantly |\n\nFuzzy mode is particularly useful when:\n\n* The user does not know the exact vocalized form of a word.\n* You want morphologically related words to appear in the same result set (e.g. searching *كتب* also surfaces *كتاب*, *كاتب*, *مكتوب*).\n* You want synonym-aware retrieval without writing explicit OR queries.\n\n\u003e **Note:** `pystemmer` must be installed for stemming to take effect (`pip install pystemmer`). If the package is absent the stem filter degrades silently to a no-op, leaving normalisation and stop-word removal still active.\n\n#### List Field Values\n\n`list_values` returns every unique indexed value for a given field. Use it to discover the full vocabulary of searchable fields — for example, all available translation identifiers, part-of-speech tags, or root words — before composing a query.\n\n```python\n# Get all unique root values in the index\n\u003e\u003e\u003e api.do({\"action\": \"list_values\", \"field\": \"root\"})\n# Returns: {\"list_values\": {\"field\": \"root\", \"values\": [...], \"count\": N}}\n\n# Discover all indexed translation IDs\n\u003e\u003e\u003e api.do({\"action\": \"list_values\", \"field\": \"trans_id\"})\n\n# Discover all part-of-speech categories for word search\n\u003e\u003e\u003e api.do({\"action\": \"list_values\", \"field\": \"pos\"})\n\n# Retrieve all indexed lemmas on demand (replaces the former show/lemmas)\n\u003e\u003e\u003e api.do({\"action\": \"list_values\", \"field\": \"lemma\"})\n```\n\n**Parameters:**\n\n* `field` (str): The name of the indexed field whose unique values you want (required).\n\n**Return value:**\n\nA dictionary with a `list_values` key containing:\n\n* `field` — the requested field name.\n* `values` — sorted list of unique non-empty indexed values.\n* `count` — length of the `values` list.\n\n#### Query Correction\n\n`correct_query()` uses Whoosh's built-in spell-checker to compare each term in the query against the index vocabulary and replace unknown terms with the closest known alternative.  When the query is already valid (all terms appear in the index) the `corrected` value in the response is identical to the original input.\n\n```python\n# Correct a query via the dedicated function\n\u003e\u003e\u003e api.correct_query(u\"الكتاب\")\n# Returns:\n# {\"correct_query\": {\"original\": \"الكتاب\", \"corrected\": \"الكتاب\"}, \"error\": ...}\n\n# Correct a misspelled / out-of-vocabulary term\n\u003e\u003e\u003e api.correct_query(u\"الكتب\")\n# Returns:\n# {\"correct_query\": {\"original\": \"الكتب\", \"corrected\": \"الكتاب\"}, \"error\": ...}\n\n# Via the unified interface\n\u003e\u003e\u003e api.do({\"action\": \"correct_query\", \"query\": u\"الكتب\", \"unit\": \"aya\"})\n```\n\n**Parameters:**\n\n* `query` (str): The raw query string to correct (required).\n* `unit` (str): Search unit — currently only `\"aya\"` is supported; other units return `None` (default: `\"aya\"`).\n* `flags` (dict): Optional dictionary of additional flags.\n\n**Return value:**\n\nA dictionary with a `correct_query` key containing:\n\n* `original` — the input query string as provided.\n* `corrected` — the corrected query string; identical to `original` when no correction is needed.\n\n#### Query Syntax\n\nAlfanous supports advanced query syntax:\n\n* **Phrases**: Use quotes - `\"الحمد لله\"`\n* **Boolean AND**: Use `+` - `الصلاة + الزكاة`\n* **Boolean OR**: Use `|` - `الصلاة | الزكاة`\n* **Boolean NOT**: Use `-` - `الصلاة - الزكاة`\n* **Wildcards**: Use `*` for multiple chars, `?` for single char - `*نبي*`, `نعم؟`\n* **Fielded Search**: Use field name - `سورة:يس`, `سجدة:نعم`\n* **Ranges**: Use `[X الى Y]` - `رقم_السورة:[1 الى 5]`\n* **Partial Vocalization**: Search with some diacritics - `آية_:'مَن'`\n* **Root/Lemma**: Use `\u003e\u003e` for root, `\u003e` for lemma - `\u003e\u003eمالك`, `\u003eمالك`\n* **Tuples**: Use `{root,type}` - `{قول،اسم}`\n\n#### Faceted Search\n\nFaceted search allows you to aggregate search results by fields:\n\n```python\n\u003e\u003e\u003e result = api.do({\n...     \"action\": \"search\",\n...     \"query\": u\"الله\",\n...     \"facets\": \"sura_id,juz,chapter\"\n... })\n\u003e\u003e\u003e print(result[\"search\"][\"facets\"])\n```\n\nAvailable facet fields:\n\n* `sura_id` - Sura (chapter) number (1-114)\n* `juz` - Juz (part) number (1-30)\n* `hizb` - Hizb (section) number\n* `chapter` - Main topic/chapter\n* `topic` - Subtopic\n* `sura_type` - Meccan/Medinan classification\n\n#### Filtering Results\n\nFilter search results by field values:\n\n```python\n\u003e\u003e\u003e api.do({\n...     \"action\": \"search\",\n...     \"query\": u\"الله\",\n...     \"filter\": {\"sura_id\": \"2\"}  # Only from Sura Al-Baqarah\n... })\n```\n\n#### Search Fields\n\nAvailable fields for fielded search:\n\n* `سورة` (sura) - Sura name\n* `رقم_السورة` (sura_id) - Sura number\n* `رقم_الآية` (aya_id) - Verse number\n* `جزء` (juz) - Juz number\n* `حزب` (hizb) - Hizb number\n* `صفحة` (page) - Page number in Mushaf\n* `سجدة` (sajda) - Has prostration\n* `موضوع` (subject) - Subject/theme\n* `فصل` (chapter) - Chapter\n* `باب` (subtopic) - Subtopic\n* `نوع_السورة` (sura_type) - Sura type (Meccan/Medinan)\n\nWord-level fields (use with `unit=\"word\"`):\n\n* `englishstate` - Nominal state in English (e.g. \"Definite state\", \"Indefinite state\")\n* `englishmood` - Verb mood in English (e.g. \"Indicative mood\", \"Subjunctive mood\", \"Jussive mood\")\n\nFor the complete field list, call:\n\n```python\n\u003e\u003e\u003e api.do({\"action\": \"show\", \"query\": \"fields\"})\n```\n\n#### Output Views\n\nDifferent views provide different levels of detail:\n\n* **minimal** - Basic verse text and identifier\n* **normal** - Verse text with essential metadata\n* **full** - All available information\n* **statistic** - Include statistical information\n* **linguistic** - Include linguistic analysis\n\nExample:\n\n```python\n\u003e\u003e\u003e api.do({\n...     \"action\": \"search\",\n...     \"query\": u\"الله\",\n...     \"view\": \"full\",\n...     \"word_info\": True,\n...     \"aya_theme_info\": True\n... })\n```\n\n#### Metadata Access\n\nGet various metadata using the \"show\" action:\n\n```python\n# Get list of available translations\n\u003e\u003e\u003e api.do({\"action\": \"show\", \"query\": \"translations\"})\n\n# Get list of recitations\n\u003e\u003e\u003e api.do({\"action\": \"show\", \"query\": \"recitations\"})\n\n# Get Sura information\n\u003e\u003e\u003e api.do({\"action\": \"show\", \"query\": \"surates\"})\n\n# Get search fields\n\u003e\u003e\u003e api.do({\"action\": \"show\", \"query\": \"fields\"})\n\n# Get default values\n\u003e\u003e\u003e api.do({\"action\": \"show\", \"query\": \"defaults\"})\n```\n\n\u003e **Note:** Lemmas are no longer exposed via `show`. Use `api.do({\"action\": \"list_values\", \"field\": \"lemma\"})` to retrieve them on demand.\n\n#### Adding New Translations\n\nYou can extend the local search index with additional Zekr-compatible `.trans.zip` translation files using `index_translations()`. This requires the `alfanous_import` package (included in the repository under `src/alfanous_import/`).\n\n```python\nimport alfanous.api as alfanous\n\n# Index all .trans.zip files found in a folder\ncount = alfanous.index_translations(source=\"/path/to/translations\")\nprint(f\"{count} translation(s) newly indexed\")\n```\n\nThe function:\n- Iterates over every `*.trans.zip` file in `source`\n- Skips translations that are already in the index (idempotent — safe to call repeatedly)\n- Returns the **count** of newly indexed translations (`0` means nothing new was added)\n- Automatically updates `configs/translations.json` so the new translations are immediately visible via `api.get_info(\"translations\")` and searchable with `unit=\"translation\"`\n\nAfter indexing, search in the new translation:\n\n```python\n# Search in a newly indexed translation\nresult = alfanous.search(u\"الرحمن\", unit=\"translation\", flags={\"translation\": \"en.newt\"})\n```\n\nSee [`examples/index_translations_example.py`](examples/index_translations_example.py) for a complete walkthrough.\n\n## Examples\n\nThe [examples/](examples/) directory contains example scripts demonstrating various features:\n\n* **facet_search_examples.py** - Faceted search and filtering examples\n\nSee [examples/README.md](examples/README.md) for more information.\n\n## MCP Server\n\nAlfanous ships an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that lets AI assistants (Claude, Copilot, etc.) search and explore the Qur'an directly. See [alfanous_mcp/README.md](src/alfanous_mcp/README.md) for the full reference.\n\nQuick start:\n\n```sh\n$ pip install alfanous3-mcp\n$ python -m alfanous_mcp.mcp_server        # stdio – works with Claude Desktop\n```\n\nTo connect Claude Desktop, add the following to your `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"alfanous\": {\n      \"type\": \"stdio\",\n      \"command\": \"python\",\n      \"args\": [\"-m\", \"alfanous_mcp.mcp_server\"],\n      \"tools\": [\n        \"search_quran\",\n        \"search_translations\",\n        \"get_quran_info\",\n        \"search_quran_by_themes\",\n        \"search_quran_by_stats\",\n        \"search_quran_by_position\",\n        \"suggest_query\",\n        \"correct_query\",\n        \"search_by_word_linguistics\",\n        \"list_field_values\"\n      ]\n    }\n  }\n}\n```\n\nThe server is also published to the [GitHub MCP Registry](https://github.com/mcp/io.github.Alfanous-team/alfanous) — you can install it with a single click from there.\n\n## Web Interface\n\nAlfanous includes a FastAPI-based web service for RESTful access. See [alfanous_webapi/README.md](src/alfanous_webapi/README.md) for:\n\n* Installation and setup\n* API endpoints\n* Request/response examples\n* Interactive API documentation (Swagger UI)\n\nQuick start:\n\n```sh\n$ pip install alfanous3 fastapi uvicorn\n$ cd src/\n$ uvicorn alfanous_webapi.web_api:app --reload\n```\n\nThen visit http://localhost:8000/docs for interactive documentation.\n\n## Contributing\n\nWe welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for:\n\n* Setting up a development environment\n* Building from source\n* Running tests\n* Submitting pull requests\n* Code style guidelines\n\nQuick development setup:\n\n```sh\n# Clone the repository\n$ git clone https://github.com/Alfanous-team/alfanous.git\n$ cd alfanous\n\n# Install dependencies\n$ pip install pyparsing whoosh pystemmer pytest\n\n# Build indexes (required for development)\n$ make build\n\n# Run tests\n$ pytest -vv --rootdir=src/\n```\n\n## Support\n\n* **GitHub Issues**: https://github.com/Alfanous-team/alfanous/issues\n* **Mailing List**: alfanous@googlegroups.com\n* **Website**: http://alfanous.org\n\n## License\n\nAlfanous is licensed under the **GNU Lesser General Public License v3 or later (LGPLv3+)**.\n\nSee [LICENSE](LICENSE) for details.\n\n## Credits\n* **Contributors**: See [AUTHORS.md](AUTHORS.md) and [THANKS.md](THANKS.md)\n\nThis project handles sacred religious text (the Holy Qur'an) - please treat the data and code with respect.\n\n## Legacy\n\nIf you are looking for the legacy Alfanous code, you can find it under the `legacy` branch.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falfanous-team%2Falfanous","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falfanous-team%2Falfanous","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falfanous-team%2Falfanous/lists"}