iris-pex-embedded-python 3.5.1b4__py3-none-any.whl → 3.5.2__py3-none-any.whl

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.

Potentially problematic release.


This version of iris-pex-embedded-python might be problematic. Click here for more details.

iop/_cli.py CHANGED
@@ -147,7 +147,7 @@ class Command:
147
147
  if migrate_path is not None:
148
148
  if not os.path.isabs(migrate_path):
149
149
  migrate_path = os.path.join(os.getcwd(), migrate_path)
150
- _Utils.migrate(migrate_path)
150
+ _Utils.migrate_remote(migrate_path)
151
151
 
152
152
  def _handle_log(self) -> None:
153
153
  if self.args.log == 'not_set':
iop/_remote.py ADDED
@@ -0,0 +1,91 @@
1
+ # This module provides a REST API for remote I/O operations
2
+ # It uses Flask to handle incoming requests and route them to the appropriate I/O functions
3
+ # It should be able to help the migrate command of IoP Cli to work remotely:
4
+ # this means copy all the .py files from the current directory of (settings.py) to the remote server
5
+ # and run the api migrate from the remote server
6
+ # the default folder is based on the NAMESPACE variable in settings.py
7
+ from flask import Flask, request, jsonify
8
+
9
+ @app.route('/remote_io', methods=['POST'])
10
+ def remote_io():
11
+ data = request.json
12
+ if not data or 'operation' not in data:
13
+ return jsonify({'error': 'Invalid request'}), 400
14
+
15
+ operation = data['operation']
16
+ # Here you would implement the logic to handle the operation
17
+ # For example, you could call a function that performs the I/O operation
18
+ # and return the result as JSON.
19
+
20
+ # Placeholder response for demonstration purposes
21
+ response = {'status': 'success', 'operation': operation}
22
+ return jsonify(response), 200
23
+
24
+ # ClassMethod UploadPackage(
25
+ # namespace As %String,
26
+ # body As %DynamicArray) As %DynamicObject
27
+ # {
28
+ # // check for namespace existence and user permissions against namespace
29
+ # If '..NamespaceCheck(namespace) {
30
+ # Return ""
31
+ # }
32
+ # New $NAMESPACE
33
+ # Set $NAMESPACE = namespace
34
+
35
+ # //Create directory for custom packages
36
+ # Do ##class(%ZHSLIB.HealthShareMgr).GetDBNSInfo(namespace,.out)
37
+ # Set customPackagesPath = ##class(%Library.File).NormalizeDirectory("fhir_packages", out.globalsDatabase.directory)
38
+ # If '##class(%Library.File).DirectoryExists(customPackagesPath) {
39
+ # If '##class(%Library.File).CreateDirectory(customPackagesPath) {
40
+ # $$$ThrowStatus($$$ERROR($$$DirectoryCannotCreate, customPackagesPath))
41
+ # }
42
+ # }
43
+
44
+ # //Find package name
45
+ # Set iterator = body.%GetIterator()
46
+ # Set packageName = ""
47
+ # While iterator.%GetNext(, .fileObject ) {
48
+ # If fileObject.name = "package.json" {
49
+ # Set packageName = fileObject.data.name_"@"_fileObject.data.version
50
+ # }
51
+ # }
52
+ # If packageName = "" {
53
+ # Do ..%ReportRESTError($$$HTTP400,$$$ERROR($$$HSFHIRErrPackageNotFound))
54
+ # Return ""
55
+ # }
56
+
57
+ # Set packagePath = ##class(%Library.File).NormalizeDirectory(packageName, customPackagesPath)
58
+ # // If the package already exists then we must be meaning to re-load it. Delete files/directory/metadata and recreate fresh.
59
+ # If ##class(%Library.File).DirectoryExists(packagePath) {
60
+ # If '##class(%Library.File).RemoveDirectoryTree(packagePath) {
61
+ # $$$ThrowStatus($$$ERROR($$$DirectoryPermission , packagePath))
62
+ # }
63
+ # }
64
+ # If '##class(%Library.File).CreateDirectory(packagePath) {
65
+ # $$$ThrowStatus($$$ERROR($$$DirectoryCannotCreate, customPackagesPath))
66
+ # }
67
+ # Set pkg = ##class(HS.FHIRMeta.Storage.Package).FindById(packageName)
68
+ # If $ISOBJECT(pkg) {
69
+ # // Will fail and throw if the package is in-use or has dependencies preventing it from being deleted.
70
+ # Do ##class(HS.FHIRServer.ServiceAdmin).DeleteMetadataPackage(packageName)
71
+ # }
72
+ # Kill pkg
73
+
74
+ # //Unpack JSON objects
75
+ # Set iterator = body.%GetIterator()
76
+ # While iterator.%GetNext(.key , .fileObject ) {
77
+ # Set fileName = ##class(%Library.File).NormalizeFilename(fileObject.name,packagePath)
78
+ # Set fileStream = ##class(%Stream.FileCharacter).%New()
79
+ # Set fileStream.TranslateTable = "UTF8"
80
+ # $$$ThrowOnError(fileStream.LinkToFile(fileName))
81
+ # Do fileObject.data.%ToJSON(.fileStream)
82
+ # $$$ThrowOnError(fileStream.%Save())
83
+ # }
84
+
85
+ # //Import package
86
+ # Do ##class(HS.FHIRMeta.Load.NpmLoader).importPackages(packagePath)
87
+ # Set pkg = ..GetOnePackage(packageName, namespace)
88
+ # Do ..%SetStatusCode($$$HTTP201)
89
+ # Do ..%SetHeader("location", %request.Application _ "packages/" _ packageName _ "?namespace=" _ namespace)
90
+ # Return pkg
91
+ # }
iop/_utils.py CHANGED
@@ -6,14 +6,24 @@ import importlib.resources
6
6
  import json
