Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
005bd26
Follow quick start guide
juliannguyen4 Apr 26, 2026
a7ac117
Prevent silent failing
juliannguyen4 Apr 26, 2026
b9676ba
Add doctest to test code examples in aerospike module rst docs. TODO …
juliannguyen4 Apr 26, 2026
9410da7
Try running with doc/*.rst to see what files get inspected
juliannguyen4 Apr 26, 2026
054b8a1
*.rst doesn't show any output. Try checking a specific file
juliannguyen4 Apr 26, 2026
7e1e1e6
need verbose mode to see number of tests run and whether they passed
juliannguyen4 Apr 26, 2026
2b0446c
Update code example to be doctest compatible. TODO - see how it appea…
juliannguyen4 Apr 26, 2026
aeee4d6
Move doctest to smoke tests to use python client build in order to im…
juliannguyen4 Apr 26, 2026
cb8f30f
Reuse job that deploys server to run doctest examples
juliannguyen4 Apr 26, 2026
ee30366
Move doctest to CE test to avoid needing to login as user
juliannguyen4 Apr 26, 2026
5bede57
Do this to avoid running doc test on every python version
juliannguyen4 Apr 26, 2026
2fd1829
fix workflow
juliannguyen4 Apr 26, 2026
c8fe007
Add sphinx_copybutton extension to make copying doctest-formatted cod…
juliannguyen4 Apr 26, 2026
865ceae
Follow 'use and customize' guide for sphinx-copybutton to skip copyin…
juliannguyen4 Apr 26, 2026
17aa74c
Add back comments
juliannguyen4 Apr 26, 2026
a15032a
Convert all code examples to be doctest compatible TODO - except for …
juliannguyen4 Apr 26, 2026
50664bc
Fix doctest formatting. Not sure why sphinx didn't fail bc of this
juliannguyen4 Apr 26, 2026
9ba17f0
Fix reported failures. Exception detail doesn't matter since it's a t…
juliannguyen4 Apr 27, 2026
14d5820
Add custom script to run all doctest code examples. This allows us to…
juliannguyen4 Apr 27, 2026
667460f
Mv script name to prevent shadowing doctest package
juliannguyen4 Apr 27, 2026
86b1f35
Fix workflow
juliannguyen4 Apr 27, 2026
1758e56
Try using this method instead to run the boilerplate code before ever…
juliannguyen4 Apr 27, 2026
f7664a2
Use doctest builder to run doctest in client.rst
juliannguyen4 Apr 27, 2026
0b3af6d
Forgot that pinned sphinx version requires 3.12 or higher
juliannguyen4 Apr 27, 2026
bebf000
Fix syntax
juliannguyen4 Apr 27, 2026
a59305f
Noticed some aerospike.* methods in aerospike.rst are returning Magic…
juliannguyen4 Apr 27, 2026
52418be
Fix HyperLogLog code example
juliannguyen4 Apr 27, 2026
d04848c
Fix formatting. Output here is correct
juliannguyen4 Apr 27, 2026
2d047be
Try testcode block, if it works then just move the other code example…
juliannguyen4 Apr 27, 2026
efb9f78
Fix hyperloglog..
juliannguyen4 Apr 27, 2026
153cfa7
Think it's safe to remove code to run doctest if we are already using…
juliannguyen4 Apr 27, 2026
5223348
Fix prepend code example
juliannguyen4 Apr 27, 2026
71c6941
Make most of the code examples in client.rst testable.
juliannguyen4 Apr 27, 2026
03fbd13
Test if this command works in aerospike_helpers
juliannguyen4 Apr 27, 2026
6e86937
Try this setting in order to build docs for aerospike_helpers.
juliannguyen4 Apr 27, 2026
7cb953d
Add back example label.
juliannguyen4 Apr 27, 2026
8ddf498
Replace 'Example::' with testcode directive for sphinx doctest to check
juliannguyen4 Apr 27, 2026
66dcce0
Revert code examples back to code-output-style blocks since sphinx do…
juliannguyen4 Apr 28, 2026
0620de5
Rm unused script now that we use sphinx doctest
juliannguyen4 Apr 28, 2026
ad7b685
Fix code example outputs causing doc build to fail
juliannguyen4 Apr 28, 2026
6e83983
Add testsetup block to fix many errors in aerospike_helpers.expressio…
juliannguyen4 Apr 28, 2026
72615a1
Fix a few bad/inconsistent code examples
juliannguyen4 Apr 28, 2026
f966c32
Fix more bad code examples..
juliannguyen4 Apr 28, 2026
16d0bbb
Improve naming for one code example. Fix another example
juliannguyen4 Apr 28, 2026
ef4ef1f
Add missing import
juliannguyen4 Apr 28, 2026
817450d
Add debug print to see why operation code is not an integer
juliannguyen4 Apr 29, 2026
d260ec0
Debug further
juliannguyen4 Apr 29, 2026
cf83d66
Add debug prints in glue code to see what type the client sees. TODO …
juliannguyen4 Apr 29, 2026
a222bd8
fix compiler error
juliannguyen4 Apr 29, 2026
65eb2d5
Make compatible with Python 3.10. PyType_GetName isn't available in t…
juliannguyen4 Apr 29, 2026
94f1a16
Use better method
juliannguyen4 Apr 29, 2026
e184e70
Printed out the type of the module constant, but try seeing what is a…
juliannguyen4 Apr 30, 2026
26e0cf3
Forgot to print to stderr. doctest captures stdout
juliannguyen4 Apr 30, 2026
21e30b6
Try not mocking out aerospike to see if doctest extension depends on …
juliannguyen4 Apr 30, 2026
d319647
Conditionally mock out aerospike if it isn't installed. This way doct…
juliannguyen4 Apr 30, 2026
792b1b6
Fix 2 code examples in aerospike.rst. This assumes the elements are r…
juliannguyen4 Apr 30, 2026
f4e3b84
Expand code example for hyperloglog
juliannguyen4 Apr 30, 2026
dca10b0
Address a few more code examples failing.
juliannguyen4 Apr 30, 2026
46b4a20
Address more code example failures. Use ellipsis for nonexact matches
juliannguyen4 Apr 30, 2026
2477217
Fix udf examples
juliannguyen4 Apr 30, 2026
5bb7d3f
Add missing import
juliannguyen4 Apr 30, 2026
3145ba7
Make sure udf output matches code example
juliannguyen4 Apr 30, 2026
fa2a5f6
Fix indentation
juliannguyen4 Apr 30, 2026
45f8580
Add missing key
juliannguyen4 Apr 30, 2026
e5b0d3a
Attempt to fix udf code example error
juliannguyen4 Apr 30, 2026
ef1a6b1
This example doesn't explicitly test ttl/gen so we can just ignore it
juliannguyen4 Apr 30, 2026
3a0a1ae
Address one test failure
juliannguyen4 Apr 30, 2026
5ec69d2
Address a few errors
juliannguyen4 May 1, 2026
8d9675a
Address a few errors
juliannguyen4 May 1, 2026
6d295c9
Getting import errors for expr op examples. Not sure why this is happ…
juliannguyen4 May 1, 2026
23e1d2a
Show logs to see why HyperLogLog code example fails
juliannguyen4 May 1, 2026
e36bc42
Add scaffolding for hll code examples TODO not done
juliannguyen4 May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/smoke-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,12 @@ jobs:
"3.13",
"3.14"
]
type: [
regular
]
include:
- type: doctest
py-version: '3.12'
fail-fast: false

steps:
Expand Down Expand Up @@ -388,6 +394,7 @@ jobs:
run: pip install *.whl

- name: Install test dependencies
if: ${{ matrix.type != 'doctest' }}
run: pip install -r test/requirements.txt

- uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
Expand All @@ -400,6 +407,7 @@ jobs:
run: docker run -d --name aerospike -p 3000-3002:3000-3002 -e DEFAULT_TTL=2592000 ${{ env.REGISTRY_NAME }}/aerospike/aerospike-server:${{ env.SERVER_TAG }}

- name: Create config.conf
if: ${{ matrix.type != 'doctest' }}
run: cp config.conf.template config.conf
working-directory: test

Expand All @@ -408,9 +416,22 @@ jobs:
container-name: aerospike

- name: Run tests
if: ${{ matrix.type != 'doctest' }}
run: python -m pytest ./new_tests -vv -W error::pytest.PytestUnraisableExceptionWarning
working-directory: test

- name: Install test dependencies
if: ${{ matrix.type == 'doctest' }}
run: pip install -r doc/requirements.txt

- if: ${{ matrix.type == 'doctest' }}
name: Run doctest
run: sphinx-build -b doctest . doctest
working-directory: doc

- if: ${{ !cancelled() }}
run: docker logs aerospike

test-ee:
runs-on: ubuntu-22.04
needs: build
Expand Down
19 changes: 17 additions & 2 deletions aerospike_helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,23 @@ class HyperLogLog(bytes):

The constructor takes in any argument that the :class:`bytes` constructor takes in.

>>> h = HyperLogLog([1, 2, 3])
>>> client.put(key, {"hyperloglog": h})
.. testcode::

from aerospike_helpers import HyperLogLog
import aerospike

h = HyperLogLog([1, 2, 3])

client = aerospike.client({'hosts': [('localhost', 3000)]})
key = ("test", "demo", 1)
client.put(key, {"hyperloglog": h})

_, _, bins = client.get(key)
print(bins["hyperloglog"])

.. testoutput::

HyperLogLog(...)
"""
def __new__(cls, o) -> "HyperLogLog":
return super().__new__(cls, o)
Expand Down
42 changes: 28 additions & 14 deletions aerospike_helpers/batch/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,13 @@ def __init__(
self, key: tuple, ops: "TypeOps", meta: Optional[dict] = None, policy: "TypeBatchPolicyWrite" = None
) -> None:
"""
Example::
Example:

.. testcode::

# Create a batch Write to increment bin "a" by 10 and read the result from the record.
import aerospike
import aerospike_helpers.operations as op
from aerospike_helpers.operations import operations as op
from aerospike_helpers.batch.records import Write

bin_name = "a"
Expand Down Expand Up @@ -140,11 +142,13 @@ def __init__(
policy: "TypeBatchPolicyRead" = None,
) -> None:
"""
Example::
Example:

.. testcode::

# Create a batch Read to read bin "a" from the record.
import aerospike
import aerospike_helpers.operations as op
from aerospike_helpers.operations import operations as op
from aerospike_helpers.batch.records import Read

bin_name = "a"
Expand Down Expand Up @@ -192,12 +196,15 @@ def __init__(
self, key: tuple, module: str, function: str, args: "TypeUDFArgs", policy: "TypeBatchPolicyApply" = None
) -> None:
"""
Example::
Example:

.. testcode::

# Create a batch Apply to apply UDF "test_func" to bin "a" from the record.
# Assume that "test_func" takes a bin name string as an argument.
# Assume the appropriate UDF module has already been registered.
import aerospike_helpers.operations as op
from aerospike_helpers.batch.records import Apply


module = "my_lua"
Expand Down Expand Up @@ -240,7 +247,9 @@ class Remove(BatchRecord):

def __init__(self, key: tuple, policy: "TypeBatchPolicyRemove" = None) -> None:
"""
Example::
Example:

.. testcode::

# Create a batch Remove to remove the record.
import aerospike_helpers.operations as op
Expand All @@ -251,7 +260,7 @@ def __init__(self, key: tuple, policy: "TypeBatchPolicyRemove" = None) -> None:
user_key = 1
key = (namespace, set, user_key)

br = Remove(key, ops)
br = Remove(key)
"""
super().__init__(key)
self._type = _Types.REMOVE
Expand All @@ -278,7 +287,9 @@ class BatchRecords:

def __init__(self, batch_records: Optional[TypeBatchRecordList] = None) -> None:
"""
Example::
Example:

.. testcode::

import aerospike
import aerospike_helpers.operations.operations as op
Expand Down Expand Up @@ -328,12 +339,15 @@ def __init__(self, batch_records: Optional[TypeBatchRecordList] = None) -> None:
for br in brs.batch_records:
print(br.result)
print(br.record)
# 0
# (('test', 'demo', 1, bytearray(b'...')), {'ttl': 4294967295, 'gen': 0}, {})
# 0
# (('test', 'demo', 2, bytearray(b'...')), {'ttl': 2592000, 'gen': 4}, {'id': 100})
# 0
# (('test', 'demo', 3, bytearray(b'...')), {'ttl': 2592000, 'gen': 3}, {'id': 1})

.. testoutput::

0
(('test', 'demo', 1, bytearray(b'...')), {...}, {})
0
(('test', 'demo', 2, bytearray(b'...')), {...}, {'id': 100})
0
(('test', 'demo', 3, bytearray(b'...')), {...}, {'id': 1})
"""

if batch_records is None:
Expand Down
12 changes: 9 additions & 3 deletions aerospike_helpers/cdt_ctx.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
Helper functions to generate complex data type context (cdt_ctx) objects for use with operations on nested CDTs (list,
map, etc).

Example::
Example:

.. testcode::

import aerospike
from aerospike import exception as ex
Expand Down Expand Up @@ -51,7 +53,6 @@

_, _, result = client.operate(key, ops)
print(result)
# {'users': 200}

# Example 2: add a new person and get their rating of Facebook
cindy = {
Expand All @@ -76,11 +77,11 @@

_, _, result = client.operate(key, ops)
print(result)
# {'users': 4}

# Example 3: create a CDT secondary index from a base64 encoded _cdt_ctx with info command
policy = {}

ctx_list_index = [cdt_ctx.cdt_ctx_list_index(0)]
bs_b4_cdt = client.get_cdtctx_base64(ctx_list_index)

r = []
Expand All @@ -101,6 +102,11 @@
client.remove(key)
client.close()

.. testoutput::

{'users': 200}
{'users': 4}

.. _path_expressions_contexts:

Path Expressions Contexts
Expand Down
57 changes: 43 additions & 14 deletions aerospike_helpers/expressions/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ def __init__(self, *args: "TypeNumber"):

:return: (integer or float value).

Example::
Example:

.. testcode::


# Integer bin "a" + "b" == 11
expr = exp.Eq(exp.Add(exp.IntBin("a"), exp.IntBin("b")), 11).compile()
Expand Down Expand Up @@ -86,7 +89,9 @@ def __init__(self, *args: "TypeNumber"):

:return: (integer or float value)

Example::
Example:

.. testcode::

# Integer bin "a" - "b" == 11
expr = exp.Eq(exp.Sub(exp.IntBin("a"), exp.IntBin("b")), 11).compile()
Expand Down Expand Up @@ -117,7 +122,9 @@ def __init__(self, *args: "TypeNumber"):

:return: (integer or float value)

Example::
Example:

.. testcode::

# Integer bin "a" * "b" >= 11
expr = exp.GE(exp.Mul(exp.IntBin("a"), exp.IntBin("b")), 11).compile()
Expand Down Expand Up @@ -150,7 +157,9 @@ def __init__(self, *args: "TypeNumber"):

:return: (integer or float value)

Example::
Example:

.. testcode::

# Integer bin "a" / "b" / "c" >= 11
expr = exp.GE(exp.Div(exp.IntBin("a"), exp.IntBin("b"), exp.IntBin("c")), 11).compile()
Expand Down Expand Up @@ -184,7 +193,9 @@ def __init__(self, base: "TypeFloat", exponent: "TypeFloat"):

:return: (float value)

Example::
Example:

.. testcode::

# Float bin "a" ** 2.0 == 16.0
expr = exp.Eq(exp.Pow(exp.FloatBin("a"), 2.0), 16.0).compile()
Expand Down Expand Up @@ -212,7 +223,9 @@ def __init__(self, num: "TypeFloat", base: "TypeFloat"):

:return: (float value)

Example::
Example:

.. testcode::

# For float bin "a", log("a", 2.0) == 16.0
expr = exp.Eq(exp.Log(exp.FloatBin("a"), 2.0), 16.0).compile()
Expand Down Expand Up @@ -240,7 +253,9 @@ def __init__(self, numerator: "TypeInteger", denominator: "TypeInteger"):

:return: (integer value)

Example::
Example:

.. testcode::

# For int bin "a" % 10 == 0
expr = exp.Eq(exp.Mod(exp.IntBin("a"), 10), 0).compile()
Expand Down Expand Up @@ -270,7 +285,9 @@ def __init__(self, value: "TypeNumber"):

:return: (number value)

Example::
Example:

.. testcode::

# For int bin "a", abs("a") == 1
expr = exp.Eq(exp.Abs(exp.IntBin("a")), 1).compile()
Expand Down Expand Up @@ -300,7 +317,9 @@ def __init__(self, value: "TypeFloat"):

:return: (float value)

Example::
Example:

.. testcode::

# Floor(2.25) == 2.0
expr = exp.Eq(exp.Floor(2.25), 2.0).compile()
Expand Down Expand Up @@ -331,7 +350,9 @@ def __init__(self, value: "TypeFloat"):

:return: (float value)

Example::
Example:

.. testcode::

# Ceil(2.25) == 3.0
expr = exp.Eq(exp.Ceil(2.25), 3.0).compile()
Expand All @@ -357,7 +378,9 @@ def __init__(self, value: "TypeFloat"):

:return: (integer value)

Example::
Example:

.. testcode::

#For float bin "a", int(exp.FloatBin("a")) == 2
expr = exp.Eq(exp.ToInt(exp.FloatBin("a")), 2).compile()
Expand All @@ -379,7 +402,9 @@ def __init__(self, value: "TypeInteger"):

:return: (float value)

Example::
Example:

.. testcode::

#For int bin "a", float(exp.IntBin("a")) == 2
expr = exp.Eq(exp.ToFloat(exp.IntBin("a")), 2).compile()
Expand All @@ -404,7 +429,9 @@ def __init__(self, *args: "TypeNumber"):

:return: (integer or float value).

Example::
Example:

.. testcode::

# for integer bins a, b, c, min(a, b, c) > 0
expr = exp.GT(exp.Min(exp.IntBin("a"), exp.IntBin("b"), exp.IntBin("c")), 0).compile()
Expand All @@ -428,7 +455,9 @@ def __init__(self, *args: "TypeNumber"):

:return: (integer or float value).

Example::
Example:

.. testcode::

# for integer bins a, b, c, max(a, b, c) > 100
expr = exp.GT(exp.Max(exp.IntBin("a"), exp.IntBin("b"), exp.IntBin("c")), 100).compile()
Expand Down
Loading
Loading