{"id":36967542,"url":"https://github.com/tomneto/steely","last_synced_at":"2026-01-13T20:06:22.599Z","repository":{"id":329275099,"uuid":"1103922483","full_name":"tomneto/steely","owner":"tomneto","description":" A Python debugging toolkit with colorful terminal output. Decorators for automatic logging, execution timing, and real-time variable tracking.","archived":false,"fork":false,"pushed_at":"2025-12-18T12:26:08.000Z","size":130,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-21T18:23:42.617Z","etag":null,"topics":["logger","logging","python3"],"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/tomneto.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":"2025-11-25T14:10:51.000Z","updated_at":"2025-12-18T12:26:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tomneto/steely","commit_stats":null,"previous_names":["tomneto/steely"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/tomneto/steely","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomneto%2Fsteely","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomneto%2Fsteely/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomneto%2Fsteely/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomneto%2Fsteely/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomneto","download_url":"https://codeload.github.com/tomneto/steely/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomneto%2Fsteely/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28399512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T14:36:09.778Z","status":"ssl_error","status_checked_at":"2026-01-13T14:35:19.697Z","response_time":56,"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":["logger","logging","python3"],"created_at":"2026-01-13T20:06:21.802Z","updated_at":"2026-01-13T20:06:22.585Z","avatar_url":"https://github.com/tomneto.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Steely\n\nA Python debugging and analysis toolkit with beautiful, colorful terminal output.\n\nSteely provides powerful decorators that help developers understand their code's behavior at runtime through automatic logging, execution timing, and real-time variable tracking.\n\n## Features\n\n- **Dan.log** - Automatic function logging with start/success/error tracking\n- **Dan.cronos** - Execution time measurement and profiling\n- **Dan.scan** - Real-time variable tracking with type-colored output\n- **Logger** - Flexible, thread-safe logging with color-coded output and file support\n- **pprint** - Pretty print with caller location information for easy debugging\n- **FastAPI Integration** - Record API requests as Postman collections or curl commands\n\n## Installation\n\n### Using pip\n\n```bash\npip install steely\n```\n\n### Using uv\n\n```bash\nuv add steely\n```\n\n### From source\n\n```bash\ngit clone https://github.com/your-username/steely.git\ncd steely\npip install -e .\n```\n\n## Requirements\n\n- Python 3.9 or higher\n- No external dependencies\n\n## Quick Start\n\n```python\nfrom steely import Dan\nfrom steely.pprint import pprint\nfrom steely.logger import Logger\n\n# Log function execution\n@Dan.log\ndef fetch_data(url):\n    return {\"data\": \"example\"}\n\n# Measure execution time\n@Dan.cronos\ndef slow_operation():\n    import time\n    time.sleep(1)\n    return \"done\"\n\n# Track variables in real-time\n@Dan.scan\ndef calculate(a, b):\n    total = a + b\n    squared = total ** 2\n    return squared\n\n# Pretty print with location info\ndef debug_function(x, y):\n    result = x + y\n    pprint(f\"Result is: {result}\")\n    return result\n\n# Set global app name for consistent logging\nLogger.set_global_app_name(\"MyApp\")\n\n# Run the functions\nfetch_data(\"https://api.example.com\")\nslow_operation()\ncalculate(3, 4)\ndebug_function(10, 20)\n```\n\n### FastAPI Quick Start\n\n```python\nfrom fastapi import FastAPI\nfrom steely.fastapi import recorder\n\napp = FastAPI()\n\n# Automatically record requests as Postman collections\n@app.get(\"/users/{user_id}\")\n@recorder.postman()\nasync def get_user(user_id: int):\n    return {\"user_id\": user_id, \"name\": \"John\"}\n\n# Also generate curl commands for testing\n@app.post(\"/users\")\n@recorder.curl()\nasync def create_user(name: str):\n    return {\"id\": 123, \"name\": name}\n```\n\n## Decorators\n\n### Dan.log\n\nThe `log` decorator automatically tracks function execution lifecycle - when it starts, succeeds, or fails.\n\n```python\nfrom steely import Dan\n\n@Dan.log\ndef process_user(user_id):\n    # Your code here\n    return {\"id\": user_id, \"status\": \"processed\"}\n\nprocess_user(123)\n```\n\n**Output:**\n```\n[PROCESS_USER] [START]: Function called\n[PROCESS_USER] [SUCCESS]: Function completed\n```\n\n#### With async functions\n\n```python\n@Dan.log\nasync def fetch_api_data(endpoint):\n    async with aiohttp.ClientSession() as session:\n        async with session.get(endpoint) as response:\n            return await response.json()\n```\n\n#### Error tracking\n\nWhen an exception occurs, the decorator logs the error before re-raising it:\n\n```python\n@Dan.log\ndef risky_operation():\n    raise ValueError(\"Something went wrong\")\n\nrisky_operation()\n# Output:\n# [RISKY_OPERATION] [START]: Function called\n# [RISKY_OPERATION] [ERROR]: Something went wrong\n# Traceback...\n```\n\n---\n\n### Dan.cronos\n\nNamed after the Greek god of time, `cronos` measures and reports function execution time.\n\n```python\nfrom steely import Dan\nimport time\n\n@Dan.cronos\ndef compute_heavy_task(n):\n    time.sleep(n)\n    return sum(range(n * 1000000))\n\ncompute_heavy_task(2)\n```\n\n**Output:**\n```\n[*-CRONOS-*] [COMPUTE_HEAVY_TASK] [TEST-RESULT]: Total Time Elapsed: 0:00:02.001234\n```\n\n#### With async functions\n\n```python\nimport asyncio\n\n@Dan.cronos\nasync def async_task():\n    await asyncio.sleep(0.5)\n    return \"completed\"\n\nasyncio.run(async_task())\n# Output: Total Time Elapsed: 0:00:00.500xxx\n```\n\n---\n\n### Dan.scan\n\nThe `scan` decorator provides real-time variable tracking with beautiful, type-colored output. It shows every variable assignment, its type, value, and the line number where it was set.\n\n```python\nfrom steely import Dan\n\n@Dan.scan\ndef example(x, y):\n    name = \"Alice\"\n    numbers = [1, 2, 3]\n    total = x + y\n    data = {\"key\": \"value\"}\n    return total\n\nexample(10, 20)\n```\n\n**Output:**\n```\n┌─────────────────────────────────────────────────────────────────────────────────────\n│ ⚡ SCAN: example\n│    module: __main__\n├─────────────────────────────────────────────────────────────────────────────────────\n│ Parameters:\n│    ◈ x: int → 10\n│    ◈ y: int → 20\n├─────────────────────────────────────────────────────────────────────────────────────\n│ Variables:\n│    ▸ line 4   ◈ name     ◉ str  → 'Alice'\n│    ▸ line 5   ◈ numbers  ◉ list → [1, 2, 3]\n│    ▸ line 6   ◈ total    ◉ int  → 30\n│    ▸ line 7   ◈ data     ◉ dict → {'key': 'value'}\n├─────────────────────────────────────────────────────────────────────────────────────\n│ ⟼ Return: int → 30\n└───────────────────────────────────────────────────────────── elapsed: 0.12ms ──────\n```\n\n#### Type Colors\n\nEach Python type is displayed in a distinct color for easy visual identification:\n\n| Type | Color |\n|------|-------|\n| `int` | Blue |\n| `float` | Deep Blue |\n| `str` | Orange |\n| `bool` | Magenta |\n| `None` | Gray |\n| `list` | Sea Green |\n| `dict` | Gold |\n| `tuple` | Light Purple |\n| `set` | Pink |\n| `callable` | Cyan |\n| `class` | Lavender |\n\n#### Async Functions\n\nFor async functions, variable tracking is disabled (due to event loop tracing limitations), but parameters and return values are still displayed:\n\n```python\n@Dan.scan\nasync def fetch_data(url):\n    response = await some_api_call(url)\n    return response\n\nawait fetch_data(\"https://api.example.com\")\n```\n\n---\n\n## Combining Decorators\n\nYou can stack multiple decorators to get combined functionality:\n\n```python\nfrom steely import Dan\n\n@Dan.log\n@Dan.cronos\n@Dan.scan\ndef important_operation(data):\n    processed = data.upper()\n    result = len(processed)\n    return result\n\nimportant_operation(\"hello world\")\n```\n\nThis will:\n1. Log the function start/success\n2. Measure execution time\n3. Track all variable assignments\n\n---\n\n## Logger\n\nThe `Logger` class provides a flexible, thread-safe logging system with color-coded terminal output and optional file logging.\n\n### Basic Usage\n\n```python\nfrom steely.logger import Logger\n\n# Create a logger instance\nlogger = Logger(\"MyApp\", \"database\")\n\n# Log messages with different levels\nlogger.info(\"Connected to database\")\nlogger.success(\"Query executed successfully\")\nlogger.warning(\"Connection pool running low\")\nlogger.error(\"Query timeout after 30s\")\n```\n\n**Output:**\n```\n25-11-2025 14:30:00 - [MYAPP] [DATABASE] [INFO]: Connected to database\n25-11-2025 14:30:00 - [MYAPP] [DATABASE] [SUCCESS]: Query executed successfully\n25-11-2025 14:30:01 - [MYAPP] [DATABASE] [WARNING]: Connection pool running low\n25-11-2025 14:30:02 - [MYAPP] [DATABASE] [ERROR]: Query timeout after 30s\n```\n\n### Log Levels\n\n| Level | Color | Method | Use Case |\n|-------|-------|--------|----------|\n| `INFO` | Cyan | `logger.info()` | General information |\n| `START` | Cyan | `logger.start()` | Process initialization |\n| `SUCCESS` | Green | `logger.success()` | Successful operations |\n| `OK` | Green | `logger.ok()` | Confirmations |\n| `WARNING` | Yellow | `logger.warning()` | Warning messages |\n| `ALERT` | Yellow | `logger.alert()` | Alert notifications |\n| `ERROR` | Red | `logger.error()` | Error messages |\n| `CRITICAL` | Red | `logger.critical()` | Critical errors |\n| `FATAL` | Red | `logger.fatal()` | Fatal errors |\n| `FAIL` | Red | `logger.fail()` | Failed operations |\n| `FAULT` | Red | `logger.fault()` | System faults |\n| `TEST` | Blue | `logger.test()` | Test messages |\n| `TEST-RESULT` | Blue | `logger.test_result()` | Test results |\n\n### File Logging\n\nEnable file logging by providing a destination directory:\n\n```python\nfrom steely.logger import Logger\n\n# Logs will be saved to /var/log/myapp/DD-MM-YYYY.log\nlogger = Logger(\"MyApp\", \"api\", destination=\"/var/log/myapp\")\n\nlogger.info(\"Request received\")      # Printed AND saved to file\nlogger.error(\"Request failed\")       # Printed AND saved to file\n```\n\nLog files are automatically named with the current date (e.g., `25-11-2025.log`) and appended throughout the day.\n\n### Additional Tags\n\nAdd custom tags to your log messages for better filtering:\n\n```python\nfrom steely.logger import Logger\n\n# Tags defined at creation apply to all messages\nlogger = Logger(\"MyApp\", \"auth\", session_id=\"abc123\", user_id=\"42\")\n\nlogger.info(\"User logged in\")\n# Output: [MYAPP] [AUTH] [ABC123] [42] [INFO]: User logged in\n\n# Or add tags per-message\nlogger.info(\"Action performed\", request_id=\"req-789\")\n# Output: [MYAPP] [AUTH] [ABC123] [42] [REQ-789] [INFO]: Action performed\n```\n\n### Using log() Method Directly\n\nFor dynamic log levels, use the `log()` method:\n\n```python\nfrom steely.logger import Logger\n\nlogger = Logger(\"MyApp\", \"main\")\n\n# Using log() with any level\nlogger.log(\"INFO\", \"Application started\")\nlogger.log(\"SUCCESS\", \"Initialization complete\")\nlogger.log(\"ERROR\", \"Connection failed\")\n\n# Logger instances are callable\nlogger(\"WARNING\", \"This also works!\")\n```\n\n### Setting Global App Name\n\nUse `set_global_app_name()` to set a global application name for all `@log` decorated functions:\n\n```python\nfrom steely.logger import Logger\nfrom steely import Dan\n\n# Set global app name once\nLogger.set_global_app_name(\"MyApp\")\n\n# All @log decorated functions will now use \"MyApp\" instead of module name\n@Dan.log\ndef process_data():\n    return \"processed\"\n\n@Dan.log\ndef fetch_api():\n    return \"fetched\"\n\n# Both functions will log with [MYAPP] prefix\nprocess_data()  # Logs: [MYAPP] [PROCESS_DATA] [START]: Function Execution Started...\nfetch_api()     # Logs: [MYAPP] [FETCH_API] [START]: Function Execution Started...\n```\n\nThis is particularly useful for applications where you want consistent app naming across all logged functions without specifying it for each logger instance.\n\n### Screen Clearing\n\nEnable screen clearing for a cleaner terminal experience:\n\n```python\nfrom steely.logger import Logger\n\n# Clear screen before each log message\nlogger = Logger(\"MyApp\", \"installer\", clean=True)\n\nlogger.info(\"Step 1: Downloading...\")  # Clears screen, then prints\nlogger.info(\"Step 2: Installing...\")   # Clears screen, then prints\nlogger.success(\"Installation complete!\")\n```\n\n### Debug Mode\n\nControl debug output with the `debug` parameter:\n\n```python\nfrom steely.logger import Logger\n\n# Debug mode enabled (default) - appends \"_debug\" to log directory\nlogger = Logger(\"MyApp\", \"main\", destination=\"/logs\", debug=True)\n# Logs go to: /logs_debug/DD-MM-YYYY.log\n\n# Production mode\nlogger = Logger(\"MyApp\", \"main\", destination=\"/logs\", debug=False)\n# Logs go to: /logs/DD-MM-YYYY.log\n```\n\n### Thread Safety\n\nAll logging operations run in separate threads for non-blocking behavior:\n\n```python\nfrom steely.logger import Logger\nimport time\n\nlogger = Logger(\"MyApp\", \"worker\")\n\ndef process_items(items):\n    for item in items:\n        logger.info(f\"Processing {item}\")  # Non-blocking\n        # Heavy processing here...\n        time.sleep(0.1)\n    logger.success(\"All items processed\")\n\n# Logging won't slow down your processing\nprocess_items([\"item1\", \"item2\", \"item3\"])\n```\n\n### Complete Example\n\n```python\nfrom steely.logger import Logger\n\nclass DatabaseService:\n    def __init__(self):\n        self.logger = Logger(\"MyApp\", \"database\", destination=\"./logs\")\n\n    def connect(self, host, port):\n        self.logger.start(f\"Connecting to {host}:{port}\")\n        try:\n            # Connection logic here...\n            self.logger.success(\"Connected successfully\")\n            return True\n        except Exception as e:\n            self.logger.error(f\"Connection failed: {e}\")\n            return False\n\n    def query(self, sql):\n        self.logger.info(f\"Executing query: {sql[:50]}...\")\n        try:\n            # Query logic here...\n            self.logger.success(\"Query executed\")\n            return {\"rows\": 42}\n        except Exception as e:\n            self.logger.error(f\"Query failed: {e}\")\n            raise\n\n# Usage\ndb = DatabaseService()\ndb.connect(\"localhost\", 5432)\ndb.query(\"SELECT * FROM users WHERE active = true\")\n```\n\n---\n\n## pprint\n\nThe `pprint` function enhances the standard print with automatic caller location information, making debugging faster and more efficient. It shows the file path and line number in a format that's clickable in most IDEs and terminals.\n\n### Basic Usage\n\n```python\nfrom steely.pprint import pprint\n\ndef calculate_total(items):\n    subtotal = sum(items)\n    pprint(f\"Subtotal: {subtotal}\")\n\n    tax = subtotal * 0.1\n    pprint(f\"Tax: {tax}\")\n\n    total = subtotal + tax\n    pprint(f\"Total: {total}\")\n\n    return total\n\ncalculate_total([10, 20, 30])\n```\n\n**Output:**\n```\n[PPRINT] File \"/path/to/your/script.py\", line 4\nSubtotal: 60\n\n[PPRINT] File \"/path/to/your/script.py\", line 7\nTax: 6.0\n\n[PPRINT] File \"/path/to/your/script.py\", line 10\nTotal: 66.0\n```\n\n### With Custom Colors\n\nYou can customize the color of the output using the `color` parameter:\n\n```python\nfrom steely.pprint import pprint\nfrom steely.design import UnicodeColors\n\n# Success message in green\npprint(\"Operation completed!\", color=UnicodeColors.success)\n\n# Error message in red\npprint(\"Something went wrong!\", color=UnicodeColors.fail)\n\n# Info message in cyan\npprint(\"Processing data...\", color=UnicodeColors.success_cyan)\n\n# Warning message in yellow\npprint(\"Low memory warning\", color=UnicodeColors.alert)\n```\n\n### Clickable Links\n\nThe file path and line number are formatted to be clickable in most modern IDEs and terminals:\n- **VS Code**: Ctrl+Click (Cmd+Click on Mac) to jump to the line\n- **PyCharm**: Click the link to navigate to the source\n- **Terminal**: Many terminals support clicking file:line patterns\n\n### Use Cases\n\nPerfect for:\n- **Quick debugging** without setting up a full logger\n- **Tracking execution flow** through complex functions\n- **Comparing values** at different points in code\n- **Temporary debug statements** that are easy to locate and remove later\n\n---\n\n## FastAPI Integration\n\nSteely provides decorators for FastAPI that automatically record your API requests for testing, documentation, and debugging purposes.\n\n### Postman Recorder\n\nThe `postman` decorator automatically captures requests and responses, generating Postman Collection v2.1 format files that can be imported directly into Postman.\n\n#### Basic Usage\n\n```python\nfrom fastapi import FastAPI\nfrom steely.fastapi import recorder\n\napp = FastAPI()\n\n@app.get(\"/users/{user_id}\")\n@recorder.postman()\nasync def get_user(user_id: int):\n    return {\"user_id\": user_id, \"name\": \"John Doe\", \"email\": \"john@example.com\"}\n\n@app.post(\"/users\")\n@recorder.postman()\nasync def create_user(name: str, email: str):\n    return {\"id\": 123, \"name\": name, \"email\": email}\n```\n\nCollections are saved to `./.postman_collections/\u003cfunction_name\u003e.json` by default.\n\n#### Grouping Endpoints\n\nGroup multiple endpoints into a single collection:\n\n```python\n@app.get(\"/users\")\n@recorder.postman(collection_name=\"user_api\")\nasync def list_users():\n    return [{\"id\": 1, \"name\": \"John\"}, {\"id\": 2, \"name\": \"Jane\"}]\n\n@app.get(\"/users/{user_id}\")\n@recorder.postman(collection_name=\"user_api\")\nasync def get_user(user_id: int):\n    return {\"id\": user_id, \"name\": \"John\"}\n\n@app.post(\"/users\")\n@recorder.postman(collection_name=\"user_api\")\nasync def create_user(name: str):\n    return {\"id\": 123, \"name\": name}\n```\n\nAll three endpoints will be saved in `./.postman_collections/user_api.json`.\n\n#### Custom Output Directory\n\n```python\n@app.get(\"/api/data\")\n@recorder.postman(output_dir=\"./docs/postman\")\nasync def get_data():\n    return {\"data\": \"example\"}\n```\n\n### Curl Recorder\n\nThe `curl` decorator captures requests and generates executable curl commands, perfect for sharing API examples or creating test scripts.\n\n#### Basic Usage\n\n```python\nfrom fastapi import FastAPI\nfrom steely.fastapi import recorder\n\napp = FastAPI()\n\n@app.get(\"/users/{user_id}\")\n@recorder.curl()\nasync def get_user(user_id: int, include_email: bool = False):\n    return {\"user_id\": user_id, \"name\": \"John\"}\n\n@app.post(\"/users\")\n@recorder.curl()\nasync def create_user(name: str, email: str):\n    return {\"id\": 123, \"name\": name, \"email\": email}\n```\n\nScripts are saved to `./.curl_scripts/\u003cfunction_name\u003e.sh` and are automatically made executable.\n\n#### Running Generated Scripts\n\n```bash\n# Execute the generated curl commands\nbash ./.curl_scripts/get_user.sh\n\n# Or make it executable and run directly\nchmod +x ./.curl_scripts/get_user.sh\n./.curl_scripts/get_user.sh\n```\n\n#### Grouping Commands\n\nGroup multiple endpoints into a single script:\n\n```python\n@app.get(\"/users\")\n@recorder.curl(script_name=\"user_api\")\nasync def list_users():\n    return [{\"id\": 1, \"name\": \"John\"}]\n\n@app.post(\"/users\")\n@recorder.curl(script_name=\"user_api\")\nasync def create_user(name: str):\n    return {\"id\": 123, \"name\": name}\n```\n\nAll commands will be appended to `./.curl_scripts/user_api.sh`.\n\n#### Custom Output Directory\n\n```python\n@app.get(\"/api/data\")\n@recorder.curl(output_dir=\"./scripts\")\nasync def get_data():\n    return {\"data\": \"example\"}\n```\n\n### Combining Recorders\n\nYou can use both decorators together to generate both Postman collections and curl scripts:\n\n```python\nfrom fastapi import FastAPI\nfrom steely.fastapi import recorder\n\napp = FastAPI()\n\n@app.get(\"/users/{user_id}\")\n@recorder.postman(collection_name=\"api_docs\")\n@recorder.curl(script_name=\"api_tests\")\nasync def get_user(user_id: int):\n    return {\"user_id\": user_id, \"name\": \"John\"}\n```\n\nThis will create:\n- `./.postman_collections/api_docs.json` - Postman collection for documentation\n- `./.curl_scripts/api_tests.sh` - Executable curl commands for testing\n\n### Benefits\n\n- **Automatic Documentation**: Generate Postman collections from real API traffic\n- **Testing**: Create reproducible test scripts without manual work\n- **Team Collaboration**: Share API examples with teammates easily\n- **CI/CD Integration**: Use generated curl scripts in your automated tests\n- **Zero Configuration**: Works out of the box with sensible defaults\n\n---\n\n## Advanced Usage\n\n### Using Individual Decorators\n\nYou can import decorators individually if you prefer:\n\n```python\nfrom steely import cronos, log, scan\n\n@log\ndef my_function():\n    pass\n\n@cronos\ndef timed_function():\n    pass\n\n@scan\ndef tracked_function():\n    pass\n```\n\n### Using Design Components\n\nSteely's design module provides terminal styling utilities you can use in your own code:\n\n```python\nfrom steely.design import UnicodeColors as C, Symbols as S, TypeColors\n\n# Colored output\nprint(f\"{C.green}Success!{C.reset}\")\nprint(f\"{C.bold}{C.red}Error!{C.reset}\")\n\n# Symbols\nprint(f\"{S.CHECK} Task completed\")\nprint(f\"{S.ARROW_RIGHT} Next step\")\nprint(f\"{S.CROSS} Failed\")\n\n# Type-based colors\nvalue = [1, 2, 3]\ncolor = TypeColors.get_color(value)\nprint(f\"{color}{value}{C.reset}\")\n```\n\n---\n\n## Examples\n\n### Web API Debugging\n\n```python\nfrom steely import Dan\nimport requests\n\n@Dan.log\n@Dan.cronos\ndef fetch_user(user_id):\n    response = requests.get(f\"https://api.example.com/users/{user_id}\")\n    return response.json()\n\nuser = fetch_user(42)\n```\n\n### Algorithm Profiling\n\n```python\nfrom steely import Dan\n\n@Dan.cronos\ndef bubble_sort(arr):\n    n = len(arr)\n    for i in range(n):\n        for j in range(0, n-i-1):\n            if arr[j] \u003e arr[j+1]:\n                arr[j], arr[j+1] = arr[j+1], arr[j]\n    return arr\n\n@Dan.cronos\ndef quick_sort(arr):\n    if len(arr) \u003c= 1:\n        return arr\n    pivot = arr[len(arr) // 2]\n    left = [x for x in arr if x \u003c pivot]\n    middle = [x for x in arr if x == pivot]\n    right = [x for x in arr if x \u003e pivot]\n    return quick_sort(left) + middle + quick_sort(right)\n\nimport random\ndata = [random.randint(0, 1000) for _ in range(1000)]\n\nbubble_sort(data.copy())  # See timing\nquick_sort(data.copy())   # Compare timing\n```\n\n### Debugging Complex Logic\n\n```python\nfrom steely import Dan\n\n@Dan.scan\ndef calculate_discount(price, quantity, member_status):\n    subtotal = price * quantity\n\n    if member_status == \"gold\":\n        discount_rate = 0.20\n    elif member_status == \"silver\":\n        discount_rate = 0.10\n    else:\n        discount_rate = 0.0\n\n    discount = subtotal * discount_rate\n    final_price = subtotal - discount\n\n    return final_price\n\ncalculate_discount(99.99, 3, \"gold\")\n# See exactly how each variable is computed\n```\n\n---\n\n## Framework Compatibility\n\nAll Steely decorators preserve the original function's signature, making them compatible with frameworks that rely on function introspection:\n\n### FastAPI\n\n```python\nfrom fastapi import FastAPI\nfrom steely import Dan\n\napp = FastAPI()\n\n@app.get(\"/users/{user_id}\")\n@Dan.log\n@Dan.cronos\nasync def get_user(user_id: int, include_email: bool = False):\n    return {\"user_id\": user_id, \"include_email\": include_email}\n```\n\n### Flask\n\n```python\nfrom flask import Flask\nfrom steely import Dan\n\napp = Flask(__name__)\n\n@app.route(\"/hello/\u003cname\u003e\")\n@Dan.log\ndef hello(name):\n    return f\"Hello, {name}!\"\n```\n\n---\n\n## License\n\nMIT License\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomneto%2Fsteely","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomneto%2Fsteely","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomneto%2Fsteely/lists"}