Python aiohttp.web 模块,HTTPBadRequest() 实例源码
我们从Python开源项目中,提取了以下49个代码示例,用于说明如何使用aiohttp.web.HTTPBadRequest()。
def get_chars(request):
peername = request.transport.get_extra_info('peername')
print('Request from: {},GET data: {!r}'.format(peername, dict(request.GET)))
query = request.GET.get('query', '')
if query:
try:
start = int(request.GET.get('start', 0))
stop = int(request.GET.get('stop', sys.maxsize))
except ValueError:
raise web.HTTPBadRequest()
stop = min(stop, start+RESULTS_PER_REQUEST)
num_results, chars = index.find_chars(query, start, stop)
else:
raise web.HTTPBadRequest()
text = ''.join(char if n % 64 else char+'\n'
for n, char in enumerate(chars, 1))
response_data = {'total': num_results, 'start': start, 'stop': stop}
print('Response to query: {query!r},start: {start},stop: {stop}'.format(
query=query, **response_data))
response_data['chars'] = text
json_obj = json.dumps(response_data)
print('Sending {} characters'.format(len(text)))
headers = {'Access-Control-Allow-Origin': '*'}
return web.Response(content_type=TEXT_TYPE, headers=headers, text=json_obj)
def handle_kkdcp(request):
length = request.content_length
if length is None:
raise web.HTTPLengthrequired(text="Length is required.")
if length > MAX_LENGTH:
raise web.HTTPRequestEntityTooLarge(text="Request is too large.")
try:
data = await request.read()
proxy_request = codec.decode(data)
except codec.ParserError as e:
raise web.HTTPBadRequest(text=str(e))
loop = asyncio.get_event_loop()
# Todo: Change this to look up the KDC to talk to
try:
krb5_response = await asyncio.wait_for(forward_kerberos(proxy_request.message, loop=loop), timeout=15, loop=loop)
except asyncio.TimeoutError:
raise web.HTTPServiceUnavailable(text="Timeout waiting for Kerberos server")
return web.Response(body=codec.encode(krb5_response), content_type="application/kerberos")
def upload_pet_image(request):
with open(os.path.join(os.path.dirname(__file__), 'sample.jpg'), 'rb') as f:
data = await request.post()
file_data = data.get('file')
content = file_data.file.read()
expected_content = f.read()
if content != expected_content:
return web.HTTPBadRequest()
if not (
request.match_info['petId'] == '42'
and data.get('userId') == '12'
):
return web.HTTPBadRequest()
return web.json_response({})
def update_pet(request):
body = await request.json()
success = body == {
'id': 42,
'category': {
'name': 'extracute',
},
'name': 'Lili',
'photoUrls': [],
'status': 'sold',
}
if success:
return web.json_response({})
return web.HTTPBadRequest()
def hook(request):
body = await request.read()
check_signature = hmac.compare_digest(
get_signature(body),
request.headers.get('X-Hub-Signature', '')
)
if not check_signature:
return web.HTTPBadRequest()
body = await request.json()
headers = dict(request.headers.items())
del headers['X-Hub-Signature']
ref = get_hook_ctx(headers, body, clean=True)
if ref:
request.app.loop.create_task(ci(ref))
return web.json_response(ref)
def call(self, request):
try:
event_data = (await request.post())['mandrill_events']
except KeyError:
raise HTTPBadRequest(text='"mandrill_events" not found in post data')
sig_generated = base64.b64encode(
hmac.new(
self.app['webhook_auth_key'],
msg=(self.app['mandrill_webhook_url'] + 'mandrill_events' + event_data).encode(),
digestmod=hashlib.sha1
).digest()
)
sig_given = request.headers.get('X-Mandrill-Signature', '<missing>').encode()
if not hmac.compare_digest(sig_generated, sig_given):
raise HTTPForbidden(text='invalid signature')
try:
events = ujson.loads(event_data)
except ValueError as e:
raise HTTPBadRequest(text=f'invalid json data: {e}')
await self.sender.update_mandrill_webhooks(events)
return Response(text='message status updated\n')
def response_middleware(app, next_handler):
async def handler(request):
result = await next_handler(request)
if not isinstance(result, Response):
accept = request.headers.get('accept', 'application/json')
if accept in ('application/json', '*/*'):
if isinstance(result, ErrorResponse):
data, status, headers = result.data, result.status, result.headers
if headers:
# Passing both Content-Type header
# and content_type or charset params is forbidden
# (json_response already passes content_type)
headers.pop('content-type', None)
else:
data, headers = result, HTTP_OK, None
result = json_response(data, status=status, headers=headers)
else:
logger.error('Unable to serialize response (accept=%s)', accept)
raise HTTPBadRequest()
return result
return handler
def test_post_max_client_size(loop, test_client):
@H_502_1916@@asyncio.coroutine
def handler(request):
try:
yield from request.post()
except ValueError:
return web.HTTPOk()
return web.HTTPBadRequest()
app = web.Application(client_max_size=10)
app.router.add_post('/', handler)
client = yield from test_client(app)
data = {"long_string": 1024 * 'x', 'file': io.BytesIO(b'test')}
resp = yield from client.post('/', data=data)
assert 200 == resp.status
def test_post_max_client_size_for_file(loop, test_client):
@H_502_1916@@asyncio.coroutine
def handler(request):
try:
yield from request.post()
except ValueError:
return web.HTTPOk()
return web.HTTPBadRequest()
app = web.Application(client_max_size=2)
app.router.add_post('/', handler)
client = yield from test_client(app)
data = {'file': io.BytesIO(b'test')}
resp = yield from client.post('/', data=data)
assert 200 == resp.status
def get_category(request):
"""
Args:
request: category_name is required
Returns:
the configuration items in the given category.
:Example:
curl -X GET http://localhost:8081/category/PURGE_READ
"""
category_name = request.match_info.get('category_name', None)
if not category_name:
raise web.HTTPBadRequest(reason="Category Name is required")
# Todo: make it optimized and elegant
cf_mgr = ConfigurationManager(connect.get_storage())
category = await cf_mgr.get_category_all_items(category_name)
if category is None:
raise web.HTTPNotFound(reason="No such Category Found for {}".format(category_name))
return web.json_response(category)
def get_category_item(request):
"""
Args:
request: category_name & config_item are required
Returns:
the configuration item in the given category.
:Example:
curl -X GET http://localhost:8081/foglamp/category/PURGE_READ/age
"""
category_name = request.match_info.get('category_name', None)
config_item = request.match_info.get('config_item', None)
if not category_name or not config_item:
raise web.HTTPBadRequest(reason="Both Category Name and Config items are required")
# Todo: make it optimized and elegant
cf_mgr = ConfigurationManager(connect.get_storage())
category_item = await cf_mgr.get_category_item(category_name, config_item)
if category_item is None:
raise web.HTTPNotFound(reason="No Category Item Found")
return web.json_response(category_item)
def get_backup_details(request):
"""
Returns the details of a backup
:Example: curl -X GET http://localhost:8082/foglamp/backup/1
"""
backup_id = request.match_info.get('backup_id', None)
if not backup_id:
raise web.HTTPBadRequest(reason='Backup id is required')
else:
try:
backup_id = int(backup_id)
except ValueError:
raise web.HTTPBadRequest(reason='Invalid backup id')
try:
# Todo : Fix after actual implementation
Backup.get_backup_details.return_value = \
{"date": '2017-08-30 04:05:10.382', "status": "running"}
except Backup.DoesNotExist:
raise web.HTTPNotFound(reason='Backup with {} does not exist'.format(backup_id))
_resp = Backup.get_backup_details(id=backup_id)
_resp["id"] = backup_id
return web.json_response(_resp)
def restore_backup(request):
"""
Restore from a backup
:Example: curl -X PUT http://localhost:8082/foglamp/backup/1/restore
"""
backup_id = request.match_info.get('backup_id', None)
if not backup_id:
raise web.HTTPBadRequest(reason='Backup id is required')
else:
try:
backup_id = int(backup_id)
except ValueError:
raise web.HTTPBadRequest(reason='Invalid backup id')
try:
# Todo : Fix after actual implementation
Backup.restore_backup.return_value = 1
except Backup.DoesNotExist:
raise web.HTTPNotFound(reason='Backup with {} does not exist'.format(backup_id))
try:
Backup.restore_backup(id=backup_id)
return web.json_response({'message': 'Restore backup with id {} started successfully'.format(backup_id)})
except Backup.RestoreFailed as ex:
return web.json_response({'error': 'Restore backup with id {} Failed,reason {}'.format(backup_id, ex)})
def get_scheduled_process(request):
"""
Returns a list of all the defined scheduled_processes from scheduled_processes table
"""
scheduled_process_name = request.match_info.get('scheduled_process_name', None)
if not scheduled_process_name:
raise web.HTTPBadRequest(reason='No Scheduled Process Name given')
payload = PayloadBuilder().SELECT(("name")).WHERE(["name", "=", scheduled_process_name]).payload()
_storage = connect.get_storage()
scheduled_process = _storage.query_tbl_with_payload('scheduled_processes', payload)
if len(scheduled_process['rows']) == 0:
raise web.HTTPNotFound(reason='No such Scheduled Process: {}.'.format(scheduled_process_name))
return web.json_response(scheduled_process['rows'][0].get("name"))
#################################
# Schedules
#################################
def delete_schedule(request):
"""
Delete a schedule from schedules table
:Example: curl -X DELETE http://localhost:8082/foglamp/schedule/dc9bfc01-066a-4cc0-b068-9c35486db87f
"""
try:
schedule_id = request.match_info.get('schedule_id', None)
if not schedule_id:
raise web.HTTPBadRequest(reason='Schedule ID is required.')
try:
assert uuid.UUID(schedule_id)
except ValueError as ex:
raise web.HTTPNotFound(reason="Invalid Schedule ID {}".format(schedule_id))
await server.Server.scheduler.delete_schedule(uuid.UUID(schedule_id))
return web.json_response({'message': 'Schedule deleted successfully', 'id': schedule_id})
except (ValueError, ScheduleNotFoundError) as ex:
raise web.HTTPNotFound(reason=str(ex))
def cancel_task(request):
"""Cancel a running task from tasks table
:Example: curl -X GET http://localhost:8082/foglamp/task/cancel/{task_id}
"""
try:
task_id = request.match_info.get('task_id', None)
if not task_id:
raise web.HTTPBadRequest(reason='Task ID is required.')
try:
assert uuid.UUID(task_id)
except ValueError as ex:
raise web.HTTPNotFound(reason="Invalid Task ID {}".format(task_id))
task = await server.Server.scheduler.get_task(task_id)
# Cancel Task
await server.Server.scheduler.cancel_task(uuid.UUID(task_id))
return web.json_response({'id': task_id, 'message': 'Task cancelled successfully'})
except (ValueError, TaskNotFoundError) as ex:
raise web.HTTPNotFound(reason=str(ex))
def unregister(request):
""" Deregister a service
:Example: curl -X DELETE http://localhost:8082/foglamp/service/dc9bfc01-066a-4cc0-b068-9c35486db87f
"""
try:
service_id = request.match_info.get('service_id', None)
if not service_id:
raise web.HTTPBadRequest(reason='Service id is required')
try:
Service.Instances.get(idx=service_id)
except Service.DoesNotExist:
raise web.HTTPBadRequest(reason='Service with {} does not exist'.format(service_id))
Service.Instances.unregister(service_id)
_resp = {'id': str(service_id), 'message': 'Service unregistered'}
return web.json_response(_resp)
except ValueError as ex:
raise web.HTTPNotFound(reason=str(ex))
def error_middleware(app, handler):
async def middleware_handler(request):
if_trace = request.query.get('trace') if 'trace' in request.query and request.query.get('trace') == '1' else None
try:
response = await handler(request)
if response.status == 404:
return handle_api_exception({"code": response.status, "message": response.message}, ex.__class__.__name__, if_trace)
return response
except (web.HTTPNotFound, web.HTTPBadRequest) as ex:
return handle_api_exception({"code": ex.status_code, "message": ex.reason}, if_trace)
except web.HTTPException as ex:
raise
# Below Exception must come last as it is the super class of all exceptions
except Exception as ex:
return handle_api_exception(ex, if_trace)
return middleware_handler
def ajax_handler(request: web.Request):
action = request.match_info.get('action')
data = await parse(request, global_handlers.keys())
if action not in global_handlers[request.method]:
raise web.HTTPBadRequest()
handler = global_handlers[request.method][action]
try:
result = await handler(*(data, request, None)[:len(signature(handler).parameters)])
except InvalidRequest as err:
return web.Response(text=json.dumps({
'status': 1,
'data': str(err)
}, ensure_ascii=False), status=err.status_code, content_type='application/json')
if isinstance(result, web.StreamResponse):
return result
return web.Response(text=json.dumps({
'status': 0,
**({'data': result} if result is not None else {})
}, content_type='application/json')
def data_factory(app, handler):
async def parse_data(request):
logging.info('data_factory...')
if request.method in ('POST', 'PUT'):
if not request.content_type:
return web.HTTPBadRequest(text='Missing Content-Type.')
content_type = request.content_type.lower()
if content_type.startswith('application/json'):
request.__data__ = await request.json()
if not isinstance(request.__data__, dict):
return web.HTTPBadRequest(text='JSON body must be object.')
logging.info('request json: %s' % request.__data__)
elif content_type.startswith(('application/x-www-form-urlencoded', 'multipart/form-data')):
params = await request.post()
request.__data__ = dict(**params)
logging.info('request form: %s' % request.__data__)
else:
return web.HTTPBadRequest(text='Unsupported Content-Type: %s' % content_type)
elif request.method == 'GET':
qs = request.query_string
request.__data__ = {k: v[0] for k, v in parse.parse_qs(qs, True).items()}
logging.info('request query: %s' % request.__data__)
else:
request.__data__ = dict()
return await handler(request)
return parse_data
# ??????????????????Response??
def sparql_endpoint(request):
result = {
"post": dict((await request.post()).items()),
"path": request.path,
}
if "failure" in result['post'].get('query', ""):
raise web.HTTPBadRequest()
if "failure" in result['post'].get('update', ""):
raise web.HTTPBadRequest()
return web.Response(text=json.dumps(result),
content_type="application/json")
def data_factory(app, handler):
async def parse_data(request):
if request.method == 'POST':
if not request.content_type:
return web.HTTPBadRequest(text='Missing Content-type.')
content_type = request.content_type.lower()
if content_type.startswith('application/json'):
request.__data__ = await request.json()
if not isinstance(request.__data__, dict):
return web.HTTPBadRequest(text='JSON body must be object.')
logging.info('request json: %s' % str(request.__data__))
elif request.content_type.startswith('application/x-www-form-urlencoded'):
params = await request.post()
request.__data__ = dict(**params)
logging.info('request form: %s' % str(request.__data__))
else:
return web.HTTPBadRequest(text='Unsupported Content_Type: %s' % content_type)
elif request.method == 'GET':
qs = request.query_string
request.__data__ = {k: v[0] for k, True).items()}
logging.info('request query: %s' % request.__data__)
else:
request.__data__ = dict()
return (await handler(request))
return parse_data
# ??????????????????Response??
def Vote(self, request):
question_id = int(request.match_info['question_id'])
data = await request.post()
try:
choice_id = int(data['choice'])
except (KeyError, TypeError, ValueError) as e:
raise web.HTTPBadRequest(
text='You have not specified choice value') from e
try:
await db.Vote(self.postgres, question_id, choice_id)
except db.RecordNotFound as e:
raise web.HTTPNotFound(text=str(e))
router = request.app.router
url = router['results'].url(parts={'question_id': question_id})
return web.HTTPFound(location=url)
def require(self, *args):
data = self.permit(*args)
for arg in args:
if type(arg) == str:
if arg not in data:
raise web.HTTPBadRequest()
elif type(arg) == Or:
found = False
for item in arg:
if item in data:
found = True
break
if not found:
raise web.HTTPBadRequest()
return data
def login(request):
if not (
request.query.get('username') == 'asyncio'
and request.query.get('password') == 'password'
and request.query.get('invalidate_sessions') == 'True'
):
return web.HTTPBadRequest()
return web.json_response('success', headers={
'X-Rate-Limit': '4711',
'X-Expires-After': 'Expiration date',
})
def simple(request):
try:
letter = request.url.query['q']
except KeyError:
raise web.HTTPBadRequest()
try:
zenline = zenlines[letter]
except KeyError:
raise web.HTTPNotFound()
return web.Response(text=zenline)
def _strftime(self, ts):
dt_tz = self.request.query.get('dttz') or 'utc'
try:
dt_tz = pytz.timezone(dt_tz)
except pytz.UnkNownTimeZoneError:
raise HTTPBadRequest(text=f'unkNown timezone: "{dt_tz}"')
dt_fmt = self.request.query.get('dtfmt') or '%a %Y-%m-%d %H:%M'
return from_unix_ms(ts, 0).astimezone(dt_tz).strftime(dt_fmt)
def set_configuration_item(request):
"""
Args:
request: category_name,config_item,{"value" : <some value>} are required
Returns:
set the configuration item value in the given category.
:Example:
curl -X PUT -H "Content-Type: application/json" -d '{"value": <some value> }' http://localhost:8081/foglamp/category/{category_name}/{config_item}
For {category_name}=>PURGE update value for {config_item}=>age
curl -X PUT -H "Content-Type: application/json" -d '{"value": 24}' http://localhost:8081/foglamp/category/PURGE/age
"""
category_name = request.match_info.get('category_name', None)
data = await request.json()
# Todo: make it optimized and elegant
cf_mgr = ConfigurationManager(connect.get_storage())
try:
value = data['value']
await cf_mgr.set_category_item_value_entry(category_name, config_item, value)
result = await cf_mgr.get_category_item(category_name, config_item)
if result is None:
raise web.HTTPNotFound(reason="No detail found for the category_name: {} and config_item: {}".format(category_name, config_item))
except KeyError:
raise web.HTTPBadRequest(reason='Missing required value for {}'.format(config_item))
return web.json_response(result)
def delete_configuration_item_value(request):
"""
Args:
request: category_name,config_item are required
Returns:
set the configuration item value to empty string in the given category
:Example:
curl -X DELETE http://localhost:8081/foglamp/category/{category_name}/{config_item}/value
For {category_name}=>PURGE delete value for {config_item}=>age
curl -X DELETE http://localhost:8081/foglamp/category/PURGE/age/value
"""
category_name = request.match_info.get('category_name', None)
if not category_name or not config_item:
raise web.HTTPBadRequest(reason="Both Category Name and Config items are required")
# Todo: make it optimized and elegant
cf_mgr = ConfigurationManager(connect.get_storage())
await cf_mgr.set_category_item_value_entry(category_name, '')
result = await cf_mgr.get_category_item(category_name, config_item)
if result is None:
raise web.HTTPNotFound(reason="No detail found for the category_name: {} and config_item: {}".format(category_name, config_item))
return web.json_response(result)
def _extract_args(data, curr_value):
try:
if 'type' in data and (not isinstance(data['type'], int) and not data['type'].isdigit()):
raise ValueError('Error in type: {}'.format(data['type']))
if 'day' in data and (not isinstance(data['day'], int) and not data['day'].isdigit()):
raise ValueError('Error in day: {}'.format(data['day']))
if 'time' in data and (not isinstance(data['time'], int) and not data['time'].isdigit()):
raise ValueError('Error in time: {}'.format(data['time']))
if 'repeat' in data and (not isinstance(data['repeat'], int) and not data['repeat'].isdigit()):
raise ValueError('Error in repeat: {}'.format(data['repeat']))
_schedule = dict()
_schedule['schedule_id'] = curr_value['schedule_id'] if curr_value else None
s_type = data.get('type') if 'type' in data else curr_value['schedule_type'] if curr_value else 0
_schedule['schedule_type'] = int(s_type)
s_day = data.get('day') if 'day' in data else curr_value['schedule_day'] if curr_value and curr_value['schedule_day'] else 0
_schedule['schedule_day'] = int(s_day)
s_time = data.get('time') if 'time' in data else curr_value['schedule_time'] if curr_value and curr_value['schedule_time'] else 0
_schedule['schedule_time'] = int(s_time)
s_repeat = data.get('repeat') if 'repeat' in data else curr_value['schedule_repeat'] if curr_value and curr_value['schedule_repeat']else 0
_schedule['schedule_repeat'] = int(s_repeat)
_schedule['schedule_name'] = data.get('name') if 'name' in data else curr_value['schedule_name'] if curr_value else None
_schedule['schedule_process_name'] = data.get('process_name') if 'process_name' in data else curr_value['schedule_process_name'] if curr_value else None
_schedule['schedule_exclusive'] = data.get('exclusive') if 'exclusive' in data else curr_value['schedule_exclusive'] if curr_value else 'True'
_schedule['schedule_exclusive'] = 'True' if _schedule['schedule_exclusive'] else 'False'
except ValueError as ex:
raise web.HTTPBadRequest(reason=str(ex))
return _schedule
def get_schedule(request):
"""
Return the @R_627_4045@ion for the given schedule from schedules table
:Example: curl -X GET http://localhost:8082/foglamp/schedule/ac6dd55d-f55d-44f7-8741-984604bf2384
"""
try:
schedule_id = request.match_info.get('schedule_id', None)
if not schedule_id:
raise web.HTTPBadRequest(reason='Schedule ID is required.')
try:
assert uuid.UUID(schedule_id)
except ValueError as ex:
raise web.HTTPNotFound(reason="Invalid Schedule ID {}".format(schedule_id))
sch = await server.Server.scheduler.get_schedule(uuid.UUID(schedule_id))
schedule = {
'id': str(sch.schedule_id),
'name': sch.name,
'process_name': sch.process_name,
'type': Schedule.Type(int(sch.schedule_type)).name,
'repeat': sch.repeat.total_seconds() if sch.repeat else 0,
'time': (sch.time.hour * 60 * 60 + sch.time.minute * 60 + sch.time.second) if sch.time else 0,
'day': sch.day,
'exclusive': sch.exclusive
}
return web.json_response(schedule)
except (ValueError, ScheduleNotFoundError) as ex:
raise web.HTTPNotFound(reason=str(ex))
def start_schedule(request):
"""
Starts a given schedule
:Example: curl -X POST http://localhost:8082/foglamp/schedule/start/fd439e5b-86ba-499a-86d3-34a6e5754b5a
"""
try:
schedule_id = request.match_info.get('schedule_id', None)
if not schedule_id:
raise web.HTTPBadRequest(reason='Schedule ID is required.')
try:
assert uuid.UUID(schedule_id)
except ValueError as ex:
raise web.HTTPNotFound(reason="Invalid Schedule ID {}".format(schedule_id))
sch = await server.Server.scheduler.get_schedule(uuid.UUID(schedule_id))
# Start schedule
await server.Server.scheduler.queue_task(uuid.UUID(schedule_id))
return web.json_response({'id': schedule_id, 'message': 'Schedule started successfully'})
except (ValueError, ScheduleNotFoundError) as ex:
raise web.HTTPNotFound(reason=str(ex))
def get_task(request):
"""
Returns a task
:Example: curl -X GET http://localhost:8082/foglamp/task/{task_id}?name=xxx&state=xxx
"""
try:
task_id = request.match_info.get('task_id', None)
if not task_id:
raise web.HTTPBadRequest(reason='Task ID is required.')
try:
assert uuid.UUID(task_id)
except ValueError as ex:
raise web.HTTPNotFound(reason="Invalid Task ID {}".format(task_id))
tsk = await server.Server.scheduler.get_task(task_id)
task = {
'id': str(tsk.task_id),
'process_name': tsk.process_name,
'state': Task.State(int(tsk.state)).name,
'start_time': str(tsk.start_time),
'end_time': str(tsk.end_time),
'exit_code': tsk.exit_code,
'reason': tsk.reason
}
return web.json_response(task)
except (ValueError, TaskNotFoundError) as ex:
raise web.HTTPNotFound(reason=str(ex))
def get_service(request):
""" Returns a list of all services or of the selected service
:Example: curl -X GET http://localhost:8082/foglamp/service
:Example: curl -X GET http://localhost:8082/foglamp/service?name=X&type=Storage
"""
service_name = request.query['name'] if 'name' in request.query else None
service_type = request.query['type'] if 'type' in request.query else None
try:
if not service_name and not service_type:
services_list = Service.Instances.all()
elif service_name and not service_type:
services_list = Service.Instances.get(name=service_name)
elif not service_name and service_type:
services_list = Service.Instances.get(s_type=service_type)
else:
services_list = Service.Instances.filter_by_name_and_type(
name=service_name, s_type=service_type
)
except Service.DoesNotExist as ex:
raise web.HTTPBadRequest(reason="Invalid service name and/or type provided" + str(ex))
services = []
for service in services_list:
svc = dict()
svc["id"] = service._id
svc["name"] = service._name
svc["type"] = service._type
svc["address"] = service._address
svc["management_port"] = service._management_port
svc["protocol"] = service._protocol
svc["status"] = service._status
if service._port:
svc["service_port"] = service._port
services.append(svc)
return web.json_response({"services": services})
def from_http(self, request):
self.total = None
self.success = None
self.errors = []
self.params = None
self.output = None
self.pagination = None
self.limit = None
self.offset = None
if not isinstance(request, web.Request):
raise web.HTTPBadRequest()
self.Meta = {
'cookies': getattr(request, 'cookies', {}),
'headers': getattr(request, 'headers', {})
}
req_params = {}
# if GET or DELETE we read a query params
if request.method in (METH_GET, METH_DELETE):
req_params = self.process_request(request.GET)
# else we read a POST-data
elif request.method in (METH_PUT, METH_POST):
try:
req_params = self.process_request(await request.json())
except (ValueError, TypeError):
req_params = self.process_request(await request.post())
# Here we add or override params by PATH-params.
# If it exist
if request.match_info:
req_params.update(request.match_info.copy())
self.limit = get_int_or_none(request.headers.get('X-Limit')) or \
get_int_or_none(req_params.pop('limit', None)) or \
get_int_or_none(request.app.settings.LIMIT)
self.offset = get_int_or_none(request.headers.get('X-Offset')) or \
get_int_or_none(req_params.pop('offset', None)) or \
get_int_or_none(request.app.settings.OFFSET)
self.params = self.validate_params(req_params)
self.result = []
self.app = request.app
self.settings = request.app.settings
def __call__(self,request):
kw = None
if self._has_var_kw_arg or self._has_named_kw_args or self._required_kw_args:
if request.method == 'POST':
if not request.content_type:
return web.HTTPBadRequest(text='Missing content_type')
ct = request.content_type.lower()
if ct.startswith('application/json'):
params = await request.json()
if not isinstance(params,dict):
return web.HTTPBadRequest(text='Json body mmust be object')
kw = params
elif ct.startswith('application/x-www-form-urlencoded') or ct.startswith('multipart/form-data'):
params = await request.post()
kw = dict(**params)
else:
return web.HTTPBadRequest(text = 'Unsupported content_type:%s' % request.content_type)
if request.method == 'GET':
qs = request.query_string
if qs:
kw = dict()
for k,v in parse.parse_qs(qs,True).items():
kw[k] = v[0]
if kw is None:
kw = dict(**request.match_info)
else:
# ????????????????request????????????????
if not self._has_var_kw_arg and self._named_kw_args:
#remove all unamed kw
copy = dict()
for name in self._named_kw_args:
if name in kw:
copy[name] = kw[name]
kw = copy
#check named arg
for k,v in request.match_info.items():
if k in kw:
logging.warning('Duplicate arg name in named arg and kw args:%s' % k)
kw[k] = v
if self._has_request_arg:
kw['request'] = request
#check required kw
if self._required_kw_args:
for name in self._required_kw_args:
if not name in kw:
return web.HTTPBadRequest(text='Missing argument : %s' % name)
logging.info('call with args:%s' % str(kw))
try:
r = await self._func(**kw)
return r
except APIError as e:
raise dict(error=e.error,data=e.data,message=e.message)
#??????????
def __call__(self, request):
kw = None
if self._has_var_kw_arg or self._has_named_kw_args or self._requested_kw_args:
if request.method == 'POST':
if not request.content_type:
return web.HTTPBadRequest('Missing Content-Type')
ct = request.content_type.lower()
if ct.startswith('application/json'):
params = yield from request.json()
if not isinstance(params, dict):
return web.HTTPBadRequest('JSON body must be object.')
kw = params
elif ct.startswith('application/x-www-form-urlencoded') or ct.startswith('multipart/form-data'):
params = yield from request.post()
kw = dict(**params)
else:
return web.HTTPBadRequest('Unsupported Content-Type: {}'.format(request.content_type))
if request.method == 'GET':
qs = request.query_string
if qs:
kw = dict()
for k, True).items():
kw[k] = v[0]
if kw is None:
kw = dict(**request.match_info)
else:
if not self._has_var_kw_arg and self._named_kw_args:
#remove all unamed kw:
copy = dict()
for name in self._named_kw_args:
if name in kw:
copy[name] = kw[name]
kw = copy
#check named arg:
for k, v in request.match_info.items():
if k in kw:
logging.warning('Duplicate arg name in named arg and args:{}'.format(k))
kw[k] = v
if self._has_request_arg:
kw['request'] = request
#check required kw:
if self._requested_kw_args:
for name in self._requested_kw_args:
if not name in kw:
return web.HTTPBadRequest('Missing argument:{}'.format(name))
logging.info('call with args: {}'.format(str(kw)))
try:
r = yield from self._func(**kw)
return r
except APIError as e:
return dict(error = e.error, data = e.data, message = e.message)
def _validate_data(data, schema, validator_cls):
"""
Validate the dict against given schema (using given validator class).
"""
validator = validator_cls(schema)
_errors = defaultdict(list)
for err in validator.iter_errors(data):
path = err.schema_path
# Code courtesy: Ruslan Karalkin
# Looking in error schema path for
# property that Failed validation
# Schema example:
# {
# "type": "object",
# "properties": {
# "foo": {"type": "number"},
# "bar": {"type": "string"}
# }
# "required": ["foo","bar"]
# }
#
# Related err.schema_path examples:
# ['required'],
# ['properties','foo','type']
if "properties" in path:
path.remove("properties")
key = path.popleft()
# If validation Failed by missing property,
# then parse err.message to find property name
# as it always first word enclosed in quotes
if key == "required":
key = err.message.split("'")[1]
_errors[key].append(str(err))
if _errors:
_raise_exception(
web.HTTPBadRequest,
"Request is invalid; There are validation errors.",
_errors)
def login_handler(request):
"""Handles login requests.
We get the ticket ID from the user,the rest comes from info stored on
the session.
"""
ticket = request.GET.get('ticket')
session = await get_session(request)
redir = session[SESSION_KEY].get('redir')
login_route = request.app[APP_KEY]['LOGIN_ROUTE']
root_url = request.app[APP_KEY]['ROOT_URL']
on_success = request.app[APP_KEY]['ON_SUCCESS']
version = request.app[APP_KEY]['VERSION']
# If we're missing neccessary data,return 400 Bad Request
if not (request.scheme and request.host):
log.warn("Invalid scheme ({}) or host ({})"
.format(request.scheme, request.host))
return web.HTTPBadRequest()
# Build the service URL.
service = parse.urlunsplit(
(request.scheme, request.host,
login_route, None, None)
)
if ticket:
# Validate the ticket.
attrs = await validate(ticket, service, root_url, version)
# If it succeeds,add the returned attributes to the session.
if attrs:
log.info("Authentication suceeded for ticket ID {}".format(ticket))
session[SESSION_KEY] = attrs
# Go to the requested redirect or,failing that,
# the default "on_success" url
return web.HTTPFound(redir or on_success)
else:
# They SHALL NOT PASS
log.info("Authentication fail for ticket ID {}".format(ticket))
return web.HTTPUnauthorized()
# If we don't get a ticket (or if something else happens),redirect
# to the CAS service login.
return web.HTTPFound(cas_url('login', service=service))
def put_file(request: web.Request):
checksum = hashlib.sha1()
with tempfile.SpooledTemporaryFile(max_size=1024 * 1024) as tmpfile:
try:
while True:
chunk = yield from request._payload.read(1024)
if chunk is streams.EOF_MARKER:
break
if isinstance(chunk, asyncio.Future):
chunk = yield from asyncio.wait_for(chunk, timeout=60)
if chunk:
checksum.update(chunk)
tmpfile.write(chunk)
except asyncio.TimeoutError:
raise web.HTTPRequestTimeout()
calculated_hash = checksum.hexdigest()
if 'X-Content-SHA1' in request.headers:
client_hash = request.headers['X-Content-SHA1'].lower()
if calculated_hash != client_hash:
logger.warn('SHA1 hash mismatch: %s != %s' % (calculated_hash, client_hash))
raise web.HTTPBadRequest(text='SHA1 hash does not match')
name = request.match_info.get('name').strip()
if name in replication.dellog:
# We kNow this is already deleted
raise web.HTTPConflict(text='This file has already been deleted in the cluster.')
is_replication = request.headers['User-Agent'].startswith('cockatiel/')
filename = generate_filename(name, calculated_hash,
get_timestamp_from_name(name) if is_replication else str(int(time.time())))
filepath = os.path.join(config.args.storage, filename)
if not os.path.exists(filepath):
directory, _ = os.path.split(filepath)
os.makedirs(directory, exist_ok=True)
tmpfile.seek(0)
with open(filepath, 'wb') as f:
for chunk in chunks(tmpfile):
f.write(chunk)
logger.debug('Created file {},scheduling replication.'.format(filename))
replication.queue_operation('PUT', filename)
return web.Response(status=201, headers={
'Location': '/' + filename
})
else:
logger.debug('File {} already existed.'.format(filename))
return web.Response(status=302, headers={
'Location': '/' + filename
})
def _go(request: web.Request):
js_profiles = request.app['js-profiles']
c = request.app['chrome-driver']
url = request.query.get('url')
if not url:
return web.HTTPBadRequest(reason='no url query param provided') # Todo: match splash reply
wait_s = float(request.query.get('wait', 0))
raw_viewport = request.query.get('viewport', '1024x768')
parts = raw_viewport.split('x')
width = int(parts[0])
height = int(parts[1])
js_profile_name = request.query.get('js', None)
if js_profile_name:
profile = js_profiles.get(js_profile_name)
if not profile:
return web.HTTPBadRequest(reason='profile name is incorrect') # Todo: match splash
# Todo: potentially validate and verify js source for errors and security concerrns
js_source = request.query.get('js_source', None)
await c.connect()
tab = c.tabs[0]
cmd = page.Page.setDeviceMetricsOverride(width=width,
height=height,
deviceScaleFactor=0.0,
mobile=False)
await tab.send_command(cmd)
await tab.enable_page_events()
await tab.go(url)
await asyncio.sleep(wait_s)
if js_profile_name:
await tab.evaluate(js_profiles[js_profile_name])
if js_source:
await tab.evaluate(js_source)
return tab
def auth_middleware(app, handler):
""" Login via Github """
def gh_client(**kw):
return GithubClient(conf['github_id'], conf['github_secret'], **kw)
async def callback(request):
session = await get_session(request)
log.debug('callback: session=%s GET=%s', session, request.GET)
if session.get('github_state') != request.GET.get('state'):
return web.HTTPBadRequest()
code = request.GET.get('code')
if not code:
return web.HTTPBadRequest()
gh = gh_client()
token, _ = await gh.get_access_token(code)
gh = gh_client(access_token=token)
req = await gh.request('GET', 'user')
user = await req.json()
req.close()
users = []
for org in conf['github_orgs']:
_, resp = await gh_api('orgs/%s/members?per_page=100' % org)
users.extend(u['login'] for u in resp)
log.debug('members %s: %s', len(users), users)
if user.get('login') in users:
session['login'] = user.get('login')
session.pop('github_state', None)
session.pop('github_url', None)
location = session.pop('location')
return web.HTTPFound(location)
return web.HTTPForbidden()
async def check_auth(request):
session = await get_session(request)
login = session.get('login')
if login:
request['login'] = login
return await handler(request)
elif 'github_state' not in session:
gh = gh_client()
state = str(uuid.uuid4())
url = gh.get_authorize_url(scope='', state=state)
session['github_state'] = state
session['github_url'] = url
session['location'] = request.path
log.debug('check_auth: %s', session)
return web.HTTPFound(conf['url_prefix'] + '/login')
async def inner(request):
if request.path == (conf['url_prefix'] + conf['github_callback']):
return await callback(request)
elif request.path == (conf['url_prefix'] + '/hook'):
return await handler(request)
elif request.path == (conf['url_prefix'] + '/login'):
return await handler(request)
else:
return await check_auth(request)
return inner
def __call__(self, request):
kw = None
if self._has_var_kw_arg or self._has_named_kw_arg or self._required_kw_args:
if request.method == 'POST':
if not request.content_type:
return web.HTTPBadRequest('Missing Content-Type.')
ct = request.content_type.lower()
if ct.startswith('application/json'):
params = await request.json()
if not isinstance(params, dict):
return web.HTTPBadRequest('JSON body must be object.')
kw = params
elif ct.startswith('application/x-www-form-urlencoded') or \
ct.startswith('multipart/form-data'):
params = await request.post()
kw = dict(**params)
else:
return web.HTTPBadRequest('Unsupported Content-Type: %s' % request.content_type)
if request.method == 'GET':
qs = request.query_string
if qs:
kw = dict()
for k, True).items():
kw[k] = v[0]
if kw is None:
kw = dict(**request.match_info)
else:
if not self._has_var_kw_arg and self._named_kw_args:
# remove all unnamed kw
copy = dict()
for name in self._named_kw_args:
if name in kw:
copy[name] = kw[name]
kw = copy
# check named arg
for k, v in request.match_info.items():
if k in kw:
logging.warning('Duplicate arg name in named arg and kw args: %s' % k)
kw[k] = v
if self._has_request_arg:
kw['request'] = request
# check required kw
if self._required_kw_args:
for name in self._required_kw_args:
if name not in kw:
return web.HTTPBadRequest('Missing argument: %s' % name)
logging.info('call with args: %s' % str(kw))
try:
r = await self._func(**kw)
return r
except APIError as e:
return dict(error=e.error, data=e.data, message=e.message)
def __call__(self, request):
kw = None
if self._has_var_kw_arg or self._has_named_kw_args or self._required_kw_args:
if request.method == 'POST':
if not request.content_type:
return web.HTTPBadRequest('Missing Content-Type.')
ct = request.content_type.lower()
if ct.startswith('application/json'):
params = yield from request.json()
if not isinstance(params, dict):
return web.HTTPBadRequest('JSON body must be object.')
kw = params
elif ct.startswith('application/x-www-form-urlencoded') or ct.startswith('multipart/form-data'):
params = yield from request.post()
kw = dict(**params)
else:
return web.HTTPBadRequest('Unsupported Content-Type: %s' % request.content_type)
if request.method == 'GET':
qs = request.query_string
if qs:
kw = dict()
for k, True).items():
kw[k] = v[0]
if kw is None:
kw = dict(**request.match_info)
else:
if not self._has_var_kw_arg and self._named_kw_args:
# remove all unamed kw:
copy = dict()
for name in self._named_kw_args:
if name in kw:
copy[name] = kw[name]
kw = copy
# check named arg:
for k, v in request.match_info.items():
if k in kw:
logging.warning('Duplicate arg name in named arg and kw args: %s' % k)
kw[k] = v
if self._has_request_arg:
kw['request'] = request
# check required kw:
if self._required_kw_args:
for name in self._required_kw_args:
if not name in kw:
return web.HTTPBadRequest('Missing argument: %s' % name)
logging.info('call with args: %s' % str(kw))
try:
r = yield from self._func(**kw)
return r
except APIError as e:
return dict(error=e.error, message=e.message)
def __call__(self, request):
kw = None
if self._has_var_kw_arg or self._has_named_kw_args or self._required_kw_args:
if request.method == 'POST':
if not request.content_type:
return web.HTTPBadRequest('Missing Content Type.')
ct = request.content_type.lower()
if ct.startswith('application/json'):
params = await request.json()
if not isinstance(params, dict):
return web.HTTPBadRequest('JSON body must be object.')
kw = params
elif ct.startswith('application/x-www-form-urlencoded') or ct.startswith('multipart/form-data'):
params = await request.post()
kw = dict(**params)
else:
return web.HTTPBadRequest('Unsupported Content-Type: %s' % request.content_type)
if request.method == 'GET':
qs = request.query_string
if qs:
kw = dict()
for k, v in request.match_info.items():
if k in kw:
logging.warning('Duplicate arg name in named arg and kw args: %s' % k)
kw[k] = v
if self._has_request_arg:
kw['request'] = request
# check required kw:
if self._required_kw_args:
for name in self._required_kw_args:
if not name in kw:
return web.HTTPBadRequest('Missing argument: %s' % name)
logging.info('call with args: %s' % str(kw))
try:
r = await self._func(**kw)
return r
except APIError as e:
return dict(error=e.error, message=e.message)
def __call__(self, request):
kw = None
if self._has_var_kw_arg or self._has_named_kw_args:
if request.method == 'POST':
if not request.content_type:
return web.HTTPBadRequest('Missing Content-Type.')
ct = request.content_type.lower()
if ct.startswith('application/json'):
params = await request.json()
if not isinstance(params, dict):
return web.HTTPBadRequest('JSON body must be object.')
kw = params
elif ct.startswith('multipart/form-data'):
params = await request.post()
kwAndFile = dict(**params)
if kwAndFile.get('packet') is None:
return web.HTTPBadRequest('packet is None')
packet = unquote(kwAndFile.get('packet'))
kw = json.loads(packet)
kwAndFile.pop('packet')
kw['file'] = kwAndFile
else:
return web.HTTPBadRequest('Unsupported Content-Type: %s' % request.content_type)
if request.method == 'GET':
qs = request.query_string
if qs:
kw = dict()
for k, True).items():
kw[k] = v[0]
if kw is None:
kw = dict(**request.match_info)
else:
if not self._has_var_kw_arg and self._has_named_kw_args:
copy = dict()
for name in self._named_kw_args:
if name in kw:
copy[name] = kw[name]
kw = copy
if self._has_request_arg:
kw['request'] = request
if self._required_kw_args:
for name in self._required_kw_args:
if not name in kw:
return web.HTTPBadRequest('Missing argument: %s' % name)
logging.info('call with args: %s' % str(kw))
logging.info('%s RequestHandlerC call start next handler %s ' % (request.__uuid__, self._fn))
r = await self._fn(**kw)
logging.info('%s RequestHandlerC call end ' % (request.__uuid__))
return r
def update_schedule(request):
"""
Update a schedule in schedules table
:Example: curl -d '{"type": 4,"name": "sleep30 updated","process_name": "sleep30","repeat": "15"}' -X PUT http://localhost:8082/foglamp/schedule/84fe4ea1-df9c-4c87-bb78-cab2e7d5d2cc
"""
try:
data = await request.json()
schedule_id = request.match_info.get('schedule_id', None)
if not schedule_id:
raise web.HTTPBadRequest(reason='Schedule ID is required.')
try:
assert uuid.UUID(schedule_id)
except ValueError as ex:
raise web.HTTPNotFound(reason="Invalid Schedule ID {}".format(schedule_id))
sch = await server.Server.scheduler.get_schedule(uuid.UUID(schedule_id))
if not sch:
raise ValueError('No such Schedule: {}.'.format(schedule_id))
curr_value = dict()
curr_value['schedule_id'] = sch.schedule_id
curr_value['schedule_process_name'] = sch.process_name
curr_value['schedule_name'] = sch.name
curr_value['schedule_type'] = sch.schedule_type
curr_value['schedule_repeat'] = sch.repeat.total_seconds() if sch.repeat else 0
curr_value['schedule_time'] = (sch.time.hour * 60 * 60 + sch.time.minute * 60 + sch.time.second) if sch.time else 0
curr_value['schedule_day'] = sch.day
curr_value['schedule_exclusive'] = sch.exclusive
go_no_go = await _check_schedule_post_parameters(data, curr_value)
if len(go_no_go) != 0:
raise ValueError("Errors in request: {}".format(','.join(go_no_go)))
updated_schedule_id = await _execute_add_update_schedule(data, curr_value)
sch = await server.Server.scheduler.get_schedule(updated_schedule_id)
schedule = {
'id': str(sch.schedule_id),
'exclusive': sch.exclusive
}
return web.json_response({'schedule': schedule})
except (ValueError, ScheduleNotFoundError) as ex:
raise web.HTTPNotFound(reason=str(ex))
def get_tasks(request):
"""
Returns the list of tasks
:Example: curl -X GET http://localhost:8082/foglamp/task
:Example: curl -X GET http://localhost:8082/foglamp/task?name=xxx
:Example: curl -X GET http://localhost:8082/foglamp/task?state=xxx
:Example: curl -X GET http://localhost:8082/foglamp/task?name=xxx&state=xxx
"""
try:
limit = request.query.get('limit') if 'limit' in request.query else '100'
if limit:
if not re.match("(^[0-9]*$)", limit):
raise web.HTTPBadRequest(reason='This limit {} not permitted.'.format(limit))
elif int(limit) > 100:
limit = 100
else:
limit = int(limit)
state = request.query.get('state') if 'state' in request.query else None
if state:
if state.upper() not in [t.name for t in list(Task.State)]:
raise web.HTTPBadRequest(reason='This state value {} not permitted.'.format(state))
else:
z = dict()
for i in list(Task.State):
z.update({i.name: i.value})
state = z[state.upper()]
name = request.query.get('name') if 'name' in request.query else None
where_clause = None
if name and state:
where_clause = (["process_name", name], ["state", state])
elif name:
where_clause = ["process_name", name]
elif state:
where_clause = ["state", state]
tasks = await server.Server.scheduler.get_tasks(where=where_clause, limit=limit)
if len(tasks) == 0:
raise TaskNotFoundError("No Tasks")
new_tasks = []
for task in tasks:
new_tasks.append(
{'id': str(task.task_id),
'process_name': task.process_name,
'state': Task.State(int(task.state)).name,
'start_time': str(task.start_time),
'end_time': str(task.end_time),
'exit_code': task.exit_code,
'reason': task.reason
}
)
return web.json_response({'tasks': new_tasks})
except (ValueError, TaskNotFoundError) as ex:
raise web.HTTPNotFound(reason=str(ex))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。