Coverage for webapp/integrations/views.py: 38%

55 statements  

« prev     ^ index     » next       coverage.py v7.16.1, created at 2026-09-18 22:11 +0000

1from datetime import datetime 

2from flask import ( 

3 Blueprint, 

4 render_template, 

5 abort, 

6) 

7from flask.json import jsonify 

8 

9from redis_cache.cache_utility import redis_cache 

10from webapp.integrations.logic import interface_logic 

11from webapp.observability.utils import trace_function 

12from webapp.store_api import publisher_gateway 

13 

14 

15integrations = Blueprint( 

16 "integrations", 

17 __name__, 

18 template_folder="/templates", 

19 static_folder="/static", 

20) 

21 

22 

23@trace_function 

24@integrations.route("/integrations.json") 

25def interfaces_json(): 

26 interfaces = interface_logic.get_interfaces() 

27 

28 response = { 

29 "interfaces": interfaces, 

30 "size": len(interfaces), 

31 } 

32 

33 return response 

34 

35 

36@trace_function 

37@integrations.route("/integrations") 

38def all_interfaces(): 

39 interfaces = interface_logic.get_interfaces() 

40 context = {"interfaces": interfaces} 

41 return render_template("interfaces/index.html", **context) 

42 

43 

44def fetch_interface_details(interface_name): 

45 key = f"get-interface-details:{interface_name}" 

46 interface_details = redis_cache.get(key, expected_type=dict) 

47 if interface_details: 

48 return interface_details 

49 

50 other_requirers = publisher_gateway.find(requires=[interface_name]).get( 

51 "results", [] 

52 ) 

53 other_providers = publisher_gateway.find(provides=[interface_name]).get( 

54 "results", [] 

55 ) 

56 

57 res = { 

58 "other_charms": { 

59 "providers": other_providers, 

60 "requirers": other_requirers, 

61 } 

62 } 

63 

64 interface = interface_logic.get_interface_from_path(interface_name) 

65 if interface is None: 

66 if other_providers or other_requirers: 

67 return res 

68 return None 

69 

70 readme_path = ( 

71 f"interfaces/{interface_name}/interface/v{interface['version']}/README.md" 

72 ) 

73 readme_contentfile = interface_logic.repo.get_contents(readme_path) 

74 readme = readme_contentfile.decoded_content.decode("utf-8") 

75 last_modified = datetime.strptime( 

76 readme_contentfile.last_modified, "%a, %d %b %Y %H:%M:%S %Z" 

77 ).isoformat() 

78 

79 res.update( 

80 { 

81 "body": interface_logic.convert_readme( 

82 interface_name, f"v{interface['version']}", readme, 2 

83 ), 

84 "name": interface_logic.get_interface_name_from_readme(readme), 

85 "charms": { 

86 "providers": interface["providers"], 

87 "requirers": interface["requirers"], 

88 }, 

89 "last_modified": last_modified, 

90 "status": interface["status"], 

91 "version": interface["version"], 

92 } 

93 ) 

94 redis_cache.set(key, res, ttl=86400) 

95 return res 

96 

97 

98@trace_function 

99@integrations.route("/integrations/<path:path>") 

100def get_single_interface(path): 

101 interface_data = fetch_interface_details(path) 

102 

103 if interface_data is None: 

104 return abort(404) 

105 

106 context = {"interface": interface_data} 

107 return render_template("interfaces/index.html", **context) 

108 

109 

110@trace_function 

111@integrations.route("/integrations/<interface_name>.json") 

112def get_single_interface_json(interface_name): 

113 interface_data = fetch_interface_details(interface_name) 

114 

115 if interface_data is None: 

116 return jsonify({"error": "Interface not found"}), 404 

117 

118 return jsonify(interface_data)