{"id":30620377,"url":"https://github.com/lafayettegabe/fastsqs","last_synced_at":"2025-09-05T21:03:23.677Z","repository":{"id":312386016,"uuid":"1047332845","full_name":"lafayettegabe/fastsqs","owner":"lafayettegabe","description":"📨 Fast, modern, async SQS routing and middleware for Python.","archived":false,"fork":false,"pushed_at":"2025-08-30T07:24:49.000Z","size":23,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-30T09:17:40.738Z","etag":null,"topics":["async","aws-sqs","event-driven","lambda","message-queue","message-r","pydantic","python","queue","serverless","sqs"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/fastsqs/","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/lafayettegabe.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-08-30T07:16:49.000Z","updated_at":"2025-08-30T07:29:36.000Z","dependencies_parsed_at":"2025-08-30T09:27:50.866Z","dependency_job_id":null,"html_url":"https://github.com/lafayettegabe/fastsqs","commit_stats":null,"previous_names":["lafayettegabe/fastsqs"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/lafayettegabe/fastsqs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lafayettegabe%2Ffastsqs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lafayettegabe%2Ffastsqs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lafayettegabe%2Ffastsqs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lafayettegabe%2Ffastsqs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lafayettegabe","download_url":"https://codeload.github.com/lafayettegabe/fastsqs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lafayettegabe%2Ffastsqs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273317749,"owners_count":25084037,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["async","aws-sqs","event-driven","lambda","message-queue","message-r","pydantic","python","queue","serverless","sqs"],"created_at":"2025-08-30T13:36:02.510Z","updated_at":"2025-09-05T21:03:23.614Z","avatar_url":"https://github.com/lafayettegabe.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fastsqs\n\n**Fast, modern, async SQS routing and middleware for Python.**\n\n[![PyPI version](https://img.shields.io/pypi/v/fastsqs.svg)](https://pypi.org/project/fastsqs/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\n---\n\n## Key Features\n\n- 🚀 **High Performance:** Async message routing for AWS SQS, designed for speed and scalability\n- 🧩 **Declarative Routing:** Organize your SQS message handling with nested routers and decorators\n- 🔄 **Auto Async/Sync:** Write handlers as sync or async functions - framework handles both automatically\n- 🔒 **Validation:** Per-route payload validation using Pydantic models\n- 🛠️ **Middleware:** Add before/after hooks for logging, timing, masking, and more\n- 🦾 **Partial Batch Failure:** Native support for AWS Lambda batch failure responses\n- 🔀 **FIFO \u0026 Standard Queues:** Full support for both SQS queue types with ordered processing for FIFO\n- 🎯 **Wildcard \u0026 Default Routes:** Flexible routing with wildcard matching and fallback handlers\n- 🏗️ **Nested Routing:** Build complex routing hierarchies with subrouters\n- 🐍 **Pythonic \u0026 Intuitive:** Type hints, editor support, and a familiar API for Python developers\n\n---\n\n## Requirements\n\n- Python 3.8+\n- [Pydantic](https://docs.pydantic.dev/) (installed automatically)\n\n---\n\n## Installation\n\n```bash\npip install fastsqs\n```\n\n---\n\n## Quick Start\n\n### Basic Example\n\n```python\nfrom fastsqs import QueueApp, QueueRouter\nfrom pydantic import BaseModel\n\nclass GreetingPayload(BaseModel):\n    type: str\n    message: str\n\n# Create router\nrouter = QueueRouter(key=\"type\")\n\n# Sync handler - no async needed!\n@router.route(\"greeting\", model=GreetingPayload)\ndef handle_greeting(payload, record, context, ctx, data):\n    print(f\"Greeting: {data.message}\")\n\n# Async handler also works\n@router.route(\"async_task\")\nasync def handle_async_task(payload, ctx):\n    # Do async work here\n    print(f\"Processing async: {payload}\")\n\n# Create app\napp = QueueApp(title=\"My SQS App\", debug=True)\napp.include_router(router)\n\n# Lambda handler\ndef lambda_handler(event, context):\n    return app.handler(event, context)\n```\n\n### Example Payloads\n\n```json\n{\n  \"type\": \"greeting\",\n  \"message\": \"Hello from SQS!\"\n}\n```\n\n```json\n{\n  \"type\": \"async_task\",\n  \"data\": \"Some async processing data\"\n}\n```\n\n---\n\n## Advanced Features\n\n### FIFO Queue Support\n\n```python\nfrom fastsqs import QueueApp, QueueType\n\napp = QueueApp(\n    queue_type=QueueType.FIFO,\n    debug=True\n)\n\n# Messages in the same messageGroupId are processed sequentially\n# Different groups are processed in parallel\n```\n\n### Wildcard and Default Routes\n\n```python\nrouter = QueueRouter(key=\"action\")\n\n# Handle specific routes\n@router.route(\"process\")\ndef handle_process(payload):\n    print(\"Processing...\")\n\n# Wildcard - matches any value\n@router.wildcard()\ndef handle_any_action(payload, ctx):\n    action = payload.get(\"action\", \"unknown\")\n    print(f\"Handling action: {action}\")\n\n# Default - called when key is missing\n@router.route()  # No value = default\ndef handle_no_action(payload):\n    print(\"No action specified\")\n```\n\n### Nested Routing\n\n```python\n# Main router routes by \"service\"\nmain_router = QueueRouter(key=\"service\")\n\n# Sub-router routes by \"action\" within a service\nuser_router = QueueRouter(key=\"action\")\n\n@user_router.route(\"create\")\ndef create_user(payload):\n    print(f\"Creating user: {payload}\")\n\n@user_router.route(\"delete\")\ndef delete_user(payload):\n    print(f\"Deleting user: {payload}\")\n\n# Attach sub-router\nmain_router.subrouter(\"users\", user_router)\n\napp.include_router(main_router)\n```\n\nExample payload for nested routing:\n```json\n{\n  \"service\": \"users\",\n  \"action\": \"create\",\n  \"user_data\": {...}\n}\n```\n\n### Middleware\n\n```python\nfrom fastsqs import Middleware, TimingMsMiddleware, LoggingMiddleware\n\n# Built-in timing middleware\napp.add_middleware(TimingMsMiddleware())\n\n# Built-in logging middleware\napp.add_middleware(LoggingMiddleware(\n    include_payload=True,\n    mask_fields=[\"password\", \"secret\"]\n))\n\n# Custom middleware\nclass AuthMiddleware(Middleware):\n    async def before(self, payload, record, context, ctx):\n        # Validate auth token\n        if not payload.get(\"auth_token\"):\n            raise ValueError(\"Missing auth token\")\n        print(\"Auth validated\")\n    \n    async def after(self, payload, record, context, ctx, error):\n        if error:\n            print(f\"Handler failed: {error}\")\n        else:\n            print(\"Handler completed successfully\")\n\napp.add_middleware(AuthMiddleware())\n```\n\n### Payload Scoping\n\n```python\n# Control what payload is passed to handlers\nrouter = QueueRouter(\n    key=\"type\",\n    payload_scope=\"both\"  # \"root\", \"current\", or \"both\"\n)\n\n@router.route(\"nested\")\ndef handle_nested(payload, current_payload, root_payload):\n    # payload = root_payload (for \"both\" scope)\n    # current_payload = current level payload\n    # root_payload = original payload\n    pass\n```\n\n### Error Handling\n\n```python\napp = QueueApp(\n    on_decode_error=\"skip\",      # Skip invalid JSON\n    on_validation_error=\"skip\",   # Skip validation failures\n    strict=False                 # Don't error on unmatched routes\n)\n\n# Custom default handler for unmatched routes\ndef default_handler(payload, ctx):\n    print(f\"Unhandled message: {payload}\")\n\napp = QueueApp(default_handler=default_handler)\n```\n\n---\n\n## Package Structure\n\nThe library is organized into clean, modular components:\n\n```\nfastsqs/\n├── __init__.py          # Main exports\n├── types.py             # Type definitions\n├── exceptions.py        # Custom exceptions\n├── utils.py             # Utility functions\n├── app.py              # Main QueueApp class\n├── middleware/         # Middleware components\n│   ├── __init__.py\n│   ├── base.py         # Base middleware\n│   ├── timing.py       # Timing middleware\n│   └── logging.py      # Logging middleware\n└── routing/            # Routing components\n    ├── __init__.py\n    ├── entry.py        # Route entry\n    └── router.py       # Router implementation\n```\n\n---\n\n## How it Works\n\n- **Automatic Async/Sync:** Write handlers as regular functions or async functions - the framework automatically detects and handles both\n- **Routing:** Use `QueueRouter` to route messages by payload fields. Decorators make it easy to register handlers\n- **Validation:** Attach Pydantic models to routes for automatic payload validation\n- **Middleware:** Add global or per-route middleware for logging, timing, masking, etc.\n- **Batch Failure:** Handles partial failures for SQS-triggered Lambda functions, so only failed messages are retried\n- **FIFO Support:** Sequential processing within message groups while maintaining parallelism across groups\n\n---\n\n## Performance Features\n\n- **Parallel Processing:** Standard SQS messages are processed concurrently\n- **FIFO Ordering:** FIFO messages maintain order within message groups\n- **Partial Batch Failures:** Only failed messages are retried, not entire batches\n- **Efficient Routing:** Fast dictionary-based message routing\n- **Memory Efficient:** Minimal overhead per message\n\n---\n\n## Documentation\n\n- [API Reference](#) (coming soon)\n- [Tutorials](#) (coming soon)\n- [Examples](#) (see `examples/`)\n\n---\n\n## Contributing\n\nContributions, issues, and feature requests are welcome!\nPlease open an issue or submit a pull request.\n\n---\n\n## License\n\nThis project is licensed under the terms of the MIT license.\n\n---\n\n**Ready to build async, robust SQS message processors? Try fastsqs today!**","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flafayettegabe%2Ffastsqs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flafayettegabe%2Ffastsqs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flafayettegabe%2Ffastsqs/lists"}