kiba-core 0.5.3.dev74__tar.gz → 0.5.3.dev76__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/CHANGELOG.md +1 -0
  2. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/Dockerfile +1 -1
  3. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/PKG-INFO +12 -12
  4. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/json_route.py +2 -0
  5. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/streaming_json_route.py +2 -0
  6. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/kiba_core.egg-info/PKG-INFO +12 -12
  7. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/kiba_core.egg-info/requires.txt +11 -11
  8. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/pyproject.toml +12 -12
  9. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_json_route.py +11 -0
  10. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_streaming_json_route.py +11 -0
  11. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/uv.lock +99 -68
  12. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/.github/pull_request_template.md +0 -0
  13. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/.github/workflows/deploy.yml +0 -0
  14. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/.github/workflows/pull-request.yml +0 -0
  15. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/.github/workflows/release.yml +0 -0
  16. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/.gitignore +0 -0
  17. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/README.md +0 -0
  18. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/__init__.py +0 -0
  19. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/__init__.py +0 -0
  20. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/api_request.py +0 -0
  21. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/api_response.py +0 -0
  22. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/authorizer.py +0 -0
  23. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/default_routes.py +0 -0
  24. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/health.py +0 -0
  25. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/middleware/__init__.py +0 -0
  26. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/middleware/database_connection_middleware.py +0 -0
  27. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/middleware/exception_handling_middleware.py +0 -0
  28. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/middleware/logging_middleware.py +0 -0
  29. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/middleware/origin_ip_middleware.py +0 -0
  30. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/middleware/server_headers_middleware.py +0 -0
  31. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/openapi.py +0 -0
  32. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/rate_limit.py +0 -0
  33. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/request_context.py +0 -0
  34. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/route.py +0 -0
  35. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/route_auth.py +0 -0
  36. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/api/route_metadata.py +0 -0
  37. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/aws_requester.py +0 -0
  38. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/caching/__init__.py +0 -0
  39. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/caching/cache.py +0 -0
  40. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/caching/dict_cache.py +0 -0
  41. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/caching/file_cache.py +0 -0
  42. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/cron/__init__.py +0 -0
  43. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/cron/api_request_cron_job_processor.py +0 -0
  44. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/cron/cron_executor.py +0 -0
  45. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/cron/cron_job_processor.py +0 -0
  46. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/cron/model.py +0 -0
  47. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/exceptions.py +0 -0
  48. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/http/__init__.py +0 -0
  49. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/http/basic_authentication.py +0 -0
  50. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/http/jwt.py +0 -0
  51. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/http/rest_method.py +0 -0
  52. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/locks/__init__.py +0 -0
  53. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/locks/lock.py +0 -0
  54. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/locks/model.py +0 -0
  55. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/locks/sql.py +0 -0
  56. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/logging.py +0 -0
  57. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/notifications/__init__.py +0 -0
  58. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/notifications/discord_client.py +0 -0
  59. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/notifications/notification_client.py +0 -0
  60. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/notifications/slack_client.py +0 -0
  61. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/py.typed +0 -0
  62. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/queues/__init__.py +0 -0
  63. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/queues/aqs.py +0 -0
  64. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/queues/cosmos.py +0 -0
  65. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/queues/message_queue.py +0 -0
  66. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/queues/message_queue_processor.py +0 -0
  67. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/queues/model.py +0 -0
  68. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/queues/sql.py +0 -0
  69. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/queues/sqs.py +0 -0
  70. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/requester/__init__.py +0 -0
  71. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/requester/requester.py +0 -0
  72. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/s3_manager.py +0 -0
  73. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/service_client.py +0 -0
  74. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/store/__init__.py +0 -0
  75. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/store/database.py +0 -0
  76. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/store/retriever.py +0 -0
  77. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/store/saver.py +0 -0
  78. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/__init__.py +0 -0
  79. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/async_util.py +0 -0
  80. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/chain_util.py +0 -0
  81. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/date_util.py +0 -0
  82. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/dict_util.py +0 -0
  83. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/file_util.py +0 -0
  84. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/hashing_util.py +0 -0
  85. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/http_util.py +0 -0
  86. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/json_util.py +0 -0
  87. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/list_util.py +0 -0
  88. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/process_util.py +0 -0
  89. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/string_util.py +0 -0
  90. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/typing_util.py +0 -0
  91. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/url_util.py +0 -0
  92. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/util/value_holder.py +0 -0
  93. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/web3/__init__.py +0 -0
  94. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/web3/eth_client.py +0 -0
  95. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/web3/eth_client_registry.py +0 -0
  96. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/core/web3/multicall3.py +0 -0
  97. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/kiba_core.egg-info/SOURCES.txt +0 -0
  98. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/kiba_core.egg-info/dependency_links.txt +0 -0
  99. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/kiba_core.egg-info/top_level.txt +0 -0
  100. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/makefile +0 -0
  101. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/setup.cfg +0 -0
  102. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/__init__.py +0 -0
  103. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_api_response.py +0 -0
  104. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_authorizer.py +0 -0
  105. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_exception_handling_middleware.py +0 -0
  106. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_openapi.py +0 -0
  107. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_origin_ip_middleware.py +0 -0
  108. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_rate_limit.py +0 -0
  109. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_request_context.py +0 -0
  110. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/api/test_route.py +0 -0
  111. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/caching/test_dict_cache.py +0 -0
  112. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/caching/test_file_cache.py +0 -0
  113. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/cron/__init__.py +0 -0
  114. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/cron/test_cron_executor.py +0 -0
  115. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/locks/test_sql_lock.py +0 -0
  116. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/queues/conftest.py +0 -0
  117. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/queues/test_aqs_queue.py +0 -0
  118. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/queues/test_cosmos_queue.py +0 -0
  119. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/queues/test_message_queue_processor.py +0 -0
  120. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/queues/test_sql_queue.py +0 -0
  121. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/queues/test_sqs_queue.py +0 -0
  122. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/requester/__init__.py +0 -0
  123. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/requester/test_requester.py +0 -0
  124. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/test_database.py +0 -0
  125. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/test_exceptions.py +0 -0
  126. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/test_logging.py +0 -0
  127. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/__init__.py +0 -0
  128. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_async_util.py +0 -0
  129. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_chain_util.py +0 -0
  130. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_date_util.py +0 -0
  131. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_dict_util.py +0 -0
  132. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_file_util.py +0 -0
  133. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_json_util.py +0 -0
  134. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_list_util.py +0 -0
  135. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_process_util.py +0 -0
  136. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_string_util.py +0 -0
  137. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/util/test_url_util.py +0 -0
  138. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/web3/__init__.py +0 -0
  139. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/web3/test_eth_client_registry.py +0 -0
  140. {kiba_core-0.5.3.dev74 → kiba_core-0.5.3.dev76}/tests/web3/test_rest_eth_client.py +0 -0
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
8
8
  ## [Unreleased]
