{"id":48805561,"url":"https://github.com/nexustech101/registers","last_synced_at":"2026-05-22T06:13:41.208Z","repository":{"id":351181169,"uuid":"1209903405","full_name":"nexustech101/registers","owner":"nexustech101","description":"A Python framework built with Developer Experience (DX) in mind. decorators uses a clean, ergonomic decorator registry design pattern to eliminate boilerplate when building CLI tools and database-backed applications.","archived":false,"fork":false,"pushed_at":"2026-04-14T03:33:41.000Z","size":166,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T04:24:15.511Z","etag":null,"topics":["cli-framework","data-engineering","data-modeling","design-patterns","framework","open-source","orm-framework","python-package"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nexustech101.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-04-13T22:38:18.000Z","updated_at":"2026-04-14T03:25:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nexustech101/registers","commit_stats":null,"previous_names":["nexustech101/decorators","nexustech101/registers"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/nexustech101/registers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nexustech101%2Fregisters","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nexustech101%2Fregisters/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nexustech101%2Fregisters/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nexustech101%2Fregisters/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nexustech101","download_url":"https://codeload.github.com/nexustech101/registers/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nexustech101%2Fregisters/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31782740,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T02:24:21.117Z","status":"ssl_error","status_checked_at":"2026-04-14T02:24:20.627Z","response_time":153,"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":["cli-framework","data-engineering","data-modeling","design-patterns","framework","open-source","orm-framework","python-package"],"created_at":"2026-04-14T05:01:14.341Z","updated_at":"2026-05-22T06:13:41.199Z","avatar_url":"https://github.com/nexustech101.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"```text\n         ______     ______     ______     __     ______     ______   ______     ______     ______    \n        /\\  == \\   /\\  ___\\   /\\  ___\\   /\\ \\   /\\  ___\\   /\\__  _\\ /\\  ___\\   /\\  == \\   /\\  ___\\   \n        \\ \\  __\u003c   \\ \\  __\\   \\ \\ \\__ \\  \\ \\ \\  \\ \\___  \\  \\/_/\\ \\/ \\ \\  __\\   \\ \\  __\u003c   \\ \\___  \\  \n         \\ \\_\\ \\_\\  \\ \\_____\\  \\ \\_____\\  \\ \\_\\  \\/\\_____\\    \\ \\_\\  \\ \\_____\\  \\ \\_\\ \\_\\  \\/\\_____\\ \n          \\/_/ /_/   \\/_____/   \\/_____/   \\/_/   \\/_____/     \\/_/   \\/_____/   \\/_/ /_/   \\/_____/ \n```\n\n**Build command systems, Pydantic-backed data services, and scheduled automation workflows with one coherent Python framework.**\n\n[![PyPI version](https://img.shields.io/pypi/v/registers?color=5C6BC0\\\u0026labelColor=111827\\\u0026style=for-the-badge)](https://pypi.org/project/registers/)\n[![Python](https://img.shields.io/pypi/pyversions/registers?color=0F766E\\\u0026labelColor=111827\\\u0026style=for-the-badge)](https://pypi.org/project/registers/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-7C3AED?labelColor=111827\\\u0026style=for-the-badge)](LICENSE)\n[![SQLAlchemy](https://img.shields.io/badge/Powered%20by-SQLAlchemy-D97706?labelColor=111827\\\u0026style=for-the-badge)](https://www.sqlalchemy.org/)\n[![Pydantic](https://img.shields.io/badge/Pydantic-v2-E92063?labelColor=111827\\\u0026style=for-the-badge)](https://docs.pydantic.dev/)\n[![Tests](https://img.shields.io/badge/Tests-290%2B-2563EB?labelColor=111827\\\u0026style=for-the-badge)](#testing)\n\n`registers.cli` · `registers.db` · `registers.cron` · `fx-tool`\n\n---\n\n## Tags\n\n`Python Framework` `Developer Experience` `CLI Tooling` `Pydantic Persistence` `SQLAlchemy` `FastAPI` `Cron Automation` `Plugin Architecture` `Internal Tools` `Ops Workflows` `AI-Agent Friendly`\n\n## What Is Registers?\n\n**Registers** is a DX-first Python framework for building production-minded backend and operations tooling with a consistent decorator-driven programming model.\n\nIt gives you three integrated surfaces:\n\n| Module           | Purpose                                                                 | Primary abstraction                  |\n| ---------------- | ----------------------------------------------------------------------- | ------------------------------------ |\n| `registers.cli`  | Command-line tools, interactive shells, plugin-driven operator consoles | `CommandRegistry`                    |\n| `registers.db`   | Pydantic-first persistence backed by SQLAlchemy engines                 | `DatabaseRegistry` + `Model.objects` |\n| `registers.cron` | Scheduled jobs, event jobs, retryable automation, workflow operations   | `CronRegistry`                       |\n\nThe companion package, **`fx-tool`**, provides project scaffolding, project operations, workflow management, and cron/runtime commands for Registers-based projects.\n\n\u003e **Positioning:** Registers is not a thin helper library. It is a coherent application infrastructure layer for engineers who want the ergonomics of decorators with the discipline of explicit registries, manager APIs, plugin composition, runtime state, and production-facing operational workflows.\n\n---\n\n## Why Registers?\n\nMost Python service projects eventually accumulate the same supporting layers:\n\n* a CLI for internal operations;\n* a persistence layer for application data;\n* scheduled jobs for maintenance and workflows;\n* scripts for deployment, validation, and project management;\n* documentation that explains how humans and coding agents should operate the project.\n\nRegisters provides these primitives through one consistent mental model:\n\n```python\n@cli.register(...)\ndef command(...): ...\n\n@db.database_registry(...)\nclass Model(BaseModel): ...\n\n@cron.job(...)\ndef job(...): ...\n```\n\nThat consistency makes small projects faster to start and medium projects easier to scale.\n\n---\n\n## Core Features\n\n| Capability                       | Description                                                                                                                  |\n| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| **Decorator-first APIs**         | Register commands, models, and jobs through explicit decorators.                                                             |\n| **Registry isolation**           | Use module-level facades for small projects or owned registry instances for tests, plugins, tenants, and multi-surface apps. |\n| **Pydantic-first persistence**   | Persist Pydantic models without full ORM boilerplate while retaining SQLAlchemy-powered storage.                             |\n| **Manager-style CRUD**           | Use `Model.objects.create`, `require`, `filter`, `upsert`, `bulk_create`, `bulk_upsert`, and schema helpers.                 |\n| **CLI command runtime**          | Build scriptable CLIs, grouped operator consoles, structured output, async commands, prompts, safety gates, plugins, and context-driven workflows. |\n| **Cron/event automation**        | Define manual, interval, cron-expression, webhook, and file-change jobs with retries and runtime state.                      |\n| **Production error semantics**   | Structured exceptions, deterministic parse failures, duplicate/collision detection, and dead-letter states.                  |\n| **FastAPI-ready patterns**       | Use lifespan hooks, exception handlers, service-layer invariants, and manager-based persistence.                             |\n| **Agent-friendly documentation** | Designed to be readable by engineers and AI coding agents building from implementation instructions.                         |\n\n---\n\n## Installation\n\nInstall Registers:\n\n```bash\npip install registers\n```\n\nInstall optional CLI shell features:\n\n```bash\npip install \"registers[cli]\"\n```\n\nThe `cli` extra enables prompt_toolkit shell completion, history, and multiline input while preserving plain-text fallback behavior when it is not installed.\n\nInstall the companion project manager:\n\n```bash\npip install fx-tool\n```\n\nOr install `fx-tool` from source:\n\n```bash\npip install git+https://github.com/nexustech101/fx.git\n```\n\nClone the companion repository directly:\n\n```bash\ngit clone https://github.com/nexustech101/fx.git\n```\n\n---\n\n## `registers.cli`\n\n`registers.cli` is built for practical internal command tools: quick scripts, small persisted apps, grouped operator consoles, plugin-composed admin surfaces, and larger CLIs that need context injection and async handlers.\n\nThe main usage modes are:\n\n* **Quick start scripts** with module-level decorators such as `@cli.register`, `@cli.argument`, and `cli.run()`.\n* **App-level presentation** where a script can use Rich directly for a specific human-facing command while keeping the framework plain and scriptable.\n* **Grouped and plugin-based CLIs** using `CommandRegistry()`, `group(...)`, `register_plugin(...)`, aliases, `Choice(...)`, `default=...`, `dry_run()`, and `confirm(...)`.\n* **Larger internal tools** where the CLI is a thin operator surface over services, with `context_factory` handling env, region, tenant, account, or profile.\n\nSmall example:\n\n```python\nfrom registers import CommandRegistry\n\n@cli.register(name=\"add\", description=\"Create a task\")\n@cli.argument(\"title\", type=str, help=\"Task title\")\n@cli.argument(\"owner\", type=str, default=\"platform\", help=\"Owning team\")\ndef add_task(title: str, owner: str = \"platform\") -\u003e dict[str, str]:\n    return {\"title\": title, \"owner\": owner}\n\nif __name__ == \"__main__\":\n    cli.run(shell_title=\"Task Desk\", shell_usage=True)\n```\n\nGrouped operator example:\n\n```python\nregistry = cli.CommandRegistry()\ndeploy = registry.group(\"deploy\", aliases=[\"d\"], description=\"Deployment workflows\")\n\n@deploy.register(\"service\", description=\"Deploy one service\")\n@deploy.argument(\"name\", type=cli.types.Choice([\"api\", \"worker\", \"billing\"]))\n@deploy.argument(\"version\", type=str, default=\"latest\")\n@deploy.dry_run()\ndef deploy_service(name: str, version: str = \"latest\", dry_run: bool = False) -\u003e str:\n    action = \"Would deploy\" if dry_run else \"Deploying\"\n    return f\"{action} {name}:{version}\"\n```\n\nHelp displays choices and defaults, so operators can discover valid invocations without guessing:\n\n```text\ndeploy service \u003cname: api|worker|billing\u003e [version] [--dry-run]\n```\n\nInteractive shell built-ins are intentionally small: `help`, `commands`, `exec`, `exit`, and `quit`. Runtime output flags include `--output json`, `--output csv`, `--output plain`, `--quiet`, and `--no-color`; use `--cli-output` when a command owns an `output` argument.\n\nFor the full CLI guide, including a todo app, a Rich table script, plugin composition, and larger internal-tool patterns, see `src/registers/cli/USAGE.md`.\n\n---\n\n## Quick Start: CLI + Database Todo App\n\nThe example below creates a small todo application with:\n\n* an isolated command registry;\n* an isolated database registry;\n* a Pydantic model persisted to SQLite;\n* commands for create/list/update/complete;\n* an optional interactive shell.\n\n```python\nfrom __future__ import annotations\n\nfrom enum import StrEnum\nfrom time import strftime\n\nfrom pydantic import BaseModel\n\nfrom registers import CommandRegistry, DatabaseRegistry, db_field\n\ncli = CommandRegistry()\ndb = DatabaseRegistry()\n\nDB_PATH = \"sqlite:///todos.db\"\nNOW = lambda: strftime(\"%Y-%m-%d %H:%M:%S\")\n\n\nclass TodoStatus(StrEnum):\n    PENDING = \"pending\"\n    COMPLETED = \"completed\"\n\n\n@db.database_registry(DB_PATH, table_name=\"todos\", key_field=\"id\")\nclass TodoItem(BaseModel):\n    id: int | None = db_field(id_strategy=\"autoincrement\", default=None)\n    title: str = db_field(index=True)\n    description: str = db_field(default=\"\")\n    status: TodoStatus = db_field(default=TodoStatus.PENDING.value)\n    created_at: str = db_field(default_factory=NOW)\n    updated_at: str = db_field(default_factory=NOW)\n\n\n@cli.register(name=\"add\", description=\"Create a todo item\")\n@cli.argument(\"title\", type=str, help=\"Todo title\")\n@cli.argument(\"description\", type=str, default=\"\", help=\"Todo description\")\n@cli.option(\"--add\")\n@cli.option(\"-a\")\ndef add_todo(title: str, description: str = \"\") -\u003e str:\n    todo = TodoItem.objects.create(title=title, description=description)\n    return f\"Added: {todo.title} (ID: {todo.id})\"\n\n\n@cli.register(name=\"list\", description=\"List todo items\")\n@cli.option(\"--list\")\n@cli.option(\"-l\")\ndef list_todos() -\u003e str:\n    todos = TodoItem.objects.all(order_by=\"id\")\n    if not todos:\n        return \"No todo items found.\"\n    return \"\\n\".join(f\"{todo.id}: {todo.title} [{todo.status}]\" for todo in todos)\n\n\n@cli.register(name=\"complete\", description=\"Mark a todo item as completed\")\n@cli.argument(\"todo_id\", type=int, help=\"Todo ID\")\n@cli.option(\"--complete\")\n@cli.option(\"-c\")\ndef complete_todo(todo_id: int) -\u003e str:\n    todo = TodoItem.objects.require(todo_id)\n    todo.status = TodoStatus.COMPLETED.value\n    todo.updated_at = NOW()\n    todo.save()\n    return f\"Completed todo ID {todo_id}.\"\n\n\n@cli.register(name=\"update\", description=\"Update a todo item\")\n@cli.argument(\"todo_id\", type=int, help=\"Todo ID\")\n@cli.argument(\"title\", type=str, default=None, help=\"New title\")\n@cli.argument(\"description\", type=str, default=None, help=\"New description\")\n@cli.option(\"--update\")\n@cli.option(\"-u\")\ndef update_todo(\n    todo_id: int,\n    title: str | None = None,\n    description: str | None = None,\n) -\u003e str:\n    todo = TodoItem.objects.require(todo_id)\n    if title is not None:\n        todo.title = title\n    if description is not None:\n        todo.description = description\n    todo.updated_at = NOW()\n    todo.save()\n    return f\"Updated todo ID {todo_id}.\"\n\n\nif __name__ == \"__main__\":\n    cli.run(\n        shell_title=\"Todo Console\",\n        shell_description=\"Manage tasks.\",\n        shell_banner=True,\n        shell_usage=True,\n    )\n```\n\nRun commands directly:\n\n```bash\npython todo.py add \"Buy groceries\" \"Milk, eggs, bread\"\npython todo.py --add \"Buy groceries\" \"Milk, eggs, bread\"\npython todo.py -a \"Buy groceries\" \"Milk, eggs, bread\"\npython todo.py add --title \"Buy groceries\" --description \"Milk, eggs, bread\"\n\npython todo.py list\npython todo.py --list\npython todo.py -l\n\npython todo.py complete 1\npython todo.py --complete 1\npython todo.py -c 1\n\npython todo.py update 1 \"Read two books\" \"Finish both novels this week\"\npython todo.py update 1 --title \"Read two books\" --description \"Finish both novels this week\"\n```\n\nRun without arguments to enter the interactive shell:\n\n```bash\npython todo.py\n```\n\nDatabase IDs and credential hashing are explicit at the field definition:\n\n```python\nfrom uuid import UUID\nfrom registers import db_field\n\nid: int | None = db_field(id_strategy=\"autoincrement\", default=None)\npublic_id: UUID | None = db_field(id_strategy=\"uuid4\", default=None)\npassword: str = db_field(hash_password=True)\n```\n\nPlain `password` fields are stored as plain strings. Use `hash_password=True` only for credential fields that should be hashed on create, save, upsert, and `update_where`.\n\nPassword hashing defaults to PBKDF2-SHA256 with a configurable policy. Use `PasswordHashPolicy`, `configure_password_policy()`, and `verify_and_upgrade_password()` when you need stronger deployment-specific settings or login-time hash upgrades.\n\nUse UUID primary keys for public-facing or distributed records:\n\n```python\nfrom uuid import UUID\n\nfrom pydantic import BaseModel\nfrom registers import DatabaseRegistry, db_field\n\ndb = DatabaseRegistry()\n\n@db.database_registry(\"sqlite:///app.db\", table_name=\"api_keys\", key_field=\"id\")\nclass ApiKey(BaseModel):\n    id: UUID | None = db_field(id_strategy=\"uuid4\", default=None)\n    name: str\n    owner_email: str\n\napi_key = ApiKey.objects.create(name=\"Production\", owner_email=\"ops@example.com\")\nassert isinstance(api_key.id, UUID)\n```\n\nRelationship descriptors support both original and cardinality-explicit names:\n\n```python\nfrom registers import ManyToMany, ManyToOne, OneToMany, prefetch\n\nAuthor.posts = OneToMany(Post, foreign_key=\"author_id\")\nPost.author = ManyToOne(Author, local_key=\"author_id\")\nPost.tags = ManyToMany(Tag, through=PostTag, source_key=\"post_id\", target_key=\"tag_id\")\n\nprefetch(Post.objects.all(), \"tags\")  # batch-load list-view relationships\n```\n\nUse `db_field(foreign_key=\"table.column\", index=True)` on child keys when the database should reject orphans and relationship lookups need an index.\n\nFor production services, keep the quickstart ergonomics but make lifecycle explicit:\n\n```python\ndb = DatabaseRegistry()\n\n@db.database_registry(\"sqlite:///app.db\", table_name=\"users\", auto_create=False)\nclass User(BaseModel):\n    id: int | None = db_field(id_strategy=\"autoincrement\", default=None)\n    email: str\n\ndb.create_all()\ndb.assert_schema_current()\n\nwith db.transaction():\n    user = User.objects.create(email=\"alice@example.com\")\n```\n\n---\n\n## Quick Start: Database + FastAPI Service\n\nRegisters works naturally with FastAPI because application models remain Pydantic models while persistence is handled by the registered manager API.\n\n```python\nfrom __future__ import annotations\n\nfrom contextlib import asynccontextmanager\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\nfrom registers import DatabaseRegistry, RecordNotFoundError, UniqueConstraintError, db_field\n\nDB_URL = \"sqlite:///shop.db\"\ndb = DatabaseRegistry()\n\n\n@db.database_registry(DB_URL, table_name=\"customers\", unique_fields=[\"email\"])\nclass Customer(BaseModel):\n    id: int | None = db_field(id_strategy=\"autoincrement\", default=None)\n    name: str\n    email: str\n\n\n@db.database_registry(DB_URL, table_name=\"products\")\nclass Product(BaseModel):\n    id: int | None = db_field(id_strategy=\"autoincrement\", default=None)\n    name: str\n    price: float\n\n\n@db.database_registry(DB_URL, table_name=\"orders\")\nclass Order(BaseModel):\n    id: int | None = db_field(id_strategy=\"autoincrement\", default=None)\n    customer_id: int\n    product_id: int\n    quantity: int\n    total: float\n\n\nMODELS = (Customer, Product, Order)\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    for model in MODELS:\n        if not model.schema_exists():\n            model.create_schema()\n    yield\n    for model in MODELS:\n        model.objects.dispose()\n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.post(\"/customers\", response_model=Customer, status_code=201)\ndef create_customer(customer: Customer):\n    return Customer.objects.create(**customer.model_dump(exclude={\"id\"}))\n\n\n@app.get(\"/customers/{customer_id}\", response_model=Customer)\ndef get_customer(customer_id: int):\n    return Customer.objects.require(customer_id)\n\n\n@app.post(\"/products\", response_model=Product, status_code=201)\ndef create_product(product: Product):\n    return Product.objects.create(**product.model_dump(exclude={\"id\"}))\n\n\n@app.post(\"/orders\", response_model=Order, status_code=201)\ndef create_order(customer_id: int, product_id: int, quantity: int):\n    Customer.objects.require(customer_id)\n    product = Product.objects.require(product_id)\n    return Order.objects.create(\n        customer_id=customer_id,\n        product_id=product_id,\n        quantity=quantity,\n        total=round(product.price * quantity, 2),\n    )\n\n\n@app.get(\"/orders\", response_model=list[Order])\ndef list_orders(limit: int = 20, offset: int = 0):\n    return Order.objects.filter(order_by=\"-id\", limit=limit, offset=offset)\n```\n\nExample requests:\n\n```bash\ncurl -X POST \"http://localhost:8000/customers\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Alice Johnson\",\"email\":\"alice@example.com\"}'\n\ncurl \"http://localhost:8000/customers/1\"\n\ncurl -X POST \"http://localhost:8000/products\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Wireless Keyboard\",\"price\":49.99}'\n\ncurl -X POST \"http://localhost:8000/orders?customer_id=1\u0026product_id=1\u0026quantity=2\"\n\ncurl \"http://localhost:8000/orders?limit=20\u0026offset=0\"\n```\n\n---\n\n## Quick Start: Cron + Workflow Operations\n\nUse `registers.cron` to define manual, interval, cron-expression, webhook, and file-change jobs.\n\n```python\nfrom __future__ import annotations\n\nfrom registers import CronRegistry\n\ncron = CronRegistry()\n\n\n@cron.job\ndef rebuild(payload: dict | None = None) -\u003e str:\n    dry_run = bool((payload or {}).get(\"dry_run\", False))\n    return f\"rebuilt: dry_run={dry_run}\"\n\n\n@cron.watch(\"src/**/*.py\", debounce_seconds=1.0)\ndef rebuild_on_source_change(event: dict) -\u003e str:\n    return f\"changed: {event['payload']['path']}\"\n\n\n@cron.job(\n    name=\"nightly\",\n    trigger=cron.cron(\"0 2 * * *\"),\n    target=\"local_async\",\n    retry_policy=\"exponential\",\n    retry_max_attempts=5,\n    retry_backoff_seconds=10,\n    retry_max_backoff_seconds=180,\n    retry_jitter_seconds=2,\n)\ndef nightly() -\u003e str:\n    return \"nightly complete\"\n\n\nprint(cron.run(\"rebuild\", payload={\"dry_run\": True}))\ncron.register(\"nightly\", root=\".\", apply=False)\n```\n\nSelf-contained CLI management is also supported:\n\n```python\nfrom __future__ import annotations\n\nfrom registers import CommandRegistry, CronRegistry\n\ncli = CommandRegistry()\ncron = CronRegistry()\n\n\n@cron.job(name=\"nightly\", trigger=cron.cron(\"0 2 * * *\"))\ndef nightly() -\u003e str:\n    return \"ok\"\n\n\ncron.install_cli()\n\n\nif __name__ == \"__main__\":\n    cli.run(shell_title=\"Automation Console\", shell_usage=True)\n```\n\n```bash\npython app.py cron jobs\npython app.py cron run nightly .\npython app.py cron register nightly . --target auto --apply\n```\n\n`--target auto` maps to the host platform scheduler and installs a persistent command that calls back into the same script.\n\n---\n\n## Architecture\n\nRegisters is built around explicit registries and predictable runtime boundaries.\n\n```text\n┌─────────────────────────────────────────────────────────────────────┐\n│                           Registers Framework                        │\n├──────────────────────┬──────────────────────┬───────────────────────┤\n│ registers.cli         │ registers.db          │ registers.cron          │\n│ Command runtime       │ Persistence layer     │ Automation runtime      │\n├──────────────────────┼──────────────────────┼───────────────────────┤\n│ CommandRegistry       │ DatabaseRegistry      │ CronRegistry            │\n│ decorators            │ model decorators      │ job decorators          │\n│ parser/dispatch       │ Model.objects         │ triggers/events         │\n│ plugins/shell         │ query/schema helpers  │ daemon/workflows        │\n└──────────────────────┴──────────────────────┴───────────────────────┘\n                                │\n                                ▼\n                          fx-tool companion\n                  scaffolding · runtime ops · workflows\n```\n\n### Module-level vs instance-level APIs\n\n| Pattern             | Use when                                            | Example                       |\n| ------------------- | --------------------------------------------------- | ----------------------------- |\n| Module-level facade | Single app surface, simple scripts, fast onboarding | `from registers import CommandRegistry` |\n| Instance registry   | Tests, plugins, isolated scopes, explicit ownership | `cli = CommandRegistry()`     |\n\nThe instance-registry pattern is the preferred production style for larger applications because it avoids global singleton coupling and makes tests/plugin boundaries explicit.\n\n---\n\n## Production Readiness\n\nRegisters is designed around production concerns that show up early in real projects:\n\n* deterministic command and alias registration;\n* collision-safe plugin composition;\n* explicit parse and error semantics;\n* schema lifecycle helpers;\n* structured exceptions with context payloads;\n* service-layer patterns for multi-record writes;\n* retry and dead-letter behavior for automation;\n* runtime history and status reporting;\n* explicit resource disposal for shutdown and tests;\n* documentation patterns that can be followed by engineers or AI coding agents.\n\n---\n\n## Who This Is For\n\nRegisters is built for:\n\n* backend engineers building internal services and application utilities;\n* platform and DevOps engineers standardizing automation workflows;\n* teams building plugin-based command ecosystems;\n* FastAPI developers who prefer Pydantic-first data modeling;\n* AI tooling teams that need clear, structured, agent-readable implementation surfaces;\n* solo engineers who want fast project setup without sacrificing architectural discipline.\n\n---\n\n## Documentation\n\n| Document                  | Path                                      |\n| ------------------------- | ----------------------------------------- |\n| Project architecture spec | `PROJECT_SPEC.md`                         |\n| CLI usage manual          | `src/registers/cli/USAGE.md`              |\n| DB usage manual           | `src/registers/db/USAGE.md`               |\n| Cron usage manual         | `src/registers/cron/USAGE.md`             |\n| FX tool repository        | `https://github.com/nexustech101/fx-tool` |\n\n---\n\n## Roadmap\n\nRegisters is production-ready today and designed to expand into higher-level automation and agentic tooling workflows.\n\nPlanned extensions include:\n\n* **MCP support** — decorator-based primitives for defining and operating MCP servers;\n* **workspace state capabilities** — structured storage and retrieval of project/worktree state;\n* **AI tooling data structures** — graph and tree primitives for context modeling, traversal, and project representation;\n* **LLM tooling decorators** — decorator-driven tool definitions and memory/knowledge wiring for agent workflows.\n\nThese additions are intended to extend the current `fx-tool + cli + db + cron` architecture rather than replace it.\n\n---\n\n## Requirements\n\n* Python 3.10+\n* Pydantic 2.x\n* SQLAlchemy 2.x\n\nOptional integrations depend on the modules you use:\n\n* FastAPI for API service examples;\n* Watchdog for file-change job triggers;\n* Docker or compatible services for multi-dialect database integration tests.\n\n---\n\n## Testing\n\nThe package is backed by a production-focused test suite covering unit behavior, edge cases, SQLite behavior, and multi-dialect integration scenarios.\n\n```bash\npytest\n```\n\nFor backend integration tests, start Docker Desktop or another compatible Docker engine before running tests that depend on services from `docker-compose.test-db.yml`.\n\n---\n\n## License\n\nMIT\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnexustech101%2Fregisters","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnexustech101%2Fregisters","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnexustech101%2Fregisters/lists"}