wherobots-python-dbapi 0.4.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/PKG-INFO +35 -3
  2. wherobots_python_dbapi-0.5.0/README.md +83 -0
  3. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/pyproject.toml +1 -1
  4. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/wherobots/db/connection.py +25 -10
  5. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/wherobots/db/constants.py +11 -2
  6. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/wherobots/db/driver.py +30 -3
  7. wherobots_python_dbapi-0.4.0/README.md +0 -51
  8. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/__init__.cpython-311.pyc +0 -0
  9. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/__init__.cpython-39.pyc +0 -0
  10. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/connection.cpython-311.pyc +0 -0
  11. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/connection.cpython-39.pyc +0 -0
  12. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/constants.cpython-311.pyc +0 -0
  13. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/constants.cpython-39.pyc +0 -0
  14. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/cursor.cpython-311.pyc +0 -0
  15. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/cursor.cpython-39.pyc +0 -0
  16. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/driver.cpython-311.pyc +0 -0
  17. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/driver.cpython-39.pyc +0 -0
  18. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/errors.cpython-311.pyc +0 -0
  19. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/errors.cpython-39.pyc +0 -0
  20. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/region.cpython-311.pyc +0 -0
  21. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/region.cpython-39.pyc +0 -0
  22. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/runtime.cpython-311.pyc +0 -0
  23. wherobots_python_dbapi-0.4.0/wherobots/db/__pycache__/runtime.cpython-39.pyc +0 -0
  24. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/LICENSE +0 -0
  25. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/wherobots/__init__.py +0 -0
  26. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/wherobots/db/__init__.py +0 -0
  27. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/wherobots/db/cursor.py +0 -0
  28. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/wherobots/db/errors.py +0 -0
  29. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/wherobots/db/region.py +0 -0
  30. {wherobots_python_dbapi-0.4.0 → wherobots_python_dbapi-0.5.0}/wherobots/db/runtime.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wherobots-python-dbapi
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Python DB-API driver for Wherobots DB
5
5
  License: Apache 2.0
6
6
  Author: Maxime Petazzoni
@@ -44,6 +44,11 @@ $ pip install git+https://github.com/wherobots/wherobots-python-dbapi-driver
44
44
 
45
45
  ## Usage
46
46
 
47
+ ### Basic usage
48
+
49
+ Basic usage follows the typical pattern of establishing the connection,
50
+ acquiring a cursor, and executing SQL queries through it:
51
+
47
52
  ```python
48
53
  from wherobots.db import connect
49
54
  from wherobots.db.region import Region
@@ -59,8 +64,8 @@ with connect(
59
64
  print(results)
60
65
  ```
61
66
 
62
- The `Cursor` also supports the context manager protocol, so you can use
63
- it within a `with` statement when needed:
67
+ The `Cursor` supports the context manager protocol, so you can use it
68
+ within a `with` statement when needed:
64
69
 
