Skip to content

Releases: KxSystems/pykx

3.1.6

02 Dec 13:12
d6dac50

Choose a tag to compare

3.1.5

02 Dec 12:52
1641417

Choose a tag to compare

3.1.4

02 Dec 12:30
6ecee2f

Choose a tag to compare

3.1.3

02 Dec 11:58
8806edd

Choose a tag to compare

3.1.2

18 Mar 16:16
a49d878

Choose a tag to compare

The release notes below cover both the 3.1.2 and 3.1.1 releases of PyKX owing to the feature merge containing the changes for both

PyKX 3.1.1

Release Date

2025-02-14

Fixes and Improvements

  • Fixed issue whereby PyKX would prompt for user inputs if a license was not found in a non-interactive session, now correctly falls back to unlicensed mode.
  • Fix throwing of errors for .pykx.safeReimport, now throws an error instead of returning a value.

PyKX 3.1.2

Release Date

2025-03-18

Fixes and Improvements

  • Fixes an issue when using PYKX_THREADING that could cause a segfault in some scenarios.

3.1.0

11 Feb 17:20

Choose a tag to compare

📦 PyKX 3.1.0 Released 📦

Full up-to-date release notes are available here.

🎉 Feature 🎉

  • Added support for Python 3.13.
  • Added support for NumPy 2.0
  • Added support for the creation and management of splayed format databases when using the pykx.DB class.
  • Addition of .copy() method for all pykx objects allowing users to modify copied objects without interfering with the original object.
  • Addition of reshape keyword to the .np() method of kx.List objects. This can provide two benefits:
    a. Conversions of kx.List objects to NumPy by default produce an array of NumPy arrays rather than an N-Dimensional NumPy array. Setting reshape=True when handling N-Dimensional rectangular lists allows the shape to be pre-processed prior to conversion and a more natural N-Dimensional NumPy array to be generated.
>>> kx.q('2 2#4?1f').np(reshape=True)
array([[0.94997503, 0.43908099],
       [0.57590514, 0.59190043]])

b. Provide a performance boost when converting regularly shaped (rectangular) N-Dimensional lists of uniform type when the shape of the resulting numpy array is known prior to conversion

>>> import pykx as kx
>>> lst = kx.q('100000 100 10#100000000?1f')
>>> %timeit lst.np()
9.72 s ± 272 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
>>> %timeit lst.np(reshape=[100000, 100, 10])
883ms ± 19.8 ms per loop (mean ± std. dev. of 7 runs, 1 loops each)
  • Added async_response keyword argument when calling AsyncQConnection objects with reuse=False and wait=False to allow keeping the connection alive until an asynchronous response message has been received.

🔧 Fixes & Improvements 🔧

  • Application of the str function on empty PyKX objects could return unexpected results
>>> import pykx as kx
>>> str(kx.q('()!()'))
'()!()'
>>> str(kx.q('()'))
'()'
  • When a client attempted to retrieve an object which could not be serialized from a PyKX server it resulted in the client process hanging. An appropriate error is now sent to the client.
  • Database generation functionality now allows users to pass any data-type which will convert to a pykx.Table as the table parameter
  • Attempting to create a partitioned databases/add a partition to a database with a sym_enum keyword but no by_field would result in a KeyError.
  • Using math.inf or -math.inf when creating numeric values now creates equivalent PyKX types
  • Fixed a bug where QFuture objects returned by AsyncQConnection objects could block each other unnecessarily.

🆕 Beta Features 🆕

Addition of support in Beta form for conversions between PyKX and PyTorch objects.

2.5.5

16 Dec 10:25
b7b256e

Choose a tag to compare

PyKX 2.5.5

Release Date

2024-11-28

Fixes and Improvements

  • PyKX Pandas dependency has been raised to allow <=2.2.3 for Python>3.8
  • PyKX Pandas dependency for Python 3.8 has been clamped to <2.0 due to support being dropped for it by Pandas after 2.0.3.

For release notes of all versions see here.

3.0.1

04 Dec 17:43
42f707b

Choose a tag to compare

Full up-to-date release notes are available here.

🎉 Feature 🎉

  • Addition of the property day to kx.Column objects to allow users to retrieve the day of month of a timestamp.

    >>> import pykx as kx
    >>> tab = kx.Table(data={
    ...     'a': kx.random.random(100, kx.TimestampAtom.inf),
    ...     'b': kx.random.random([100, 3], 10.0)
    ...     })
    >>> tab.exec(kx.Column('a').day)
    pykx.IntVector(pykx.q('7 10 12..'))

