mirror of
https://github.com/clearml/clearml-server
synced 2025-06-26 23:15:47 +00:00
Fix schema for Task.runtime
Add infrastructure for API calls limits handling
This commit is contained in:
parent
add3f011a0
commit
27d086bca2
@ -617,6 +617,11 @@ _definitions {
|
|||||||
"$ref": "#/definitions/configuration_item"
|
"$ref": "#/definitions/configuration_item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
runtime {
|
||||||
|
description: "Task runtime mapping"
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
task_urls {
|
task_urls {
|
||||||
@ -1361,6 +1366,11 @@ edit {
|
|||||||
type: object
|
type: object
|
||||||
additionalProperties { type: string }
|
additionalProperties { type: string }
|
||||||
}
|
}
|
||||||
|
runtime {
|
||||||
|
description: "Task runtime mapping"
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
from functools import partial
|
||||||
|
|
||||||
from flask import request, Response, redirect
|
from flask import request, Response, redirect
|
||||||
from werkzeug.exceptions import BadRequest
|
from werkzeug.exceptions import BadRequest
|
||||||
|
|
||||||
|
from apiserver.apierrors import APIError
|
||||||
from apiserver.apierrors.base import BaseError
|
from apiserver.apierrors.base import BaseError
|
||||||
from apiserver.config_repo import config
|
from apiserver.config_repo import config
|
||||||
from apiserver.service_repo import ServiceRepo, APICall
|
from apiserver.service_repo import ServiceRepo, APICall
|
||||||
@ -25,7 +28,10 @@ class RequestHandlers:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
call = self._create_api_call(request)
|
call = self._create_api_call(request)
|
||||||
content, content_type = ServiceRepo.handle_call(call)
|
load_data_callback = partial(self._load_call_data, req=request)
|
||||||
|
content, content_type = ServiceRepo.handle_call(
|
||||||
|
call, load_data_callback=load_data_callback
|
||||||
|
)
|
||||||
|
|
||||||
if call.result.redirect:
|
if call.result.redirect:
|
||||||
response = redirect(call.result.redirect.url, call.result.redirect.code)
|
response = redirect(call.result.redirect.url, call.result.redirect.code)
|
||||||
@ -137,9 +143,6 @@ class RequestHandlers:
|
|||||||
auth_cookie=auth_cookie,
|
auth_cookie=auth_cookie,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update call data from request
|
|
||||||
self._update_call_data(call, req)
|
|
||||||
|
|
||||||
except PathParsingError as ex:
|
except PathParsingError as ex:
|
||||||
call = self._call_or_empty_with_error(call, req, ex.args[0], 400)
|
call = self._call_or_empty_with_error(call, req, ex.args[0], 400)
|
||||||
call.log_api = False
|
call.log_api = False
|
||||||
@ -156,3 +159,18 @@ class RequestHandlers:
|
|||||||
)
|
)
|
||||||
|
|
||||||
return call
|
return call
|
||||||
|
|
||||||
|
def _load_call_data(self, call: APICall, req):
|
||||||
|
"""Update call data from request"""
|
||||||
|
try:
|
||||||
|
self._update_call_data(call, req)
|
||||||
|
except BadRequest as ex:
|
||||||
|
call.set_error_result(msg=ex.description, code=400)
|
||||||
|
except BaseError as ex:
|
||||||
|
call.set_error_result(msg=ex.msg, code=ex.code, subcode=ex.subcode)
|
||||||
|
except APIError as ex:
|
||||||
|
call.set_error_result(
|
||||||
|
msg=ex.msg, code=ex.code, subcode=ex.subcode, error_data=ex.error_data
|
||||||
|
)
|
||||||
|
except Exception as ex:
|
||||||
|
call.set_error_result(msg=ex.args[0] if ex.args else type(ex).__name__)
|
||||||
|
@ -13,7 +13,12 @@ from .apicall import APICall
|
|||||||
from .endpoint import Endpoint
|
from .endpoint import Endpoint
|
||||||
from .errors import MalformedPathError, InvalidVersionError, CallFailedError
|
from .errors import MalformedPathError, InvalidVersionError, CallFailedError
|
||||||
from .util import parse_return_stack_on_code
|
from .util import parse_return_stack_on_code
|
||||||
from .validators import validate_all
|
from .validators import (
|
||||||
|
validate_data,
|
||||||
|
validate_auth,
|
||||||
|
validate_role,
|
||||||
|
validate_impersonation,
|
||||||
|
)
|
||||||
|
|
||||||
log = config.logger(__file__)
|
log = config.logger(__file__)
|
||||||
|
|
||||||
@ -227,18 +232,6 @@ class ServiceRepo(object):
|
|||||||
return True
|
return True
|
||||||
return subcode in subcode_list
|
return subcode in subcode_list
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _validate_call(cls, call: APICall) -> Optional[Endpoint]:
|
|
||||||
endpoint = cls._resolve_endpoint_from_call(call)
|
|
||||||
if call.failed:
|
|
||||||
return
|
|
||||||
validate_all(call, endpoint)
|
|
||||||
return endpoint
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def validate_call(cls, call: APICall):
|
|
||||||
cls._validate_call(call)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_company(
|
def _get_company(
|
||||||
cls, call: APICall, endpoint: Endpoint = None, ignore_error: bool = False
|
cls, call: APICall, endpoint: Endpoint = None, ignore_error: bool = False
|
||||||
@ -252,7 +245,7 @@ class ServiceRepo(object):
|
|||||||
return call.identity.company
|
return call.identity.company
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def handle_call(cls, call: APICall):
|
def handle_call(cls, call: APICall, load_data_callback: Callable = None):
|
||||||
try:
|
try:
|
||||||
if call.failed:
|
if call.failed:
|
||||||
raise CallFailedError()
|
raise CallFailedError()
|
||||||
@ -262,7 +255,18 @@ class ServiceRepo(object):
|
|||||||
if call.failed:
|
if call.failed:
|
||||||
raise CallFailedError()
|
raise CallFailedError()
|
||||||
|
|
||||||
validate_all(call, endpoint)
|
validate_auth(endpoint, call)
|
||||||
|
validate_role(endpoint, call)
|
||||||
|
if validate_impersonation(endpoint, call):
|
||||||
|
# if impersonating, validate role again
|
||||||
|
validate_role(endpoint, call)
|
||||||
|
|
||||||
|
if load_data_callback:
|
||||||
|
load_data_callback(call)
|
||||||
|
if call.failed:
|
||||||
|
raise CallFailedError()
|
||||||
|
|
||||||
|
validate_data(call, endpoint)
|
||||||
|
|
||||||
if call.failed:
|
if call.failed:
|
||||||
raise CallFailedError()
|
raise CallFailedError()
|
||||||
|
@ -14,17 +14,9 @@ from .errors import CallParsingError
|
|||||||
log = config.logger(__file__)
|
log = config.logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
def validate_all(call: APICall, endpoint: Endpoint):
|
def validate_data(call: APICall, endpoint: Endpoint):
|
||||||
""" Perform all required call/endpoint validation, update call result appropriately """
|
""" Perform all required call/endpoint validation, update call result appropriately """
|
||||||
try:
|
try:
|
||||||
validate_auth(endpoint, call)
|
|
||||||
|
|
||||||
validate_role(endpoint, call)
|
|
||||||
|
|
||||||
if validate_impersonation(endpoint, call):
|
|
||||||
# if impersonating, validate role again
|
|
||||||
validate_role(endpoint, call)
|
|
||||||
|
|
||||||
# todo: remove vaildate_required_fields once all endpoints have json schema
|
# todo: remove vaildate_required_fields once all endpoints have json schema
|
||||||
validate_required_fields(endpoint, call)
|
validate_required_fields(endpoint, call)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user