65
70
  ```python
66
71
  with connect(...) as conn:
@@ -73,3 +78,30 @@ It also implements the `close()` method, as suggested by the PEP-2049
73
78
  specification, to support situations where the cursor is wrapped in a
74
79
  `contextmanager.closing()`.
75
80
 
81
+ ### Runtime and region selection
82
+
83
+ You can chose the Wherobots runtime you want to use using the `runtime`
84
+ parameter, passing in one of the `Runtime` enum values. For more
85
+ information on runtime sizing and selection, please consult the
86
+ [Wherobots product documentation](https://docs.wherobots.com).
87
+
88
+ The only supported Wherobots compute region for now is `aws-us-west-2`,
89
+ in AWS's Oregon (`us-west-2`) region.
90
+
91
+ ### Advanced parameters
92
+
93
+ The `connect()` method takes some additional parameters that advanced
94
+ users may find useful:
95
+
96
+ * `results_format`: one of the `ResultsFormat` enum values;
97
+ Arrow encoding is the default and most efficient format for
98
+ receiving query results.
99
+ * `data_compression`: one of the `DataCompression` enum values; Brotli
100
+ compression is the default and the most efficient compression
101
+ algorithm for receiving query results.
102
+ * `geometry_representation`: one of the `GeometryRepresentation` enum
103
+ values; selects the encoding of geometry columns returned to the
104
+ client application. The default is EWKT (string) and the most
105
+ convenient for human inspection while still being usable by
106
+ libraries like Shapely.
107
+
@@ -0,0 +1,83 @@
1
+ # wherobots-python-dbapi-driver
2
+
3
+ Python DB-API implementation for Wherobots DB. This package implements a
4
+ PEP-0249 compatible driver to programmatically connect to a Wherobots DB
5
+ runtime and execute Spatial SQL queries.
6
+
7
+ ## Installation
8
+
9
+ If you use [Poetry](https://python-poetry.org) in your project, add the
10
+ dependency with `poetry add`:
11
+
12
+ ```
13
+ $ poetry add git+https://github.com/wherobots/wherobots-python-dbapi-driver
14
+ ```
15
+
16
+ Otherwise, just `pip install` it:
17
+
18
+ ```
19
+ $ pip install git+https://github.com/wherobots/wherobots-python-dbapi-driver
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Basic usage
25
+
26
+ Basic usage follows the typical pattern of establishing the connection,
27
+ acquiring a cursor, and executing SQL queries through it:
28
+
29
+ ```python
30
+ from wherobots.db import connect
31
+ from wherobots.db.region import Region
32
+ from wherobots.db.runtime import Runtime
33
+
34
+ with connect(
35
+ api_key='...',
36
+ runtime=Runtime.SEDONA,
37
+ region=Region.AWS_US_WEST_2) as conn:
38
+ curr = conn.cursor()
39
+ curr.execute("SHOW SCHEMAS IN wherobots_open_data")
40
+ results = curr.fetchall()
41
+ print(results)
42
+ ```
43
+
44
+ The `Cursor` supports the context manager protocol, so you can use it
45
+ within a `with` statement when needed:
46
+
47
+ ```python
48
+ with connect(...) as conn:
49
+ with conn.cursor() as curr:
50
+ curr.execute(...)
51
+ results = curr.fetchall()
52
+ ```
53
+
54
+ It also implements the `close()` method, as suggested by the PEP-2049
55
+ specification, to support situations where the cursor is wrapped in a
56
+ `contextmanager.closing()`.
57
+
58
+ ### Runtime and region selection
59
+
60
+ You can chose the Wherobots runtime you want to use using the `runtime`
61
+ parameter, passing in one of the `Runtime` enum values. For more
62
+ information on runtime sizing and selection, please consult the
63
+ [Wherobots product documentation](https://docs.wherobots.com).
64
+
65
+ The only supported Wherobots compute region for now is `aws-us-west-2`,
66
+ in AWS's Oregon (`us-west-2`) region.
67
+
68
+ ### Advanced parameters
69
+
70
+ The `connect()` method takes some additional parameters that advanced
71
+ users may find useful:
72
+
73
+ * `results_format`: one of the `ResultsFormat` enum values;
74
+ Arrow encoding is the default and most efficient format for
75
+ receiving query results.
76
+ * `data_compression`: one of the `DataCompression` enum values; Brotli
77
+ compression is the default and the most efficient compression
78
+ algorithm for receiving query results.
79
+ * `geometry_representation`: one of the `GeometryRepresentation` enum
80
+ values; selects the encoding of geometry columns returned to the
81
+ client application. The default is EWKT (string) and the most
82
+ convenient for human inspection while still being usable by
83
+ libraries like Shapely.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "wherobots-python-dbapi"
3
- version = "0.4.0"
3
+ version = "0.5.0"
4
4
  description = "Python DB-API driver for Wherobots DB"
5
5
  authors = ["Maxime Petazzoni <max@wherobots.com>"]
6
6
  license = "Apache 2.0"
@@ -1,9 +1,10 @@
1
1
  import json
2
2
  import logging
3
+ import textwrap
3
4
  import threading
4
5
  import uuid
5
6
  from dataclasses import dataclass
6
- from typing import Callable, Any
7
+ from typing import Any, Callable, Union
7
8
 
8
9
  import cbor2
9
10
  import pyarrow
@@ -18,13 +19,11 @@ from wherobots.db.constants import (
18
19
  ExecutionState,
19
20
  ResultsFormat,
20
21
  DataCompression,
22
+ GeometryRepresentation,
21
23
  )
22
24
  from wherobots.db.cursor import Cursor
23
25
  from wherobots.db.errors import NotSupportedError, OperationalError
24
26
 
25
- _DEFAULT_RESULTS_FORMAT = ResultsFormat.ARROW
26
- _DEFAULT_DATA_COMPRESSION = DataCompression.BROTLI
27
-
28
27
 
29
28
  @dataclass
30
29
  class Query:
@@ -53,9 +52,16 @@ class Connection:
53
52
  self,
54
53
  ws: websockets.sync.client.ClientConnection,
55
54
  read_timeout: float = DEFAULT_READ_TIMEOUT_SECONDS,
55
+ results_format: Union[ResultsFormat, None] = None,
56
+ data_compression: Union[DataCompression, None] = None,
57
+ geometry_representation: Union[GeometryRepresentation, None] = None,
56
58
  ):
57
59
  self.__ws = ws
58
60
  self.__read_timeout = read_timeout
61
+ self.__results_format = results_format
62
+ self.__data_compression = data_compression
63
+ self.__geometry_representation = geometry_representation
64
+
59
65
  self.__queries: dict[str, Query] = {}
