crate 1.0.0.dev2__tar.gz → 2.0.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.
- crate-1.0.0.dev2/CHANGES.txt → crate-2.0.0/CHANGES.rst +52 -14
- {crate-1.0.0.dev2 → crate-2.0.0}/DEVELOP.rst +13 -16
- {crate-1.0.0.dev2 → crate-2.0.0}/PKG-INFO +20 -7
- {crate-1.0.0.dev2 → crate-2.0.0}/README.rst +1 -1
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/by-example/http.rst +1 -1
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/index.rst +2 -2
- {crate-1.0.0.dev2 → crate-2.0.0}/pyproject.toml +7 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/setup.py +4 -4
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/client/__init__.py +2 -1
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/client/http.py +55 -27
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate.egg-info/PKG-INFO +20 -7
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate.egg-info/SOURCES.txt +1 -3
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate.egg-info/requires.txt +4 -4
- crate-1.0.0.dev2/docs/backlog.rst +0 -6
- crate-1.0.0.dev2/src/crate/testing/__init__.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/CONTRIBUTING.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/LICENSE +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/MANIFEST.in +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/NOTICE +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/_extra/robots.txt +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/blobs.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/by-example/blob.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/by-example/client.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/by-example/connection.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/by-example/cursor.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/by-example/https.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/by-example/index.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/conf.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/connect.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/data-types.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/docutils.conf +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/getting-started.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/index-all.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/other-options.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/query.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/requirements.txt +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/docs/sqlalchemy.rst +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/requirements.txt +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/setup.cfg +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/client/_pep440.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/client/blob.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/client/connection.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/client/converter.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/client/cursor.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/client/exceptions.py +0 -0
- {crate-1.0.0.dev2/src/crate → crate-2.0.0/src/crate/testing}/__init__.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/testing/layer.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate/testing/util.py +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate.egg-info/dependency_links.txt +0 -0
- {crate-1.0.0.dev2 → crate-2.0.0}/src/crate.egg-info/top_level.txt +0 -0
@@ -5,13 +5,45 @@ Changes for crate
|
|
5
5
|
Unreleased
|
6
6
|
==========
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
2025/01/30 2.0.0
|
9
|
+
================
|
10
|
+
|
11
|
+
- Switched JSON encoder to use the `orjson`_ library, to improve JSON
|
12
|
+
marshalling performance. Thanks, @widmogrod.
|
13
|
+
|
14
|
+
orjson is fast and in some spots even more correct when compared against
|
15
|
+
Python's stdlib ``json`` module. Contrary to the stdlib variant, orjson
|
16
|
+
will serialize to ``bytes`` instead of ``str``. When sending data to CrateDB,
|
17
|
+
``crate-python`` uses a custom encoder to add support for additional data
|
18
|
+
types.
|
19
|
+
|
20
|
+
- Python's ``Decimal`` type will be serialized to ``str``.
|
21
|
+
- Python's ``dt.datetime`` and ``dt.date`` types will be serialized to
|
22
|
+
``int`` (``LONG``) after converting to milliseconds since epoch, to
|
23
|
+
optimally accommodate CrateDB's `TIMESTAMP`_ representation.
|
24
|
+
- NumPy's data types will be handled by ``orjson`` without any ado.
|
25
|
+
|
26
|
+
.. _orjson: https://github.com/ijl/orjson
|
27
|
+
.. _TIMESTAMP: https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#type-timestamp
|
28
|
+
|
29
|
+
2024/11/23 1.0.1
|
30
|
+
================
|
31
|
+
|
32
|
+
- Python: Fixed "implicit namespace packages" migration by omitting
|
33
|
+
``__init__.py`` from ``crate`` namespace package, see `PEP 420`_
|
34
|
+
and `Package Discovery and Namespace Package » Finding namespace packages`_.
|
35
|
+
|
36
|
+
|
37
|
+
2024/11/05 1.0.0
|
38
|
+
================
|
39
|
+
|
40
|
+
- BREAKING CHANGE: The SQLAlchemy dialect has been split off into
|
41
|
+
the `sqlalchemy-cratedb`_ package, see notice below.
|
42
|
+
- Feature: Returned Python ``datetime`` objects are now always timezone-aware,
|
43
|
+
using UTC by default.
|
44
|
+
It may be a breaking change for some users of the library that don't expect
|
45
|
+
to receive "aware" instead of "naive" Python ``datetime`` objects from now
|
46
|
+
on, i.e. instances with or without the ``tzinfo`` attribute set.
|
15
47
|
When no ``time_zone`` information is specified when creating a database
|
16
48
|
connection or cursor, ``datetime`` objects will now use Coordinated
|
17
49
|
Universal Time (UTC), like CrateDB is storing timestamp values in this
|
@@ -19,13 +51,11 @@ Unreleased
|
|
19
51
|
This update is coming from a deprecation of Python's
|
20
52
|
``datetime.utcfromtimestamp()``, which is effectively also phasing out
|
21
53
|
the use of "naive" timestamp objects in Python, in favor of using
|
22
|
-
timezone-aware objects, also to represent datetimes in UTC.
|
23
|
-
|
24
|
-
|
25
|
-
-
|
26
|
-
|
27
|
-
- Added ``error_trace`` to string representation of an Error to relay
|
28
|
-
server stacktraces into exception messages.
|
54
|
+
timezone-aware objects, also to represent datetimes in UTC.
|
55
|
+
- Feature: Configured DB API interface attribute ``threadsafety = 1``,
|
56
|
+
which signals "Threads may share the module, but not connections."
|
57
|
+
- Feature: Added ``error_trace`` to string representation of an Error,
|
58
|
+
to relay server stacktraces into exception messages.
|
29
59
|
- Refactoring: The module namespace ``crate.client.test_util`` has been
|
30
60
|
renamed to ``crate.testing.util``.
|
31
61
|
- Error handling: At two spots in cursor / value converter handling, where
|
@@ -35,7 +65,15 @@ Unreleased
|
|
35
65
|
namespaces" for the ``crate`` namespace package, see `PEP 420`_.
|
36
66
|
|
37
67
|
|
68
|
+
.. note::
|
69
|
+
|
70
|
+
For learning about the transition to `sqlalchemy-cratedb`_,
|
71
|
+
we recommend to read the enumeration of necessary migration steps
|
72
|
+
at `Migrate from crate.client to sqlalchemy-cratedb`_.
|
73
|
+
|
74
|
+
|
38
75
|
.. _Migrate from crate.client to sqlalchemy-cratedb: https://cratedb.com/docs/sqlalchemy-cratedb/migrate-from-crate-client.html
|
76
|
+
.. _Package Discovery and Namespace Package » Finding namespace packages: https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#namespace-packages
|
39
77
|
.. _PEP 420: https://peps.python.org/pep-0420/
|
40
78
|
.. _sqlalchemy-cratedb: https://pypi.org/project/sqlalchemy-cratedb/
|
41
79
|
|
@@ -5,7 +5,7 @@ CrateDB Python developer guide
|
|
5
5
|
Setup
|
6
6
|
=====
|
7
7
|
|
8
|
-
Optionally install Python package and project manager
|
8
|
+
Optionally install Python package and project manager `uv`_,
|
9
9
|
in order to significantly speed up the package installation::
|
10
10
|
|
11
11
|
{apt,brew,pip,zypper} install uv
|
@@ -67,16 +67,11 @@ To inspect the whole list of test cases, run::
|
|
67
67
|
|
68
68
|
bin/test --list-tests
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
on your ``$PATH``.
|
76
|
-
|
77
|
-
To run against a single interpreter, you can also invoke::
|
78
|
-
|
79
|
-
tox -e py37
|
70
|
+
The CI setup on GitHub Actions (GHA) provides a full test matrix covering
|
71
|
+
relevant Python versions. You can invoke the software tests against a specific
|
72
|
+
Python interpreter or multiple `Python versions`_ on your workstation using
|
73
|
+
`uv`_, by supplying the ``--python`` command-line option, or by defining the
|
74
|
+
`UV_PYTHON`_ environment variable prior to invoking ``source bootstrap.sh``.
|
80
75
|
|
81
76
|
*Note*: Before running the tests, make sure to stop all CrateDB instances which
|
82
77
|
are listening on the default CrateDB transport port to avoid side effects with
|
@@ -104,7 +99,7 @@ Renew certificates
|
|
104
99
|
==================
|
105
100
|
|
106
101
|
For conducting TLS connectivity tests, there are a few X.509 certificates at
|
107
|
-
`
|
102
|
+
`tests/assets/pki/*.pem`_. In order to renew them, follow the instructions
|
108
103
|
within the README file in this folder.
|
109
104
|
|
110
105
|
|
@@ -121,7 +116,7 @@ In the release branch:
|
|
121
116
|
|
122
117
|
- Update ``__version__`` in ``src/crate/client/__init__.py``
|
123
118
|
|
124
|
-
- Add a section for the new version in the ``CHANGES.
|
119
|
+
- Add a section for the new version in the ``CHANGES.rst`` file
|
125
120
|
|
126
121
|
- Commit your changes with a message like "prepare release x.y.z"
|
127
122
|
|
@@ -130,7 +125,7 @@ In the release branch:
|
|
130
125
|
- Create a tag by running ``./devtools/create_tag.sh``. This will trigger a
|
131
126
|
Github action which releases the new version to PyPi.
|
132
127
|
|
133
|
-
On
|
128
|
+
On branch ``main``:
|
134
129
|
|
135
130
|
- Update the release notes to reflect the release
|
136
131
|
|
@@ -168,12 +163,14 @@ nothing special you need to do to get the live docs to update.
|
|
168
163
|
.. _@crate/docs: https://github.com/orgs/crate/teams/docs
|
169
164
|
.. _buildout: https://pypi.python.org/pypi/zc.buildout
|
170
165
|
.. _PyPI: https://pypi.python.org/pypi
|
166
|
+
.. _Python versions: https://docs.astral.sh/uv/concepts/python-versions/
|
171
167
|
.. _Read the Docs: http://readthedocs.org
|
172
168
|
.. _ReStructuredText: http://docutils.sourceforge.net/rst.html
|
173
169
|
.. _Sphinx: http://sphinx-doc.org/
|
174
|
-
..
|
175
|
-
.. _tox: http://testrun.org/tox/latest/
|
170
|
+
.. _tests/assets/pki/*.pem: https://github.com/crate/crate-python/tree/main/tests/assets/pki
|
176
171
|
.. _twine: https://pypi.python.org/pypi/twine
|
177
172
|
.. _useful command-line options for zope-testrunner: https://pypi.org/project/zope.testrunner/#some-useful-command-line-options-to-get-you-started
|
173
|
+
.. _uv: https://docs.astral.sh/uv/
|
174
|
+
.. _UV_PYTHON: https://docs.astral.sh/uv/configuration/environment/#uv_python
|
178
175
|
.. _versions hosted on ReadTheDocs: https://readthedocs.org/projects/crate-python/versions/
|
179
176
|
.. _zope.testrunner: https://pypi.org/project/zope.testrunner/
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: crate
|
3
|
-
Version:
|
3
|
+
Version: 2.0.0
|
4
4
|
Summary: CrateDB Python Client
|
5
5
|
Home-page: https://github.com/crate/crate-python
|
6
6
|
Author: Crate.io
|
@@ -29,6 +29,7 @@ Requires-Python: >=3.6
|
|
29
29
|
Description-Content-Type: text/x-rst
|
30
30
|
License-File: LICENSE
|
31
31
|
License-File: NOTICE
|
32
|
+
Requires-Dist: orjson<4
|
32
33
|
Requires-Dist: urllib3
|
33
34
|
Requires-Dist: verlib2
|
34
35
|
Provides-Extra: doc
|
@@ -38,15 +39,27 @@ Provides-Extra: test
|
|
38
39
|
Requires-Dist: backports.zoneinfo<1; python_version < "3.9" and extra == "test"
|
39
40
|
Requires-Dist: certifi; extra == "test"
|
40
41
|
Requires-Dist: createcoverage<2,>=1; extra == "test"
|
41
|
-
Requires-Dist: mypy<1.
|
42
|
-
Requires-Dist: poethepoet<0.
|
43
|
-
Requires-Dist: ruff<0.
|
42
|
+
Requires-Dist: mypy<1.15; extra == "test"
|
43
|
+
Requires-Dist: poethepoet<0.33; extra == "test"
|
44
|
+
Requires-Dist: ruff<0.10; extra == "test"
|
44
45
|
Requires-Dist: stopit<2,>=1.1.2; extra == "test"
|
45
|
-
Requires-Dist: tox<5,>=3; extra == "test"
|
46
46
|
Requires-Dist: pytz; extra == "test"
|
47
47
|
Requires-Dist: zc.customdoctests<2,>=1.0.1; extra == "test"
|
48
48
|
Requires-Dist: zope.testing<6,>=4; extra == "test"
|
49
49
|
Requires-Dist: zope.testrunner<7,>=5; extra == "test"
|
50
|
+
Dynamic: author
|
51
|
+
Dynamic: author-email
|
52
|
+
Dynamic: classifier
|
53
|
+
Dynamic: description
|
54
|
+
Dynamic: description-content-type
|
55
|
+
Dynamic: home-page
|
56
|
+
Dynamic: keywords
|
57
|
+
Dynamic: license
|
58
|
+
Dynamic: platform
|
59
|
+
Dynamic: provides-extra
|
60
|
+
Dynamic: requires-dist
|
61
|
+
Dynamic: requires-python
|
62
|
+
Dynamic: summary
|
50
63
|
|
51
64
|
=====================
|
52
65
|
CrateDB Python Client
|
@@ -56,7 +69,7 @@ CrateDB Python Client
|
|
56
69
|
:target: https://github.com/crate/crate-python/actions?workflow=Tests
|
57
70
|
:alt: Build status
|
58
71
|
|
59
|
-
.. image:: https://codecov.io/gh/crate/crate-python/branch/
|
72
|
+
.. image:: https://codecov.io/gh/crate/crate-python/branch/main/graph/badge.svg
|
60
73
|
:target: https://app.codecov.io/gh/crate/crate-python
|
61
74
|
:alt: Coverage
|
62
75
|
|
@@ -6,7 +6,7 @@ CrateDB Python Client
|
|
6
6
|
:target: https://github.com/crate/crate-python/actions?workflow=Tests
|
7
7
|
:alt: Build status
|
8
8
|
|
9
|
-
.. image:: https://codecov.io/gh/crate/crate-python/branch/
|
9
|
+
.. image:: https://codecov.io/gh/crate/crate-python/branch/main/graph/badge.svg
|
10
10
|
:target: https://app.codecov.io/gh/crate/crate-python
|
11
11
|
:alt: Coverage
|
12
12
|
|
@@ -228,7 +228,7 @@ When connecting to non-CrateDB servers, the HttpClient will raise a ConnectionEr
|
|
228
228
|
>>> http_client.server_infos(http_client._get_server())
|
229
229
|
Traceback (most recent call last):
|
230
230
|
...
|
231
|
-
crate.client.exceptions.ProgrammingError: Invalid server response of content-type 'text/html
|
231
|
+
crate.client.exceptions.ProgrammingError: Invalid server response of content-type 'text/html':
|
232
232
|
...
|
233
233
|
>>> http_client.close()
|
234
234
|
|
@@ -174,12 +174,12 @@ The project is licensed under the terms of the Apache 2.0 license, like
|
|
174
174
|
.. _CrateDB source: https://github.com/crate/crate
|
175
175
|
.. _Create an issue: https://github.com/crate/crate-python/issues
|
176
176
|
.. _Dask: https://en.wikipedia.org/wiki/Dask_(software)
|
177
|
-
.. _development sandbox: https://github.com/crate/crate-python/blob/
|
177
|
+
.. _development sandbox: https://github.com/crate/crate-python/blob/main/DEVELOP.rst
|
178
178
|
.. _cratedb-examples repository: https://github.com/crate/cratedb-examples
|
179
179
|
.. _FIWARE QuantumLeap data historian: https://github.com/orchestracities/ngsi-timeseries-api
|
180
180
|
.. _GeoJSON: https://geojson.org/
|
181
181
|
.. _GeoJSON geometry objects: https://tools.ietf.org/html/rfc7946#section-3.1
|
182
|
-
.. _LICENSE: https://github.com/crate/crate-python/blob/
|
182
|
+
.. _LICENSE: https://github.com/crate/crate-python/blob/main/LICENSE
|
183
183
|
.. _managed on GitHub: https://github.com/crate/crate-python
|
184
184
|
.. _migrate to sqlalchemy-cratedb: https://cratedb.com/docs/sqlalchemy-cratedb/migrate-from-crate-client.html
|
185
185
|
.. _pandas: https://en.wikipedia.org/wiki/Pandas_(software)
|
@@ -71,6 +71,13 @@ lint.per-file-ignores."tests/*" = [
|
|
71
71
|
"S106", # Possible hardcoded password assigned to argument: "password"
|
72
72
|
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes
|
73
73
|
]
|
74
|
+
lint.per-file-ignores."src/crate/client/{connection.py,http.py}" = [
|
75
|
+
"A004", # Import `ConnectionError` is shadowing a Python builtin
|
76
|
+
"A005", # Import `ConnectionError` is shadowing a Python builtin
|
77
|
+
]
|
78
|
+
lint.per-file-ignores."tests/client/test_http.py" = [
|
79
|
+
"A004", # Import `ConnectionError` is shadowing a Python builtin
|
80
|
+
]
|
74
81
|
|
75
82
|
|
76
83
|
# ===================
|
@@ -54,6 +54,7 @@ setup(
|
|
54
54
|
packages=find_namespace_packages("src"),
|
55
55
|
package_dir={"": "src"},
|
56
56
|
install_requires=[
|
57
|
+
"orjson<4",
|
57
58
|
"urllib3",
|
58
59
|
"verlib2",
|
59
60
|
],
|
@@ -66,11 +67,10 @@ setup(
|
|
66
67
|
'backports.zoneinfo<1; python_version<"3.9"',
|
67
68
|
"certifi",
|
68
69
|
"createcoverage>=1,<2",
|
69
|
-
"mypy<1.
|
70
|
-
"poethepoet<0.
|
71
|
-
"ruff<0.
|
70
|
+
"mypy<1.15",
|
71
|
+
"poethepoet<0.33",
|
72
|
+
"ruff<0.10",
|
72
73
|
"stopit>=1.1.2,<2",
|
73
|
-
"tox>=3,<5",
|
74
74
|
"pytz",
|
75
75
|
"zc.customdoctests>=1.0.1,<2",
|
76
76
|
"zope.testing>=4,<6",
|
@@ -29,8 +29,9 @@ __all__ = [
|
|
29
29
|
|
30
30
|
# version string read from setup.py using a regex. Take care not to break the
|
31
31
|
# regex!
|
32
|
-
__version__ = "
|
32
|
+
__version__ = "2.0.0"
|
33
33
|
|
34
|
+
# codeql[py/unused-global-variable]
|
34
35
|
apilevel = "2.0"
|
35
36
|
threadsafety = 1
|
36
37
|
paramstyle = "qmark"
|
@@ -21,22 +21,22 @@
|
|
21
21
|
|
22
22
|
|
23
23
|
import calendar
|
24
|
+
import datetime as dt
|
24
25
|
import heapq
|
25
26
|
import io
|
26
|
-
import json
|
27
27
|
import logging
|
28
28
|
import os
|
29
29
|
import re
|
30
30
|
import socket
|
31
31
|
import ssl
|
32
32
|
import threading
|
33
|
+
import typing as t
|
33
34
|
from base64 import b64encode
|
34
|
-
from datetime import date, datetime, timezone
|
35
35
|
from decimal import Decimal
|
36
36
|
from time import time
|
37
37
|
from urllib.parse import urlparse
|
38
|
-
from uuid import UUID
|
39
38
|
|
39
|
+
import orjson
|
40
40
|
import urllib3
|
41
41
|
from urllib3 import connection_from_url
|
42
42
|
from urllib3.connection import HTTPConnection
|
@@ -86,25 +86,53 @@ def super_len(o):
|
|
86
86
|
return None
|
87
87
|
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
89
|
+
epoch_aware = dt.datetime(1970, 1, 1, tzinfo=dt.timezone.utc)
|
90
|
+
epoch_naive = dt.datetime(1970, 1, 1)
|
91
|
+
|
92
|
+
|
93
|
+
def json_encoder(obj: t.Any) -> t.Union[int, str]:
|
94
|
+
"""
|
95
|
+
Encoder function for orjson, with additional type support.
|
96
|
+
|
97
|
+
- Python's `Decimal` type will be serialized to `str`.
|
98
|
+
- Python's `dt.datetime` and `dt.date` types will be
|
99
|
+
serialized to `int` after converting to milliseconds
|
100
|
+
since epoch.
|
101
|
+
|
102
|
+
https://github.com/ijl/orjson#default
|
103
|
+
https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#type-timestamp
|
104
|
+
"""
|
105
|
+
if isinstance(obj, Decimal):
|
106
|
+
return str(obj)
|
107
|
+
if isinstance(obj, dt.datetime):
|
108
|
+
if obj.tzinfo is not None:
|
109
|
+
delta = obj - epoch_aware
|
110
|
+
else:
|
111
|
+
delta = obj - epoch_naive
|
112
|
+
return int(
|
113
|
+
delta.microseconds / 1000.0
|
114
|
+
+ (delta.seconds + delta.days * 24 * 3600) * 1000.0
|
115
|
+
)
|
116
|
+
if isinstance(obj, dt.date):
|
117
|
+
return calendar.timegm(obj.timetuple()) * 1000
|
118
|
+
raise TypeError
|
119
|
+
|
120
|
+
|
121
|
+
def json_dumps(obj: t.Any) -> bytes:
|
122
|
+
"""
|
123
|
+
Serialize to JSON format, using `orjson`, with additional type support.
|
124
|
+
|
125
|
+
https://github.com/ijl/orjson
|
126
|
+
"""
|
127
|
+
return orjson.dumps(
|
128
|
+
obj,
|
129
|
+
default=json_encoder,
|
130
|
+
option=(
|
131
|
+
orjson.OPT_PASSTHROUGH_DATETIME
|
132
|
+
| orjson.OPT_NON_STR_KEYS
|
133
|
+
| orjson.OPT_SERIALIZE_NUMPY
|
134
|
+
),
|
135
|
+
)
|
108
136
|
|
109
137
|
|
110
138
|
class Server:
|
@@ -180,7 +208,7 @@ class Server:
|
|
180
208
|
|
181
209
|
def _json_from_response(response):
|
182
210
|
try:
|
183
|
-
return
|
211
|
+
return orjson.loads(response.data)
|
184
212
|
except ValueError as ex:
|
185
213
|
raise ProgrammingError(
|
186
214
|
"Invalid server response of content-type '{}':\n{}".format(
|
@@ -223,7 +251,7 @@ def _raise_for_status_real(response):
|
|
223
251
|
if response.status == 503:
|
224
252
|
raise ConnectionError(message)
|
225
253
|
if response.headers.get("content-type", "").startswith("application/json"):
|
226
|
-
data =
|
254
|
+
data = orjson.loads(response.data)
|
227
255
|
error = data.get("error", {})
|
228
256
|
error_trace = data.get("error_trace", None)
|
229
257
|
if "results" in data:
|
@@ -323,7 +351,7 @@ def _update_pool_kwargs_for_ssl_minimum_version(server, kwargs):
|
|
323
351
|
kwargs["ssl_minimum_version"] = ssl.TLSVersion.MINIMUM_SUPPORTED
|
324
352
|
|
325
353
|
|
326
|
-
def _create_sql_payload(stmt, args, bulk_args):
|
354
|
+
def _create_sql_payload(stmt, args, bulk_args) -> bytes:
|
327
355
|
if not isinstance(stmt, str):
|
328
356
|
raise ValueError("stmt is not a string")
|
329
357
|
if args and bulk_args:
|
@@ -334,7 +362,7 @@ def _create_sql_payload(stmt, args, bulk_args):
|
|
334
362
|
data["args"] = args
|
335
363
|
if bulk_args:
|
336
364
|
data["bulk_args"] = bulk_args
|
337
|
-
return
|
365
|
+
return json_dumps(data)
|
338
366
|
|
339
367
|
|
340
368
|
def _get_socket_opts(
|
@@ -670,7 +698,7 @@ class Client:
|
|
670
698
|
# if this is the last server raise exception, otherwise try next
|
671
699
|
if not self._active_servers:
|
672
700
|
raise ConnectionError(
|
673
|
-
("No more Servers available,
|
701
|
+
("No more Servers available, exception from last server: %s")
|
674
702
|
% message
|
675
703
|
)
|
676
704
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: crate
|
3
|
-
Version:
|
3
|
+
Version: 2.0.0
|
4
4
|
Summary: CrateDB Python Client
|
5
5
|
Home-page: https://github.com/crate/crate-python
|
6
6
|
Author: Crate.io
|
@@ -29,6 +29,7 @@ Requires-Python: >=3.6
|
|
29
29
|
Description-Content-Type: text/x-rst
|
30
30
|
License-File: LICENSE
|
31
31
|
License-File: NOTICE
|
32
|
+
Requires-Dist: orjson<4
|
32
33
|
Requires-Dist: urllib3
|
33
34
|
Requires-Dist: verlib2
|
34
35
|
Provides-Extra: doc
|
@@ -38,15 +39,27 @@ Provides-Extra: test
|
|
38
39
|
Requires-Dist: backports.zoneinfo<1; python_version < "3.9" and extra == "test"
|
39
40
|
Requires-Dist: certifi; extra == "test"
|
40
41
|
Requires-Dist: createcoverage<2,>=1; extra == "test"
|
41
|
-
Requires-Dist: mypy<1.
|
42
|
-
Requires-Dist: poethepoet<0.
|
43
|
-
Requires-Dist: ruff<0.
|
42
|
+
Requires-Dist: mypy<1.15; extra == "test"
|
43
|
+
Requires-Dist: poethepoet<0.33; extra == "test"
|
44
|
+
Requires-Dist: ruff<0.10; extra == "test"
|
44
45
|
Requires-Dist: stopit<2,>=1.1.2; extra == "test"
|
45
|
-
Requires-Dist: tox<5,>=3; extra == "test"
|
46
46
|
Requires-Dist: pytz; extra == "test"
|
47
47
|
Requires-Dist: zc.customdoctests<2,>=1.0.1; extra == "test"
|
48
48
|
Requires-Dist: zope.testing<6,>=4; extra == "test"
|
49
49
|
Requires-Dist: zope.testrunner<7,>=5; extra == "test"
|
50
|
+
Dynamic: author
|
51
|
+
Dynamic: author-email
|
52
|
+
Dynamic: classifier
|
53
|
+
Dynamic: description
|
54
|
+
Dynamic: description-content-type
|
55
|
+
Dynamic: home-page
|
56
|
+
Dynamic: keywords
|
57
|
+
Dynamic: license
|
58
|
+
Dynamic: platform
|
59
|
+
Dynamic: provides-extra
|
60
|
+
Dynamic: requires-dist
|
61
|
+
Dynamic: requires-python
|
62
|
+
Dynamic: summary
|
50
63
|
|
51
64
|
=====================
|
52
65
|
CrateDB Python Client
|
@@ -56,7 +69,7 @@ CrateDB Python Client
|
|
56
69
|
:target: https://github.com/crate/crate-python/actions?workflow=Tests
|
57
70
|
:alt: Build status
|
58
71
|
|
59
|
-
.. image:: https://codecov.io/gh/crate/crate-python/branch/
|
72
|
+
.. image:: https://codecov.io/gh/crate/crate-python/branch/main/graph/badge.svg
|
60
73
|
:target: https://app.codecov.io/gh/crate/crate-python
|
61
74
|
:alt: Coverage
|
62
75
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
CHANGES.
|
1
|
+
CHANGES.rst
|
2
2
|
CONTRIBUTING.rst
|
3
3
|
DEVELOP.rst
|
4
4
|
LICENSE
|
@@ -8,7 +8,6 @@ README.rst
|
|
8
8
|
pyproject.toml
|
9
9
|
requirements.txt
|
10
10
|
setup.py
|
11
|
-
docs/backlog.rst
|
12
11
|
docs/blobs.rst
|
13
12
|
docs/conf.py
|
14
13
|
docs/connect.rst
|
@@ -29,7 +28,6 @@ docs/by-example/cursor.rst
|
|
29
28
|
docs/by-example/http.rst
|
30
29
|
docs/by-example/https.rst
|
31
30
|
docs/by-example/index.rst
|
32
|
-
src/crate/__init__.py
|
33
31
|
src/crate.egg-info/PKG-INFO
|
34
32
|
src/crate.egg-info/SOURCES.txt
|
35
33
|
src/crate.egg-info/dependency_links.txt
|
@@ -1,3 +1,4 @@
|
|
1
|
+
orjson<4
|
1
2
|
urllib3
|
2
3
|
verlib2
|
3
4
|
|
@@ -8,11 +9,10 @@ sphinx<9,>=3.5
|
|
8
9
|
[test]
|
9
10
|
certifi
|
10
11
|
createcoverage<2,>=1
|
11
|
-
mypy<1.
|
12
|
-
poethepoet<0.
|
13
|
-
ruff<0.
|
12
|
+
mypy<1.15
|
13
|
+
poethepoet<0.33
|
14
|
+
ruff<0.10
|
14
15
|
stopit<2,>=1.1.2
|
15
|
-
tox<5,>=3
|
16
16
|
pytz
|
17
17
|
zc.customdoctests<2,>=1.0.1
|
18
18
|
zope.testing<6,>=4
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|