iris-pex-embedded-python 3.5.1b3__py3-none-any.whl → 3.5.2b1__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,85 @@ 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_SETTING' then it will use the value of that key
268
+ as the remote host to connect to.
269
+ the REMOTE_SETTING 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_SETTING', 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_SETTING 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
+ # check the response status
337
+ if response.status_code != 200:
338
+ raise RuntimeError(f"Failed to migrate: {response.status_code} - {response.text}")
339
+ else:
340
+ print(f"Migration successful: {response.status_code} - {response.text}")
341
+
253
342
  @staticmethod
254
343
  def migrate(filename=None):
255
344
  """
@@ -265,43 +354,96 @@ class _Utils():
265
354
  * SCHEMAS
266
355
  List of classes
267
356
  """
268
- path = None
269
- # try to load the settings file
357
+ settings, path = _Utils._load_settings(filename)
358
+
359
+ _Utils._register_settings_components(settings, path)
360
+
361
+ _Utils._cleanup_sys_path(path)
362
+
363
+ @staticmethod
364
+ def _load_settings(filename):
365
+ """Load settings module from file or default location.
366
+
367
+ Returns:
368
+ tuple: (settings_module, path_added_to_sys)
369
+ """
370
+ path_added = None
371
+
270
372
  if filename:
271
373
  # check if the filename is absolute or relative
272
- if os.path.isabs(filename):
273
- path = os.path.dirname(filename)
274
- else:
374
+ if not os.path.isabs(filename):
275
375
  raise ValueError("The filename must be absolute")
376
+
276
377
  # add the path to the system path to the beginning
277
- sys.path.insert(0,os.path.normpath(path))
378
+ path_added = os.path.normpath(os.path.dirname(filename))
379
+ sys.path.insert(0, path_added)
278
380
  # import settings from the specified file
279
- settings = _Utils.import_module_from_path('settings',filename)
381
+ settings = _Utils.import_module_from_path('settings', filename)
280
382
  else:
281
383
  # 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))
384
+ import settings # type: ignore
385
+
386
+ return settings, path_added
387
+
388
+ @staticmethod
389
+ def _get_folder_path(filename, path_added_to_sys):
390
+ """Get the folder path for migration operations.
391
+
392
+ Args:
393
+ filename: Original filename parameter
394
+ path_added_to_sys: Path that was added to sys.path
395
+
396
+ Returns:
397
+ str: Folder path to use for migration
398
+ """
399
+ if filename:
400
+ return os.path.dirname(filename)
401
+ else:
402
+ return os.getcwd()
403
+
404
+ @staticmethod
405
+ def _register_settings_components(settings, path):
406
+ """Register all components from settings (classes, productions, schemas).
407
+
408
+ Args:
409
+ settings: Settings module containing CLASSES, PRODUCTIONS, SCHEMAS
410
+ path: Base path for component registration
411
+ """
412
+ # Use settings file location if path not provided
413
+ if not path:
414
+ path = os.path.dirname(inspect.getfile(settings))
415
+
285
416
  try:
286
417
  # set the classes settings
287
- _Utils.set_classes_settings(settings.CLASSES,path)
418
+ _Utils.set_classes_settings(settings.CLASSES, path)
288
419
  except AttributeError:
289
420
  print("No classes to register")
421
+
290
422
  try:
291
423
  # set the productions settings
292
- _Utils.set_productions_settings(settings.PRODUCTIONS,path)
424
+ _Utils.set_productions_settings(settings.PRODUCTIONS, path)
293
425
  except AttributeError:
294
426
  print("No productions to register")
427
+
295
428
  try:
296
429
  # set the schemas
297
430
  for cls in settings.SCHEMAS:
298
431
  _Utils.register_message_schema(cls)
299
432
  except AttributeError:
300
433
  print("No schemas to register")
301
- try:
302
- sys.path.remove(os.path.normpath(path))
303
- except ValueError:
304
- pass
434
+
435
+ @staticmethod
436
+ def _cleanup_sys_path(path):
437
+ """Remove path from sys.path if it was added.
438
+
439
+ Args:
440
+ path: Path to remove from sys.path
441
+ """
442
+ if path:
443
+ try:
444
+ sys.path.remove(os.path.normpath(path))
445
+ except ValueError:
446
+ pass
305
447
 
306
448
  @staticmethod
307
449
  def import_module_from_path(module_name, file_path):