🔧 Fixes & Improvements 🔧

  • Added warning to kx.q.system.load and context registration when attempting to load path with a space. Can be suppressed by enabling PYKX_SUPPRESS_WARNINGS.

  • Changed %%python heading to %%py when calling Python code during jupyter_qfirst mode so as not to conflict with inbuilt Jupyter cell magics.

  • Fixed kx.license.check(format='string') to remove newline characters during comparison.

  • Configuration file .pykx-config now supports use of boolean toml configuration

    $ cat ~/.pykx-config
    [default]
    PYKX_QDEBUG = true
    $ python
    >>> import pykx as kx
    >>> kx.config.pykx_qdebug
    True
  • Reintroduced unsetting/setting of PYKX_SKIP_UNDERQ in PyKXReimport these had been removed in the 3.0.0 release.

  • Added type checking for the cast flag when calling kx.toq() or creating a kx.K variable such as kx.FloatVector() or kx.DatetimeAtom().

  • Removed the need to enable PYKX_BETA_FEATURES to use pykx_threading.

  • Fixed a memory leak when calling pickle.loads on a PyKX object which previously had been called with pickle.dumps.

  • Removal of column type from the return of dtypes method for kx.Table objects, previously this had raised a deprecation warning

    >>> tab = kx.q('([] a:1 2 3j;b:4 5 6i)')
    >>> tab.dtypes
    pykx.Table(pykx.q('
    columns datatypes
    ---------------------
    a       "kx.LongAtom"
    b       "kx.IntAtom" 
    '))

3.0.0

12 Nov 11:34
bf05b31

Choose a tag to compare

Full up-to-date release notes are available here.

🎉 Major Features/Changes 🎉

  • Addition of functionality to allow for development of end-to-end streaming workflows consisting of data-ingestion, persistence and query. This functionality is outlined in-depth here.
  • Update to the PyKX Query API to support a significantly more Python first approach to querying kdb+ in-memory and on-disk databases.
>>> table = kx.Table(data={
...     'sym': kx.random.random(100, ['AAPL', 'GOOG', 'MSFT']),
...     'date': kx.random.random(100, kx.q('2022.01.01') + [0,1,2]),
...     'price': kx.random.random(100, 1000.0),
...     'size': kx.random.random(100, 100) 
... })
>>> table.select(columns=kx.Column('price').max(), where=kx.Column('size') > 5)
>>> table.update(column=kx.Column('price').wavg(kx.Column('size')).rename('vwap'), by=kx.Column('sym'))
>>> table.delete(column=kx.Column('sym'))
>>> table.update(column=(kx.Column('price') * kx.Column('size')).rename('total'))

Beta features available in the 2.* versions of PyKX have now been migrated to full support.
- The full list of these features are as follows:
- Database Creation and Management
- Compression and Encryption Module
- Remote Function Execution
- Streamlit Integration
- Multi-threaded use of PyKX

❓ What else? ❓

  • Extension to our integration with Jupyter Notebooks by adding a q-first mode of operation which allows users working between the two languages to more easily automate workflows depending on both
  • Addition of a new utility function kx.util.detect_bad_columns to validate if the columns of a table object conform to the naming conventions supported by kdb+ and highlighting if the table contains duplicate column names raising a warning indicating potential issues and returning True if the table contains invalid columns.
  • When generating IPC connections with reconnection_attempts users can now configure the initial delay between first and second attempts and the function which updates the delay on successive attempts using the reconnection_delay and reconnection_function keywords. See here for a worked example.
  • Two new options added on first initialisation of PyKX to allow users to:
    • Use the path to their already downloaded kc.lic/k4.lic licenses without going through the “Do you want to install a license” workflow
    • Allow users to persist for future use that they wish to use the IPC only unlicensed mode of PyKX, this will persist a file ~/.pykx-config which sets configuration denoting unlicensed mode is to be used.
  • Addition of function kx.util.install_q to allow users who do not have access to a q executable at the time of installing PyKX. See here for instructions regarding its use.
    Addition of function kx.util.start_q_subprocess to allow a q process to be started on a specified port with supplied initialisation arguments

🔧 Fixes & Improvements 🔧

As with any release PyKX 3.0 provides a significant number of bug fixes and improvements, the following are a subset:

  • Addition of support for help when interacting with q keywords and operators via PyKX
  • Previously loading pykx.q during q startup using QINIT or QHOME/q.q resulted in a segfault or a corruption.
  • The function kx.util.debug_environment now returns the applied configuration values at startup instead of customised values
  • Operations on kx.GroupbyTable objects which have been indexed previously would raise an error indicating invalid key access
  • Attempts to load a database using the kx.DB module previously would raise an nyi error if the path to the database contained a space

2.5.2

05 Jul 12:34
8b9cfb6

Choose a tag to compare

PyKX 2.5.2 has been released 🎉 Full release notes for client consumption can be found here.

Highlights:

Converting PyKX generic lists using the keyword parameter raw=True would previously return incorrect results, the values received being the memory address of the individual elements of the list, this has now been resolved:

>>> a = kx.q('(1; 3.4f; `asad; "asd")')
>>> a.np(raw=True)
array([1, 3.4, b'asad', b'asd'], dtype=object)
  • Fix to issue where use of kx.SymbolAtom with getitem method on kx.Table objects would return a table rather then vector/list. The return now mirrors the expected return which matches str type inputs
>>> import pykx as kx
>>> tab = kx.Table(data={'x': [1, 2, 3], 'y': ['a', 'b', 'c']})
>>> tab['x']
pykx.LongVector(pykx.q('1 2 3'))
>>> tab[kx.SymbolAtom('x')]
pykx.LongVector(pykx.q('1 2 3'))

Fix to issue where loading PyKX on Windows from 2.5.0 could result in a users working directory being changed to site-packages/pykx

The full list including more fixes and improvements is available here.