Skip to content

Commit

Permalink
add znsocket.List (#5)
Browse files Browse the repository at this point in the history
* add `znsocket.List`

* unit test List

* more unit tests

* better tests

* add tests

* do not test with redis

* use redis server container

* always test against redis

* improve testing and small bugfix

* add pypi badge

* raise exceptions

* test Server.from_url

* add lpush, improve tests

* update `srem`

* update README

* remove

* bump version

* update description
  • Loading branch information
PythonFZ authored May 29, 2024
1 parent d59d34e commit 96f262e
Show file tree
Hide file tree
Showing 13 changed files with 627 additions and 101 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ jobs:
- "3.10"
os:
- ubuntu-latest

services:
# Label used to access the service container
redis:
# Docker Hub image
image: redis
# Set health checks to wait until redis has started
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps port 6379 on service container to the host
- 6379:6379

steps:
- uses: actions/checkout@v4
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[![PyPI version](https://badge.fury.io/py/znsocket.svg)](https://badge.fury.io/py/znsocket)
[![Coverage Status](https://coveralls.io/repos/github/zincware/ZnSocket/badge.svg?branch=main)](https://coveralls.io/github/zincware/ZnSocket?branch=main)
![PyTest](https://github.com/zincware/ZnSocket/actions/workflows/pytest.yaml/badge.svg)
[![zincware](https://img.shields.io/badge/Powered%20by-zincware-darkcyan)](https://github.com/zincware)
Expand Down Expand Up @@ -38,3 +39,25 @@ assert c.get("name") == "Fabian"

> [!NOTE]
> ZnSocket does not decode strings automatically. Using it is equivalent to using `Redis.from_url(storage, decode_responses=True)` in the Redis client.

## Lists
ZnSocket provides a synchronized version of the Python `list` implementation. Unlike a regular Python list, the data in `znsocket.List` is not stored locally; instead, it is dynamically pushed to and pulled from the server.

Below is a step-by-step example of how to use `znsocket.List` to interact with a ZnSocket server.

```python
from znsocket import Client, List

# Connect to the ZnSocket server using the provided URL
client = Client.from_url("znsocket://127.0.0.1:5000")

# Create a synchronized list associated with the specified key
sync_list = List(client=client, key="list:1")

# Extend the list with multiple elements
sync_list.extend(["a", "b", "c", "d"])

# Print every second element from the list
print(sync_list[::2])
```
36 changes: 18 additions & 18 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]
name = "znsocket"
version = "0.1.1"
description = "Create objects with shared attributes through a socket connection."
version = "0.1.2"
description = "Python implementation of a Redis-compatible API using websockets."
authors = ["Fabian Zills <fzills@icp.uni-stuttgart.de>"]
license = "Apache-2.0"
readme = "README.md"
Expand Down
51 changes: 51 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import eventlet.wsgi

eventlet.monkey_patch() # MUST BE THERE FOR THE TESTS TO WORK

import random

import pytest
import redis
import socketio.exceptions

from znsocket import Client, Server


@pytest.fixture
def eventlet_memory_server():
port = random.randint(10000, 20000)

def start_server():
server = Server(port=port)
server.run()

thread = eventlet.spawn(start_server)

# wait for the server to be ready
for _ in range(100):
try:
with socketio.SimpleClient() as client:
client.connect(f"http://localhost:{port}")
break
except socketio.exceptions.ConnectionError:
eventlet.sleep(0.1)
else:
raise TimeoutError("Server did not start in time")

yield f"znsocket://127.0.0.1:{port}"

thread.kill()


@pytest.fixture
def znsclient(eventlet_memory_server):
r = Client.from_url(eventlet_memory_server)
yield r
r.flushall()


@pytest.fixture
def redisclient():
r = redis.Redis.from_url("redis://localhost:6379/0", decode_responses=True)
yield r
r.flushdb()
Loading

0 comments on commit 96f262e

Please sign in to comment.