@@ -0,0 +1,48 @@
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("AutheEnabled") = 32
22
+ set webProperties("ServeFiles")=2
23
+ set webProperties("Recurse")=1
24
+ if ##class(Security.Applications).Exists(webName) {
25
+ // If the web application already exists, delete it first
26
+ $$$ThrowOnError(##class(Security.Applications).Delete(webName))
27
+ }
28
+ $$$ThrowOnError(##class(Security.Applications).Create(webName, .webProperties))
29
+ }
30
+ Catch ex {
31
+
32
+ Write !,"Error creating web application: ", ex.DisplayString(), !
33
+
34
+ }
35
+
36
+ znspace tCurrentNamespace
37
+ Return tSC
38
+ }
39
+
40
+ ClassMethod RemoveProjection(
41
+ cls As %String,
42
+ ByRef params,
43
+ recompile As %Boolean) As %Status
44
+ {
45
+ Quit $$$OK
46
+ }
47
+
48
+ }
@@ -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,90 @@
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
+ // Get the request body
32
+ set dyna = {}.%FromJSON(%request.Content)
33
+ set body = dyna.%Get("body")
34
+ set namespace = dyna.%Get("namespace")
35
+ set targetDirectory = dyna.%Get("remote_folder")
36
+ set packageName = dyna.%Get("package")
37
+ // check for namespace existence and user permissions against namespace
38
+ If '..NamespaceCheck(namespace) {
39
+ Return ""
40
+ }
41
+ New $NAMESPACE
42
+ Set $NAMESPACE = namespace
43
+
44
+
45
+ //Create directory for custom packages
46
+ If targetDirectory '= "" {
47
+ If '##class(%Library.File).DirectoryExists(targetDirectory) {
48
+ If '##class(%Library.File).CreateDirectory(targetDirectory) {
49
+ $$$ThrowStatus($$$ERROR($$$DirectoryCannotCreate, targetDirectory))
50
+ }
51
+ }
52
+ }
53
+ Else {
54
+ // Set targetDirectory to the CODE DATABASE directory
55
+ do ##class(%SYS.Namespace).GetAllNSInfo("USER",.info)
56
+ Set targetDirectory = info("RoutineDB","Directory")
57
+ }
58
+
59
+ Set packagePath = ##class(%Library.File).NormalizeDirectory(packageName, targetDirectory)
60
+ // If the package already exists then we must be meaning to re-load it. Delete files/directory/metadata and recreate fresh.
61
+ If ##class(%Library.File).DirectoryExists(packagePath) {
62
+ If '##class(%Library.File).RemoveDirectoryTree(packagePath) {
63
+ $$$ThrowStatus($$$ERROR($$$DirectoryPermission , packagePath))
64
+ }
65
+ }
66
+ If '##class(%Library.File).CreateDirectory(packagePath) {
67
+ $$$ThrowStatus($$$ERROR($$$DirectoryCannotCreate, packagePath))
68
+ }
69
+
70
+ //Unpack JSON objects
71
+ Set iterator = body.%GetIterator()
72
+ While iterator.%GetNext(.key , .fileObject ) {
73
+ // If fileObject.name has '/' then it is a path, we need to normalize it
74
+ Set fileName = ##class(%Library.File).NormalizeFilename(fileObject.name,packagePath)
75
+ do ##class(%Library.File).CreateDirectoryChain(##class(%Library.File).GetDirectory(fileName))
76
+ Set fileStream = ##class(%Stream.FileCharacter).%New()
77
+ Set fileStream.TranslateTable = "UTF8"
78
+ $$$ThrowOnError(fileStream.LinkToFile(fileName))
79
+ Do fileStream.Write(fileObject.data)
80
+ $$$ThrowOnError(fileStream.%Save())
81
+ }
82
+
83
+ //Do the iop migration
84
+ set iopUtils = ##class(IOP.Wrapper).Import("iop._utils")
85
+ do iopUtils."_Utils".migrate(##class(%Library.File).NormalizeFilename("settings.py", packagePath))
86
+
87
+ return $$$OK
88
+ }
89
+
90
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris_pex_embedded_python
3
- Version: 3.5.1b3
3
+ Version: 3.5.2b1
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=UBeWhSZo1Ya4_f3fgyRhC2zYc5TFGLF6BuhrO3EPmBk,27012
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=9pKPm5SLAKmTnrcJWwLo9kPycWJsiT-YVYnQIqzNN1U,1241
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=LR8nUIEvGb7bO1AwiVMeh70RGePwhPt7sHYGGfR9coA,3033
81
85
  iop/wsgi/handlers.py,sha256=NrFLo_YbAh-x_PlWhAiWkQnUUN2Ss9HoEm63dDWCBpQ,2947
82
- iris_pex_embedded_python-3.5.1b3.dist-info/licenses/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
83
- iris_pex_embedded_python-3.5.1b3.dist-info/METADATA,sha256=3kiGbRy7HjWhzMGcyNba6jbgEiskLUwtrK5Wm6IxLBM,4415
84
- iris_pex_embedded_python-3.5.1b3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
85
- iris_pex_embedded_python-3.5.1b3.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
86
- iris_pex_embedded_python-3.5.1b3.dist-info/top_level.txt,sha256=4p0q6hCATmYIVMVi3I8hOUcJE1kwzyBeHygWv_rGvrU,13
87
- iris_pex_embedded_python-3.5.1b3.dist-info/RECORD,,
86
+ iris_pex_embedded_python-3.5.2b1.dist-info/licenses/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
87
+ iris_pex_embedded_python-3.5.2b1.dist-info/METADATA,sha256=2v-X7ose-o8tZwWw-8nA1X-nbdSfIKxMOuUQ62HqOIg,4415
88
+ iris_pex_embedded_python-3.5.2b1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
89
+ iris_pex_embedded_python-3.5.2b1.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
90
+ iris_pex_embedded_python-3.5.2b1.dist-info/top_level.txt,sha256=4p0q6hCATmYIVMVi3I8hOUcJE1kwzyBeHygWv_rGvrU,13
91
+ iris_pex_embedded_python-3.5.2b1.dist-info/RECORD,,