Skip to content

Commit 53cb36b

Browse files
committed
3.1.5
1 parent 6ecee2f commit 53cb36b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1007
-373
lines changed

DEVELOPING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Additional Pythonic practices exist concerning the Python type system. Some of t
6161
- When type checking is required, check against the standard [abstract base classes](https://docs.python.org/3/library/collections.abc.html) where applicable. These implement what's known as "virtual subclasses" by hooking into the mechanism behind `issubclass` to make classes which do not inherit them still match against them. For example, for any class `x` which implements `__contains__`, `__iter__`, and `__len__`, `issubclass(x, collections.abc.Collection) is True`.
6262
- When delegating the methods (particularly the `__init__` method) to the super-class, have the method accept and pass on arbitrary arguments to ensure future changes to the signature of the method do not break the delegation chain. This can be accomplished by having `*args` and `**kwargs` in the parameter list, and then calling the super-class method with `*args` and `**kwargs`.
6363

64-
Other miscellaneous Pythonic tips include:
64+
Other miscellaneous Pythonic tips include:
6565
- Prefer `try` over `if` blocks where reasonable. See [EAFP](https://docs.python.org/3/glossary.html#term-eafp). For example, instead of checking if a key in a dictionary is present with an `if` statement prior to accessing it, one should access the dictionary within a `try` block, and handle the `KeyError` should it arise.
6666
- Avoid extracting a sequence from an iterator without good reason. Iterators can produce infinite sequences (which will freeze the process). Additionally it can be a waste of memory to extract a sequence, as it's common for less than the entire output of an iterator to be consumed.
6767
- Do not rely on CPython-specific behavior, such as the builtin function `id` returning the address of the object in memory.

custom_theme/partials/header.html.tpl

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
{#-
22
This file was automatically generated - do not edit
33
-#}
4-
<!-- Announcement begins-->
5-
{% block announce %}
6-
<div class="md-grid">
7-
<h2>New Documentation Site!</h2>
8-
<p style="font-size: 14px;">
9-
We are excited to announce the launch of our enhanced product documentation site for <a href="https://docs.kx.com/3.1/PyKX/home.htm" style="color: var(--md-typeset-a-color);">PyKX</a> at <a href="https://docs.kx.com/home/index.htm" style="color: var(--md-typeset-a-color);">docs.kx.com</a>.
10-
It offers improved search capabilities, organized navigation, and developer-focused content. Please, take a moment to explore the site and share your feedback with us.
11-
</p>
12-
</div>
13-
{% endblock %}
14-
<!-- ends -->
154
{% set class = "md-header" %}
165
{% if "navigation.tabs.sticky" in features %}
176
{% set class = class ~ " md-header--lifted" %}

docs/api/pykx-q-data/type_conversions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ A breakdown of each of the `pykx.K` types and their analogous `Python`, `NumPy`,
2323
| [Timespan](#pykxtimespanatom) | timedelta | timedelta64[ns] | DurationArray |
2424
| [Minute](#pykxminuteatom) | timedelta | timedelta64[m] | Not Supported |
2525
| [Second](#pykxsecondatom) | timedelta | timedelta64[s] | DurationArray |
26-
| [Time](#TimeAtom) | timedelta | timedelta64[ms] | DurationArray |
26+
| [Time](#pykxtimeatom) | timedelta | timedelta64[ms] | DurationArray |
2727
| [Dictionary](#pykxdictionary) | dict | Not Supported | Not Supported |
2828
| [Table](#pykxtable) | dict | records | Table |
2929

3030
??? "Cheat Sheet: `Pandas 1.*`, `Pandas 2.*`, `Pandas 2.* PyArrow backed`"
3131

32-
**Note:** Creating PyArrow backed Pandas objects uses `as_arrow=True` using NumPy arrays as an intermediate data format.
32+
**Note:** Creating PyArrow backed Pandas objects uses `as_arrow=True` using NumPy arrays as an intermediate data format.
3333

3434
| PyKX type | Pandas 1.\* dtype | Pandas 2.\* dtype | Pandas 2.\* as_arrow=True dtype |
3535
| ------------------------------- | ----------------- | ----------------- | ------------------------------- |
@@ -50,7 +50,7 @@ A breakdown of each of the `pykx.K` types and their analogous `Python`, `NumPy`,
5050
| [Timespan](#pykxtimespanatom) | timedelta64[ns] | timedelta64[ns] | duration[ns][pyarrow] |
5151
| [Minute](#pykxminuteatom) | timedelta64[ns] | timedelta64[s] | duration[s][pyarrow] |
5252
| [Second](#pykxsecondatom) | timedelta64[ns] | timedelta64[s] | duration[s][pyarrow] |
53-
| [Time](#TimeAtom) | timedelta64[ns] | timedelta64[ms] | duration[ms][pyarrow] |
53+
| [Time](#pykxtimeatom) | timedelta64[ns] | timedelta64[ms] | duration[ms][pyarrow] |
5454
| [Dictionary](#pykxdictionary) | Not Supported | Not Supported | Not Supported |
5555
| [Table](#pykxtable) | DataFrame | DataFrame | DataFrame |
5656

docs/api/tick.md

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,3 @@ tags: tick, rdb, hdb, idb, streaming, stream
88
# Streaming tickerplant
99

1010
::: pykx.tick
11-
rendering:
12-
show_root_heading: false
13-
options:
14-
show_root_heading: false
15-
members_order: source
16-
members:
17-
- STREAMING
18-
- BASIC
19-
- TICK
20-
- RTP
21-
- HDB
22-
- GATEWAY
1.63 KB
Binary file not shown.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import asyncio
2+
import time
3+
4+
import pykx as kx
5+
6+
7+
class ConnectionManager:
8+
connections = {}
9+
10+
async def open(self, port):
11+
self.connections[port] = await kx.AsyncQConnection(port=port)
12+
13+
async def __aenter__(self):
14+
return self
15+
16+
async def __aexit__(self, exc_type, exc_val, exc_tb):
17+
for v in self.connections.values():
18+
await v.close()
19+
20+
def __call__(self, port, query, *args):
21+
return self.connections[port](query, *args)
22+
23+
24+
async def main():
25+
async with ConnectionManager() as cm:
26+
await cm.open(5050)
27+
await cm.open(5051)
28+
start = time.monotonic_ns()
29+
queries = [
30+
cm(5050, '{system"sleep 10"; til x + y}', 6, 7),
31+
cm(5051, '{system"sleep 5"; til 10}[]')
32+
]
33+
queries = [await x for x in queries]
34+
end = time.monotonic_ns()
35+
[print(x) for x in queries]
36+
print(f'took {(end - start) / 1_000_000_000} seconds')
37+
38+
39+
if __name__ == '__main__':
40+
asyncio.run(main())
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: Asynchronous Querying Example
3+
date: July 2025
4+
author: KX Systems, Inc.
5+
tags: PyKX, q, asyncio, IPC, asynchronous
6+
---
7+
8+
# PyKX Calling into multiple q servers without blocking
9+
10+
_This example provides a quick start for setting up a Python process using `PyKX` to call into
11+
multiple q servers without blocking each other._
12+
13+
To follow along, feel free to download this <a href="./archive.zip" download>zip archive</a> that
14+
contains a copy of the python scripts and this writeup.
15+
16+
## Quickstart
17+
18+
This example creates a python process that sends 2 queries meant to simulate long running queries to
19+
two separate q servers to show how to query q servers without blocking using `PyKX`.
20+
21+
### Run the Example
22+
23+
The example uses 2 servers opened up on ports 5050 and 5051, these servers can be opened with the
24+
commands `$ q -p 5050` and `$ q -p 5051` respectively.
25+
The script `async_query.py` can then be run to send the two queries simultaneously with
26+
`$ python async_query.py`.
27+
28+
### Outcome
29+
30+
The script will send the two queries and print their results followed by the total time taken
31+
by the script.
32+
33+
The first query takes 10 seconds and the second takes 5 seconds to complete showing that both
34+
queries were processed without blocking eachother.
35+
36+
```bash
37+
0 1 2 3 4 5 6 7 8 9 10 11 12
38+
0 1 2 3 4 5 6 7 8 9
39+
took 10.001731808 seconds
40+
```
41+
42+
### Important notes on usage of `QConnections`
43+
44+
While the `#!python with` syntax for `QConnection` objects is useful for sending one shot requests it
45+
should be avoided where possible when repeatedly querying the same server. This is because
46+
connecting to q servers is blocking and the closing of `QConnection` objects is also blocking which
47+
will cause other queries to be delayed in certain cases. There is a simple class called
48+
`ConnectionManager` provided in this example to handle opening connections to servers and allow
49+
querying them by supplying a port alongside the query and any arguments. This class will also clean
50+
up the stored `QConnection` objects when its `#!python with` block ends, much like the normal
51+
`QConnection` objects do themselves.

docs/examples/db-management.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
"id": "2e91160e",
8080
"metadata": {},
8181
"source": [
82-
"Database interactions are facilitated through use of the `pykx.DB` class. All methods/attributes used in this notebook are contained within this class. \n",
82+
"Database interactions are facilitated through use of the `pykx.DB` class. All methods/attributes used in this notebook are contained within this class. Only one `DB` object can exist at a time within a process.\n",
8383
"\n",
8484
"Initialise the `DB` class to start. The expected input is the file path where you intend to save the partitioned database and its associated tables. In this case we're going to use the temporary directory we just created. "
8585
]

docs/examples/interface-overview.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@
644644
"metadata": {},
645645
"outputs": [],
646646
"source": [
647-
"conn.qsql.select('tab', where=['col1=`a', 'col2<0.3'])"
647+
"conn.qsql.select('tab', where=((kx.Column('col1')=='a') & (kx.Column('col2')>0.3)))"
648648
]
649649
},
650650
{

docs/examples/server/server.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,4 @@ set the `#!python conn_gc_time` to `#!python 10.0` then this clean-up happens ev
9191

9292
!!! Note
9393

94-
[reval](../../api/pykx-execution/q.md#reval) will not impose read only exection on a PyKX server as Python manages the sockets rather than `q`.
94+
[reval](../../api/pykx-execution/q.md#reval) will not impose read only execution on a PyKX server as Python manages the sockets rather than `q`.

0 commit comments

Comments
 (0)