tagreader 5.4.0__tar.gz → 6.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tagreader
3
- Version: 5.4.0
3
+ Version: 6.0.0
4
4
  Summary: Tagreader is a Python package for reading trend data from the OSIsoft PI and Aspen Infoplus.21 IMS systems.
5
5
  Home-page: https://github.com/equinor/tagreader-python
6
6
  License: MIT
@@ -26,11 +26,11 @@ Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Transla
26
26
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
27
  Classifier: Topic :: Utilities
28
28
  Provides-Extra: notebooks
29
- Requires-Dist: certifi (>=2023.7.22,<2024.0.0)
29
+ Requires-Dist: certifi (>=2024.7.4,<2025.0.0)
30
30
  Requires-Dist: diskcache (>=5.6.1,<6.0.0)
31
- Requires-Dist: matplotlib (>=3,<4) ; extra == "notebooks"
32
- Requires-Dist: msal-bearer (>=0.2.1,<1.1.0)
33
- Requires-Dist: notebook (>=7.0.3,<8.0.0) ; extra == "notebooks"
31
+ Requires-Dist: matplotlib (>=3.7.0,<4.0.0) ; extra == "notebooks"
32
+ Requires-Dist: msal-bearer (>=0.2.1,<1.2.0)
33
+ Requires-Dist: notebook (>=7.2.0,<8.0.0) ; extra == "notebooks"
34
34
  Requires-Dist: pandas (>=1)
35
35
  Requires-Dist: pycryptodome (>=3.20.0,<4.0.0)
36
36
  Requires-Dist: requests (>=2,<3)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "tagreader"
3
- version = "5.4.0"
3
+ version = "6.0.0"
4
4
  description = "Tagreader is a Python package for reading trend data from the OSIsoft PI and Aspen Infoplus.21 IMS systems."
5
5
  authors = ["Einar S. Idsø <eiids@equinor.com>", "Morten Dæhli Aslesen <masl@equinor.com"]
6
6
  license = "MIT"
