viqi-api 0.0__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.
@@ -0,0 +1,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: viqi_api
3
+ Version: 0.0
4
+ Summary: ViQi Python API
5
+ Author-email: ViQi Inc <info@viqi.org>
6
+ Project-URL: homepage, https://www.viqi.org
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.8
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: configparser
13
+ Requires-Dist: bisque-metadoc>=0.6.4.16
14
+ Requires-Dist: tifffile
15
+ Requires-Dist: furl
16
+ Requires-Dist: simplejson
17
+ Requires-Dist: shortuuid>=1.0.8
18
+ Requires-Dist: tenacity
19
+ Requires-Dist: importlib-metadata; python_version < "3.10"
20
+ Requires-Dist: boto3>=1.28.52
21
+ Requires-Dist: urllib3>=2.0.0
22
+ Requires-Dist: requests>=2.32.0
23
+ Requires-Dist: requests-cache>=1.1.0
24
+ Requires-Dist: requests-toolbelt>=1.0.0
25
+ Provides-Extra: test
26
+ Requires-Dist: pytest; extra == "test"
27
+ Requires-Dist: pytest-cov; extra == "test"
28
+ Requires-Dist: webtest; extra == "test"
29
+ Requires-Dist: pandas; extra == "test"
30
+ Requires-Dist: numpy; extra == "test"
31
+ Requires-Dist: tables; extra == "test"
32
+ Requires-Dist: responses; extra == "test"
33
+ Requires-Dist: imagecodecs; extra == "test"
34
+ Provides-Extra: image-service
35
+ Requires-Dist: tifffile; extra == "image-service"
36
+ Requires-Dist: tables; extra == "image-service"
37
+ Provides-Extra: table-service
38
+ Requires-Dist: numpy; extra == "table-service"
39
+ Requires-Dist: pandas; extra == "table-service"
40
+ Requires-Dist: tables; extra == "table-service"
41
+
42
+ # ViQi API
43
+
44
+ Low level interface to ViQi services
45
+
46
+
47
+ ## Install
48
+
49
+
50
+ `pip install viqi-api `
51
+
52
+ ## Configuration
53
+
54
+ For command line tools create `~/.config/viqi/profiles` or `~/config/viqi/profiles`` (windows) with the following
55
+
56
+ ```
57
+ [default]
58
+ host=https://science.viqiai.cloud
59
+ user=myuser
60
+ password=mysecret
61
+
62
+ [science-user2]
63
+ host=https://science.viqiai.cloud
64
+ user=myuser2
65
+ password=mysecret2
66
+
67
+ # Admin can switch to another user
68
+ [science-secret-user]
69
+ host=https://science.viqiai.cloud
70
+ user=admin@viqi.org
71
+ password=admin_secret
72
+ alias=secret-user@viqi.org
73
+ ```
74
+
75
+ ## Documentation
76
+ * [viqi-api](https://viqi.gitlab.io/viqi-common/bisque-api/)
77
+ 1. [Service-oriented API](https://viqi.gitlab.io/viqi-common/bisque-api/soapi.html)
78
+ 1. [Object-oriented API](https://viqi.gitlab.io/viqi-common/bisque-api/ooapi.html)
79
+
80
+
81
+ ## Usage & Initialization
82
+
83
+ The `viqi_session` helper provides a flexible way to initialize a session, whether from command line arguments, configuration files, or direct parameters in Python.
84
+
85
+ ### 1. From Command Line Arguments (Scripts)
86
+
87
+ When used in a script without arguments, `viqi_session()` automatically parses `sys.argv`. This is the standard way to write scripts that can be configured via flags or config files.
88
+
89
+ **myscript.py**:
90
+ ```python
91
+ from vqapi import viqi_session
92
+ session = viqi_session()
93
+
94
+ if session:
95
+ # Session is ready and connected
96
+ print(f"Connected to {session.bqServer} as {session.user}")
97
+
98
+ # Access services
99
+ meta = session.service("meta")
100
+ # ...
101
+ ```
102
+
103
+ **Run it:**
104
+ ```bash
105
+ # Using explicit credentials
106
+ python myscript.py --host https://science.viqiai.cloud --user myuser --password mysecret
107
+
108
+ # Using a profile defined in ~/.config/viqi/profiles
109
+ python myscript.py --profile default
110
+ ```
111
+
112
+ ### 2. From Python Parameters (Interactive/Library)
113
+
114
+ You can pass arguments directly as keyword arguments. This is useful for interactive sessions (like IPython/Jupyter) or when embedding the library.
115
+
116
+ ```python
117
+ from vqapi import viqi_session
118
+
119
+ # Using a profile defined in ~/.config/viqi/profiles
120
+ session = viqi_session(profile="science-user2")
121
+
122
+ # Using explicit credentials
123
+ session = viqi_session(
124
+ host="https://science.viqiai.cloud",
125
+ user="myuser",
126
+ password="mysecret"
127
+ )
128
+
129
+ # Using an auth token
130
+ session = viqi_session(
131
+ host="https://science.viqiai.cloud",
132
+ authtoken="YOUR_AUTH_TOKEN"
133
+ )
134
+ ```
135
+
136
+ ### 3. Simulating Command Line Arguments
137
+
138
+ You can pass a list of strings to `args` to simulate command line input.
139
+
140
+ ```python
141
+ session = viqi_session(args=["--host", "https://science.viqiai.cloud", "--user", "admin", "--password", "secret"])
142
+ ```
143
+
144
+ ### 4. Custom Argument Parser
145
+
146
+ If your script requires its own custom arguments, you can extend the standard ViQi parser.
147
+
148
+ ```python
149
+ import argparse
150
+ from vqapi import viqi_session, viqi_argument_parser
151
+
152
+ # 1. Start with the standard ViQi parser
153
+ parser = viqi_argument_parser()
154
+
155
+ # 2. Add your custom arguments
156
+ parser.add_argument("--dataset-id", required=True, help="ID of dataset to process")
157
+
158
+ # 3. Parse args (handles both ViQi args and custom args)
159
+ args = parser.parse_args()
160
+
161
+ # 4. Initialize session using the parsed arguments
162
+ session = viqi_session(args=args)
163
+
164
+ # 5. Use your custom argument
165
+ print(f"Processing dataset: {args.dataset_id}")
166
+ ```
@@ -0,0 +1,28 @@
1
+ vqapi/__init__.py,sha256=QZ7xXIfkeGzi21EMSpyAKFdlYebTJJTecXOpL3cGDaI,411
2
+ vqapi/blockable_module.py,sha256=zMeKq_h2TZLGAvnvuJbf9K0LdzWHNjs_iRdRaB81f8M,1746
3
+ vqapi/bqclass.py,sha256=QOUA_nAMdDuyOQ9Kv-Jdu7B003_3IJxsH7OeGUZLqQ8,28753
4
+ vqapi/casauth.py,sha256=Q6oSLC0reYxMTJ_I-h76hoyT6BP2LM1kTltC9RAX5nU,1594
5
+ vqapi/cmd.py,sha256=Pz0lh0971jxds1pJVBDLAkwBPAge6slVR9hiPAxZO18,12519
6
+ vqapi/comm.py,sha256=110YQ6siXCw0kCf9JuzzcgsJt5UtATUhiThIdfpI4fI,52083
7
+ vqapi/exception.py,sha256=JYoJrReRe-QMFzkOYXPq9TMQ7Va4Gz21VBsEWDUbb4Y,17395
8
+ vqapi/loggingpool.py,sha256=YH6VvN5PtVo-dWuxPPQ35wYgu9PzR_4hGUfQcwwFCZ0,4740
9
+ vqapi/plugins.py,sha256=E8oIcaBetoo80TkjWZqks1N2Mz3QW3H5x7eRRXMj0Fs,4824
10
+ vqapi/util.py,sha256=-P8t1TVEqUWCuKuzDbDcTSQ9EoAtzEpyxdNKln7eCqc,16380
11
+ vqapi/version.py,sha256=UC5T8KT6NqfFyLIGvmK4WnGPXZQFrOLavnm8I-_0Bg8,515
12
+ vqapi/vqclass.py,sha256=aJnWauXIpZqcc6BaaaFqYVWvd9blAkv9wvDcLZRfs5I,78987
13
+ vqapi/vqquery.py,sha256=RTqo2c_ornG2Lmi3QoH4S5pxVBY7TPF3fuaTQGbcGIk,11547
14
+ vqapi/RequestsMonkeyPatch/__init__.py,sha256=9_8wL9Scv8_Cs8HJyJHGvx1vwXErsuvlsAqNZLcJQR0,8
15
+ vqapi/RequestsMonkeyPatch/monkeypatch.py,sha256=Dl9WR-wicHkgxKRWZ4yXvs4RMuu9v3CSY3fBMlH3Fl0,138
16
+ vqapi/RequestsMonkeyPatch/requests_patch.py,sha256=1sIq472wvuAY5F96E_Q8jHsxiDlq0iBT3Ycm5eQUNZ0,1993
17
+ vqapi/services/__init__.py,sha256=fndmO-p3S3jd5c0cP7dlDj-emxPHjm7X4L_f8PP_YA8,120
18
+ vqapi/services/base_proxy.py,sha256=9jwdP51Pc6IwLBz43m3SmhBVAlN_Y47EW4O3HwyZlck,24658
19
+ vqapi/services/core_services.py,sha256=BjWkmSBBFbN5j_Pw0f7DRURczJt5v3yO4MB1LN6rHDs,56635
20
+ vqapi/services/factory.py,sha256=HSUE-lEo086FKbJcESjotL5Yrlk7sRfX02co6ehPgW0,1877
21
+ vqapi/services/image_proxy.py,sha256=QGmCAGk5qI8qVOx50ioeu8ZrHBYSLrgAUm9XtUKinAI,3253
22
+ vqapi/services/import_proxy.py,sha256=cZx8HZI5mAXSfO-O9N_xyBxBhKGlPvN4shnxw1R9PlI,50223
23
+ vqapi/services/table_proxy.py,sha256=Yn6svLCtElnfbEUtaJw-c050ntF_jSCjMOmjjr1V0uM,11664
24
+ vqapi/services/threadpool.py,sha256=PcWx52hVYwteol_wvHiwwTe-RMqZoL2gMDRN6afjDLA,5733
25
+ viqi_api-0.0.dist-info/METADATA,sha256=AjJdCZL9-7SyXNVJiSu3ZpTTAi7uYnMg8KrJt6Rg8Qw,4671
26
+ viqi_api-0.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
27
+ viqi_api-0.0.dist-info/top_level.txt,sha256=3tj8lcUB1FkjX_EiiFuj3I18i3_LJydRRS0stEFKdJU,6
28
+ viqi_api-0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ vqapi
@@ -0,0 +1 @@
1
+ # empty
@@ -0,0 +1,6 @@
1
+ def monkeypatch_method(cls):
2
+ def decorator(func):
3
+ setattr(cls, func.__name__, func)
4
+ return func
5
+
6
+ return decorator
@@ -0,0 +1,66 @@
1
+ """
2
+ A patch to format_header_param in urllib3
3
+
4
+ If a value has unicode the header will be returned
5
+ as 'name="value"; name*=utf-8''value' else
6
+ 'name="value"'
7
+ """
8
+
9
+ import email.utils
10
+
11
+ # import mimetypes
12
+ import warnings
13
+
14
+ import requests
15
+
16
+ try:
17
+ import requests.packages.urllib3 as urllib3 # pylint: disable=import-error
18
+ except ImportError:
19
+ import urllib3
20
+
21
+ # from requests.packages.urllib3.packages import six #pylint: disable=import-error
22
+ from .monkeypatch import monkeypatch_method
23
+
24
+ REQUESTS_V = [int(s) for s in requests.__version__.split(".")]
25
+
26
+ if REQUESTS_V < [2, 4, 0]: # or REQUESTS_V > [2, 19, 0]:
27
+ warnings.warn(
28
+ """\
29
+ We need to patch requests 2.4.0 make sure your version of requests \
30
+ needs this patch, greater than 2.X we do not know if this patch applys."""
31
+ )
32
+ raise ImportError("Requests > 2.4.0 is required!")
33
+ # elif requests_v > [3, 0, 0]:
34
+ # #does not require this patch
35
+ # pass
36
+ else:
37
+
38
+ @monkeypatch_method(urllib3.fields)
39
+ def format_header_param(name, value):
40
+ """
41
+ Helper function to format and quote a single header parameter.
42
+
43
+ Particularly useful for header parameters which might contain
44
+ non-ASCII values, like file names. This follows RFC 2231, as
45
+ suggested by RFC 2388 Section 4.4.
46
+
47
+ :param name:
48
+ The name of the parameter, a string expected to be ASCII only.
49
+ :param value:
50
+ The value of the parameter, provided as a unicode string.
51
+ """
52
+ if not any(ch in value for ch in '"\\\r\n'):
53
+ result = f'{name}="{value}"'
54
+ try:
55
+ result.encode("ascii")
56
+ except UnicodeEncodeError:
57
+ pass
58
+ else:
59
+ return result
60
+
61
+ value_encode = str(value)
62
+ # if not six.PY3: # Python 2:
63
+ # value_encode = value.encode('utf-8')
64
+
65
+ value = '{}="{}"; {}*={}'.format(name, value, name, email.utils.encode_rfc2231(value_encode, "utf-8"))
66
+ return value
vqapi/__init__.py ADDED
@@ -0,0 +1,17 @@
1
+ #
2
+ from .cmd import (
3
+ bisque_argument_parser,
4
+ bisque_config,
5
+ bisque_session,
6
+ viqi_argument_parser,
7
+ viqi_config,
8
+ viqi_session,
9
+ )
10
+ from .comm import BQServer, BQSession
11
+ from .exception import *
12
+ from .services import ResponseFile, ResponseFolder, StorageLevel, SearchScope, FilterType
13
+ from .vqclass import *
14
+
15
+ __author__ = "ViQi Inc"
16
+ __copyright__ = "2018-2025 ViQi Inc"
17
+ __project__ = "vqapi"
@@ -0,0 +1,59 @@
1
+ import collections
2
+ import logging
3
+
4
+ from vqapi import BQSession
5
+
6
+ # import sys
7
+
8
+
9
+ # logging.basicConfig(filename='BlockableModule.log',level=logging.DEBUG) #!!!
10
+ log = logging.getLogger("vqapi.blockable_module")
11
+
12
+
13
+ class BlockableModule:
14
+ """Base class for module that can run over blocks of parameters"""
15
+
16
+ def main(self, mex_url=None, auth_token=None, bq=None, **kw):
17
+ # Allow for testing by passing an alreay initialized session
18
+ if bq is None:
19
+ bq = BQSession().init_mex(mex_url, auth_token)
20
+
21
+ # check for list parameters
22
+ params = bq.get_mex_inputs()
23
+ if isinstance(params, dict) or not isinstance(params, collections.abc.Iterable):
24
+ params = [params]
25
+ # pass values directly as args
26
+ for single_params in params:
27
+ for param_name in single_params:
28
+ if "value" in single_params[param_name]:
29
+ single_params[param_name] = single_params[param_name].get("value")
30
+
31
+ # TODO: measure block startup time
32
+ self.start_block(bq, params)
33
+
34
+ for kw in params:
35
+ # TODO: measure single item time
36
+ # TODO: run in parallel
37
+ if "mex_url" in kw:
38
+ # set (innermost) single item mex
39
+ sub_bq = BQSession().init_mex(kw["mex_url"], auth_token)
40
+ else:
41
+ sub_bq = bq
42
+ self.process_single(sub_bq, **kw)
43
+ if "mex_url" in kw:
44
+ sub_bq.close()
45
+
46
+ # TODO: measure block teardown time
47
+ self.end_block(bq)
48
+
49
+ # sys.exit(0)
50
+ bq.close()
51
+
52
+ def start_block(self, bq, all_kw):
53
+ pass
54
+
55
+ def end_block(self, bq):
56
+ pass
57
+
58
+ def process_single(self, bq, **kw):
59
+ pass