9
9
 
10
10
  ### Added
11
+ - [PATCH] Fixed `json_route` and `streaming_json_route` returning a 500 when the JSON body isn't an object (e.g. `true` or `[1]`); they now raise `BadRequestException` (400)
11
12
  - [MINOR] Added `shouldNotifyRetriedFailures` (default `True`) to `MessageQueueProcessor`: when `False`, failure notifications are only sent once the queue gives up on a message, not for failures it will retry. `MessageQueue.fail_message` now returns whether the queue scheduled another attempt: `SqlMessageQueue` and `CosmosMessageQueue` return `True` until `maxAttempts` is reached, while `SqsMessageQueue` and `AqsMessageQueue` always return `False` as the platform decides on redelivery, so they keep notifying every failure
12
13
  - [MAJOR] Updated `CosmosMessageQueue` to retry failed messages like `SqlMessageQueue`: added `maxAttempts` (default 3) and `failureRetryDelaySeconds` (default 60). `fail_message` reschedules the message with linear backoff and stores `lastError`, and a visible message whose lease expired counts as an attempt when it is claimed again. Once `postCount` reaches `maxAttempts` the message is removed, along with its deduplication item. Previously failed or abandoned messages reappeared once their lease expired and were retried forever
13
14
  - [MINOR] Added `pollLogIntervalSeconds` (default 600) to `MessageQueueProcessor`: `Retrieving messages...` is now logged on the first poll and then at most once per interval instead of on every poll, so it still shows the worker is alive without flooding the logs; pass `0` to log every poll as before
@@ -1,4 +1,4 @@
1
- FROM python:3.12.0-slim
1
+ FROM python:3.14.8-slim
2
2
 
3
3
  RUN apt-get update && apt-get install --yes --no-install-recommends make git
4
4
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kiba-core
3
- Version: 0.5.3.dev74
3
+ Version: 0.5.3.dev76
4
4
  Summary: Kiba Labs' python utilities
5
5
  Project-URL: repository, https://github.com/kibalabs/core-py
6
6
  Requires-Python: <4,>=3.12
@@ -12,32 +12,32 @@ Provides-Extra: api
12
12
  Requires-Dist: fastapi>=0.141.1; extra == "api"
13
13
  Requires-Dist: uvicorn[standard]>=0.53.0; extra == "api"