@@ -30,12 +30,12 @@ classifiers=[
30
30
  [tool.poetry.dependencies]
31
31
  python = "^3.8"
32
32
  pandas = ">=1"
33
- certifi = "^2023.7.22"
33
+ certifi = "^2024.7.4"
34
34
  requests = "^2"
35
35
  requests-kerberos = "^0"
36
- msal-bearer = ">=0.2.1,<1.1.0"
37
- notebook = { version = "^7.0.3", optional = true }
38
- matplotlib = { version = "^3", optional = true }
36
+ msal-bearer = ">=0.2.1,<1.2.0"
37
+ notebook = { version = "^7.2.0", optional = true }
38
+ matplotlib = { version = "^3.7.0", optional = true }
39
39
  diskcache = "^5.6.1"
40
40
  pycryptodome = "^3.20.0"
41
41
  requests-ntlm = ">=1.1,<=2.0"
@@ -19,7 +19,7 @@ from urllib3.exceptions import InsecureRequestWarning
19
19
 
20
20
  from tagreader.cache import BucketCache, SmartCache
21
21
  from tagreader.logger import logger
22
- from tagreader.utils import ReaderType, is_mac, is_windows, urljoin
22
+ from tagreader.utils import IMSType, ReaderType, is_mac, is_windows, urljoin
23
23
 
24
24
 
25
25
  class MD4:
@@ -144,6 +144,33 @@ def list_piwebapi_sources(
144
144
  logger.error(f"Could not decode JSON response: {e}")
145
145
 
146
146
 
147
+ def get_piwebapi_source_to_webid_dict(
148
+ url: Optional[str] = None,
149
+ auth: Optional[Any] = None,
150
+ verify_ssl: Optional[bool] = True,
151
+ ) -> List[str]:
152
+ if url is None:
153
+ url = get_url_pi()
154
+
155
+ if auth is None:
156
+ auth = get_auth_pi()
157
+
158
+ if verify_ssl is None:
159
+ verify_ssl = get_verify_ssl()
160
+
161
+ if verify_ssl is False:
162
+ urllib3.disable_warnings(InsecureRequestWarning)
163
+
164
+ url_ = urljoin(url, "dataservers")
165
+ res = requests.get(url_, auth=auth, verify=verify_ssl)
166
+
167
+ res.raise_for_status()
168
+ try:
169
+ return {item["Name"]: item["WebId"] for item in res.json()["Items"]}
170
+ except JSONDecodeError as e:
171
+ logger.error(f"Could not decode JSON response: {e}")
172
+
173
+
147
174
  class BaseHandlerWeb(ABC):
148
175
  def __init__(
149
176
  self,
@@ -242,12 +269,13 @@ class AspenHandlerWeb(BaseHandlerWeb):
242
269
  tag: Optional[str],
243
270
  desc: Optional[str],
244
271
  datasource: Optional[str],
272
+ max: Optional[int] = 100000,
245
273
  ) -> Dict[str, Any]:
246
274
  if not datasource:
247
275
  raise ValueError("Data source is required argument")
248
276
  # Aspen Web API expects single space instead of consecutive spaces.
249
277
  tag = " ".join(tag.split())
250
- params = {"datasource": datasource, "tag": tag, "max": 100, "getTrendable": 0}
278
+ params = {"datasource": datasource, "tag": tag, "max": max, "getTrendable": 0}
251
279
  return params
252
280
 
253
281
  def generate_read_query(
@@ -450,7 +478,7 @@ class AspenHandlerWeb(BaseHandlerWeb):
450
478
  desc = desc.replace("*", ".*") if isinstance(desc, str) else None
451
479
 
452
480
  params = self.generate_search_query(
453
- tag=tag, desc=desc, datasource=self.datasource
481
+ tag=tag, desc=desc, datasource=self.datasource, max=100000
454
482
  )
455
483
  # Ensure space is encoded as "%20" instead of default "+" and leave asterisks
456
484
  # unencoded. Otherwise, searches for tags containing spaces break, as do wildcard
@@ -740,7 +768,7 @@ class PIHandlerWeb(BaseHandlerWeb):
740
768
  )
741
769
 
742
770
  @staticmethod
743
- def generate_search_query(
771
+ def generate_search_params(
744
772
  tag: Optional[str],
745
773
  desc: Optional[str],
746
774
  datasource: Optional[str],
@@ -751,10 +779,12 @@ class PIHandlerWeb(BaseHandlerWeb):
751
779
  if desc is not None:
752
780
  q.extend([f"description:{PIHandlerWeb.escape(desc)}"])
753
781
  query = " AND ".join(q)
754
- params = {"q": f"{query}"}
782
+ params = {"query": f"{query}"}
755
783
 
756
784
  if datasource is not None:
757
- params["scope"] = f"pi:{datasource}"
785
+ params["dataserverwebid"] = (
786
+ f"{get_piwebapi_source_to_webid_dict()[datasource]}"
787
+ )
758
788
 
759
789
  return params
760
790
 
@@ -864,23 +894,23 @@ class PIHandlerWeb(BaseHandlerWeb):
864
894
  timeout: Optional[int] = None,
865
895
  return_desc: bool = True,
866
896
  ) -> Union[List[Tuple[str, str]], List[str]]:
867
- params = self.generate_search_query(
897
+ params = self.generate_search_params(
868
898
  tag=tag, desc=desc, datasource=self.datasource
869
899
  )
870
- url = urljoin(self.base_url, "search", "query")
900
+ url = urljoin(self.base_url, "points", "search")
871
901
  done = False
872
902
  ret = []
873
903
  while not done:
874
904
  data = self.fetch(url, params=params, timeout=timeout)
875
905
 
876
906
  for item in data["Items"]:
877
- description = item["Description"] if "Description" in item else ""
907
+ description = item["Descriptor"] if "Descriptor" in item else ""
878
908
  ret.append((item["Name"], description))
879
- next_start = int(data["Links"]["Next"].split("=")[-1])
880
- if int(data["Links"]["Last"].split("=")[-1]) >= next_start:
881
- params["start"] = next_start # noqa
882
- else:
883
- done = True
909
+ # next_start = int(data["Links"]["Next"].split("=")[-1])
910
+ # if int(data["Links"]["Last"].split("=")[-1]) >= next_start:
911
+ # params["start"] = next_start # noqa
912
+ # else:
913
+ done = True
884
914
 
885
915
  if not return_desc:
886
916
  ret = [x[0] for x in ret]
@@ -920,17 +950,12 @@ class PIHandlerWeb(BaseHandlerWeb):
920
950
  if self.web_id_cache and tag in self.web_id_cache:
921
951
  return self.web_id_cache[tag]
922
952
 
923
- params = self.generate_search_query(
953
+ params = self.generate_search_params(
924
954
  tag=tag, datasource=self.datasource, desc=None
925
955
  )
926
- params["fields"] = "name;webid"
927
- url = urljoin(self.base_url, "search", "query")
956
+ url = urljoin(self.base_url, "points", "search")
928
957
  data = self.fetch(url, params=params)
929
958
 
930
- if len(data["Errors"]) > 0:
931
- msg = f"Received error from server when searching for WebId for {tag}: {data['Errors']}"
932
- raise ValueError(msg)
933
-
934
959
  if len(data["Items"]) > 1:
935
960
  # Compare elements and if same, return the first
936
961
  first = data["Items"][0]
File without changes
File without changes
File without changes
File without changes
File without changes