60
66
  self.__thread = threading.Thread(
61
67
  target=self.__main_loop, daemon=True, name="wherobots-connection"
@@ -155,9 +161,7 @@ class Connection:
155
161
  query.handler(reader.read_pandas())
156
162
  else:
157
163
  query.handler(
158
- OperationalError(
159
- f"Unsupported results format {result_format}"
160
- )
164
+ OperationalError(f"Unsupported results format {result_format}")
161
165
  )
162
166
  elif kind == EventKind.ERROR:
163
167
  query.state = ExecutionState.FAILED
@@ -167,7 +171,9 @@ class Connection:
167
171
  logging.warning("Received unknown %s event!", kind)
168
172
 
169
173
  def __send(self, message: dict[str, Any]) -> None:
170
- self.__ws.send(json.dumps(message))
174
+ request = json.dumps(message)
175
+ logging.debug("Request: %s", request)
176
+ self.__ws.send(request)
171
177
 
172
178
  def __recv(self) -> dict[str, Any]:
173
179
  frame = self.__ws.recv(timeout=self.__read_timeout)
@@ -194,6 +200,10 @@ class Connection:
194
200
  state=ExecutionState.EXECUTION_REQUESTED,
195
201
  handler=handler,
196
202
  )
203
+
204
+ logging.info(
205
+ "Executing SQL query %s: %s", execution_id, textwrap.shorten(sql, width=60)
206
+ )
197
207
  self.__send(request)
198
208
  return execution_id
199
209
 
@@ -205,9 +215,14 @@ class Connection:
205
215
  request = {
206
216
  "kind": RequestKind.RETRIEVE_RESULTS.value,
207
217
  "execution_id": execution_id,
208
- "format": _DEFAULT_RESULTS_FORMAT.value,
209
- "compression": _DEFAULT_DATA_COMPRESSION.value,
210
218
  }
219
+ if self.__results_format:
220
+ request["format"] = self.__results_format.value
221
+ if self.__data_compression:
222
+ request["compression"] = self.__data_compression.value
223
+ if self.__geometry_representation:
224
+ request["geometry"] = self.__geometry_representation.value
225
+
211
226
  query.state = ExecutionState.RESULTS_REQUESTED
212
227
  logging.info("Requesting results from %s ...", execution_id)
213
228
  self.__send(request)
@@ -5,13 +5,14 @@ from .region import Region
5
5
  from .runtime import Runtime
6
6
 
7
7
 
8
- DEFAULT_ENDPOINT: str = "api.wherobots.services" # "api.cloud.wherobots.com"
9
- STAGING_ENDPOINT: str = "api.staging.wherobots.services" # "api.staging.wherobots.com"
8
+ DEFAULT_ENDPOINT: str = "api.cloud.wherobots.com" # "api.cloud.wherobots.com"
9
+ STAGING_ENDPOINT: str = "api.staging.wherobots.com" # "api.staging.wherobots.com"
10
10
  DEFAULT_RUNTIME: Runtime = Runtime.SEDONA
11
11
  DEFAULT_REGION: Region = Region.AWS_US_WEST_2
12
12
  DEFAULT_READ_TIMEOUT_SECONDS: float = 0.25
13
13
  DEFAULT_SESSION_WAIT_TIMEOUT_SECONDS: float = 300
14
14
  MAX_MESSAGE_SIZE: int = 100 * 2**20 # 100MiB
15
+ PROTOCOL_VERSION: str = "1.0.0"
15
16
 
16
17
 
17
18
  class ExecutionState(LowercaseStrEnum):
@@ -58,3 +59,11 @@ class ResultsFormat(LowercaseStrEnum):
58
59
 
59
60
  class DataCompression(LowercaseStrEnum):
60
61
  BROTLI = auto()