14
14
  Provides-Extra: core-api
15
- Requires-Dist: starlette>=1.6.0; extra == "core-api"
15
+ Requires-Dist: starlette>=1.7.0; extra == "core-api"
16
16
  Requires-Dist: uvicorn[standard]>=0.53.0; extra == "core-api"
17
17
  Provides-Extra: storage
18
- Requires-Dist: aiobotocore>=3.9.1; extra == "storage"
18
+ Requires-Dist: aiobotocore>=3.9.2; extra == "storage"
19
19
  Provides-Extra: queues
20
- Requires-Dist: aiobotocore>=3.9.1; extra == "queues"
20
+ Requires-Dist: aiobotocore>=3.9.2; extra == "queues"
21
21
  Provides-Extra: queue-sqs
22
- Requires-Dist: aiobotocore>=3.9.1; extra == "queue-sqs"
22
+ Requires-Dist: aiobotocore>=3.9.2; extra == "queue-sqs"
23
23
  Provides-Extra: queue-aqs
24
- Requires-Dist: azure-storage-queue[aio]>=12.17.0; extra == "queue-aqs"
24
+ Requires-Dist: azure-storage-queue[aio]>=12.18.0; extra == "queue-aqs"
25
25
  Provides-Extra: queue-cosmos
26
- Requires-Dist: azure-cosmos>=4.17.0; extra == "queue-cosmos"
26
+ Requires-Dist: azure-cosmos>=4.17.1; extra == "queue-cosmos"
27
27
  Provides-Extra: database-psql
28
- Requires-Dist: sqlalchemy[asyncio]>=2.0.54; extra == "database-psql"
28
+ Requires-Dist: sqlalchemy[asyncio]>=2.1.3; extra == "database-psql"
29
29
  Requires-Dist: asyncpg>=0.31.0; extra == "database-psql"
30
30
  Provides-Extra: database-sqlite
31
- Requires-Dist: sqlalchemy[asyncio]>=2.0.54; extra == "database-sqlite"
31
+ Requires-Dist: sqlalchemy[asyncio]>=2.1.3; extra == "database-sqlite"
32
32
  Requires-Dist: aiosqlite>=0.22.1; extra == "database-sqlite"
33
33
  Provides-Extra: requester
34
- Requires-Dist: httpx2>=2.13.0; extra == "requester"
34
+ Requires-Dist: httpx2>=2.13.1; extra == "requester"
35
35
  Provides-Extra: web3
36
36
  Requires-Dist: web3<8.0.0,>=7.16.0; extra == "web3"
37
37
  Provides-Extra: cron
38
- Requires-Dist: apscheduler<4,>=3.11.0; extra == "cron"
38
+ Requires-Dist: apscheduler<4,>=3.11.3; extra == "cron"
39
39
  Provides-Extra: types
40
- Requires-Dist: types-aiobotocore[essential]>=3.9.1; extra == "types"
40
+ Requires-Dist: types-aiobotocore[essential]>=3.9.2; extra == "types"
41
41
  Requires-Dist: types-aiofiles>=25.1.0.20260518; extra == "types"
42
42
 
43
43
  # Core-Py
