kiba-core 0.5.3.dev46__tar.gz → 0.5.3.dev48__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.
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/PKG-INFO +1 -1
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/middleware/exception_handling_middleware.py +8 -2
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/streaming_json_route.py +1 -1
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/kiba_core.egg-info/PKG-INFO +1 -1
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/kiba_core.egg-info/SOURCES.txt +1 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/pyproject.toml +1 -1
- kiba_core-0.5.3.dev48/tests/api/test_authorizer.py +154 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/.github/pull_request_template.md +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/.github/workflows/deploy.yml +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/.github/workflows/pull-request.yml +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/.github/workflows/release.yml +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/.gitignore +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/CHANGELOG.md +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/Dockerfile +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/README.md +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/api_request.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/api_response.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/authorizer.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/default_routes.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/health.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/json_route.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/middleware/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/middleware/database_connection_middleware.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/middleware/logging_middleware.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/middleware/server_headers_middleware.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/aws_requester.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/caching/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/caching/cache.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/caching/dict_cache.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/caching/file_cache.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/exceptions.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/http/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/http/basic_authentication.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/http/jwt.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/http/rest_method.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/logging.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/notifications/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/notifications/discord_client.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/notifications/notification_client.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/notifications/slack_client.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/py.typed +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/queues/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/queues/aqs.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/queues/message_queue.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/queues/message_queue_processor.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/queues/model.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/queues/sqs.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/requester/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/requester/requester.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/s3_manager.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/service_client.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/store/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/store/database.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/store/retriever.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/store/saver.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/async_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/chain_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/date_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/dict_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/file_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/hashing_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/http_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/json_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/list_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/string_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/typing_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/url_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/util/value_holder.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/web3/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/web3/eth_client.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/web3/multicall3.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/kiba_core.egg-info/dependency_links.txt +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/kiba_core.egg-info/requires.txt +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/kiba_core.egg-info/top_level.txt +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/makefile +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/setup.cfg +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/api/test_json_route.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/api/test_streaming_json_route.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/caching/test_dict_cache.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/caching/test_file_cache.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/test_async_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/test_chain_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/test_date_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/test_dict_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/test_file_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/test_json_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/test_list_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/test_string_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/util/test_url_util.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/web3/__init__.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/tests/web3/test_rest_eth_client.py +0 -0
- {kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/uv.lock +0 -0
{kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/middleware/exception_handling_middleware.py
RENAMED
|
@@ -12,9 +12,10 @@ from core.exceptions import RedirectException
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class ExceptionHandlingMiddleware(BaseHTTPMiddleware):
|
|
15
|
-
def __init__(self, app: ASGIApp, shouldSquashClientExceptions: bool = True) -> None:
|
|
15
|
+
def __init__(self, app: ASGIApp, shouldSquashClientExceptions: bool = True, shouldHideInternalErrors: bool = True) -> None:
|
|
16
16
|
super().__init__(app=app)
|
|
17
17
|
self.shouldSquashClientExceptions = shouldSquashClientExceptions
|
|
18
|
+
self.shouldHideInternalErrors = shouldHideInternalErrors
|
|
18
19
|
|
|
19
20
|
@staticmethod
|
|
20
21
|
def _convert_exception(exception: KibaException) -> Response:
|
|
@@ -38,8 +39,13 @@ class ExceptionHandlingMiddleware(BaseHTTPMiddleware):
|
|
|
38
39
|
response = self._convert_exception(exception=exception)
|
|
39
40
|
except KibaException as exception:
|
|
40
41
|
logging.exception(exception)
|
|
42
|
+
if self.shouldHideInternalErrors:
|
|
43
|
+
exception = KibaException(message='Internal Server Error', statusCode=exception.statusCode, exceptionType=exception.exceptionType)
|
|
41
44
|
response = self._convert_exception(exception=exception)
|
|
42
45
|
except Exception as exception: # noqa: BLE001
|
|
43
46
|
logging.exception(exception)
|
|
44
|
-
|
|
47
|
+
kibaException = KibaException.from_exception(exception=exception)
|
|
48
|
+
if self.shouldHideInternalErrors:
|
|
49
|
+
kibaException = KibaException(message='Internal Server Error', statusCode=kibaException.statusCode)
|
|
50
|
+
response = self._convert_exception(exception=kibaException)
|
|
45
51
|
return response
|
|
@@ -52,7 +52,7 @@ def streaming_json_route[ApiRequest: BaseModel, ApiResponse: BaseModel](
|
|
|
52
52
|
raise BadRequestException(f'Invalid request: {validationErrorMessage}')
|
|
53
53
|
kibaRequest: KibaApiRequest[ApiRequest] = KibaApiRequest(scope=receivedRequest.scope, receive=receivedRequest._receive, send=receivedRequest._send) # noqa: SLF001
|
|
54
54
|
kibaRequest.data = requestParams
|
|
55
|
-
responseGeneratorOrAwaitable = func(kibaRequest)
|
|
55
|
+
responseGeneratorOrAwaitable = func(request=kibaRequest)
|
|
56
56
|
responseGenerator = await responseGeneratorOrAwaitable if inspect.isawaitable(responseGeneratorOrAwaitable) else responseGeneratorOrAwaitable
|
|
57
57
|
wrappedGenerator = _convert_to_json_generator(typing.cast(AsyncIterator[BaseModel], responseGenerator), expectedType=typing.cast(typing.Type[BaseModel], responseType))
|
|
58
58
|
# NOTE(krishan711): we set content-encoding to identity to prevent gzip from trying to process it (cos it buffers all the content)
|
|
@@ -76,6 +76,7 @@ kiba_core.egg-info/dependency_links.txt
|
|
|
76
76
|
kiba_core.egg-info/requires.txt
|
|
77
77
|
kiba_core.egg-info/top_level.txt
|
|
78
78
|
tests/__init__.py
|
|
79
|
+
tests/api/test_authorizer.py
|
|
79
80
|
tests/api/test_json_route.py
|
|
80
81
|
tests/api/test_streaming_json_route.py
|
|
81
82
|
tests/caching/test_dict_cache.py
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from collections.abc import AsyncIterator
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
from starlette.applications import Starlette
|
|
5
|
+
from starlette.routing import Route
|
|
6
|
+
from starlette.testclient import TestClient
|
|
7
|
+
|
|
8
|
+
from core.api.api_request import KibaApiRequest
|
|
9
|
+
from core.api.authorizer import Authorizer, authorize_bearer_jwt
|
|
10
|
+
from core.api.json_route import json_route
|
|
11
|
+
from core.api.middleware.exception_handling_middleware import ExceptionHandlingMiddleware
|
|
12
|
+
from core.api.streaming_json_route import streaming_json_route
|
|
13
|
+
from core.exceptions import ForbiddenException
|
|
14
|
+
from core.http.jwt import Jwt
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
VALID_TOKEN = 'valid-token'
|
|
18
|
+
VALID_USER_ID = 'user-123'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MockAuthorizer(Authorizer):
|
|
22
|
+
async def validate_jwt(self, jwtString: str) -> Jwt:
|
|
23
|
+
if jwtString != VALID_TOKEN:
|
|
24
|
+
raise ForbiddenException('Invalid token')
|
|
25
|
+
jwt = Jwt(payloadDict={'sub': VALID_USER_ID})
|
|
26
|
+
jwt.userId = VALID_USER_ID # type: ignore[attr-defined]
|
|
27
|
+
return jwt
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class SimpleRequest(BaseModel):
|
|
31
|
+
value: str
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SimpleResponse(BaseModel):
|
|
35
|
+
result: str
|
|
36
|
+
user_id: str | None = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
authorizer = MockAuthorizer()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.fixture
|
|
43
|
+
def json_client():
|
|
44
|
+
@json_route(requestType=SimpleRequest, responseType=SimpleResponse)
|
|
45
|
+
@authorize_bearer_jwt(authorizer=authorizer)
|
|
46
|
+
async def protected_endpoint(request: KibaApiRequest[SimpleRequest]) -> SimpleResponse:
|
|
47
|
+
jwt = request.authJwt
|
|
48
|
+
return SimpleResponse(result=request.data.value, user_id=getattr(jwt, 'userId', None))
|
|
49
|
+
|
|
50
|
+
app = Starlette(routes=[Route('/protected', protected_endpoint, methods=['POST'])])
|
|
51
|
+
app.add_middleware(ExceptionHandlingMiddleware)
|
|
52
|
+
return TestClient(app, raise_server_exceptions=False)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@pytest.fixture
|
|
56
|
+
def streaming_client():
|
|
57
|
+
@streaming_json_route(requestType=SimpleRequest, responseType=SimpleResponse)
|
|
58
|
+
@authorize_bearer_jwt(authorizer=authorizer)
|
|
59
|
+
async def protected_streaming_endpoint(request: KibaApiRequest[SimpleRequest]) -> AsyncIterator[SimpleResponse]:
|
|
60
|
+
jwt = request.authJwt
|
|
61
|
+
yield SimpleResponse(result=request.data.value, user_id=getattr(jwt, 'userId', None))
|
|
62
|
+
|
|
63
|
+
app = Starlette(routes=[Route('/protected-stream', protected_streaming_endpoint, methods=['POST'])])
|
|
64
|
+
app.add_middleware(ExceptionHandlingMiddleware)
|
|
65
|
+
return TestClient(app, raise_server_exceptions=False)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# --- json_route + authorize_bearer_jwt ---
|
|
69
|
+
|
|
70
|
+
def test_json_no_auth_header_returns_403(json_client):
|
|
71
|
+
response = json_client.post('/protected', json={'value': 'hello'})
|
|
72
|
+
assert response.status_code == 403
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_json_malformed_auth_header_not_bearer_returns_403(json_client):
|
|
76
|
+
response = json_client.post('/protected', json={'value': 'hello'}, headers={'Authorization': 'Basic some-creds'})
|
|
77
|
+
assert response.status_code == 403
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_json_bearer_with_no_token_returns_403(json_client):
|
|
81
|
+
response = json_client.post('/protected', json={'value': 'hello'}, headers={'Authorization': 'Bearer '})
|
|
82
|
+
assert response.status_code == 403
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_json_invalid_token_returns_403(json_client):
|
|
86
|
+
response = json_client.post('/protected', json={'value': 'hello'}, headers={'Authorization': 'Bearer bad-token'})
|
|
87
|
+
assert response.status_code == 403
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_json_valid_token_returns_200(json_client):
|
|
91
|
+
response = json_client.post('/protected', json={'value': 'hello'}, headers={'Authorization': f'Bearer {VALID_TOKEN}'})
|
|
92
|
+
assert response.status_code == 200
|
|
93
|
+
assert response.json()['result'] == 'hello'
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_json_valid_token_sets_auth_jwt_on_request(json_client):
|
|
97
|
+
response = json_client.post('/protected', json={'value': 'hello'}, headers={'Authorization': f'Bearer {VALID_TOKEN}'})
|
|
98
|
+
assert response.status_code == 200
|
|
99
|
+
assert response.json()['user_id'] == VALID_USER_ID
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_json_missing_request_body_field_returns_400(json_client):
|
|
103
|
+
response = json_client.post('/protected', json={}, headers={'Authorization': f'Bearer {VALID_TOKEN}'})
|
|
104
|
+
assert response.status_code == 400
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# --- streaming_json_route + authorize_bearer_jwt ---
|
|
108
|
+
|
|
109
|
+
def test_streaming_no_auth_header_returns_403(streaming_client):
|
|
110
|
+
response = streaming_client.post('/protected-stream', json={'value': 'hello'})
|
|
111
|
+
assert response.status_code == 403
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_streaming_malformed_auth_header_not_bearer_returns_403(streaming_client):
|
|
115
|
+
response = streaming_client.post('/protected-stream', json={'value': 'hello'}, headers={'Authorization': 'Basic some-creds'})
|
|
116
|
+
assert response.status_code == 403
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def test_streaming_bearer_with_no_token_returns_403(streaming_client):
|
|
120
|
+
response = streaming_client.post('/protected-stream', json={'value': 'hello'}, headers={'Authorization': 'Bearer '})
|
|
121
|
+
assert response.status_code == 403
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_streaming_invalid_token_returns_403(streaming_client):
|
|
125
|
+
response = streaming_client.post('/protected-stream', json={'value': 'hello'}, headers={'Authorization': 'Bearer bad-token'})
|
|
126
|
+
assert response.status_code == 403
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def test_streaming_valid_token_returns_200(streaming_client):
|
|
130
|
+
response = streaming_client.post('/protected-stream', json={'value': 'hello'}, headers={'Authorization': f'Bearer {VALID_TOKEN}'})
|
|
131
|
+
assert response.status_code == 200
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_streaming_valid_token_streams_correct_data(streaming_client):
|
|
135
|
+
response = streaming_client.post('/protected-stream', json={'value': 'hello'}, headers={'Authorization': f'Bearer {VALID_TOKEN}'})
|
|
136
|
+
assert response.status_code == 200
|
|
137
|
+
import json
|
|
138
|
+
lines = [l for l in response.content.decode().strip().split('\n') if l]
|
|
139
|
+
assert len(lines) == 1
|
|
140
|
+
data = json.loads(lines[0])
|
|
141
|
+
assert data['result'] == 'hello'
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def test_streaming_valid_token_sets_auth_jwt_on_request(streaming_client):
|
|
145
|
+
response = streaming_client.post('/protected-stream', json={'value': 'hello'}, headers={'Authorization': f'Bearer {VALID_TOKEN}'})
|
|
146
|
+
assert response.status_code == 200
|
|
147
|
+
import json
|
|
148
|
+
data = json.loads(response.content.decode().strip())
|
|
149
|
+
assert data['user_id'] == VALID_USER_ID
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def test_streaming_missing_request_body_field_returns_400(streaming_client):
|
|
153
|
+
response = streaming_client.post('/protected-stream', json={}, headers={'Authorization': f'Bearer {VALID_TOKEN}'})
|
|
154
|
+
assert response.status_code == 400
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kiba_core-0.5.3.dev46 → kiba_core-0.5.3.dev48}/core/api/middleware/server_headers_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|