{"id":38215858,"url":"https://github.com/fodydev/afrim-py","last_synced_at":"2026-01-17T00:47:41.578Z","repository":{"id":316142559,"uuid":"1062149300","full_name":"fodydev/afrim-py","owner":"fodydev","description":"afrim-py is a python bindings for library, helping to build input method applications using python.","archived":false,"fork":false,"pushed_at":"2025-11-03T16:12:06.000Z","size":36,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-03T18:20:21.101Z","etag":null,"topics":["afrim","ime","python","typing"],"latest_commit_sha":null,"homepage":"","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/fodydev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2025-09-22T21:51:26.000Z","updated_at":"2025-11-03T16:12:09.000Z","dependencies_parsed_at":"2025-10-24T02:36:14.060Z","dependency_job_id":"36211560-8918-44c3-87e1-3945094cd79e","html_url":"https://github.com/fodydev/afrim-py","commit_stats":null,"previous_names":["esubaalew/afrim-py","fodydev/afrim-py"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fodydev/afrim-py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fodydev%2Fafrim-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fodydev%2Fafrim-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fodydev%2Fafrim-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fodydev%2Fafrim-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fodydev","download_url":"https://codeload.github.com/fodydev/afrim-py/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fodydev%2Fafrim-py/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28490572,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T23:55:29.509Z","status":"ssl_error","status_checked_at":"2026-01-16T23:55:29.108Z","response_time":107,"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":["afrim","ime","python","typing"],"created_at":"2026-01-17T00:47:40.846Z","updated_at":"2026-01-17T00:47:41.571Z","avatar_url":"https://github.com/fodydev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n  \u003ch1\u003e\u003ccode\u003eafrim-py\u003c/code\u003e\u003c/h1\u003e\n\n  \u003cstrong\u003ePython bindings for the \u003ca href=\"https://github.com/pythonbrad/afrim\"\u003eafrim ime engine\u003c/a\u003e.\u003c/strong\u003e\n\n  \u003cp\u003e\n    \u003cimg alt=\"Python\" src=\"https://img.shields.io/badge/python-3.8+-blue.svg\"/\u003e\n    \u003cimg alt=\"Rust\" src=\"https://img.shields.io/badge/rust-1.70+-orange.svg\"/\u003e\n    \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-green.svg\"/\u003e\n    \u003ca href=\"https://github.com/fodydev/afrim/blob/main/CHANGELOG.md\"\u003e\u003cimg alt=\"Changelog\" src=\"https://img.shields.io/badge/Keep%20a%20Changelog--555.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmMTVkMzAiIHZpZXdCb3g9IjAgMCAxODcgMTg1Ij48cGF0aCBkPSJNNjIgN2MtMTUgMy0yOCAxMC0zNyAyMmExMjIgMTIyIDAgMDAtMTggOTEgNzQgNzQgMCAwMDE2IDM4YzYgOSAxNCAxNSAyNCAxOGE4OSA4OSAwIDAwMjQgNCA0NSA0NSAwIDAwNiAwbDMtMSAxMy0xYTE1OCAxNTggMCAwMDU1LTE3IDYzIDYzIDAgMDAzNS01MiAzNCAzNCAwIDAwLTEtNWMtMy0xOC05LTMzLTE5LTQ3LTEyLTE3LTI0LTI4LTM4LTM3QTg1IDg1IDAgMDA2MiA3em0zMCA4YzIwIDQgMzggMTQgNTMgMzEgMTcgMTggMjYgMzcgMjkgNTh2MTJjLTMgMTctMTMgMzAtMjggMzhhMTU1IDE1NSAwIDAxLTUzIDE2bC0xMyAyaC0xYTUxIDUxIDAgMDEtMTItMWwtMTctMmMtMTMtNC0yMy0xMi0yOS0yNy01LTEyLTgtMjQtOC0zOWExMzMgMTMzIDAgMDE4LTUwYzUtMTMgMTEtMjYgMjYtMzMgMTQtNyAyOS05IDQ1LTV6TTQwIDQ1YTk0IDk0IDAgMDAtMTcgNTQgNzUgNzUgMCAwMDYgMzJjOCAxOSAyMiAzMSA0MiAzMiAyMSAyIDQxLTIgNjAtMTRhNjAgNjAgMCAwMDIxLTE5IDUzIDUzIDAgMDA5LTI5YzAtMTYtOC0zMy0yMy01MWE0NyA0NyAwIDAwLTUtNWMtMjMtMjAtNDUtMjYtNjctMTgtMTIgNC0yMCA5LTI2IDE4em0xMDggNzZhNTAgNTAgMCAwMS0yMSAyMmMtMTcgOS0zMiAxMy00OCAxMy0xMSAwLTIxLTMtMzAtOS01LTMtOS05LTEzLTE2YTgxIDgxIDAgMDEtNi0zMiA5NCA5NCAwIDAxOC0zNSA5MCA5MCAwIDAxNi0xMmwxLTJjNS05IDEzLTEzIDIzLTE2IDE2LTUgMzItMyA1MCA5IDEzIDggMjMgMjAgMzAgMzYgNyAxNSA3IDI5IDAgNDJ6bS00My03M2MtMTctOC0zMy02LTQ2IDUtMTAgOC0xNiAyMC0xOSAzN2E1NCA1NCAwIDAwNSAzNGM3IDE1IDIwIDIzIDM3IDIyIDIyLTEgMzgtOSA0OC0yNGE0MSA0MSAwIDAwOC0yNCA0MyA0MyAwIDAwLTEtMTJjLTYtMTgtMTYtMzEtMzItMzh6bS0yMyA5MWgtMWMtNyAwLTE0LTItMjEtN2EyNyAyNyAwIDAxLTEwLTEzIDU3IDU3IDAgMDEtNC0yMCA2MyA2MyAwIDAxNi0yNWM1LTEyIDEyLTE5IDI0LTIxIDktMyAxOC0yIDI3IDIgMTQgNiAyMyAxOCAyNyAzM3MtMiAzMS0xNiA0MGMtMTEgOC0yMSAxMS0zMiAxMXptMS0zNHYxNGgtOFY2OGg4djI4bDEwLTEwaDExbC0xNCAxNSAxNyAxOEg5NnoiLz48L3N2Zz4K\"/\u003e\u003c/a\u003e\n\n  \u003c/p\u003e\n\n  \u003ch3\u003e\n    \u003ca href=\"https://github.com/fodydev/afrim-py\"\u003eRepository\u003c/a\u003e\n  \u003c/h3\u003e\n\n  \u003csub\u003eBuilt with 🦀🐍 by \u003ca href=\"https://github.com/esubaalew\"\u003e@esubaalew\u003c/a\u003e\u003c/sub\u003e\n\u003c/div\u003e\n\n## About\n\n`afrim-py` provides Python bindings for the powerful afrim input method engine, enabling developers to build sophisticated input method applications in Python. This project brings the capabilities of the Rust-based afrim engine to the Python ecosystem through PyO3 bindings.\n\n## 🔋 Features Included\n\n* **Preprocessor** - Advanced key sequence processing and input transformation\n* **Translator** - Dictionary-based text translation with multiple candidates\n* **TOML Support** - Easy configuration through TOML files\n* **Unicode Support** - Full support for international characters\n* **Rhai Scripting** - Dynamic translation scripts (when `rhai` feature is enabled)\n* **String Similarity** - Fuzzy matching with `strsim` feature\n\n## Installation\n\n`afrim-py` is available on pypi.\n\n```bash\npip install afrim-py\n```\n\n## Usage\n\n### Basic Example\n\n```python\nfrom afrim_py import Preprocessor, Translator, Config\n\n# Configure the preprocessor with key mappings\npreprocessor_data = {\n    \"a1\": \"à\",\n    \"e1\": \"é\", \n    \"u1\": \"ù\",\n    \"hello\": \"hi\"\n}\n\n# Configure the translator with dictionary\ntranslator_dict = {\n    \"hello\": [\"hi\", \"hey\", \"greetings\"],\n    \"world\": [\"earth\", \"globe\", \"planet\"],\n    \"python\": [\"snake\", \"programming language\"]\n}\n\n# Create instances\npreprocessor = Preprocessor(preprocessor_data, buffer_size=64)\ntranslator = Translator(translator_dict, auto_commit=True)\n\n# Process keyboard events\nchanged = preprocessor.process(\"h\", \"keydown\")\nchanged = preprocessor.process(\"e\", \"keydown\") \nchanged = preprocessor.process(\"l\", \"keydown\")\nchanged = preprocessor.process(\"l\", \"keydown\")\nchanged = preprocessor.process(\"o\", \"keydown\")\n\n# Get the processed input\ncurrent_input = preprocessor.get_input()  # \"hello\"\n\n# Translate the input\ntranslations = translator.translate(current_input)\nprint(translations)\n# [{'texts': ['hi', 'hey', 'greetings'], 'code': 'hello', 'remaining_code': '', 'can_commit': True}]\n\n# Process commands from the queue\nwhile True:\n    command = preprocessor.pop_queue()\n    if command == \"NOP\":\n        break\n    print(f\"Command: {command}\")\n```\n\n### Configuration\n\n```python\nfrom afrim_py import Config\nimport json\n\n# Configuration file `config.toml`\n'''\n[core]\nbuffer_size = 64\nauto_capitalize = false\nauto_commit = false\npage_size = 10\n\n[data]\na1 = \"à\"\ne2 = \"é\"\n\n[translators]\ndatetime = { path = \"./scripts/datetime.toml\" }\n\n[translation]\nhi = 'hello'\n'''\nconfig = Config('config.toml')\n\n# Use the configuration\npreprocessor_data = config.extract_data()\npreprocessor = Preprocessor(preprocessor_data, 64)\ntranslator_dict = config.extract_translation()\ntranslator = Translator(translator_dict, True)\n```\n\n### Advanced Usage with Command Processing\n\n```python\nimport asyncio\nfrom afrim_py import Preprocessor, Translator, Config\n\nclass InputMethodEngine:\n    def __init__(self, config_file: str):\n        config = Config(config_file)\n        self.preprocessor = Preprocessor(config.extract_data(), 64)\n        self.translator = Translator(config.extract_translation(), True)\n        self.running = False\n    \n    async def process_commands(self):\n        \"\"\"Process commands from the preprocessor queue\"\"\"\n        while self.running:\n            command = self.preprocessor.pop_queue()\n            \n            if command == \"NOP\":\n                await asyncio.sleep(0.01)  # Small delay\n                continue\n                \n            # Handle different command types\n            if isinstance(command, dict):\n                if \"Insert\" in command:\n                    text = command[\"Insert\"][\"text\"]\n                    print(f\"Insert: {text}\")\n                elif \"Delete\" in command:\n                    count = command[\"Delete\"][\"count\"]\n                    print(f\"Delete: {count} characters\")\n            else:\n                print(f\"Command: {command}\")\n    \n    def handle_key_event(self, key, state=\"keydown\"):\n        \"\"\"Handle keyboard events\"\"\"\n        changed = self.preprocessor.process(key, state)\n        \n        if changed:\n            current_input = self.preprocessor.get_input()\n            if current_input:\n                translations = self.translator.translate(current_input)\n                return translations\n        return []\n    \n    def commit_text(self, text):\n        \"\"\"Commit selected text\"\"\"\n        self.preprocessor.commit(text)\n    \n    async def start(self):\n        \"\"\"Start the input method engine\"\"\"\n        self.running = True\n        await self.process_commands()\n    \n    def stop(self):\n        \"\"\"Stop the input method engine\"\"\"\n        self.running = False\n\n# Usage\nasync def main():\n    ime = InputMethodEngine(\n        preprocessor_data={\"A\": \"ዕ\", \"Aa\": \"ዓ\", \"C\": \"ጭ\"},\n        translator_dict={\"Atarah\": [\"ዓጣራ\"], \"Adiel\": [\"ዓዲዔል\"]}\n    )\n    \n    # Simulate key events\n    translations = ime.handle_key_event(\"A\")\n    translations = ime.handle_key_event(\"a\")\n    translations = ime.handle_key_event(\"C\")\n    \n    print(\"Translations:\", translations)\n    \n    # Commit text\n    if translations:\n        ime.commit_text(translations[0][\"texts\"][0])\n\n# Run the example\n# asyncio.run(main())\n```\n\n## Development\n\n### Build requirements\n\n- Rust 1.70+\n- Cargo\n\n- Python 3.8+ and and [maturin](https://www.maturin.rs/installation.html)\n- [uv](https://docs.astral.sh/uv/getting-started/installation/) *(optional)*\n\n### Build from source\n\nTo simplify the development, we recommend to use `uv`.\n\n**Using maturin**\n\n```bash\n# Clone the repository\ngit clone https://github.com/fodydev/afrim-py.git\ncd afrim-py\n\n# Create virtual environment\npython -m venv .venv\nsource .venv/bin/activate  # On Windows: .venv\\Scripts\\activate\n\n# Development build\nmaturin develop\n\n# Release build\nmaturin build --release\n\n# Build wheel\nmaturin build --interpreter python\n```\n\n**Using uv**\n\n```bash\n# Clone the repository\ngit clone https://github.com/fodydev/afrim-py.git\ncd afrim-py\n\n# Prerelease build\nuv build --prerelease\n\n# Release build\nuv build\n```\n\n### Testing\n\nThe project includes tests that represent a real user scenario:\n\n```bash\n# Run all tests\npython -m pytest tests/ -v\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n## Acknowledgments\n\n- **[afrim-js](https://github.com/pythonbrad/afrim-js)** - Web bindings that inspired this project\n\n## License\n\nLicensed under the [MIT LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffodydev%2Fafrim-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffodydev%2Fafrim-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffodydev%2Fafrim-py/lists"}