@@ -30,6 +30,8 @@ def json_route[ApiRequest: BaseModel, ApiResponse: BaseModel](
30
30
  body = typing.cast(JsonObject, json_util.loads(bodyBytes.decode()))
31
31
  except json_util.JsonDecodeException as exception:
32
32
  raise BadRequestException(f'Invalid JSON body: {exception}')
33
+ if not isinstance(body, dict):
34
+ raise BadRequestException('Invalid JSON body: expected an object')
33
35
  allParams = {**pathParams, **body, **queryParams}
34
36
  try:
35
37
  requestParams = requestType(**allParams)
@@ -39,6 +39,8 @@ def streaming_json_route[ApiRequest: BaseModel, ApiResponse: BaseModel](
39
39
  body = typing.cast(JsonObject, json_util.loads(bodyBytes.decode()))
40
40
  except json_util.JsonDecodeException as exception:
41
41
  raise BadRequestException(f'Invalid JSON body: {exception}')
42
+ if not isinstance(body, dict):
43
+ raise BadRequestException('Invalid JSON body: expected an object')
42
44
  allParams = {**pathParams, **body, **queryParams}
43
45
  try:
44
46
  requestParams = requestType(**allParams)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kiba-core
3
- Version: 0.5.3.dev74
3
+ Version: 0.5.3.dev76
4
4
  Summary: Kiba Labs' python utilities
5
5
  Project-URL: repository, https://github.com/kibalabs/core-py
6
6
  Requires-Python: <4,>=3.12
@@ -12,32 +12,32 @@ Provides-Extra: api
12
12
  Requires-Dist: fastapi>=0.141.1; extra == "api"
13
13
  Requires-Dist: uvicorn[standard]>=0.53.0; extra == "api"
14
14
  Provides-Extra: core-api
15
- Requires-Dist: starlette>=1.6.0; extra == "core-api"
15
+ Requires-Dist: starlette>=1.7.0; extra == "core-api"
16
16
  Requires-Dist: uvicorn[standard]>=0.53.0; extra == "core-api"
17
17
  Provides-Extra: storage
18
- Requires-Dist: aiobotocore>=3.9.1; extra == "storage"
18
+ Requires-Dist: aiobotocore>=3.9.2; extra == "storage"
19
19
  Provides-Extra: queues
20
- Requires-Dist: aiobotocore>=3.9.1; extra == "queues"
20
+ Requires-Dist: aiobotocore>=3.9.2; extra == "queues"
21
21
  Provides-Extra: queue-sqs
22
- Requires-Dist: aiobotocore>=3.9.1; extra == "queue-sqs"
22
+ Requires-Dist: aiobotocore>=3.9.2; extra == "queue-sqs"
23
23
  Provides-Extra: queue-aqs
24
- Requires-Dist: azure-storage-queue[aio]>=12.17.0; extra == "queue-aqs"
24
+ Requires-Dist: azure-storage-queue[aio]>=12.18.0; extra == "queue-aqs"
25
25
  Provides-Extra: queue-cosmos
26
- Requires-Dist: azure-cosmos>=4.17.0; extra == "queue-cosmos"
26
+ Requires-Dist: azure-cosmos>=4.17.1; extra == "queue-cosmos"
27
27
  Provides-Extra: database-psql
28
- Requires-Dist: sqlalchemy[asyncio]>=2.0.54; extra == "database-psql"
28
+ Requires-Dist: sqlalchemy[asyncio]>=2.1.3; extra == "database-psql"
29
29
  Requires-Dist: asyncpg>=0.31.0; extra == "database-psql"
30
30
  Provides-Extra: database-sqlite
31
- Requires-Dist: sqlalchemy[asyncio]>=2.0.54; extra == "database-sqlite"
31
+ Requires-Dist: sqlalchemy[asyncio]>=2.1.3; extra == "database-sqlite"
32
32
  Requires-Dist: aiosqlite>=0.22.1; extra == "database-sqlite"
33
33
  Provides-Extra: requester
34
- Requires-Dist: httpx2>=2.13.0; extra == "requester"
34
+ Requires-Dist: httpx2>=2.13.1; extra == "requester"
35
35
  Provides-Extra: web3
36
36
  Requires-Dist: web3<8.0.0,>=7.16.0; extra == "web3"
37
37
  Provides-Extra: cron
38
- Requires-Dist: apscheduler<4,>=3.11.0; extra == "cron"
38
+ Requires-Dist: apscheduler<4,>=3.11.3; extra == "cron"
39
39
  Provides-Extra: types
40
- Requires-Dist: types-aiobotocore[essential]>=3.9.1; extra == "types"
40
+ Requires-Dist: types-aiobotocore[essential]>=3.9.2; extra == "types"
41
41
  Requires-Dist: types-aiofiles>=25.1.0.20260518; extra == "types"
42
42
 
43
43
  # Core-Py
@@ -7,40 +7,40 @@ fastapi>=0.141.1
7
7
  uvicorn[standard]>=0.53.0
8
8
 
9
9
  [core-api]
10
- starlette>=1.6.0
10
+ starlette>=1.7.0
11
11
  uvicorn[standard]>=0.53.0
12
12
 
13
13
  [cron]
14
- apscheduler<4,>=3.11.0
14
+ apscheduler<4,>=3.11.3
15
15
 
16
16
  [database-psql]
17
- sqlalchemy[asyncio]>=2.0.54
17
+ sqlalchemy[asyncio]>=2.1.3
18
18
  asyncpg>=0.31.0
19
19
 
20
20
  [database-sqlite]
21
- sqlalchemy[asyncio]>=2.0.54
21
+ sqlalchemy[asyncio]>=2.1.3
22
22
  aiosqlite>=0.22.1
23
23
 
24
24
  [queue-aqs]
25
- azure-storage-queue[aio]>=12.17.0
25
+ azure-storage-queue[aio]>=12.18.0
26
26
 
27
27
  [queue-cosmos]
28
- azure-cosmos>=4.17.0
28
+ azure-cosmos>=4.17.1
29
29
 
30
30
  [queue-sqs]
31
- aiobotocore>=3.9.1
31
+ aiobotocore>=3.9.2
32
32
 
33
33
  [queues]
34
- aiobotocore>=3.9.1
34
+ aiobotocore>=3.9.2
35
35
 
36
36
  [requester]
37
- httpx2>=2.13.0
37
+ httpx2>=2.13.1
38
38
 
39
39
  [storage]
40
- aiobotocore>=3.9.1
40
+ aiobotocore>=3.9.2
41
41
 
42
42
  [types]
43
- types-aiobotocore[essential]>=3.9.1
43
+ types-aiobotocore[essential]>=3.9.2
44
44
  types-aiofiles>=25.1.0.20260518
45
45
 
46
46
  [web3]
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kiba-core"
3
- version = "0.5.3.dev74"
3
+ version = "0.5.3.dev76"
4
4
  description = "Kiba Labs' python utilities"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12, <4"
@@ -16,44 +16,44 @@ api = [
16
16
  "uvicorn[standard]>=0.53.0",
17
17
  ]
18
18
  core-api = [
19
- "starlette>=1.6.0",
19
+ "starlette>=1.7.0",
20
20
  "uvicorn[standard]>=0.53.0",
21
21
  ]
22
22
  storage = [
23
- "aiobotocore>=3.9.1",
23
+ "aiobotocore>=3.9.2",
24
24
  ]
25
25
  # TODO(krishan711): remove this in next major update
26
26
  queues = [
27
- "aiobotocore>=3.9.1",
27
+ "aiobotocore>=3.9.2",
28
28
  ]
29
29
  queue-sqs = [
30
- "aiobotocore>=3.9.1",
30
+ "aiobotocore>=3.9.2",
31
31
  ]
32
32
  queue-aqs = [
33
- "azure-storage-queue[aio]>=12.17.0",
33
+ "azure-storage-queue[aio]>=12.18.0",
34
34
  ]
35
35
  queue-cosmos = [
36
- "azure-cosmos>=4.17.0",
36
+ "azure-cosmos>=4.17.1",
37
37
  ]
38
38
  database-psql = [
39
- "sqlalchemy[asyncio]>=2.0.54",
39
+ "sqlalchemy[asyncio]>=2.1.3",
40
40
  "asyncpg>=0.31.0",
41
41
  ]
42
42
  database-sqlite = [
43
- "sqlalchemy[asyncio]>=2.0.54",
43
+ "sqlalchemy[asyncio]>=2.1.3",
44
44
  "aiosqlite>=0.22.1",
45
45
  ]
46
46
  requester = [
47
- "httpx2>=2.13.0",
47
+ "httpx2>=2.13.1",
48
48
  ]
49
49
  web3 = [
50
50
  "web3>=7.16.0,<8.0.0",
51
51
  ]
52
52
  cron = [
53
- "apscheduler>=3.11.0,<4",
53
+ "apscheduler>=3.11.3,<4",
54
54
  ]
55
55
  types = [
56
- "types-aiobotocore[essential]>=3.9.1",
56
+ "types-aiobotocore[essential]>=3.9.2",
57
57
  "types-aiofiles>=25.1.0.20260518",
58
58
  ]
59
59
 
@@ -134,3 +134,14 @@ def test_json_route_empty_body(client):
134
134
  data = response.json()
135
135
  assert data["request_name"] == "EmptyBody"
136
136
  assert data["request_age"] == 50
137
+
138
+
139
+ @pytest.mark.parametrize("content", ["true", "[1, 2]", "\"text\"", "null", "1"])
140
+ def test_json_route_with_non_object_json(client, content):
141
+ response = client.post(
142
+ "/test?name=NonObject&age=1",
143
+ content=content,
144
+ headers={"Content-Type": "application/json"}
145
+ )
146
+ assert response.status_code == 400
147
+ assert "expected an object" in response.json().get("message", "")
@@ -184,3 +184,14 @@ def test_error_thrown_by_endpoint(client):
184
184
  data = dataList[0]
185
185
  assert data["request_name"] == "Name"
186
186
  assert data["request_age"] == 30
187
+
188
+
189
+ @pytest.mark.parametrize("content", ["true", "[1, 2]", "\"text\"", "null", "1"])
190
+ def test_streaming_json_route_with_non_object_json(client, content):
191
+ response = client.post(
192
+ "/test?name=NonObject&age=1",
193
+ content=content,
194
+ headers={"Content-Type": "application/json"}
195
+ )
196
+ assert response.status_code == 400
197
+ assert "expected an object" in response.json().get("message", "")