Overview
The fc.Client manages the connection, with a separate class for KV specific commands (and in the future, arrays, lists, etc).
The command classes require a Client object.
Connect
import fc
async def connect() -> fc.Client:
try:
client = await fc.fcache(uri='ws://127.0.0.1:1987')
# or: client = await fc.fcache(ip='127.0.0.1', port=1987)
except:
print ('Failed to connect')
client = None
return client
Exceptions
ResponseError: raised when a failed response is receivedValueError: raised by the API before a request is sentOSError: if opening the connection fails
KV
List Values
- A list cannot be empty
- If a key's value is a
list, all elements must be the same type:
from fc.kv import KV
async def kv():
if (client := await connect()) is None:
return
# create API object for KV commands
kv = KV(client)
await kv.set({'player':'Monster',
'level':25,
'active':True,
'perks':['Armour','Kilt']})
# get single key, returns the value (or None if key not found)
age = await kv.get(key='level')
print(f'Age: {age}')
# get multiple keys, returns dict
rsp = await kv.get(keys=['player', 'active'])
print(f"Player: {rsp['player']}, Active: {rsp['active']}")
# get list
print(await kv.get(key='perks'))
Types
| Python | FlatBuffers/FlexBuffers | Server |
|---|---|---|
| int | int | int64 |
| float | float | float (4 bytes) |
| str | string | std::vector<char> |
| bool | bool | bool |
| bytes | BLOB | std::vector<uint8_t> |
| list[int] | TypedVector: VECTOR_INT | std::vector<int64> |
| list[float] | TypedVector: VECTOR_FLOAT | std::vector<float> |
| list[str] | TypedVector: VECTOR_KEY | std::vector<uint8_t> |
| list[bool] | TypedVector: VECTOR_BOOL | std::vector<bool> |
Note
A TypedVector is a type of FlexBuffer vector, where each element is the same type.
Lists
Lists are node based doubly linked lists. There are two types, SortedList and UnsortedList.
Unsorted
Unsorted
from fc.list import UnsortedList
async def unsorted_lists():
if (client := await connect()) is None:
return
# create API object for list functions
list = List(client)
# delete any existing lists
await list.delete_all()
# create list for integers
await list.create('scores', type='int')
# add these items to head
await list.add_head('scores', [25,35,45,55])
# insert in between 35 and 45 (at position 2)
await list.add('scores', [40], pos=2)
# add two more to the tail
await list.add_tail('scores', [60, 65])
# get everything from the first item
print(f"a. {await list.get_n('scores')}")
# get everything in reverse
print(f"b. {await list.get_n_reverse('scores')}")
# # get the first 3
print(f"c. {await list.get_n('scores', count=3)}")
# # get the last 2
print(f"d. {await list.get_n('scores', start=5)}")
# get middle 3 with range (could also use get_n())
print(f"e. {await list.get_range('scores', start=2, stop=5)}")
# get middle 5 in reverse, using negative index
print(f"f. {await list.get_range_reverse('scores', start=1, stop=-1)}")
Output
a. [25, 35, 40, 45, 55, 60, 65]
b. [65, 60, 55, 45, 40, 35, 25]
c. [25, 35, 40]
d. [60, 65]
e. [40, 45, 55]
f. [60, 55, 45, 40, 35]
Sorted
Sorted
from fc.list import SortedList
async def sorted_lists():
if (client := await connect()) is None:
return
lst = SortedList(client)
await lst.delete_all()
await lst.create('scores', type='int')
await lst.add('scores', [45,35,25,55])
print(await lst.get_n('scores'))
await lst.add('scores', [50,20,100,40,90])
print(await lst.get_n('scores'))
await lst.add('scores', [41,42], items_sorted=True)
print(await lst.get_n('scores'))
await lst.add('scores', [1,2,3], items_sorted=True)
print(await lst.get_n('scores'))
await lst.add('scores', [100,101,102], items_sorted=True)
print(await lst.get_n('scores'))
print(await lst.get_n('scores', start=5, count=4))
print(await lst.get_n_reverse('scores', start=8, count=4))