Coverage for /builds/BuildGrid/buildgrid/buildgrid/browser/app.py: 100.00%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

40 statements  

1# Copyright (C) 2021 Bloomberg LP 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# <http://www.apache.org/licenses/LICENSE-2.0> 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15import os 

16import re 

17 

18from aiohttp import web 

19from aiohttp_middlewares import cors_middleware 

20from aiohttp_middlewares.annotations import Handler, Middleware, UrlCollection 

21 

22from buildgrid.browser import rest_api, utils 

23 

24 

25def serve_client(base_path): 

26 async def _serve_client(request): 

27 if not request.match_info['path']: 

28 path = os.path.join(base_path, 'index.html') 

29 else: 

30 path = os.path.join(base_path, request.match_info['path']) 

31 if not os.path.exists(path): 

32 path = os.path.join(base_path, 'index.html') 

33 return web.FileResponse(path) 

34 return _serve_client 

35 

36 

37def cors_middleware_with_error( 

38 allow_all: bool=False, 

39 origins: UrlCollection=None, 

40 urls: UrlCollection=None 

41) -> Middleware: 

42 middleware = cors_middleware(allow_all=allow_all, origins=origins, urls=urls) 

43 

44 @web.middleware 

45 async def _middleware(request: web.Request, handler: Handler) -> web.StreamResponse: 

46 origin = request.headers.get("Origin") 

47 headers = utils.get_cors_headers(origin, origins, allow_all) 

48 try: 

49 return await middleware(request, handler) 

50 

51 except web.HTTPNotFound: 

52 raise web.HTTPNotFound(headers=headers) 

53 

54 except web.HTTPBadRequest: 

55 raise web.HTTPBadRequest(headers=headers) 

56 

57 except web.HTTPInternalServerError: 

58 raise web.HTTPInternalServerError(headers=headers) 

59 return _middleware 

60 

61 

62def create_app(context, cors_origins, static_path=None, allow_cancelling_operations=False, tarball_dir=None): 

63 allow_all = len(cors_origins) == 0 

64 app = web.Application( 

65 middlewares=( 

66 cors_middleware_with_error(allow_all=allow_all, 

67 origins=cors_origins, 

68 urls=[re.compile(r'^\/api')]), 

69 ) 

70 ) 

71 routes = [ 

72 web.get('/api/v1/operations', rest_api.list_operations_handler(context)), 

73 web.get('/api/v1/operations/{name}', rest_api.get_operation_handler(context)), 

74 web.get( 

75 '/api/v1/operations/{name}/request_metadata', 

76 rest_api.get_operation_request_metadata_handler(context) 

77 ), 

78 web.get('/api/v1/action_results/{hash}/{size_bytes}', rest_api.get_action_result_handler(context)), 

79 web.get( 

80 '/api/v1/blobs/{hash}/{size_bytes}', 

81 rest_api.get_blob_handler(context, allow_all=allow_all, allowed_origins=cors_origins) 

82 ), 

83 web.get( 

84 '/api/v1/tarballs/{hash}_{size_bytes}.tar.gz', 

85 rest_api.get_tarball_handler( 

86 context, 

87 allow_all=allow_all, 

88 allowed_origins=cors_origins, 

89 tarball_dir=tarball_dir 

90 ) 

91 ), 

92 web.get('/ws/logstream', rest_api.logstream_handler(context)) 

93 ] 

94 

95 if allow_cancelling_operations: 

96 routes.append(web.delete('/api/v1/operations/{name}', rest_api.cancel_operation_handler(context))) 

97 

98 if static_path is not None: 

99 routes.append(web.get('/{path:.*}', serve_client(static_path))) 

100 app.add_routes(routes) 

101 return app