{"id":48805561,"url":"https://github.com/nexustech101/registers","last_synced_at":"2026-04-21T07:03:45.733Z","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-04-21T07:03:45.715Z","avatar_url":"https://github.com/nexustech101.png","language":"Python","readme":"# Registers\n\n[![PyPI version](https://img.shields.io/pypi/v/registers)](https://pypi.org/project/registers/)\n[![Python versions](https://img.shields.io/pypi/pyversions/registers)](https://pypi.org/project/registers/)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![Module](https://img.shields.io/badge/module-registers-green)](#registers)\n[![CLI](https://img.shields.io/badge/module-registers.cli-blue)](#architecture)\n[![DB](https://img.shields.io/badge/module-registers.db-darkorange)](#architecture)\n[![Cron](https://img.shields.io/badge/module-registers.cron-purple)](#architecture)\n[![FX Tool](https://img.shields.io/badge/tool-fx--tool-black)](https://github.com/nexustech101/fx-tool)\n![Tests](https://img.shields.io/badge/tests-200%2B%20unit%20tests-brightgreen)\n\nRegisters is a DX-first Python framework for building:\n\n- CLI tooling systems\n- Data and API services\n- Scheduled/event automation workflows\n\nIt uses decorators for command, model, and job definitions, and pairs with `fx-tool`, the project manager for scaffolding, running, validating, and operating Registers projects.\n\nThis framework is for teams and developers who want one coherent toolkit for backend development and DevOps workflows instead of stitching together many unrelated layers. Build, manage, and deploy at the speed of thought.\n\n## Why Registers\n\n- Fast setup: generate ready-to-run CLI or DB/API projects with `fx init`.\n- Unified patterns: decorators for commands (`cli`), models (`db`), and jobs (`cron`).\n- Operational workflow support via `fx-tool`: run, install, update, pull plugins, and manage cron runtime.\n- Plugin architecture: organize command suites into modules and load them cleanly.\n- Production-minded behavior: structured state, health checks, operation history, and test coverage.\n- Projects that use `registers.cli` module come with a built-in interactive shell.\n\n## Install\n\n```bash\npip install registers  # Package name is `registers`; module name is `registers`\n```\n\nInstall the project manager (`fx-tool`) as a companion:\n\n```bash\npip install fx-tool\n# or from source\npip install git+https://github.com/nexustech101/fx.git\n```\n\nYou can also clone directly from the repo `nexustech101/fx`:\n\n```bash\ngit clone https://github.com/nexustech101/fx.git\n```\n\n## Quick Start Guide\n\n1. Build one CLI command with a decorator.\n2. Build one DB model with a decorator.\n3. Use `Model.objects` for CRUD.\n\n### CLI in minutes\n\n```python\nfrom __future__ import annotations\n\nfrom enum import StrEnum\nfrom time import strftime\n\nimport registers.cli as cli\nimport registers.db as db\nfrom registers.db import db_field\nfrom pydantic import BaseModel\n\nDB_PATH = \"todos.db\"\nTABLE = \"todos\"\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=TABLE, key_field=\"id\")\nclass TodoItem(BaseModel):\n    id: int | None = 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(title=title, description=description)\n    todo.save()\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()\n    if not todos:\n        return \"No todo items found.\"\n    return \"\\n\".join(f\"{t.id}: {t.title} [{t.status}]\" for t 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.get(id=todo_id)\n    if not todo:\n        return f\"Todo item with ID {todo_id} not found.\"\n\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(todo_id: int, title: str | None = None, description: str | None = None) -\u003e str:\n    todo = TodoItem.objects.get(id=todo_id)\n    if not todo:\n        return f\"Todo item with ID {todo_id} not found.\"\n\n    todo.title = title or \"\"\n    todo.description = description or \"\"\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_colors=None,\n        shell_banner=True,\n        shell_usage=True,  # Prints usage menu on startup\n    )\n```\n\n`registers.cli` also supports explicit instance-mode registries for isolated\ncommand scopes:\n\n```python\nimport registers.cli as cli\n\n\nregistry = cli.CommandRegistry()\n\n\n@registry.register(description=\"Say hello\")\n@registry.argument(\"name\", type=str)\n@registry.option(\"--hello\")\ndef hello(name: str) -\u003e str:\n    return f\"Hello, {name}!\"\n\n\nif __name__ == \"__main__\":\n    registry.run()\n```\n\nRun it as follows:\n\n```bash\n# Add\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\n# List\npython todo.py list\npython todo.py --list\npython todo.py -l\n\n# Complete\npython todo.py complete 1\npython todo.py --complete 1\npython todo.py -c 1\n\n# Update\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\"\npython todo.py --update 1 --title \"Read two books\"\n```\n\nOr:\n\n```bash\n# Run directly for interactive mode\npython todo.py\n```\nInteractive mode:\n\n![Screenshot](img1.png)\n\n`fx-tool` is the recommended way to manage Registers projects end-to-end.\nThink of it as the project operations companion for Registers, similar to how\n`pip` supports Python package workflows or how `npm` supports Node package workflows.\nFor full `fx` usage, see the `fx-tool` docs in the separate repo.\n\n### Database + FastAPI in 5 minutes\n\n```python\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI, HTTPException\nfrom pydantic import BaseModel\nfrom registers.db import (\n    RecordNotFoundError,\n    UniqueConstraintError,\n    database_registry,\n)\n\nDB_URL = \"sqlite:///shop.db\"\n\n# --- Models ---\n\n@database_registry(DB_URL, table_name=\"customers\", unique_fields=[\"email\"])\nclass Customer(BaseModel):\n    id: int | None = None\n    name: str\n    email: str\n\n@database_registry(DB_URL, table_name=\"products\")\nclass Product(BaseModel):\n    id: int | None = None\n    name: str\n    price: float\n\n@database_registry(DB_URL, table_name=\"orders\")\nclass Order(BaseModel):\n    id: int | None = None\n    customer_id: int\n    product_id: int\n    quantity: int\n    total: float\n\n# --- App ---\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    for model in (Customer, Product, Order):\n        model.create_schema()\n    yield\n    for model in (Customer, Product, Order):\n        model.objects.dispose()\n\napp = FastAPI(lifespan=lifespan)\n\n# --- Routes ---\n\n@app.post(\"/customers\", response_model=Customer, status_code=201)\ndef create_customer(name: str, email: str):\n    return Customer.objects.create(name=name, email=email)\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@app.post(\"/products\", response_model=Product, status_code=201)\ndef create_product(name: str, price: float):\n    return Product.objects.create(name=name, price=price)\n\n@app.post(\"/orders\", response_model=Order, status_code=201)\ndef create_order(customer_id: int, product_id: int, quantity: int):\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=product.price * quantity,\n    )\n\n@app.get(\"/orders/desc\", response_model=list[Order])\ndef list_orders_desc(limit: int = 20, offset: int = 0):  # Filter by oldest   (1, 2, 3,..., n)\n    return Order.objects.filter(order_by=\"id\", limit=limit, offset=offset)\n\n@app.get(\"/orders/asc\", response_model=list[Order])\ndef list_orders_asc(limit: int = 20, offset: int = 0):  # Filter by newest  (n,..., 3, 2, 1)\n    return Order.objects.filter(order_by=\"-id\", limit=limit, offset=offset)\n```\n\n```bash\n# POST /customers\ncurl -X POST \"http://localhost:8000/customers\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"Alice Johnson\", \"email\": \"alice@example.com\"}'\n\n# Response\n{\"id\": 1, \"name\": \"Alice Johnson\", \"email\": \"alice@example.com\"}\n\n\n# GET /customers/1\ncurl \"http://localhost:8000/customers/1\"\n\n# Response\n{\"id\": 1, \"name\": \"Alice Johnson\", \"email\": \"alice@example.com\"}\n\n\n# POST /products\ncurl -X POST \"http://localhost:8000/products\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"Wireless Keyboard\", \"price\": 49.99}'\n\n# Response\n{\"id\": 1, \"name\": \"Wireless Keyboard\", \"price\": 49.99}\n\n\n# POST /orders\ncurl -X POST \"http://localhost:8000/orders\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"customer_id\": 1, \"product_id\": 1, \"quantity\": 2}'\n\n# Response\n{\"id\": 1, \"customer_id\": 1, \"product_id\": 1, \"quantity\": 2, \"total\": 99.98}\n\n\n# GET /orders/asc  (oldest first)\ncurl \"http://localhost:8000/orders/asc?limit=20\u0026offset=0\"\n\n# Response\n[\n  {\"id\": 1, \"customer_id\": 1, \"product_id\": 1, \"quantity\": 2, \"total\": 99.98}\n]\n\n\n# GET /orders/desc  (newest first)\ncurl \"http://localhost:8000/orders/desc?limit=20\u0026offset=0\"\n\n# Response\n[\n  {\"id\": 1, \"customer_id\": 1, \"product_id\": 1, \"quantity\": 2, \"total\": 99.98}\n]\n```\n\n## Cron + Workflow Operations\n\nUse `registers.cron` decorators to define interval/cron/event jobs.\nFor runtime lifecycle and workflow operations (`start`, `status`, `generate`,\n`apply`, `register`, `run-workflow`), use `fx-tool`.\n\nBoth cron registration styles are supported:\n\n```python\n# Module-level style\nimport registers.cron as cron\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 \"ok\"\n```\n\n```python\n# Explicit instance style\nfrom registers.cron import CronRegistry\n\ncron = CronRegistry()\n\n@cron.job(\n    name=\"nightly\",\n    trigger=cron.cron(\"0 2 * * *\"),\n    target=\"local_async\",\n    retry_policy=\"fixed\",\n    retry_max_attempts=3,\n    retry_backoff_seconds=15,\n)\ndef nightly() -\u003e str:\n    return \"ok\"\n```\n\nRetry-capable jobs are moved to `dead_letter` state when max attempts are exhausted.\n\n## Architecture\n\n- `registers.cli`\n  Decorator-driven command registration (module facade + explicit registry instances), parser/dispatch, interactive shell, and plugin loading.\n\n- `registers.db`\n  Decorator-driven persistence for Pydantic models with SQLAlchemy-backed storage and model manager patterns.\n\n- `registers.cron`\n  Decorator-driven interval/cron/event jobs with async runtime and deployment artifact generation.\n\n- `fx-tool` (separate package)\n  Project manager and operations CLI for Registers workflows (scaffolding, runtime ops, cron lifecycle, and workflow orchestration).\n\n## Who This Is For\n\n- Backend engineers building internal tools and service utilities.\n- Platform and DevOps engineers standardizing automation workflows.\n- Teams building plugin-based command ecosystems for shared operations.\n- AI tooling teams that need a clear path from local workflows to managed automation.\n- Any engineer who needs a fast and robust solution to data intensive applications.\n\n## Documentation\n\n- Project architecture spec: `PROJECT_SPEC.md`\n- CLI manual: `src/registers/cli/USAGE.md`\n- DB manual: `src/registers/db/USAGE.md`\n- FX tool docs (separate package): `https://github.com/nexustech101/fx-tool`\n- Cron manual: `src/registers/cron/USAGE.md` (if present in your version)\n\n## Roadmap and Planned Extensions\n\nRegisters is production-ready today and actively expanding into agentic tooling workflows. Planned additions include:\n\n- MCP support:\n  A decorator-based framework for defining and operating MCP servers.\n\n- Worktree data capabilities:\n  Structured storage/retrieval of project workspace state for tooling and automation contexts.\n\n- Data-structure library for AI tooling:\n  Graph and tree primitives (including knowledge graph patterns) for efficient lookup, relationship modeling, hierarchy traversal, and large-project representation.\n\n- LLM tooling decorators:\n  Decorator-driven tool definitions and memory/knowledge wiring for agent workflows.\n\nThese additions are designed to work with the current `fx-tool + cli + db + cron` architecture rather than replace it.\n\n## Requirements\n\n- Python 3.10+\n- `pydantic\u003e=2.0`\n- `sqlalchemy\u003e=2.0`\n\n## Testing\n\n- The default `pytest` suite includes SQLite coverage along with PostgreSQL/MySQL integration tests for rename-state behavior.\n- Run Docker Desktop, or another compatible Docker engine, before executing the backend integration suite so the services in `docker-compose.test-db.yml` can boot successfully.\n- The package is backed by a rigorous, production-focused test suite (200+ tests) covering unit behavior, edge cases, and multi-dialect integration scenarios.\n\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"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"}