7
7
  import inspect
8
8
  import ast
9
- from typing import Any, Dict, Optional, Union, Tuple
9
+ from typing import Any, Dict, Optional, Union, Tuple, TypedDict
10
10
 
11
11
  import xmltodict
12
+ import requests
12
13
  from pydantic import TypeAdapter
13
14
 
14
15
  from . import _iris
15
16
  from ._message import _Message, _PydanticMessage
16
17
 
18
+ class RemoteSettings(TypedDict, total=False):
19
+ """Typed dictionary for remote migration settings."""
20
+ url: str # Required: the host url to connect to
21
+ namespace: str # Optional: the namespace to use (default: 'USER')
22
+ package: str # Optional: the package to use (default: 'python')
23
+ remote_folder: str # Optional: the folder to use (default: '')
24
+ username: str # Optional: the username to use to connect (default: '')
25
+ password: str # Optional: the password to use to connect (default: '')
26
+
17
27
  class _Utils():
18
28
  @staticmethod
19
29
  def raise_on_error(sc):
@@ -250,6 +260,83 @@ class _Utils():
250
260
 
251
261
  return module
252
262
 
263
+ @staticmethod
264
+ def migrate_remote(filename=None):
265
+ """
266
+ Read a settings file from the filename
267
+ If the settings.py file has a key 'REMOTE_SETTINGS' then it will use the value of that key
268
+ as the remote host to connect to.
269
+ the REMOTE_SETTINGS is a RemoteSettings dictionary with the following keys:
270
+ * 'url': the host url to connect to (mandatory)
271
+ * 'namespace': the namespace to use (optional, default is 'USER')
272
+ * 'package': the package to use (optional, default is 'python')
273
+ * 'remote_folder': the folder to use (optional, default is '')
274
+ * 'username': the username to use to connect (optional, default is '')
275
+ * 'password': the password to use to connect (optional, default is '')
276
+
277
+ The remote host is a rest API that will be used to register the components
278
+ The payload will be a json object with the following keys:
279
+ * 'namespace': the namespace to use
280
+ * 'package': the package to use
281
+ * 'body': the body of the request, it will be a json object with the following keys:
282
+ * 'name': name of the file
283
+ * 'data': the data of the file, it will be an UTF-8 encoded string
284
+
285
+ 'body' will be constructed with all the files in the folder if the folder is not empty else use root folder of settings.py
286
+ """
287
+ settings, path = _Utils._load_settings(filename)
288
+ remote_settings: Optional[RemoteSettings] = getattr(settings, 'REMOTE_SETTINGS', None) if settings else None
289
+
290
+ if not remote_settings:
291
+ _Utils.migrate(filename)
292
+ return
293
+
294
+ # Validate required fields
295
+ if 'url' not in remote_settings:
296
+ raise ValueError("REMOTE_SETTINGS must contain 'url' field")
297
+
298
+ # prepare the payload with defaults
299
+ payload = {
300
+ 'namespace': remote_settings.get('namespace', 'USER'),
301
+ 'package': remote_settings.get('package', 'python'),
302
+ 'remote_folder': remote_settings.get('remote_folder', ''),
303
+ 'body': []
304
+ }
305
+
306
+ # get the folder to register
307
+ folder = _Utils._get_folder_path(filename, path)
308
+
309
+ # iterate over all files in the folder
310
+ for root, _, files in os.walk(folder):
311
+ for file in files:
312
+ if file.endswith('.py') or file.endswith('.cls'):
313
+ file_path = os.path.join(root, file)
314
+ relative_path = os.path.relpath(file_path, folder)
315
+ # Normalize path separators for cross-platform compatibility
316
+ relative_path = relative_path.replace(os.sep, '/')
317
+ with open(file_path, 'r', encoding='utf-8') as f:
318
+ data = f.read()
319
+ payload['body'].append({
320
+ 'name': relative_path,
321
+ 'data': data
322
+ })
323
+
324
+ # send the request to the remote settings
325
+ response = requests.put(
326
+ url=f"{remote_settings['url']}/api/iop/migrate",
327
+ json=payload,
328
+ headers={
329
+ 'Content-Type': 'application/json',
330
+ 'Accept': 'application/json'
331
+ },
332
+ auth=(remote_settings.get('username', ''), remote_settings.get('password', '')),
333
+ timeout=10
334
+ )
335
+
336
+ print(f"Response from remote migration: {response.text}")
337
+
338
+ response.raise_for_status() # Raise an error for bad responses
339
+
253
340
  @staticmethod