62
+
63
+
64
+ class GeometryRepresentation(LowercaseStrEnum):
65
+ WKT = auto()
66
+ WKB = auto()
67
+ EWKT = auto()
68
+ EWKB = auto()
69
+ GEOJSON = auto()
@@ -4,11 +4,13 @@ A PEP-0249 compatible driver for interfacing with Wherobots DB.
4
4
  """
5
5
 
6
6
  import logging
7
+ import os
7
8
  import urllib.parse
8
9
  import queue
9
10
  import requests
10
11
  import tenacity
11
12
  import threading
13
+ from typing import Union
12
14
  import websockets.sync.client
13
15
 
14
16
  from .constants import (
@@ -18,6 +20,10 @@ from .constants import (
18
20
  DEFAULT_READ_TIMEOUT_SECONDS,
19
21
  DEFAULT_SESSION_WAIT_TIMEOUT_SECONDS,
20
22
  MAX_MESSAGE_SIZE,
23
+ PROTOCOL_VERSION,
24
+ ResultsFormat,
25
+ DataCompression,
26
+ GeometryRepresentation,
21
27
  )
22
28
  from .errors import (
23
29
  InterfaceError,
@@ -40,6 +46,9 @@ def connect(
40
46
  region: Region = None,
41
47
  wait_timeout: float = DEFAULT_SESSION_WAIT_TIMEOUT_SECONDS,
42
48
  read_timeout: float = DEFAULT_READ_TIMEOUT_SECONDS,
49
+ results_format: Union[ResultsFormat, None] = None,
50
+ data_compression: Union[DataCompression, None] = None,
51
+ geometry_representation: Union[GeometryRepresentation, None] = None,
43
52
  ) -> Connection:
44
53
  if not token and not api_key:
45
54
  raise ValueError("At least one of `token` or `api_key` is required")
@@ -113,6 +122,9 @@ def connect(
113
122
  uri=http_to_ws(session_uri),
114
123
  headers=headers,
115
124
  read_timeout=read_timeout,
125
+ results_format=results_format,
126
+ data_compression=data_compression,
127
+ geometry_representation=geometry_representation,
116
128
  )
117
129
 
118
130
 
@@ -125,18 +137,27 @@ def http_to_ws(uri: str) -> str:
125
137
  return str(urllib.parse.urlunparse(parsed))
126
138
 
127
139
 
140
+ def append_protocol(uri: str, protocol: str) -> str:
141
+ """Appends the protocol version to the URI."""
142
+ return urllib.parse.urljoin(os.path.join(uri, ""), protocol)
143
+
144
+
128
145
  def connect_direct(
129
146
  uri: str,
130
147
  headers: dict[str, str] = None,
131
148
  read_timeout: float = DEFAULT_READ_TIMEOUT_SECONDS,
149
+ results_format: Union[ResultsFormat, None] = None,
150
+ data_compression: Union[DataCompression, None] = None,
151
+ geometry_representation: Union[GeometryRepresentation, None] = None,
132
152
  ) -> Connection:
133
153
  q = queue.SimpleQueue()
154
+ uri_with_protocol = append_protocol(uri, PROTOCOL_VERSION)
134
155
 
135
156
  def create_ws_connection():
136
157
  try:
137
- logging.info("Connecting to SQL session at %s ...", uri)
158
+ logging.info("Connecting to SQL session at %s ...", uri_with_protocol)
138
159
  ws = websockets.sync.client.connect(
139
- uri=uri,
160
+ uri=uri_with_protocol,
140
161
  additional_headers=headers,
141
162
  max_size=MAX_MESSAGE_SIZE,
142
163
  )
@@ -156,4 +177,10 @@ def connect_direct(
156
177
  if isinstance(result, Exception):
157
178
  raise InterfaceError("Failed to connect to SQL session!") from result
158
179
 
159
- return Connection(result, read_timeout)
180
+ return Connection(
181
+ result,
182
+ read_timeout=read_timeout,
183
+ results_format=results_format,
184
+ data_compression=data_compression,
185
+ geometry_representation=geometry_representation,
186
+ )
@@ -1,51 +0,0 @@
1
- # wherobots-python-dbapi-driver
2
-
3
- Python DB-API implementation for Wherobots DB. This package implements a
4
- PEP-0249 compatible driver to programmatically connect to a Wherobots DB
5
- runtime and execute Spatial SQL queries.
6
-
7
- ## Installation
8
-
9
- If you use [Poetry](https://python-poetry.org) in your project, add the
10
- dependency with `poetry add`:
11
-
12
- ```
13
- $ poetry add git+https://github.com/wherobots/wherobots-python-dbapi-driver
14
- ```
15
-
16
- Otherwise, just `pip install` it:
17
-
18
- ```
19
- $ pip install git+https://github.com/wherobots/wherobots-python-dbapi-driver
20
- ```
21
-
22
- ## Usage
23
-
24
- ```python
25
- from wherobots.db import connect
26
- from wherobots.db.region import Region
27
- from wherobots.db.runtime import Runtime
28
-
29
- with connect(
30
- api_key='...',
31
- runtime=Runtime.SEDONA,
32
- region=Region.AWS_US_WEST_2) as conn:
33
- curr = conn.cursor()
34
- curr.execute("SHOW SCHEMAS IN wherobots_open_data")
35
- results = curr.fetchall()
36
- print(results)
37
- ```
38
-
39
- The `Cursor` also supports the context manager protocol, so you can use
40
- it within a `with` statement when needed:
41
-
42
- ```python
43
- with connect(...) as conn:
44
- with conn.cursor() as curr:
45
- curr.execute(...)
46
- results = curr.fetchall()
47
- ```
48
-
49
- It also implements the `close()` method, as suggested by the PEP-2049
50
- specification, to support situations where the cursor is wrapped in a
51
- `contextmanager.closing()`.