iris-pex-embedded-python 2.3.22b3__py3-none-any.whl → 2.3.23b2__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.
- grongier/cls/Grongier/Service/WSGI.cls +278 -73
- grongier/pex/wsgi/handlers.py +91 -38
- intersystems_iris/_DBList.py +6 -0
- intersystems_iris/_IRISEmbedded.py +2 -2
- intersystems_iris/_ListWriter.py +5 -1
- intersystems_iris/dbapi/_DBAPI.py +37 -13
- intersystems_iris/dbapi/_ResultSetRow.py +4 -0
- iris/__init__.pyi +187 -0
- iris/iris_ipm.pyi +17 -0
- {iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/METADATA +2 -2
- {iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/RECORD +15 -13
- {iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/LICENSE +0 -0
- {iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/WHEEL +0 -0
- {iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/entry_points.txt +0 -0
- {iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Class Grongier.Service.WSGI Extends
|
|
1
|
+
Class Grongier.Service.WSGI Extends %CSP.REST [ ServerOnly = 1 ]
|
|
2
2
|
{
|
|
3
3
|
|
|
4
4
|
Parameter CLASSPATHS;
|
|
@@ -7,99 +7,304 @@ Parameter MODULENAME;
|
|
|
7
7
|
|
|
8
8
|
Parameter APPNAME;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
ClassMethod write(data)
|
|
12
|
-
{
|
|
13
|
-
w data
|
|
14
|
-
}
|
|
10
|
+
Parameter DEVMODE = 1;
|
|
15
11
|
|
|
16
|
-
///
|
|
17
|
-
ClassMethod
|
|
12
|
+
/// This method matches the request and method and calls the dispatcher
|
|
13
|
+
ClassMethod Page(skipheader As %Boolean = 0) As %Status [ ProcedureBlock = 1 ]
|
|
18
14
|
{
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
#dim tSC As %Status = $$$OK
|
|
16
|
+
#dim e As %Exception.AbstractException
|
|
17
|
+
|
|
18
|
+
#dim tAuthorized,tRedirected As %Boolean
|
|
19
|
+
#dim tRedirectRoutine,tURL As %String = ""
|
|
20
|
+
#dim %response As %CSP.Response
|
|
21
|
+
|
|
22
|
+
Try {
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
#; Ensure that we honor the requested charset
|
|
25
|
+
Set %response.CharSet=..#CHARSET
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
#; Ensure that we honor the requested CONTENTTYPE
|
|
28
|
+
If ..#CONTENTTYPE'="" Set %response.ContentType=..#CONTENTTYPE
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
#; Ensure that we honor the requested HTTP_ACCEPT_LANGUAGE
|
|
31
|
+
Set %response.Domain = ..#DOMAIN
|
|
32
|
+
Do %response.MatchLanguage()
|
|
33
|
+
|
|
34
|
+
#; Record if device re-direction is already active
|
|
35
|
+
Set tRedirected=##class(%Library.Device).ReDirectIO()
|
|
36
|
+
|
|
37
|
+
#; Record the redirect routine
|
|
38
|
+
Set tRedirectRoutine=$System.Device.GetMnemonicRoutine()
|
|
39
|
+
|
|
40
|
+
if ..#DEVMODE {
|
|
41
|
+
#; Not so pretty but help to for reload the WSGI application
|
|
42
|
+
do outputError^%SYS.cspServer2("","","","")
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
#; Now switch to using THIS routine for device redirection
|
|
46
|
+
Use $io::("^%SYS.cspServer2")
|
|
38
47
|
|
|
39
|
-
|
|
48
|
+
#; Switch device redirection on (may already be on but thats ok)
|
|
49
|
+
Do ##class(%Library.Device).ReDirectIO(1)
|
|
50
|
+
}
|
|
40
51
|
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
#; Ensure that the application is defined (security check)
|
|
53
|
+
If $$$GetSecurityApplicationsDispatchClass(%request.AppData)="" {
|
|
54
|
+
|
|
55
|
+
#; Report not authorized
|
|
56
|
+
Set tSC=..Http403()
|
|
57
|
+
|
|
58
|
+
#; Done
|
|
59
|
+
Quit
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#; GgiEnvs are not defined in the CSP shell
|
|
63
|
+
Set tURL=$Get(%request.CgiEnvs("CSPLIB"))
|
|
64
|
+
If tURL="" Set tURL=%request.URL
|
|
65
|
+
|
|
66
|
+
#; Do an access check
|
|
67
|
+
Set tSC=..AccessCheck(.tAuthorized)
|
|
68
|
+
If $$$ISERR(tSC) Quit
|
|
43
69
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if onePath?1"$$IRISHOME"1P.E set onePath = $e($system.Util.InstallDirectory(),1,*-1)_$e(onePath,11,*)
|
|
55
|
-
if onePath'="" do sys.path.append(onePath)
|
|
70
|
+
If tAuthorized=0 {
|
|
71
|
+
|
|
72
|
+
#; Don't want the session token
|
|
73
|
+
Set %response.OutputSessionToken=0
|
|
74
|
+
|
|
75
|
+
#; Set the Http Status
|
|
76
|
+
Set %response.Status=..#HTTP403FORBIDDEN
|
|
77
|
+
|
|
78
|
+
#; Done
|
|
79
|
+
Quit
|
|
56
80
|
}
|
|
81
|
+
|
|
82
|
+
#; Extract the match url from the application name
|
|
83
|
+
Set tMatchUrl = "/"_$Extract(tURL,$Length(%request.Application)+1,*)
|
|
84
|
+
|
|
85
|
+
#; Dispatch the request
|
|
86
|
+
Set tSC=..DispatchRequest(tMatchUrl,%request.Method)
|
|
87
|
+
|
|
88
|
+
} Catch (e) {
|
|
89
|
+
Set tSC=e.AsStatus()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
If $$$ISERR(tSC) {
|
|
93
|
+
|
|
94
|
+
#; Don't want the session token
|
|
95
|
+
Set %response.OutputSessionToken=0
|
|
96
|
+
|
|
97
|
+
Do ..Http500(##class(%Exception.StatusException).CreateFromStatus(tSC))
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#; Ensure that at least something is written out as the body
|
|
101
|
+
#; This will trigger the device redirect capture and force headers to be written
|
|
102
|
+
#; (if not already done)
|
|
103
|
+
Write ""
|
|
104
|
+
|
|
105
|
+
#; Reset redirect device if necessary
|
|
106
|
+
If tRedirected {
|
|
107
|
+
|
|
108
|
+
#; Use the original redirected routine
|
|
109
|
+
Use $io::("^"_tRedirectRoutine)
|
|
110
|
+
|
|
111
|
+
#; Switch device redirection on
|
|
112
|
+
Do ##class(%Library.Device).ReDirectIO(1)
|
|
57
113
|
}
|
|
114
|
+
|
|
115
|
+
#; Any errors should have been caught and reported
|
|
116
|
+
Quit $$$OK
|
|
117
|
+
}
|
|
58
118
|
|
|
59
|
-
|
|
60
|
-
|
|
119
|
+
ClassMethod OnPreDispatch(
|
|
120
|
+
pUrl As %String,
|
|
121
|
+
pMethod As %String,
|
|
122
|
+
ByRef pContinue As %Boolean) As %Status
|
|
123
|
+
{
|
|
124
|
+
Set path = ..#CLASSPATHS
|
|
125
|
+
Set appName = ..#APPNAME
|
|
126
|
+
Set module = ..#MODULENAME
|
|
127
|
+
Set devmode = ..#DEVMODE
|
|
128
|
+
Set pContinue = 1
|
|
129
|
+
Do ..DispatchREST(pUrl, path, appName, module, devmode)
|
|
130
|
+
Quit $$$OK
|
|
131
|
+
}
|
|
61
132
|
|
|
62
|
-
|
|
63
|
-
|
|
133
|
+
ClassMethod DispatchREST(
|
|
134
|
+
PathInfo As %String,
|
|
135
|
+
appPath As %String,
|
|
136
|
+
appName As %String,
|
|
137
|
+
module As %String,
|
|
138
|
+
devmode As %Boolean = 1) As %Status
|
|
139
|
+
{
|
|
140
|
+
Set builtins = ##CLASS(%SYS.Python).Builtins()
|
|
141
|
+
Set interface = ##CLASS(%SYS.Python).Import("grongier.pex.wsgi.handlers")
|
|
142
|
+
Set rawformdata = ""
|
|
143
|
+
Set environ = builtins.dict()
|
|
144
|
+
Set key = %request.NextCgiEnv("")
|
|
64
145
|
|
|
65
|
-
|
|
66
|
-
|
|
146
|
+
// Let's check if the WSGI application has been loaded or not for this session.
|
|
147
|
+
|
|
148
|
+
If (($DATA(%session.Data("application")) && $ISOBJECT(%session.Data("application"))) && 'devmode) {
|
|
149
|
+
Set application = %session.Data("Application")
|
|
150
|
+
}
|
|
151
|
+
Else{
|
|
67
152
|
|
|
68
|
-
|
|
69
|
-
|
|
153
|
+
Set application = ..GetPythonClass(appName, module, appPath)
|
|
154
|
+
If application = "" {
|
|
155
|
+
throw ##class(%Exception.General).%New("Error loading WSGI application: "_module_"."_appName_" from "_appPath)
|
|
156
|
+
}
|
|
157
|
+
Else {
|
|
158
|
+
Set %session.Data("Application") = application
|
|
159
|
+
}
|
|
160
|
+
}
|
|
70
161
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
162
|
+
// Editing some CGI variables that may be incorrect in %request
|
|
163
|
+
// Also filling in environ with as many CGI variables as possible from %request
|
|
164
|
+
// WSGI states that all CGI variables are valid and should be included if possible
|
|
165
|
+
While (key'="") {
|
|
166
|
+
Set value = %request.GetCgiEnv(key)
|
|
167
|
+
If key = "PATH_INFO" {
|
|
168
|
+
Set app=$$getapp^%SYS.cspServer(%request.URL,.path,.match,.updatedurl)
|
|
169
|
+
Set value = $EXTRACT(updatedurl,$LENGTH(path),*)
|
|
170
|
+
}
|
|
171
|
+
If key = "SCRIPT_NAME" {
|
|
172
|
+
//%request will sometimes have Script_name include Path_info
|
|
173
|
+
Set value = $PIECE(%request.Application, "/",1,*-1)
|
|
174
|
+
}
|
|
175
|
+
Do environ."__setitem__"(key,value)
|
|
176
|
+
Set key = %request.NextCgiEnv(key)
|
|
177
|
+
}
|
|
77
178
|
|
|
78
|
-
|
|
79
|
-
|
|
179
|
+
//Have to set up a correct wsgi.input stream from %request
|
|
180
|
+
Set stream = %request.Content
|
|
181
|
+
|
|
182
|
+
Set contentType = %request.ContentType
|
|
183
|
+
Set contentLength = 0
|
|
80
184
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
185
|
+
If contentType = "application/x-www-form-urlencoded" {
|
|
186
|
+
Set formdict = builtins.dict()
|
|
187
|
+
Set key = $ORDER(%request.Data(""))
|
|
188
|
+
While (key'="") {
|
|
189
|
+
Set value = $GET(%request.Data(key,1))
|
|
190
|
+
Do formdict."__setitem__"(key,value)
|
|
191
|
+
Set key = $ORDER(%request.Data(key))
|
|
192
|
+
}
|
|
193
|
+
Do environ."__setitem__"("formdata", formdict)
|
|
194
|
+
}
|
|
195
|
+
ElseIf contentType = "multipart/form-data" {
|
|
196
|
+
Set boundary = $PIECE(%request.GetCgiEnv("CONTENT_TYPE"), "=",2)
|
|
197
|
+
Set stream = ##CLASS(%CSP.BinaryStream).%New()
|
|
90
198
|
|
|
91
|
-
|
|
92
|
-
set application = ..GetPyhonApp()
|
|
199
|
+
Do stream.Write($CHAR(13,10))
|
|
93
200
|
|
|
94
|
-
|
|
95
|
-
do handler.run(application)
|
|
201
|
+
//Get the Form Data values
|
|
96
202
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
203
|
+
Set key = $ORDER(%request.Data(""))
|
|
204
|
+
While (key'="") {
|
|
205
|
+
Do stream.Write("--")
|
|
206
|
+
Do stream.Write(boundary)
|
|
207
|
+
Do stream.Write($CHAR(13,10))
|
|
208
|
+
Set value = $GET(%request.Data(key,1))
|
|
209
|
+
Do stream.Write("Content-Disposition: form-data; name=")
|
|
210
|
+
Do stream.Write(""""_key_"""")
|
|
211
|
+
Do stream.Write($CHAR(13,10,13,10))
|
|
212
|
+
Do stream.Write(value)
|
|
213
|
+
Do stream.Write($CHAR(13,10))
|
|
214
|
+
Set key = $ORDER(%request.Data(key))
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
//Now get the possible MIME data streams
|
|
218
|
+
Set key = %request.NextMimeData("")
|
|
219
|
+
While key'="" {
|
|
220
|
+
Set numMimeStreams = %request.CountMimeData(key)
|
|
221
|
+
Set index = %request.NextMimeDataIndex(key, "")
|
|
222
|
+
Do stream.Write("--")
|
|
223
|
+
Do stream.Write(boundary)
|
|
224
|
+
Do stream.Write($CHAR(13,10))
|
|
225
|
+
If numMimeStreams > 1 {
|
|
226
|
+
//I need to create a boundary for a nested multipart content type
|
|
227
|
+
Set internalboundary = "--"
|
|
228
|
+
For i = 1 : 1 : 7 {
|
|
229
|
+
Set internalboundary = internalboundary _ $RANDOM(10)
|
|
230
|
+
}
|
|
231
|
+
While index '= "" {
|
|
232
|
+
Set mimestream = %request.GetMimeData(key, index)
|
|
233
|
+
Set headers = mimestream.Headers
|
|
234
|
+
Do stream.Write("--")
|
|
235
|
+
Do stream.Write(internalboundary)
|
|
236
|
+
Do stream.Write($CHAR(13,10))
|
|
237
|
+
Do stream.Write(headers)
|
|
238
|
+
Do stream.Write($CHAR(13,10,13,10))
|
|
239
|
+
Set sc = stream.CopyFrom(mimestream)
|
|
240
|
+
//TODO error handling
|
|
241
|
+
Do stream.Write($CHAR(13,10))
|
|
242
|
+
Set index = %request.NextMimeDataIndex(key, index)
|
|
243
|
+
}
|
|
244
|
+
Do stream.Write("--")
|
|
245
|
+
Do stream.Write(internalboundary)
|
|
246
|
+
Do stream.Write("--")
|
|
247
|
+
}
|
|
248
|
+
Else {
|
|
249
|
+
Set mimestream = %request.GetMimeData(key, index)
|
|
250
|
+
Set headers = mimestream.Headers
|
|
251
|
+
Do stream.Write(headers)
|
|
252
|
+
Do stream.Write($CHAR(13,10,13,10))
|
|
253
|
+
Set sc = stream.CopyFrom(mimestream)
|
|
254
|
+
//TODO error handling
|
|
255
|
+
Do stream.Write($CHAR(13,10))
|
|
256
|
+
}
|
|
257
|
+
Set key = %request.NextMimeData(key)
|
|
258
|
+
}
|
|
259
|
+
Do stream.Write("--")
|
|
260
|
+
Do stream.Write(boundary)
|
|
261
|
+
Do stream.Write("--")
|
|
262
|
+
Do stream.Rewind()
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
Try {
|
|
267
|
+
Do interface."make_request"(environ, stream, application, appPath)
|
|
268
|
+
}
|
|
269
|
+
Catch exception {
|
|
270
|
+
throw exception
|
|
271
|
+
}
|
|
272
|
+
Quit $$$OK
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
ClassMethod GetPythonClass(
|
|
276
|
+
pClassname As %String,
|
|
277
|
+
pModule As %String,
|
|
278
|
+
pClasspath As %String) As %SYS.Python
|
|
279
|
+
{
|
|
280
|
+
Try {
|
|
281
|
+
If pClasspath '="" {
|
|
282
|
+
set sys = ##class(%SYS.Python).Import("sys")
|
|
283
|
+
|
|
284
|
+
for i=0:1:(sys.path."__len__"()-1) {
|
|
285
|
+
Try {
|
|
286
|
+
if sys.path."__getitem__"(i) = pClasspath {
|
|
287
|
+
do sys.path."__delitem__"(i)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
Catch ex {
|
|
291
|
+
// do nothing
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
}
|
|
295
|
+
do sys.path.insert(0, pClasspath)
|
|
296
|
+
}
|
|
101
297
|
|
|
102
|
-
|
|
298
|
+
Set importlib = ##class(%SYS.Python).Import("importlib")
|
|
299
|
+
Set builtins = ##class(%SYS.Python).Import("builtins")
|
|
300
|
+
Set module = importlib."import_module"(pModule)
|
|
301
|
+
Set class = builtins.getattr(module, pClassname)
|
|
302
|
+
}
|
|
303
|
+
Catch ex {
|
|
304
|
+
throw ##class(%Exception.General).%New("Error loading WSGI application: "_pModule_"."_pClassname_" from "_pClasspath)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
Quit class
|
|
103
308
|
}
|
|
104
309
|
|
|
105
310
|
}
|
grongier/pex/wsgi/handlers.py
CHANGED
|
@@ -1,51 +1,104 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
import os, sys, importlib, urllib.parse
|
|
2
|
+
from io import BytesIO
|
|
3
|
+
|
|
4
|
+
__ospath = os.getcwd()
|
|
5
|
+
|
|
3
6
|
import iris
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
os.chdir(__ospath)
|
|
9
|
+
|
|
10
|
+
enc, esc = sys.getfilesystemencoding(), 'surrogateescape'
|
|
11
|
+
|
|
12
|
+
rest_service = iris.cls('%REST.Impl')
|
|
13
|
+
|
|
14
|
+
def get_from_module(app_path, app_module, app_name):
|
|
15
|
+
|
|
16
|
+
# Add the path to the application
|
|
17
|
+
if (app_path not in sys.path) :
|
|
18
|
+
sys.path.append(app_path)
|
|
19
|
+
|
|
20
|
+
# retrieve the application
|
|
21
|
+
return getattr(importlib.import_module(app_module), app_name)
|
|
22
|
+
|
|
23
|
+
# Changes the current working directory to the manager directory of the instance.
|
|
24
|
+
def goto_manager_dir():
|
|
25
|
+
iris.system.Process.CurrentDirectory(iris.system.Util.ManagerDirectory())
|
|
26
|
+
|
|
27
|
+
def unicode_to_wsgi(u):
|
|
28
|
+
# Convert an environment variable to a WSGI "bytes-as-unicode" string
|
|
29
|
+
return u.encode(enc, esc).decode('iso-8859-1')
|
|
30
|
+
|
|
31
|
+
def wsgi_to_bytes(s):
|
|
32
|
+
return s.encode('iso-8859-1')
|
|
33
|
+
|
|
34
|
+
def write(chunk):
|
|
35
|
+
rest_service._WriteResponse(chunk)
|
|
36
|
+
|
|
37
|
+
def start_response(status, response_headers, exc_info=None):
|
|
38
|
+
'''WSGI start_response callable'''
|
|
39
|
+
if exc_info:
|
|
40
|
+
try:
|
|
41
|
+
raise exc_info[1].with_traceback(exc_info[2])
|
|
42
|
+
finally:
|
|
43
|
+
exc_info = None
|
|
7
44
|
|
|
8
|
-
|
|
9
|
-
|
|
45
|
+
rest_service._SetStatusCode(status)
|
|
46
|
+
for tuple in response_headers:
|
|
47
|
+
rest_service._SetHeader(tuple[0], tuple[1])
|
|
48
|
+
return write
|
|
10
49
|
|
|
11
|
-
Usage::
|
|
12
50
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
)
|
|
16
|
-
handler.run(app)"""
|
|
51
|
+
# Make request to application
|
|
52
|
+
def make_request(environ, stream, application, path):
|
|
17
53
|
|
|
18
|
-
|
|
19
|
-
|
|
54
|
+
# Change the working directory for logging purposes
|
|
55
|
+
goto_manager_dir()
|
|
20
56
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
self.stderr = stderr
|
|
27
|
-
self.base_env = environ
|
|
28
|
-
self.wsgi_multithread = multithread
|
|
29
|
-
self.wsgi_multiprocess = multiprocess
|
|
57
|
+
error_log_file = open('WSGI.log', 'a+')
|
|
58
|
+
|
|
59
|
+
# We want the working directory to be the app's directory
|
|
60
|
+
if (not path.endswith(os.path.sep)):
|
|
61
|
+
path = path + os.path.sep
|
|
30
62
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
63
|
+
#iris.system.Process.CurrentDirectory(path)
|
|
64
|
+
|
|
65
|
+
# Set up the body of the request
|
|
66
|
+
if stream != '':
|
|
67
|
+
bytestream = stream
|
|
68
|
+
elif (environ['CONTENT_TYPE'] == 'application/x-www-form-urlencoded'):
|
|
69
|
+
bytestream = BytesIO()
|
|
70
|
+
part = urllib.parse.urlencode(environ['formdata'])
|
|
71
|
+
bytestream.write(part.encode('utf-8'))
|
|
72
|
+
bytestream.seek(0)
|
|
73
|
+
else:
|
|
74
|
+
bytestream = BytesIO(b'')
|
|
38
75
|
|
|
76
|
+
#for k,v in os.environ.items():
|
|
77
|
+
#environ[k] = unicode_to_wsgi(v)
|
|
78
|
+
environ['wsgi.input'] = bytestream
|
|
79
|
+
environ['wsgi.errors'] = error_log_file
|
|
80
|
+
environ['wsgi.version'] = (1, 0)
|
|
81
|
+
environ['wsgi.multithread'] = False
|
|
82
|
+
environ['wsgi.multiprocess'] = True
|
|
83
|
+
environ['wsgi.run_once'] = True
|
|
39
84
|
|
|
40
|
-
def get_stderr(self):
|
|
41
|
-
return self.stderr
|
|
42
85
|
|
|
43
|
-
|
|
44
|
-
|
|
86
|
+
if environ.get('HTTPS', 'off') in ('on', '1'):
|
|
87
|
+
environ['wsgi.url_scheme'] = 'https'
|
|
88
|
+
else:
|
|
89
|
+
environ['wsgi.url_scheme'] = 'http'
|
|
90
|
+
|
|
91
|
+
# Calling WSGI application
|
|
92
|
+
response = application(environ, start_response)
|
|
45
93
|
|
|
46
|
-
|
|
47
|
-
iris.cls('Grongier.Service.WSGI').write(data)
|
|
94
|
+
error_log_file.close()
|
|
48
95
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
96
|
+
try:
|
|
97
|
+
for data in response:
|
|
98
|
+
if data:
|
|
99
|
+
# (REST.Impl).Write() needs a utf-8 string
|
|
100
|
+
write(data.decode('utf-8'))
|
|
101
|
+
write(b'')
|
|
102
|
+
finally:
|
|
103
|
+
if hasattr(response, 'close'):
|
|
104
|
+
response.close()
|
intersystems_iris/_DBList.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import struct
|
|
2
2
|
import decimal
|
|
3
3
|
import functools
|
|
4
|
+
import uuid
|
|
4
5
|
import math
|
|
5
6
|
import intersystems_iris._IRISOREF
|
|
6
7
|
import datetime
|
|
@@ -326,6 +327,10 @@ class _DBList(object):
|
|
|
326
327
|
offset = cls.__stuff_multibyte(buffer, offset, data, is_oref, locale)
|
|
327
328
|
return offset
|
|
328
329
|
|
|
330
|
+
@classmethod
|
|
331
|
+
def _stuff_uuid(cls, buffer, offset, data, locale, is_unicode, *args):
|
|
332
|
+
return cls._stuff_str(buffer, offset, str(data), locale=locale, is_unicode=is_unicode)
|
|
333
|
+
|
|
329
334
|
@classmethod
|
|
330
335
|
def _stuff_datetime(cls, buffer, offset, data, locale, is_unicode, *args):
|
|
331
336
|
return cls._stuff_str(buffer, offset, data.strftime('%Y-%m-%d %H:%M:%S.%f'), locale=locale, is_unicode=is_unicode)
|
|
@@ -496,5 +501,6 @@ _DBList._set_switcher = {
|
|
|
496
501
|
float: _DBList._stuff_double,
|
|
497
502
|
decimal.Decimal: _DBList._stuff_decimal,
|
|
498
503
|
str: _DBList._stuff_str,
|
|
504
|
+
uuid.UUID: _DBList._stuff_uuid,
|
|
499
505
|
intersystems_iris._IRISOREF._IRISOREF: _DBList._stuff_str,
|
|
500
506
|
}
|
|
@@ -51,7 +51,7 @@ class _IRISEmbedded:
|
|
|
51
51
|
reset_vars(current_vars)
|
|
52
52
|
self.iris = iris
|
|
53
53
|
self._connection_info._delimited_ids = 1
|
|
54
|
-
self.
|
|
54
|
+
self.autoCommit = autoCommit
|
|
55
55
|
|
|
56
56
|
def __enter__(self):
|
|
57
57
|
return self
|
|
@@ -60,7 +60,6 @@ class _IRISEmbedded:
|
|
|
60
60
|
self.close()
|
|
61
61
|
|
|
62
62
|
def close(self):
|
|
63
|
-
self.iris.system.SQL.SetAutoCommit(self.restore_autocommit)
|
|
64
63
|
self.iris = None
|
|
65
64
|
|
|
66
65
|
def isClosed(self):
|
|
@@ -76,6 +75,7 @@ class _IRISEmbedded:
|
|
|
76
75
|
self._pre_preparse_cache[sql] = CachedSQL(cursor)
|
|
77
76
|
|
|
78
77
|
def setAutoCommit(self, autoCommit):
|
|
78
|
+
self.autoCommit = autoCommit
|
|
79
79
|
return self.iris.system.SQL.SetAutoCommit(0 if autoCommit is None else 1 if autoCommit else 2)
|
|
80
80
|
|
|
81
81
|
def commit(self):
|
intersystems_iris/_ListWriter.py
CHANGED
|
@@ -51,6 +51,7 @@ class _ListWriter(object):
|
|
|
51
51
|
param_switcher = {
|
|
52
52
|
SQLType.LONGVARBINARY: self._set_stream,
|
|
53
53
|
SQLType.LONGVARCHAR: self._set_stream,
|
|
54
|
+
SQLType.GUID: self._set_uuid,
|
|
54
55
|
SQLType.DATE: None,
|
|
55
56
|
SQLType.TIME: None,
|
|
56
57
|
SQLType.TIMESTAMP: None,
|
|
@@ -90,7 +91,10 @@ class _ListWriter(object):
|
|
|
90
91
|
def _set_stream(self, stream):
|
|
91
92
|
self._set(stream)
|
|
92
93
|
# raise NotImplementedError("Stream functionality not yet available with iris.dbapi")
|
|
93
|
-
|
|
94
|
+
|
|
95
|
+
def _set_uuid(self, val):
|
|
96
|
+
self._set(str(val))
|
|
97
|
+
|
|
94
98
|
def _set_date_h(self, date):
|
|
95
99
|
HOROLOG_ORDINAL = datetime.date(1840, 12, 31).toordinal()
|
|
96
100
|
if isinstance(date, datetime.date):
|
|
@@ -2,6 +2,7 @@ import struct
|
|
|
2
2
|
import copy
|
|
3
3
|
import enum
|
|
4
4
|
import copy
|
|
5
|
+
import uuid
|
|
5
6
|
import decimal
|
|
6
7
|
import intersystems_iris
|
|
7
8
|
from collections import namedtuple
|
|
@@ -337,7 +338,7 @@ class _BaseCursor:
|
|
|
337
338
|
raise ValueError("INOUT/OUT parameters not permitted")
|
|
338
339
|
|
|
339
340
|
self._prepared_update_execute()
|
|
340
|
-
|
|
341
|
+
|
|
341
342
|
return self._rowcount
|
|
342
343
|
|
|
343
344
|
def _process_sqlcode(self, sqlcode, message=None):
|
|
@@ -367,8 +368,9 @@ class _BaseCursor:
|
|
|
367
368
|
if not self._is_batch_update:
|
|
368
369
|
raise TypeError("Unsupported argument type: " + str(type(item)))
|
|
369
370
|
for ele in item:
|
|
370
|
-
if
|
|
371
|
-
|
|
371
|
+
if not intersystems_iris._DBList._DBList._set_switcher.get(type(ele), None) and not issubclass(
|
|
372
|
+
type(ele), enum.Enum
|
|
373
|
+
):
|
|
372
374
|
raise TypeError("Unsupported argument type: " + str(type(ele)))
|
|
373
375
|
elif intersystems_iris._DBList._DBList._set_switcher.get(type(item), None) is None:
|
|
374
376
|
item = str(item)
|
|
@@ -661,7 +663,7 @@ class _BaseCursor:
|
|
|
661
663
|
def description(self):
|
|
662
664
|
if self._statementType is StatementType.UPDATE:
|
|
663
665
|
return None
|
|
664
|
-
|
|
666
|
+
|
|
665
667
|
if self._columns is None:
|
|
666
668
|
return None
|
|
667
669
|
|
|
@@ -757,7 +759,7 @@ class Cursor(_BaseCursor):
|
|
|
757
759
|
return True
|
|
758
760
|
else:
|
|
759
761
|
return False
|
|
760
|
-
|
|
762
|
+
|
|
761
763
|
def _reset_cached_info(self):
|
|
762
764
|
if not self._connection._preparedCache or not hasattr(self._connection._preparedCache, "__iter__"):
|
|
763
765
|
return
|
|
@@ -1178,7 +1180,7 @@ class Cursor(_BaseCursor):
|
|
|
1178
1180
|
sets = self._parameter_sets or 1
|
|
1179
1181
|
self.params = list(self.params).copy()
|
|
1180
1182
|
param_types = [param.type for param in self._params._params_list]
|
|
1181
|
-
|
|
1183
|
+
|
|
1182
1184
|
for i in range(sets):
|
|
1183
1185
|
params = self._params.collect(i)
|
|
1184
1186
|
for pi, param in enumerate(params):
|
|
@@ -1207,14 +1209,18 @@ class Cursor(_BaseCursor):
|
|
|
1207
1209
|
if size == 0:
|
|
1208
1210
|
break
|
|
1209
1211
|
size = 4096 if size > 4096 else size
|
|
1210
|
-
chunk = value[offset:offset + size]
|
|
1212
|
+
chunk = value[offset : offset + size]
|
|
1211
1213
|
if not isinstance(chunk, bytes):
|
|
1212
1214
|
chunk = bytes(chunk, "utf-8")
|
|
1213
1215
|
offset += size
|
|
1214
1216
|
full_size -= size
|
|
1215
1217
|
|
|
1216
1218
|
# message header
|
|
1217
|
-
code =
|
|
1219
|
+
code = (
|
|
1220
|
+
_Message.STORE_BINARY_STREAM
|
|
1221
|
+
if param_type == SQLType.LONGVARBINARY
|
|
1222
|
+
else _Message.STORE_CHARACTER_STREAM
|
|
1223
|
+
)
|
|
1218
1224
|
self._out_message.wire._write_header(code)
|
|
1219
1225
|
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
|
1220
1226
|
self._out_message.wire.buffer, self._statement_id
|
|
@@ -2240,10 +2246,23 @@ class EmbdeddedCursor(_BaseCursor):
|
|
|
2240
2246
|
self._sql = connection.iris.sql
|
|
2241
2247
|
self._iris = connection.iris
|
|
2242
2248
|
self._closed = False
|
|
2249
|
+
self._connection = connection
|
|
2250
|
+
self.restore_selectmode = self._iris.system.SQL.SetSelectMode(1)
|
|
2251
|
+
self.restore_autocommit = self._iris.system.SQL.SetAutoCommit(
|
|
2252
|
+
0 if self._connection.autoCommit is None else 1 if self._connection.autoCommit else 2
|
|
2253
|
+
)
|
|
2243
2254
|
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2255
|
+
def close(self):
|
|
2256
|
+
self._iris.system.SQL.SetSelectMode(self.restore_selectmode)
|
|
2257
|
+
self._iris.system.SQL.SetAutoCommit(self.restore_autocommit)
|
|
2258
|
+
super().close()
|
|
2259
|
+
|
|
2260
|
+
def __del__(self):
|
|
2261
|
+
try:
|
|
2262
|
+
self.close()
|
|
2263
|
+
except:
|
|
2264
|
+
pass
|
|
2265
|
+
return
|
|
2247
2266
|
|
|
2248
2267
|
def _get_cached_info(self):
|
|
2249
2268
|
return False
|
|
@@ -2386,14 +2405,18 @@ class EmbdeddedCursor(_BaseCursor):
|
|
|
2386
2405
|
sets = self._parameter_sets or 1
|
|
2387
2406
|
metadata = self._statement.Statement._Metadata.parameters
|
|
2388
2407
|
param_types = [metadata.GetAt(i + 1).ODBCType for i in range(metadata.Size)]
|
|
2389
|
-
|
|
2408
|
+
|
|
2390
2409
|
stream_chunk_size = 32000
|
|
2391
2410
|
|
|
2392
2411
|
for i in range(sets):
|
|
2393
2412
|
params = self._get_parameters(i)
|
|
2394
2413
|
for ip, param in enumerate(params):
|
|
2395
2414
|
if param_types[ip] in (SQLType.LONGVARBINARY, SQLType.LONGVARCHAR):
|
|
2396
|
-
stream_class =
|
|
2415
|
+
stream_class = (
|
|
2416
|
+
"%Stream.GlobalBinary"
|
|
2417
|
+
if param_types[ip] == SQLType.LONGVARBINARY
|
|
2418
|
+
else "%Stream.GlobalCharacter"
|
|
2419
|
+
)
|
|
2397
2420
|
stream = self._iris.cls(stream_class)._New()
|
|
2398
2421
|
while param:
|
|
2399
2422
|
stream.Write(param[:stream_chunk_size])
|
|
@@ -2448,6 +2471,7 @@ class EmbdeddedCursor(_BaseCursor):
|
|
|
2448
2471
|
row = namedtuple("Row", [col.name for col in self._columns], rename=True)
|
|
2449
2472
|
|
|
2450
2473
|
_types = {
|
|
2474
|
+
SQLType.GUID: uuid.UUID,
|
|
2451
2475
|
SQLType.BIGINT: int,
|
|
2452
2476
|
SQLType.BINARY: bytes,
|
|
2453
2477
|
SQLType.VARBINARY: bytes,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import uuid
|
|
1
2
|
from datetime import datetime
|
|
2
3
|
from collections import namedtuple
|
|
3
4
|
from ._SQLType import SQLType
|
|
@@ -67,6 +68,7 @@ class _ResultSetRow:
|
|
|
67
68
|
|
|
68
69
|
class DataRow:
|
|
69
70
|
_types = {
|
|
71
|
+
SQLType.GUID: uuid.UUID,
|
|
70
72
|
SQLType.BIGINT: int,
|
|
71
73
|
SQLType.BINARY: bytes,
|
|
72
74
|
SQLType.BIT: None,
|
|
@@ -157,6 +159,8 @@ class _ResultSetRow:
|
|
|
157
159
|
ctype = _column.type
|
|
158
160
|
value_type = self._types[ctype] if ctype in self._types else None
|
|
159
161
|
try:
|
|
162
|
+
if ctype == SQLType.GUID:
|
|
163
|
+
item = uuid.UUID(item)
|
|
160
164
|
if ctype == SQLType.TIMESTAMP_POSIX:
|
|
161
165
|
item = from_timestamp_posix(item)
|
|
162
166
|
|
iris/__init__.pyi
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any
|
|
3
|
+
from iris.iris_ipm import ipm
|
|
4
|
+
from . import iris_ipm
|
|
5
|
+
__all__ = [ 'check_status', 'cls', 'execute', 'gref', 'ipm', 'iris_ipm', 'lock', 'os', 'ref', 'routine', 'sql', 'system', 'tcommit', 'tlevel', 'trollback', 'trollbackone', 'tstart', 'unlock', 'utils']
|
|
6
|
+
def check_status(self, status):
|
|
7
|
+
"""
|
|
8
|
+
Raises an exception on an error status, or returns None if no error condition occurs.
|
|
9
|
+
Example: iris.check_status(st) checks the status code st to see if it contains an error.
|
|
10
|
+
"""
|
|
11
|
+
def cls(self, class_name):
|
|
12
|
+
"""
|
|
13
|
+
Returns a reference to an InterSystems IRIS class.
|
|
14
|
+
Example: iris.cls("%SYSTEM.INetInfo").LocalHostName() calls a method in the class %SYSTEM.INetInfo.
|
|
15
|
+
"""
|
|
16
|
+
def execute(self, statements):
|
|
17
|
+
"""
|
|
18
|
+
execute IRIS statements.
|
|
19
|
+
Example: iris.execute("set x="Hello"\nw x,!\n") returns nothing.
|
|
20
|
+
"""
|
|
21
|
+
def gref(self, global_name):
|
|
22
|
+
"""
|
|
23
|
+
Returns a reference to an InterSystems IRIS global.
|
|
24
|
+
Example: g = iris.gref("^foo") sets g to a reference to global ^foo
|
|
25
|
+
"""
|
|
26
|
+
def lock(self, lock_list, timeout_value, locktype):
|
|
27
|
+
"""
|
|
28
|
+
Sets locks, given a list of lock names, an optional timeout value (in seconds), and an optional locktype.
|
|
29
|
+
Example: iris.lock(["^foo","^bar"], 30, "S") sets locks "^foo" and "^bar", waiting up to 30 seconds, and using shared locks.
|
|
30
|
+
"""
|
|
31
|
+
def ref(self, value):
|
|
32
|
+
"""
|
|
33
|
+
Creates an iris.ref object with a specified value.
|
|
34
|
+
Example: iris.ref("hello") creates an iris.ref object with the value "hello"
|
|
35
|
+
"""
|
|
36
|
+
def routine(self, routine, args):
|
|
37
|
+
"""
|
|
38
|
+
Invokes an InterSystems IRIS routine, optionally at a given tag.
|
|
39
|
+
Example: iris.routine("Stop^SystemPerformance", "20211221_160620_test") calls tag Stop in routine ^SystemPerformance.
|
|
40
|
+
"""
|
|
41
|
+
def tcommit(self):
|
|
42
|
+
"""
|
|
43
|
+
Marks a successful end of an InterSystems IRIS transaction.
|
|
44
|
+
Example: iris.commit() marks the successful end of a transaction and decrements the nesting level by 1
|
|
45
|
+
"""
|
|
46
|
+
def tlevel(self):
|
|
47
|
+
"""
|
|
48
|
+
Detects whether a transaction is currently in progress and returns the nesting level. Zero means not in a transaction.
|
|
49
|
+
Example: iris.tlevel() returns the current transaction nesting level, or zero if not in a transaction
|
|
50
|
+
"""
|
|
51
|
+
def trollback(self):
|
|
52
|
+
"""
|
|
53
|
+
Terminates the current transaction and restores all journaled database values to their values at the start of the transaction.
|
|
54
|
+
Example: iris.trollback() rolls back all current transactions in progress and resets the transaction nesting level to 0
|
|
55
|
+
"""
|
|
56
|
+
def trollbackone(self):
|
|
57
|
+
"""
|
|
58
|
+
Rolls back the current level of nested transactions, that is, the one initiated by the most recent tstart().
|
|
59
|
+
Example: iris.trollbackone() rolls back the current level of nested transactions and decrements the nesting level by 1
|
|
60
|
+
"""
|
|
61
|
+
def tstart(self):
|
|
62
|
+
"""
|
|
63
|
+
Starts an InterSystems IRIS transaction.
|
|
64
|
+
Example: iris.tstart() marks the beginning of a transaction.
|
|
65
|
+
"""
|
|
66
|
+
def unlock(self, lock_list, timout_value, locktype):
|
|
67
|
+
"""
|
|
68
|
+
Removes locks, given a list of lock names, an optional timeout value (in seconds), and an optional locktype.
|
|
69
|
+
Example: iris.unlock(["^foo","^bar"], 30, "S") removes locks "^foo" and "^bar", waiting up to 30 seconds, and using shared locks.
|
|
70
|
+
"""
|
|
71
|
+
def utils(self):
|
|
72
|
+
"""
|
|
73
|
+
Returns a reference to the InterSystems IRIS utilities class.
|
|
74
|
+
Example: iris.utils().$Job() returns the current job number.
|
|
75
|
+
"""
|
|
76
|
+
# stubs for the sql object
|
|
77
|
+
class sql:
|
|
78
|
+
"""
|
|
79
|
+
The sql object provides access to the InterSystems IRIS SQL API.
|
|
80
|
+
"""
|
|
81
|
+
def exec(self, query: str) -> Any:
|
|
82
|
+
"""
|
|
83
|
+
Execute a query
|
|
84
|
+
"""
|
|
85
|
+
def prepare(self, query: str) -> PreparedQuery:
|
|
86
|
+
"""
|
|
87
|
+
Prepare a query
|
|
88
|
+
"""
|
|
89
|
+
class PreparedQuery:
|
|
90
|
+
def execute(self, **kwargs) -> Any:
|
|
91
|
+
"""
|
|
92
|
+
Execute a prepared query, you can pass values
|
|
93
|
+
"""
|
|
94
|
+
# stubs for the system object
|
|
95
|
+
class system:
|
|
96
|
+
"""
|
|
97
|
+
The system object provides access to the InterSystems IRIS system API.
|
|
98
|
+
The following classes are available:
|
|
99
|
+
'DocDB', 'Encryption', 'Error', 'Event', 'Monitor', 'Process', 'Python', 'SQL', 'SYS', 'Security', 'Semaphore', 'Status', 'Util', 'Version'
|
|
100
|
+
"""
|
|
101
|
+
class DocDB:
|
|
102
|
+
"""
|
|
103
|
+
The DocDB class provides access to the InterSystems IRIS Document Database API.
|
|
104
|
+
The following methods are available:
|
|
105
|
+
'CreateDatabase', 'DropAllDatabases', 'DropDatabase', 'Exists', 'GetAllDatabases', 'GetDatabase', 'Help'
|
|
106
|
+
"""
|
|
107
|
+
def CreateDatabase(self, name: str, path: str, **kwargs) -> Any:
|
|
108
|
+
"""
|
|
109
|
+
Create a database
|
|
110
|
+
"""
|
|
111
|
+
def DropAllDatabases(self) -> Any:
|
|
112
|
+
"""
|
|
113
|
+
Drop all databases
|
|
114
|
+
"""
|
|
115
|
+
def DropDatabase(self, name: str) -> Any:
|
|
116
|
+
"""
|
|
117
|
+
Drop a database
|
|
118
|
+
"""
|
|
119
|
+
def Exists(self, name: str) -> Any:
|
|
120
|
+
"""
|
|
121
|
+
Check if a database exists
|
|
122
|
+
"""
|
|
123
|
+
def GetAllDatabases(self) -> Any:
|
|
124
|
+
"""
|
|
125
|
+
Get all databases
|
|
126
|
+
"""
|
|
127
|
+
def GetDatabase(self, name: str) -> Any:
|
|
128
|
+
"""
|
|
129
|
+
Get a database
|
|
130
|
+
"""
|
|
131
|
+
def Help(self) -> Any:
|
|
132
|
+
"""
|
|
133
|
+
Get help
|
|
134
|
+
"""
|
|
135
|
+
def Encryption(self) -> Any:
|
|
136
|
+
"""
|
|
137
|
+
The Encryption class provides access to the InterSystems IRIS Encryption API.
|
|
138
|
+
"""
|
|
139
|
+
def Error(self) -> Any:
|
|
140
|
+
"""
|
|
141
|
+
The Error class provides access to the InterSystems IRIS Error API.
|
|
142
|
+
"""
|
|
143
|
+
def Event(self) -> Any:
|
|
144
|
+
"""
|
|
145
|
+
The Event class provides access to the InterSystems IRIS Event API.
|
|
146
|
+
"""
|
|
147
|
+
def Monitor(self) -> Any:
|
|
148
|
+
"""
|
|
149
|
+
The Monitor class provides access to the InterSystems IRIS Monitor API.
|
|
150
|
+
"""
|
|
151
|
+
def Process(self) -> Any:
|
|
152
|
+
"""
|
|
153
|
+
The Process class provides access to the InterSystems IRIS Process API.
|
|
154
|
+
"""
|
|
155
|
+
def Python(self) -> Any:
|
|
156
|
+
"""
|
|
157
|
+
The Python class provides access to the InterSystems IRIS Python API.
|
|
158
|
+
"""
|
|
159
|
+
def SQL(self) -> Any:
|
|
160
|
+
"""
|
|
161
|
+
The SQL class provides access to the InterSystems IRIS SQL API.
|
|
162
|
+
"""
|
|
163
|
+
def SYS(self) -> Any:
|
|
164
|
+
"""
|
|
165
|
+
The SYS class provides access to the InterSystems IRIS SYS API.
|
|
166
|
+
"""
|
|
167
|
+
def Security(self) -> Any:
|
|
168
|
+
"""
|
|
169
|
+
The Security class provides access to the InterSystems IRIS Security API.
|
|
170
|
+
"""
|
|
171
|
+
def Semaphore(self) -> Any:
|
|
172
|
+
"""
|
|
173
|
+
The Semaphore class provides access to the InterSystems IRIS Semaphore API.
|
|
174
|
+
"""
|
|
175
|
+
def Status(self) -> Any:
|
|
176
|
+
"""
|
|
177
|
+
The Status class provides access to the InterSystems IRIS Status API.
|
|
178
|
+
"""
|
|
179
|
+
def Util(self) -> Any:
|
|
180
|
+
"""
|
|
181
|
+
The Util class provides access to the InterSystems IRIS Util API.
|
|
182
|
+
"""
|
|
183
|
+
def Version(self) -> Any:
|
|
184
|
+
"""
|
|
185
|
+
The Version class provides access to the InterSystems IRIS Version API.
|
|
186
|
+
"""
|
|
187
|
+
|
iris/iris_ipm.pyi
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
__all__ = ['ipm']
|
|
3
|
+
def ipm(cmd, *args):
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
Executes shell command with IPM:
|
|
7
|
+
Parameters
|
|
8
|
+
----------
|
|
9
|
+
cmd : str
|
|
10
|
+
The command to execute
|
|
11
|
+
Examples
|
|
12
|
+
--------
|
|
13
|
+
`ipm('help')`
|
|
14
|
+
`ipm('load /home/irisowner/dev -v')`
|
|
15
|
+
`ipm('install webterminal')`
|
|
16
|
+
|
|
17
|
+
"""
|
{iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
|
-
Name:
|
|
3
|
-
Version: 2.3.
|
|
2
|
+
Name: iris_pex_embedded_python
|
|
3
|
+
Version: 2.3.23b2
|
|
4
4
|
Summary: Iris Interoperability based on Embedded Python
|
|
5
5
|
Author-email: grongier <guillaume.rongier@intersystems.com>
|
|
6
6
|
License: MIT License
|
{iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/RECORD
RENAMED
|
@@ -18,7 +18,7 @@ grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls,sha256=WbBn7pWj5mzruVfL
|
|
|
18
18
|
grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls,sha256=2lj-e20AH7RR8UgGJaldrk-1kd8WjQJNPiH-duds_4A,987
|
|
19
19
|
grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls,sha256=DAtq4DyRqFq2_4Isa0cZjjwuAzdHjsQu8wMppK4myzs,994
|
|
20
20
|
grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls,sha256=ofVKjrN6UPFasalrjPFWYNwlJ5IBlAE62IH8_U07c0g,1435
|
|
21
|
-
grongier/cls/Grongier/Service/WSGI.cls,sha256=
|
|
21
|
+
grongier/cls/Grongier/Service/WSGI.cls,sha256=2KrnsATyoarrN6un-2sJwNK-ANw36Waa8GgFx97XQKA,10598
|
|
22
22
|
grongier/pex/__init__.py,sha256=nvcmRCxLy-lpL5GzlCKrmsSK8LF8Q0aKddx6ib8U50E,1166
|
|
23
23
|
grongier/pex/__main__.py,sha256=ebEYPDOBKiXOlmdI4onpQLzfBKU4wyfijYyquA5dWV4,107
|
|
24
24
|
grongier/pex/_business_host.py,sha256=G4-eWlQzWMvjaHauISfSoogPsfQYJavmRi563ak6FS8,20858
|
|
@@ -35,20 +35,20 @@ grongier/pex/_pickle_message.py,sha256=noKfc2VkXufV3fqjKvNHN_oANQ1YN9ffCaSV0XSTA
|
|
|
35
35
|
grongier/pex/_private_session_duplex.py,sha256=Qj_xzwwFnFVwi_Sl7Q7nKk4zmL6UC8iqBAuwnz7mVX8,5033
|
|
36
36
|
grongier/pex/_private_session_process.py,sha256=_2r_csWcVRLmIUt4O0Y1Hg1FcX6A08lt9DvALQhwu8s,1722
|
|
37
37
|
grongier/pex/_utils.py,sha256=GjHT5WolQAoeYkhHP3a0uDBlRzPIkyGG_bi-TwrMdjI,15877
|
|
38
|
-
grongier/pex/wsgi/handlers.py,sha256=
|
|
38
|
+
grongier/pex/wsgi/handlers.py,sha256=NrFLo_YbAh-x_PlWhAiWkQnUUN2Ss9HoEm63dDWCBpQ,2947
|
|
39
39
|
intersystems_iris/_BufferReader.py,sha256=BXjHQs-sclAnvW9mvdlIrtku9m2Jf67Rc5rsZll7a5g,299
|
|
40
40
|
intersystems_iris/_BufferWriter.py,sha256=i2BKM99J8pB5fGn-Gjdo4vcwXPEZQymsLEQd69nJrhs,1337
|
|
41
41
|
intersystems_iris/_ConnectionInformation.py,sha256=Xr6sOPy3uKFyOG05hTmutDHTNjHDhCnCVwH0TTNEwBE,1896
|
|
42
42
|
intersystems_iris/_ConnectionParameters.py,sha256=5-VwMJP_6Ya0lNnMf0UuwJQQfwHcozjknnUekMwCgQ4,578
|
|
43
43
|
intersystems_iris/_Constant.py,sha256=g2NdV669sNH4kUoAjQFNq2xWaEMQiPMoQytNNrrXOnk,1483
|
|
44
|
-
intersystems_iris/_DBList.py,sha256=
|
|
44
|
+
intersystems_iris/_DBList.py,sha256=D0m_N50ZhpUnGwQiPZ1ZPtNecqROZvSnVbP46RY6juA,20340
|
|
45
45
|
intersystems_iris/_Device.py,sha256=02rNhk32bLrcOdGDOsRHuX79-MLblGvAdBa-XfHtVkw,2311
|
|
46
46
|
intersystems_iris/_GatewayContext.py,sha256=anipv7v5rDS2Ha2MmXTuMtFjo6UNgzUF3SwKQSS-co8,618
|
|
47
47
|
intersystems_iris/_GatewayException.py,sha256=Hs5en7W1mhtt2heuoeyhF5IqFKGqbRD5GWyWZUhwDzs,96
|
|
48
48
|
intersystems_iris/_GatewayUtility.py,sha256=gJTslU_UZBI8bWPTPe6b41DwhaAmlpzUNYT0LkAKXKk,2735
|
|
49
49
|
intersystems_iris/_IRIS.py,sha256=vlxyMtfvyTkHHw5CkfNYqNbR1zUdAknfbLVTGxEOv3E,49548
|
|
50
50
|
intersystems_iris/_IRISConnection.py,sha256=MmPIQJPZ28HoSYafvf4r5cbenzDiHmZhKgZXVfSxnCw,21467
|
|
51
|
-
intersystems_iris/_IRISEmbedded.py,sha256=
|
|
51
|
+
intersystems_iris/_IRISEmbedded.py,sha256=yYL71oLvHjLK_jF8wcyNjXu3ManQ_PpY2wD4GkOfa-E,2503
|
|
52
52
|
intersystems_iris/_IRISGlobalNode.py,sha256=o2MEvyRmNrvLAR0dpeQ76r9b8Yw2sKDaaRLFyGYdcDQ,12049
|
|
53
53
|
intersystems_iris/_IRISGlobalNodeView.py,sha256=0yw9z_mpSLk2m3we5z_vKSjnEdmKfZb11bbASZiiSm8,797
|
|
54
54
|
intersystems_iris/_IRISIterator.py,sha256=m1n_fRdoO8YPfDi7l-JvJTqdJuxq_kxC60aMxkxLJUE,6906
|
|
@@ -61,7 +61,7 @@ intersystems_iris/_InStream.py,sha256=6g4HdDoQ0MFub8Yn-Git8DkJNEoyyAtAhrvjkUdDA7
|
|
|
61
61
|
intersystems_iris/_LegacyIterator.py,sha256=K1CPMBDWBCwKVqIq9hBJ2q_uMiBnht_OdN66g7ZqXfw,4130
|
|
62
62
|
intersystems_iris/_ListItem.py,sha256=k9m0Q0W3e3WuI5cpB1GSZOR9NkkCT87lgvBwYFMzvic,354
|
|
63
63
|
intersystems_iris/_ListReader.py,sha256=wgK0HC56lI1Wdp9Sr3rax6w8NoR5p2YpklswpNIS5X8,2966
|
|
64
|
-
intersystems_iris/_ListWriter.py,sha256=
|
|
64
|
+
intersystems_iris/_ListWriter.py,sha256=zBQd7Mx3ho0jOd_q4RNAhw1ub1kUXVptwRYMN36OQew,5612
|
|
65
65
|
intersystems_iris/_LogFileStream.py,sha256=Dv3S8-zY3b7P4xXx7w0UVGm2vuz7bWTyaOTg6eK0l2s,3797
|
|
66
66
|
intersystems_iris/_MessageHeader.py,sha256=N45Qp25ER7ftGA0BRBxErIpavDF-j4qWv_0kobkAp6U,1662
|
|
67
67
|
intersystems_iris/_OutStream.py,sha256=_I83KPUCv9yBHsaB4QGBeSatypdiMGJxckKdNY1Jzyg,1327
|
|
@@ -71,13 +71,13 @@ intersystems_iris/_SharedMemorySocket.py,sha256=2iUaS1FdJNSCUEaE-VT0O_dxF6NRwqZS
|
|
|
71
71
|
intersystems_iris/__init__.py,sha256=Tk1tD28LwvF6X3yXQsJFLE1Bc-PR3gUJWcX5UnNYOdY,1773
|
|
72
72
|
intersystems_iris/__main__.py,sha256=rCtINTfJcADMAsw1ja-MEO7Q-XekrWthYowzWV8xGIQ,218
|
|
73
73
|
intersystems_iris/dbapi/_Column.py,sha256=VCLHLXs3wuGcUa9w_qy7HBFsuGvhmmI3kGYBagQg59U,2535
|
|
74
|
-
intersystems_iris/dbapi/_DBAPI.py,sha256=
|
|
74
|
+
intersystems_iris/dbapi/_DBAPI.py,sha256=sqkUxjhK683icHlE56ywygV8ODz7yudeIJOQSQTeb78,102938
|
|
75
75
|
intersystems_iris/dbapi/_Descriptor.py,sha256=IjyITxvjygDrhpk-0lGhdqQPh91SG6nTb1vi-AqyJNI,1391
|
|
76
76
|
intersystems_iris/dbapi/_IRISStream.py,sha256=dGJntWo4HXgM1nUHZl2hA4xHkBFEU2xkoEplVDFWhnA,2115
|
|
77
77
|
intersystems_iris/dbapi/_Message.py,sha256=jpLG3HZElqp981iNPFW8UNRO3NbHf6poEv6yywX0Ssw,4076
|
|
78
78
|
intersystems_iris/dbapi/_Parameter.py,sha256=lvPlQkoLlyEjg5J_a9t2I_6vRDkAav6kN1fGyukH4DY,5293
|
|
79
79
|
intersystems_iris/dbapi/_ParameterCollection.py,sha256=kcgNiGv2nH5AwuA6LlPpM4dWqhSqRyD3VtwqHqDGRGU,5541
|
|
80
|
-
intersystems_iris/dbapi/_ResultSetRow.py,sha256=
|
|
80
|
+
intersystems_iris/dbapi/_ResultSetRow.py,sha256=1V5ixV2VQz0-LDEvVz-khW4e1V6xmlgZ6VyV4PbuQsE,13052
|
|
81
81
|
intersystems_iris/dbapi/_SQLType.py,sha256=IlDacXwQzUMWaJ02Zsu2bUfvUC3-5mBx-m6mE0Yp7ts,557
|
|
82
82
|
intersystems_iris/dbapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
83
83
|
intersystems_iris/dbapi/preparser/_PreParser.py,sha256=024w-s3n_JNsk_ISC8avJMK3QEZE3hSuD0Nr8arJdZw,78828
|
|
@@ -100,12 +100,14 @@ intersystems_iris/pex/_Message.py,sha256=Ugaa_lsEYke__pI5kdC7phAuyPQ7rxXUcROJL4c
|
|
|
100
100
|
intersystems_iris/pex/_OutboundAdapter.py,sha256=ao2Ubbta2DcrQGdzDUD_j1Zsk8bvUfcZNKTZkzPTNBU,1628
|
|
101
101
|
intersystems_iris/pex/__init__.py,sha256=l_I1dpnluWawbFrGMDC0GLHpuHwjbpd-nho8otFX6TE,1379
|
|
102
102
|
iris/__init__.py,sha256=VyBPMqjkad0JPoza38YZbBeLHM7jZUMS90t8KKEIW94,1045
|
|
103
|
+
iris/__init__.pyi,sha256=BtE0ZohcTo2EYDQhlqqEndMUnIyQIHUte3OIx3S6DKo,6994
|
|
103
104
|
iris/iris_ipm.py,sha256=Q0jcNItjywlqOPZr0hgdTFSeLPNEmB-tcICOI_cXnaY,790
|
|
105
|
+
iris/iris_ipm.pyi,sha256=j7CNUZcjeDu5sgeWUZJO_Qi4vQmHh6aD-jPWv8OdoUs,374
|
|
104
106
|
irisnative/_IRISNative.py,sha256=HQ4nBhc8t8_5OtxdMG-kx1aa-T1znf2I8obZOPLOPzg,665
|
|
105
107
|
irisnative/__init__.py,sha256=6YmvBLQSURsCPKaNg7LK-xpo4ipDjrlhKuwdfdNb3Kg,341
|
|
106
|
-
iris_pex_embedded_python-2.3.
|
|
107
|
-
iris_pex_embedded_python-2.3.
|
|
108
|
-
iris_pex_embedded_python-2.3.
|
|
109
|
-
iris_pex_embedded_python-2.3.
|
|
110
|
-
iris_pex_embedded_python-2.3.
|
|
111
|
-
iris_pex_embedded_python-2.3.
|
|
108
|
+
iris_pex_embedded_python-2.3.23b2.dist-info/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
|
|
109
|
+
iris_pex_embedded_python-2.3.23b2.dist-info/METADATA,sha256=i4jd-lv7DrBSOBzsc01noZTT-lszckwRwEG4DFy312Y,49682
|
|
110
|
+
iris_pex_embedded_python-2.3.23b2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
111
|
+
iris_pex_embedded_python-2.3.23b2.dist-info/entry_points.txt,sha256=atkAtHoIuwXcZ0jl5gwof0l__ru_lt8WhVYk6HxYf70,47
|
|
112
|
+
iris_pex_embedded_python-2.3.23b2.dist-info/top_level.txt,sha256=Tl4ZHgeNefaZW2Oug30vSldhD-tWzixsIfzASBrZ9ps,43
|
|
113
|
+
iris_pex_embedded_python-2.3.23b2.dist-info/RECORD,,
|
{iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/LICENSE
RENAMED
|
File without changes
|
{iris_pex_embedded_python-2.3.22b3.dist-info → iris_pex_embedded_python-2.3.23b2.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|