254
341
  def migrate(filename=None):
255
342
  """
@@ -265,43 +352,96 @@ class _Utils():
265
352
  * SCHEMAS
266
353
  List of classes
267
354
  """
268
- path = None
269
- # try to load the settings file
355
+ settings, path = _Utils._load_settings(filename)
356
+
357
+ _Utils._register_settings_components(settings, path)
358
+
359
+ _Utils._cleanup_sys_path(path)
360
+
361
+ @staticmethod
362
+ def _load_settings(filename):
363
+ """Load settings module from file or default location.
364
+
365
+ Returns:
366
+ tuple: (settings_module, path_added_to_sys)
367
+ """
368
+ path_added = None
369
+
270
370
  if filename:
271
371
  # check if the filename is absolute or relative
272
- if os.path.isabs(filename):
273
- path = os.path.dirname(filename)
274
- else:
372
+ if not os.path.isabs(filename):
275
373
  raise ValueError("The filename must be absolute")
374
+
276
375
  # add the path to the system path to the beginning
277
- sys.path.insert(0,os.path.normpath(path))
376
+ path_added = os.path.normpath(os.path.dirname(filename))
377
+ sys.path.insert(0, path_added)
278
378
  # import settings from the specified file
279
- settings = _Utils.import_module_from_path('settings',filename)
379
+ settings = _Utils.import_module_from_path('settings', filename)
280
380
  else:
281
381
  # import settings from the settings module
282
- import settings # type: ignore
283
- # get the path of the settings file
284
- path = os.path.dirname(inspect.getfile(settings))
382
+ import settings # type: ignore
383
+
384
+ return settings, path_added
385
+
386
+ @staticmethod
387
+ def _get_folder_path(filename, path_added_to_sys):
388
+ """Get the folder path for migration operations.
389
+
390
+ Args:
391
+ filename: Original filename parameter
392
+ path_added_to_sys: Path that was added to sys.path
393
+
394
+ Returns:
395
+ str: Folder path to use for migration
396
+ """
397
+ if filename:
398
+ return os.path.dirname(filename)
399
+ else:
400
+ return os.getcwd()
401
+
402
+ @staticmethod
403
+ def _register_settings_components(settings, path):
404
+ """Register all components from settings (classes, productions, schemas).
405
+
406
+ Args:
407
+ settings: Settings module containing CLASSES, PRODUCTIONS, SCHEMAS
408
+ path: Base path for component registration
409
+ """
410
+ # Use settings file location if path not provided
411
+ if not path:
412
+ path = os.path.dirname(inspect.getfile(settings))
413
+
285
414
  try:
286
415
  # set the classes settings
287
- _Utils.set_classes_settings(settings.CLASSES,path)
416
+ _Utils.set_classes_settings(settings.CLASSES, path)
288
417
  except AttributeError:
289
418
  print("No classes to register")
419
+
290
420
  try:
291
421
  # set the productions settings
292
- _Utils.set_productions_settings(settings.PRODUCTIONS,path)
422
+ _Utils.set_productions_settings(settings.PRODUCTIONS, path)
293
423
  except AttributeError:
294
424
  print("No productions to register")
425
+
295
426
  try:
296
427
  # set the schemas
297
428
  for cls in settings.SCHEMAS:
298
429
  _Utils.register_message_schema(cls)
299
430
  except AttributeError:
300
431
  print("No schemas to register")
301
- try:
302
- sys.path.remove(os.path.normpath(path))
303
- except ValueError:
304
- pass
432
+
433
+ @staticmethod
434
+ def _cleanup_sys_path(path):
435
+ """Remove path from sys.path if it was added.
436
+
437
+ Args:
438
+ path: Path to remove from sys.path
439
+ """
440
+ if path:
441
+ try:
442
+ sys.path.remove(os.path.normpath(path))
443
+ except ValueError:
444
+ pass
305
445
 
306
446
  @staticmethod
307
447
  def import_module_from_path(module_name, file_path):
