1+ # -------------------------------------------------------------------------
2+ # Copyright (c) PTC Inc. and/or all its affiliates. All rights reserved.
3+ # See License.txt in the project root for
4+ # license information.
5+ # --------------------------------------------------------------------------
6+
7+
8+ r"""`profile` exposes an API to allow modifications (add, delete, modify) to
9+ profile objects for the UDD Profile Library plug-in within the Kepware Configuration API
10+ """
11+
12+ from kepconfig import connection
13+ from typing import Union
14+
15+ PROFILE_ROOT = '/project/_profile_library/profiles'
16+
17+ def add_profile (server : connection .server , DATA : Union [dict , list ]) -> Union [bool , list ]:
18+ '''Add a "profile" or a list of "profile" objects to the UDD Profile Library plug-in for Kepware.
19+
20+ Additionally it can be used to pass a list of exchanges and it's children to be added all at once.
21+
22+ INPUTS:
23+
24+ "server" - instance of the "server" class
25+
26+ "DATA" - properly JSON object (dict) of the exchange and it's children
27+ expected by Kepware Configuration API
28+
29+ RETURNS:
30+
31+ True - If a "HTTP 201 - Created" is received from Kepware
32+
33+ List - If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all
34+ exchanges added that failed.
35+
36+ False - If a non-expected "2xx successful" code is returned
37+
38+
39+ EXCEPTIONS:
40+
41+ KepHTTPError - If urllib provides an HTTPError
42+ KepURLError - If urllib provides an URLError
43+ '''
44+
45+ r = server ._config_add (f'{ server .url } { PROFILE_ROOT } ' , DATA )
46+ if r .code == 201 : return True
47+ elif r .code == 207 :
48+ errors = []
49+ for item in r .payload :
50+ if item ['code' ] != 201 :
51+ errors .append (item )
52+ return errors
53+ else : return False
54+
55+ def del_profile (server : connection .server , profile_name : str ) -> bool :
56+ '''Delete a "profile" object in UDD Profile Library plug-in for Kepware.
57+
58+ INPUTS:
59+
60+ "server" - instance of the "server" class
61+
62+ "profile_name" - name of profile
63+
64+ RETURNS:
65+
66+ True - If a "HTTP 200 - OK" is received from Kepware
67+
68+ EXCEPTIONS:
69+
70+ KepHTTPError - If urllib provides an HTTPError
71+ KepURLError - If urllib provides an URLError
72+ '''
73+
74+ r = server ._config_del (f'{ server .url } { PROFILE_ROOT } /{ profile_name } ' )
75+ if r .code == 200 : return True
76+ else : return False
77+
78+ def modify_profile (server : connection .server , DATA : dict , profile_name : str = None , force : bool = False ) -> bool :
79+ '''Modify a profile object and it's properties in Kepware. If a "profile_name" is not provided as an input,
80+ you need to identify the profile in the 'common.ALLTYPES_NAME' property field in the "DATA". It will
81+ assume that is the profile that is to be modified.
82+
83+ INPUTS:
84+
85+ "server" - instance of the "server" class
86+
87+ "DATA" - properly JSON object (dict) of the exchange properties to be modified.
88+
89+ "profile_name" (optional) - name of exchange to modify. Only needed if not existing in "DATA"
90+
91+ "force" (optional) - if True, will force the configuration update to the Kepware server
92+
93+ RETURNS:
94+
95+ True - If a "HTTP 200 - OK" is received from Kepware
96+
97+ EXCEPTIONS:
98+
99+ KepHTTPError - If urllib provides an HTTPError
100+ KepURLError - If urllib provides an URLError
101+ '''
102+
103+ profile_data = server ._force_update_check (force , DATA )
104+ if profile_name == None :
105+ try :
106+ r = server ._config_update (f"{ server .url } { PROFILE_ROOT } /{ profile_data ['common.ALLTYPES_NAME' ]} " , profile_data )
107+ if r .code == 200 : return True
108+ else : return False
109+ except KeyError as err :
110+ print ('Error: No profile identified in DATA | Key Error: {}' .format (err ))
111+ return False
112+ # except Exception as e:
113+ # return 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e))
114+ else :
115+ r = server ._config_update (f'{ server .url } { PROFILE_ROOT } /{ profile_name } ' , profile_data )
116+ if r .code == 200 : return True
117+ else : return False
118+
119+ def get_profile (server : connection .server , profile_name : str = None ) -> Union [dict , list ]:
120+ '''Returns the properties of the profile object or a list of all profiles and their
121+ properties. Returned object is JSON.
122+
123+ INPUTS:
124+
125+ "server" - instance of the "server" class
126+
127+ "profile_name" - (optional) name of exchange. If not defined, get all profiles
128+
129+ RETURNS:
130+
131+ JSON - data for the exchange requested or a list of exchanges and their properties
132+
133+ EXCEPTIONS:
134+
135+ KepHTTPError - If urllib provides an HTTPError
136+ KepURLError - If urllib provides an URLError
137+ '''
138+ if profile_name == None :
139+ r = server ._config_get (f'{ server .url } { PROFILE_ROOT } ' )
140+ else :
141+ r = server ._config_get (f'{ server .url } { PROFILE_ROOT } /{ profile_name } ' )
142+ return r .payload
143+
144+ def get_all_profiles (server : connection .server ):
145+ '''Returns list of all profile objects and their properties. Returned object is JSON list.
146+
147+ INPUTS:
148+
149+ "server" - instance of the "server" class
150+
151+ RETURNS:
152+
153+ List - list of all profiles in the Profile Library
154+
155+ EXCEPTIONS:
156+
157+ KepHTTPError - If urllib provides an HTTPError
158+ KepURLError - If urllib provides an URLError
159+ '''
160+ return get_profile (server )
0 commit comments