mirror of
https://github.com/clearml/clearml-server
synced 2025-05-02 03:03:58 +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"
|
||||
}
|
||||
}
|
||||
runtime {
|
||||
description: "Task runtime mapping"
|
||||
type: object
|
||||
additionalProperties: true
|
||||
}
|
||||
}
|
||||
}
|
||||
task_urls {
|
||||
@ -1361,6 +1366,11 @@ edit {
|
||||
type: object
|
||||
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 werkzeug.exceptions import BadRequest
|
||||
|
||||
from apiserver.apierrors import APIError
|
||||
from apiserver.apierrors.base import BaseError
|
||||
from apiserver.config_repo import config
|
||||
from apiserver.service_repo import ServiceRepo, APICall
|
||||
@ -25,7 +28,10 @@ class RequestHandlers:
|
||||
|
||||
try:
|
||||
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:
|
||||
response = redirect(call.result.redirect.url, call.result.redirect.code)
|
||||
@ -137,9 +143,6 @@ class RequestHandlers:
|
||||
auth_cookie=auth_cookie,
|
||||
)
|
||||
|
||||
# Update call data from request
|
||||
self._update_call_data(call, req)
|
||||
|
||||
except PathParsingError as ex:
|
||||
call = self._call_or_empty_with_error(call, req, ex.args[0], 400)
|
||||
call.log_api = False
|
||||
@ -156,3 +159,18 @@ class RequestHandlers:
|
||||
)
|
||||
|
||||
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 .errors import MalformedPathError, InvalidVersionError, CallFailedError
|
||||
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__)
|
||||
|
||||
@ -227,18 +232,6 @@ class ServiceRepo(object):
|
||||
return True
|
||||
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
|
||||
def _get_company(
|
||||
cls, call: APICall, endpoint: Endpoint = None, ignore_error: bool = False
|
||||
@ -252,7 +245,7 @@ class ServiceRepo(object):
|
||||
return call.identity.company
|
||||
|
||||
@classmethod
|
||||
def handle_call(cls, call: APICall):
|
||||
def handle_call(cls, call: APICall, load_data_callback: Callable = None):
|
||||
try:
|
||||
if call.failed:
|
||||
raise CallFailedError()
|
||||
@ -262,7 +255,18 @@ class ServiceRepo(object):
|
||||
if call.failed:
|
||||
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:
|
||||
raise CallFailedError()
|
||||
|
@ -14,17 +14,9 @@ from .errors import CallParsingError
|
||||
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 """
|
||||
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
|
||||
validate_required_fields(endpoint, call)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user