@@ -0,0 +1,49 @@
1
+ Class IOP.Projection Extends %Projection.AbstractProjection
2
+ {
3
+
4
+ /// Projection to make install on compile
5
+ Projection Reference As Projection;
6
+
7
+ /// Call of the projection
8
+ ClassMethod CreateProjection(
9
+ cls As %String,
10
+ ByRef params) As %Status
11
+ {
12
+ set tSC = $$$OK
13
+ set tCurrentNamespace = $Namespace
14
+
15
+ Try {
16
+ set $NAMESPACE = "%SYS"
17
+ // Create a new Web App for IOP Remote Handler
18
+ set webName = "/api/iop"
19
+ set webProperties("NameSpace") = tCurrentNamespace
20
+ set webProperties("Enabled") = 1
21
+ set webProperties("DispatchClass") = "IOP.Service.Remote.Handler"
22
+ set webProperties("AutheEnabled") = 32
23
+ set webProperties("ServeFiles")=2
24
+ set webProperties("Recurse")=1
25
+ if ##class(Security.Applications).Exists(webName) {
26
+ // If the web application already exists, delete it first
27
+ $$$ThrowOnError(##class(Security.Applications).Delete(webName))
28
+ }
29
+ $$$ThrowOnError(##class(Security.Applications).Create(webName, .webProperties))
30
+ }
31
+ Catch ex {
32
+
33
+ Write !,"Error creating web application: ", ex.DisplayString(), !
34
+
35
+ }
36
+
37
+ znspace tCurrentNamespace
38
+ Return tSC
39
+ }
40
+
41
+ ClassMethod RemoveProjection(
42
+ cls As %String,
43
+ ByRef params,
44
+ recompile As %Boolean) As %Status
45
+ {
46
+ Quit $$$OK
47
+ }
48
+
49
+ }
@@ -0,0 +1,30 @@
1
+ Class IOP.Service.Remote.Handler Extends %CSP.REST
2
+ {
3
+
4
+ Parameter CHARSET = "utf-8";
5
+
6
+ Parameter CONVERTINPUTSTREAM = 1;
7
+
8
+ Parameter CONTENTTYPE = "application/json";
9
+
10
+ /// This parameter influences the CORS support. The default is an empty string meaning 'not specified'.
11
+ /// If set to true (1) then CORS processing is ON. If set to false (0) then CORS processing is OFF.
12
+ /// If left unset "" then the decision to process CORS is delegated to the setting on the URL map route.
13
+ Parameter HandleCorsRequest = 1;
14
+
15
+ Parameter UseSession As Integer = 0;
16
+
17
+ /// Ignore any writes done directly by the REST method.
18
+ Parameter IgnoreWrites = 0;
19
+
20
+ XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
21
+ {
22
+ <Routes>
23
+ <!-- Iop Management -->
24
+ <Map Prefix="/v1" Forward="IOP.Service.Remote.Rest.v1"/>
25
+ <!-- make the default forward to the highest current version of the API -->
26
+ <Map Prefix="/*" Forward="IOP.Service.Remote.Rest.v1"/>
27
+ </Routes>
28
+ }
29
+
30
+ }
@@ -0,0 +1,97 @@
1
+ Class IOP.Service.Remote.Rest.v1 Extends %CSP.REST
2
+ {
3
+
4
+ XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
5
+ {
6
+ <Routes>
7
+ <Route Url="/migrate" Method="PUT" Call="PutMigrate"/>
8
+ <Route Url="/version" Method="GET" Call="GetVersion"/>
9
+ </Routes>
10
+ }
11
+
12
+ ClassMethod GetVersion() As %String
13
+ {
14
+ // Return the version of the IOP service
15
+ Return {
16
+ "version": "1.0.0",
17
+ "description": "Interoperability Embedded Python Service API"
18
+ }.%ToJSON()
19
+ }
20
+
21
+ ClassMethod NamespaceCheck(pNamespace As %String) As %Boolean [ Internal, Private ]
22
+ {
23
+ If '##class(%SYS.Namespace).Exists(pNamespace) {
24
+ throw $$$ERROR("NamespaceDoesNotExist")
25
+ }
26
+ Return 1
27
+ }
28
+
29
+ ClassMethod PutMigrate() As %DynamicObject
30
+ {
31
+ Try {
32
+ // Get the request body
33
+ set dyna = {}.%FromJSON(%request.Content)
34
+ set body = dyna.%Get("body")
35
+ set namespace = dyna.%Get("namespace")
36
+ set targetDirectory = dyna.%Get("remote_folder")
37
+ set packageName = dyna.%Get("package")
38
+ // check for namespace existence and user permissions against namespace
39
+ If '..NamespaceCheck(namespace) {
40
+ Return ""
41
+ }
42
+ New $NAMESPACE
43
+ Set $NAMESPACE = namespace
44
+
45
+
46
+ //Create directory for custom packages
47
+ If targetDirectory '= "" {
48
+ If '##class(%Library.File).DirectoryExists(targetDirectory) {
49
+ If '##class(%Library.File).CreateDirectory(targetDirectory) {
50
+ $$$ThrowStatus($$$ERROR($$$DirectoryCannotCreate, targetDirectory))
51
+ }
52
+ }
53
+ }
54
+ Else {
55
+ // Set targetDirectory to the CODE DATABASE directory
56
+ do ##class(%SYS.Namespace).GetAllNSInfo("USER",.info)
57
+ Set targetDirectory = info("RoutineDB","Directory")
58
+ }
59
+
60
+ Set packagePath = ##class(%Library.File).NormalizeDirectory(packageName, targetDirectory)
61
+ // If the package already exists then we must be meaning to re-load it. Delete files/directory/metadata and recreate fresh.
62
+ If ##class(%Library.File).DirectoryExists(packagePath) {
63
+ If '##class(%Library.File).RemoveDirectoryTree(packagePath) {
64
+ $$$ThrowStatus($$$ERROR($$$DirectoryPermission , packagePath))
65
+ }
66
+ }
67
+ If '##class(%Library.File).CreateDirectory(packagePath) {
68
+ $$$ThrowStatus($$$ERROR($$$DirectoryCannotCreate, packagePath))
69
+ }
70
+
71
+ //Unpack JSON objects
72
+ Set iterator = body.%GetIterator()
73
+ While iterator.%GetNext(.key , .fileObject ) {
74
+ // If fileObject.name has '/' then it is a path, we need to normalize it
75
+ Set fileName = ##class(%Library.File).NormalizeFilename(fileObject.name,packagePath)
76
+ do ##class(%Library.File).CreateDirectoryChain(##class(%Library.File).GetDirectory(fileName))
77
+ Set fileStream = ##class(%Stream.FileCharacter).%New()
78
+ Set fileStream.TranslateTable = "UTF8"
79
+ $$$ThrowOnError(fileStream.LinkToFile(fileName))
80
+ Do fileStream.Write(fileObject.data)
81
+ $$$ThrowOnError(fileStream.%Save())
82
+ }
83
+
84
+ //Do the iop migration
85
+
86
+ set iopUtils = ##class(IOP.Wrapper).Import("iop._utils")
87
+ do iopUtils."_Utils".migrate(##class(%Library.File).NormalizeFilename("settings.py", packagePath))
88
+ }
89
+ Catch ex {
90
+ $$$ThrowOnError(ex.AsStatus())
91
+ }
92
+
93
+
94
+ return $$$OK
95
+ }
96
+
97
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris_pex_embedded_python
3
- Version: 3.5.1b4
3
+ Version: 3.5.2
4
4
  Summary: Iris Interoperability based on Embedded Python
5
5
  Author-email: grongier <guillaume.rongier@intersystems.com>
6
6
  License: MIT License
@@ -34,7 +34,7 @@ iop/_business_host.py,sha256=asX2z9Jfbwrs-B0TI2-JeXvSsYUMKUUlnJ4-kohZg8U,11280
34
34
  iop/_business_operation.py,sha256=1-jWTejFBlIPlV83KiIfU0n33IYc7QMpt0KFqTybWEI,3037
35
35
  iop/_business_process.py,sha256=2W4tA8kPGrKp2bP0RVkXR8JSiVnSKCUgN24mDmPkJEU,8548
36
36
  iop/_business_service.py,sha256=UGZ-bxbEzec9z6jf-pKIaLo8BL-V1D2aqJGZM9m37qo,3984
37
- iop/_cli.py,sha256=FJGPcJKEKKph3XIJgDGUF-QpE_DMt7YSO8G7yYD9UnI,8046
37
+ iop/_cli.py,sha256=tyKBzedisxEfr6sU06o4fAgxkt_SJjdnvT1Y579uvOs,8053
38
38
  iop/_common.py,sha256=W39gb-K7oh93YdxOIIud0TT64Z6dSogVT4Rpda7_IvU,13986
39
39
  iop/_debugpy.py,sha256=EJ3XK29cDQ1mBklEgUwG6HyHYJAmhVa3-8m_FvtbVOs,6008
40
40
  iop/_decorators.py,sha256=LpK0AK4GIzXbPFSIw_x6zzM3FwsHvFjgQUh-MnqtTE8,2322
@@ -49,8 +49,9 @@ iop/_message_validator.py,sha256=ooDFWp8XvqJWP91RDbkFgpA5V3LbNrQO6IMx2vSjoF8,151
49
49
  iop/_outbound_adapter.py,sha256=cN7dkZyx9ED89yUGePsUYsUhlR3ze3w1JorCG8HvDCw,723
50
50
  iop/_private_session_duplex.py,sha256=c6Q0k-qnZi_JcIOdpUx1Edu44zVbUE2Kf2aCHM8Eq80,5202
51
51
  iop/_private_session_process.py,sha256=rvZFO6nWVwZtaEWJkSHyLTV-vhzDqQhsVi7INQLLwWI,1685
52
+ iop/_remote.py,sha256=gCXXK67RFP8njSnbEsZdsOl9Rlt8TYtBDiHr3rwRvLA,3789
52
53
  iop/_serialization.py,sha256=C9-88bb6vC8A4ugQ3QqjahAbv7NjAD2sZy8_D-X0Ois,7721
53
- iop/_utils.py,sha256=yAvssj3O3p9mLVJ_RvDIuawyYNhOIm5WrK0SANaSIwU,21256
54
+ iop/_utils.py,sha256=Gr_Z1K6eJLnvMFbZ71KBnCxbwCec0bruZ80L8JLuNgo,26885
54
55
  iop/cls/IOP/BusinessOperation.cls,sha256=td4tFxy9KbZ6u5QEr9xCuCNjcqEJavdeYHErNrt-szk,941
55
56
  iop/cls/IOP/BusinessProcess.cls,sha256=XJxzbiV0xokzRm-iI2Be5UIJLE3MlXr7W3WS_LkOCYs,3363
56
57
  iop/cls/IOP/BusinessService.cls,sha256=fplKrbQgA7cQgjKIqDR2IK2iD1iNHmT-QvWrozhE4n4,1189
@@ -60,6 +61,7 @@ iop/cls/IOP/InboundAdapter.cls,sha256=H-gZfUy8M9YxAZXfp5HVYl3uLo-7Xg9YgojioB_eYM
60
61
  iop/cls/IOP/Message.cls,sha256=6_iZzQaY0cA9FjXg0qECYZC6We8soAIrUwRBrlerC4w,25373
61
62
  iop/cls/IOP/OutboundAdapter.cls,sha256=OQoGFHUy2qV_kcsShTlWGOngDrdH5dhwux4eopZyIv4,967
62
63
  iop/cls/IOP/PickleMessage.cls,sha256=S3y7AClQ8mAILjxPuHdCjGosBZYzGbUQ5WTv4mYPNMQ,1673
64
+ iop/cls/IOP/Projection.cls,sha256=AZgbfpbEk02llhyIwrSw0M3QMcQNcjhjY3_vU_yx8FU,1315
63
65
  iop/cls/IOP/Test.cls,sha256=gAC9PEfMZsvAEWIa241-ug2FWAhITbN1SOispZzJPnI,2094
64
66
  iop/cls/IOP/Utils.cls,sha256=NGnfi2Kif3OyYwR6pm5c_-UKm5vEwQyfzvJpZGxFeeA,18546
65
67
  iop/cls/IOP/Wrapper.cls,sha256=37fUol-EcktdfGhpfi4o12p04975lKGaRYEFhw-fuaM,1614
@@ -78,10 +80,12 @@ iop/cls/IOP/PrivateSession/Message/Poll.cls,sha256=z3ALYmGYQasTcyYNyBeoHzJdNXI4n
78
80
  iop/cls/IOP/PrivateSession/Message/Start.cls,sha256=RsJLrhglrONBDGT0RqW2K9MDXa98vMYcxJfgeD8lhAE,943
79
81
  iop/cls/IOP/PrivateSession/Message/Stop.cls,sha256=7g3gKFUjNg0WXBLuWnj-VnCs5G6hSE09YTzGEp0zbGc,1390
80
82
  iop/cls/IOP/Service/WSGI.cls,sha256=VLNCXEwmHW9dBnE51uGE1nvGX6T4HjhqePT3LVhsjAE,10440
83
+ iop/cls/IOP/Service/Remote/Handler.cls,sha256=JfsXse2jvoVvQfW8_rVEt2DCQJ9SVqReCcOUngOkpzE,938
84
+ iop/cls/IOP/Service/Remote/Rest/v1.cls,sha256=JWORGJR7Z_Sc8BBevke14GAnLuWdQTuCSPjillOrQZU,3052
81
85
  iop/wsgi/handlers.py,sha256=NrFLo_YbAh-x_PlWhAiWkQnUUN2Ss9HoEm63dDWCBpQ,2947
82
- iris_pex_embedded_python-3.5.1b4.dist-info/licenses/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
83
- iris_pex_embedded_python-3.5.1b4.dist-info/METADATA,sha256=jJmEok5aBknQQRV23tnjcCAnkOLd0ZDThz91yH3NPw8,4415
84
- iris_pex_embedded_python-3.5.1b4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
85
- iris_pex_embedded_python-3.5.1b4.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
86
- iris_pex_embedded_python-3.5.1b4.dist-info/top_level.txt,sha256=4p0q6hCATmYIVMVi3I8hOUcJE1kwzyBeHygWv_rGvrU,13
87
- iris_pex_embedded_python-3.5.1b4.dist-info/RECORD,,
86
+ iris_pex_embedded_python-3.5.2.dist-info/licenses/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
87
+ iris_pex_embedded_python-3.5.2.dist-info/METADATA,sha256=jTsQiHR2xDbGZP6IGdlzhKUmIKi-vtFMqVdWH_KwcMM,4413
88
+ iris_pex_embedded_python-3.5.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
89
+ iris_pex_embedded_python-3.5.2.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
90
+ iris_pex_embedded_python-3.5.2.dist-info/top_level.txt,sha256=4p0q6hCATmYIVMVi3I8hOUcJE1kwzyBeHygWv_rGvrU,13
91
+ iris_pex_embedded_python-3.5.2.dist-info/RECORD,,