netTime6 Connector#
Use the netTime6 connector to interact with netTime.
Import module#
from spec_utils import NT6Client, NT6Query
Client settings#
URL = '<your-nettime-url>'
USERNAME = '<your-username>'
PWD = '<your-password>'
Start session manually#
client = NT6Client(url=URL, username=USERNAME, pwd=PWD)
client.start_session()
client.is_connected
See out...
True
Close session manually#
client.close_session()
client.is_connected
See out...
False
Get employees#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
employees = client.get_employees()
# check result
employees
See out...
{
'total': 2,
'items': [{'id': 1, 'nif': '123789456'}, {'id': 2, 'nif': '987321654'}
]}
Specifying fields#
query = NT6Query(
fields=["nif", "Apellidos_Nombre", "Province", "birthdate"]
)
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
employees = client.get_employees(query=query)
# check result
employees
See out...
{
"total": 2,
"items": [
{
"nif": "12345678",
"Apellidos_Nombre": "Lucyk, Lucas",
"Province": "CABA",
"birthdate": "1995-01-12T00:00:00.0000000",
},
{
"nif": "9876451",
"Apellidos_Nombre": "Doe, John",
"Province": "Ciudad Autónoma de Buenos Aires",
"birthdate": "1987-08-05T00:00:00.0000000",
}
],
}
Filtering in backend#
query = NT6Query(
fields=["id", "nif", "Apellidos_Nombre", "Province", "birthdate"],
filterExp='Contains(this.nif, "987321654")'
)
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
employees = client.get_employees(query=query)
# check result
employees
See out...
{
"total": 1,
"items": [
{
"id": 2,
"nif": "987321654",
"Apellidos_Nombre": "Doe, John",
"Province": "Ciudad Autónoma de Buenos Aires",
"birthdate": "1987-08-05T00:00:00.0000000",
}
],
}
Get Fields definition#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
fields = client.get_fields("Persona")
# check result
fields
See out...
{
"total": 433,
"items": [
{
"id": 30,
"name": "id",
"displayName": "Id",
"expr": "this.id",
"type": "int",
"align": 2,
"sortable": False,
"width": 0,
"group": "",
"numTempOperators": 0,
},
{
"id": 31,
"name": "name",
"displayName": "Clave",
"expr": "this.name",
"type": "String",
"align": 2,
"sortable": True,
"width": 20,
"group": "Datos personales",
"numTempOperators": 0,
},
{
"id": 32,
"name": "LastName",
"displayName": "Apellidos",
"expr": "this.LastName",
# show more (open the raw output data in a text editor) ...
"align": 4,
"sortable": True,
"ir": "TimeLabelIR",
"width": 5,
"group": "Resultados.Aritmético.HE 100%",
"numTempOperators": 2,
},
],
}
Properties only#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
fields = client.get_fields(container="Persona", filterFields=True)
# check result
fields
See out...
{
"total": 428,
"items": [
{
"id": 30,
"name": "id",
"displayName": "Id",
"expr": "this.id",
"type": "int",
"align": 2,
"sortable": False,
"width": 0,
"group": "",
"numTempOperators": 0,
},
{
"id": 31,
"name": "name",
"displayName": "Clave",
"expr": "this.name",
"type": "String",
"align": 2,
"sortable": True,
"width": 20,
"group": "Datos personales",
"numTempOperators": 0,
},
{
"id": 32,
"name": "LastName",
"displayName": "Apellidos",
"expr": "this.LastName",
# show more (open the raw output data in a text editor) ...
"align": 4,
"sortable": True,
"ir": "TimeLabelIR",
"width": 5,
"group": "Resultados.Aritmético.HE 100%",
"numTempOperators": 2,
},
],
}
Get timetypes#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
timetypes = client.get_elements(container="Incidencia").get('items')
# check result
timetypes[:10]
See out...
[
{"id": 0, "name": "Sin incidencia"},
{"id": 1, "name": "Inc. horas extra"},
{"id": 2, "name": "ART-Empresa"},
{"id": 3, "name": "Vacaciones"},
{"id": 4, "name": "Lactancia 30 minutos"},
{"id": 5, "name": "Lactancia 1 hora"},
{"id": 6, "name": "Visita al médico"},
{"id": 7, "name": "ART-ILT"},
{"id": 8, "name": "Licencia Gremial"},
{"id": 9, "name": "Enfermedad"},
]
Assign to employee#
# list of dict like [{"id": 1}, {"id": 2}, ...]
employee_timetypes = [{"id": i.get("id")} for i in timetypes]
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
saved = client.save_element(
container="Persona",
elements=[2], # employee id
dataObj={"TimeTypesEmployee": employee_timetypes}
)
To add periods, use the validity key with a list of employee_timetypes like:
{
"id": incidencia.get("id"),
"validity": [{
"end": "2040-12-31T00:00:00-03:00",
"start": "2004-01-01T00:00:00-03:00",
}]
}
Get elements definition#
When you want to add a data to the employee's structure or edit an empty data, you can know the structure of the field with:
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
employee = client.get_element_def(container="Persona", elements=[])
employee = employee[0]
# show calendars
employee.get('Calendar')
See out...
{
"id": -1,
"_c_": "",
"created": "0001-01-01T00:00:00.0000000",
"modified": "0001-01-01T00:00:00.0000000",
"name": "-1",
"rev": 0,
"Cycles": [],
"Calendars": [],
"nodesSource": [],
"multiName": {"es-ES": "-1"},
}
Get a blank form#
When you want to create an item, you can get the default values using the method get_create_form.
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
form = client.get_create_form(container="Jornada")
# check result
form
See out...
{
"_c_": "Jornada",
"id": -1,
"modified": "0001-01-01T00:00:00.0000000",
"created": "0001-01-01T00:00:00.0000000",
"color": "808080",
"rev": 0,
"minutosCortesia": 0,
"minutosPenalizacion": 0,
"totalTeorico": 480,
"minutoFinal": 2880,
"minutosRetraso": 0,
"resultados": [],
"multiName": {},
"nodesSource": [],
"incidencias": [],
"baObligada": [],
"baFlexible": [],
"pausas": [],
"intervalSource": [
{"data": "flex", "label": "Bloque flexible"},
{"data": "oblig", "label": "Bloque obligatorio"},
{"data": "all", "label": "Toda la jornada"},
{"data": "bloque", "label": "Bloque del grupo de incidencia"},
{"data": "relative", "label": "Relativo a...", "state": "relative"},
{"data": "delete", "label": "Sin validez"},
],
"ShifttimeTypesMassIdinci": [],
"relativeSource": [
{"data": "inishift", "label": "Inicio de la jornada"},
{"data": "firstflexmin", "label": "Inicio bloque flexible"},
{"data": "firstoblmin", "label": "Inicio bloque obligatorio"},
{"data": "endshift", "label": "Final de la jornada"},
{"data": "endflex", "label": "Final bloque flexible"},
{"data": "endobli", "label": "Final bloque obligatorio"},
],
}
Duplicate element#
To duplicate an element, you can use the method get_for_duplicate, Edit and then save the edited item.
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
form = client.get_for_duplicate(container="Arbol", element=3)
# now you can edit and after save element with `save_element` method
# check result
form
See out...
{
"_c_": "Arbol",
"id": -1,
"name": "Information Technology",
"rev": 0,
"createdBy": "Admin",
"created": "2020-08-03T11:08:27.4050000",
"modified": "0001-01-01T00:00:00.0000000",
"color": "7D7D7D",
"allowedContainerNames": "Empleados",
"order": 0,
"internalName": "Information_Technology",
"idNodeParent": 2,
"baAllowedContainers": [14],
"nodesSource": [],
"nodes": [],
"multiName": {"es-ES": "Information Technology"},
}
Delete element#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
deleted = client.delete_element(container="Jornada", elements=[6])
# check result
deleted
See out...
[
{
"type": 8,
"id": "BwAAAAEAAgeAAA==",
"rev": 60,
"message": "Los elementos se han eliminado correctamente.",
}
]
Get day info of employee#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
day_info = client.get_day_info(
employee=2,
_from="2020-07-03",
to="2020-07-03"
)
# check result
day_info
See out...
{
"idEmp": 2,
"days": [
{
"date": "2020-07-03T00:00:00.0000000",
"shift": {
"date": "2020-07-03T00:00:00.0000000",
"idEmp": 2,
"shift": 5,
"minFin": 2880,
"minFinForced": False,
"shiftPetition": {"actions": ["Change"]},
"clockings": [
{
"id": 1,
"date": "2020-07-03T08:55:00.0000000",
"idElem": 0,
"type": "timetypes",
"idReader": 0,
"user": "Admin",
"ip": "127.0.0.1",
"status": {
"effective": True,
"desc": "Entrando",
"state": "",
"entering": True,
"actions": ["Delete", "Edit", "Comment"],
},
"app": True,
"numDocuments": 0,
},
{
"id": 2,
"date": "2020-07-03T18:30:00.0000000",
"idElem": 0,
"type": "timetypes",
"idReader": 0,
"user": "Admin",
"ip": "127.0.0.1",
"status": {
"effective": True,
"desc": "Saliendo",
"state": "",
"entering": False,
"actions": ["Delete", "Edit", "Comment"],
},
"app": True,
"numDocuments": 0,
},
],
"info": {
"Change": "Cambiar",
"Delete": "Eliminar",
"Edit": "Editar",
"Comment": "Comentar",
},
},
"results": {
"date": "2020-07-03T00:00:00.0000000",
"hasComments": False,
"hasPending": False,
"shift": {"id": 5, "minutes": {"start": 1440, "end": 2880}},
"minutesTypes": [
{
"name": "Incidencia",
"results": [
{
"id": 0,
"minutes": [
{"start": 1975, "end": 2160, "endApr": True},
{"start": 2220, "end": 2550, "startApr": True},
],
}
],
},
{
"name": "Sistema",
"results": [
{"id": 9, "minutes": [{"start": 2160, "end": 2220}]}
],
},
],
},
}
],
"taskConfig": 71,
"info": [
{"id": 0, "type": "Incidencia", "name": "Sin incidencia", "color": "009933"},
{"id": 5, "type": "Jornada", "name": "09:00 a 18:00", "color": "808080"},
{"id": 9, "type": "Sistema", "name": "Pausas", "color": "F0F0F0"},
],
}
Get Results#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
results = client.get_results(
employee=2,
_from="2020-07-03",
to="2020-07-03"
)
# check result
results
See out...
{'results': [{'date': '2020-07-03T00:00:00.0000000',
'hasComments': False,
'hasPending': False,
'shift': {'id': 5, 'minutes': {'start': 1440, 'end': 2880}},
'minutesTypes': [{'name': 'Lector',
'results': [{'id': -1,
'values': [{'name': 'Min', 'value': 575},
{'name': 'MinDes', 'value': 0},
{'name': 'Evt', 'value': 1},
{'name': 'EvtDes', 'value': 0}]}]},
{'name': 'Incidencia',
'results': [{'id': 0,
'values': [{'name': 'Min', 'value': 515},
{'name': 'MinDes', 'value': 60},
{'name': 'Evt', 'value': 1},
{'name': 'EvtDes', 'value': 1}]}]},
{'name': 'Sistema',
'results': [{'id': 0,
'values': [{'name': 'Min', 'value': 515},
{'name': 'MinDes', 'value': 60},
{'name': 'Evt', 'value': 1},
{'name': 'EvtDes', 'value': 1}]},
{'id': 5,
'values': [{'name': 'Min', 'value': 0},
{'name': 'MinDes', 'value': 0},
# show more (open the raw output data in a text editor) ...
{'id': 3, 'type': 'Aritmetico', 'name': 'Saldo anual', 'color': 'FF6600'},
{'id': 4,
'type': 'Aritmetico',
'name': 'Saldo Días Vacaciones',
'color': '007373',
'numeric': True}]}
Clockings#
To manage clockings, it is not possible to use the methods get_elements and save_element, but you can use specific methods for clockings.
Add clocking#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
added = client.add_clocking(employee=2, date="2020-07-02", time="18:30")
# check result
added
See out...
{'ok': True}
Get clockings#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
clockings = client.get_day_clockings(employee=2, date="2020-07-02")
# check result
clockings
See out...
{
"date": "2020-07-02T00:00:00.0000000",
"idEmp": 2,
"shift": 5,
"minFin": 0,
"minFinForced": False,
"shiftPetition": {"actions": ["Change"]},
"clockings": [
{
"id": 3,
"date": "2020-07-02T09:00:00.0000000",
"idElem": 0,
"type": "timetypes",
"idReader": 0,
"user": "Admin",
"ip": "127.0.0.1",
"status": {
"effective": True,
"desc": "Entrando",
"state": "",
"entering": True,
"actions": ["Delete", "Edit", "Comment"],
},
"app": True,
"numDocuments": 0,
},
{
"id": 7,
"date": "2020-07-02T18:30:00.0000000",
"idElem": 0,
"type": "timetypes",
"idReader": 0,
"user": "Admin",
"ip": "::1",
"status": {
"effective": True,
"desc": "Saliendo",
"state": "",
"entering": False,
"actions": ["Delete", "Edit", "Comment"],
},
"app": True,
"numDocuments": 0,
},
],
"info": {
"Change": "Cambiar",
"Delete": "Eliminar",
"Edit": "Editar",
"Comment": "Comentar",
},
}
Edit clocking#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
edited = client.edit_clocking(
employee=2,
clocking_id=7,
date="2020-07-02",
time="20:30"
)
# check result
edited
See out...
{'ok': True}
Delete clocking#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
deleted = client.delete_clocking(
employee=2,
clocking_id=7,
date="2020-07-02",
time="20:30"
)
# check result
deleted
See out...
{'ok': True}
Plannings#
To manage plannings, you can use generic methods, but for creation you can use the add_planning summary method.
Add planning#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
created = client.add_planning(
employee=2,
name="Testing summary planning",
timetype=9,
days=["2020-10-10", "2020-10-11"],
)
# check result
created
See out...
[
{
"type": 6,
"dataObject": {
"id": 4,
"_c_": "IncidenciaFutura",
"firstDay": "2020-10-10T00:00:00.0000000",
"rev": 53,
"modifiedBy": "Admin",
"modified": "2020-08-05T19:20:18.5712279-03:00",
"createdBy": "Admin",
"created": "2020-08-05T19:20:18.5457647-03:00",
"allDayId": 9,
"allDay": True,
"selfOwner": False,
"state": "0",
"name": "Testing summary planning",
"comments": "",
"intState": 0,
"isAccepted": True,
"lastDay": "2020-10-11T00:00:00.0000000",
"numDays": 2,
"confirmBy": "Admin",
"confirm": "2020-08-05T19:20:18.5586427-03:00",
"describe": "2 días, del 10/10/2020 al 11/10/2020 Todo el día con incidencia Enfermedad",
"hasComment": False,
"error": "",
"stateDescription": "Aceptada",
# show more (open the raw output data in a text editor) ...
"timeTypes": [9],
"nodesSource": [],
"employee": 2,
},
"message": "El elemento se ha creado correctamente.",
"showActions": True,
}
]
Edit planning#
- Search planning
planning_query = NT6Query(
fields=["id", "name", "allDayId"],
filterExp="((this.employee.nif = '12345678') && (this.firstDay = '2020-10-10'))"
)
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
plannings = client.get_elements(
container="IncidenciaFutura",
query=planning_query
)
# check result
plannings
See out...
{
'total': 1,
'items': [{'id': 4, 'name': 'Testing summary planning', 'allDayId': 9}]
}
- Inspect days
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
planning = client.get_element_def(
container="IncidenciaFutura",
elements=[4]
)
planning = planning[0]
# check interval
planning["dateInterval"]
See out...
[6127, 6128]
- Edit with utils
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
# ever fix employe; must be a list
planning["employee"] = [planning.get("employee")]
# apply your changes
day_to_add = client.get_days_offset(["2020-10-12"])
planning["dateInterval"].extend(day_to_add)
# save element
response = client.save_element(
container="IncidenciaFutura",
elements=[4],
dataObj=planning
)
# check result
response[0].get('message')
See out...
'El elemento se ha modificado correctamente.'
Add activator#
- Get available activators
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
activators = client.get_elements(container="Activadores")
# check result
activators
See out...
{'total': 1, 'items': [{'id': 1, 'name': 'APROBACION HS'}]}
- Add to employee
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
added = client.add_activator(
name="Testing summary activator",
employees=[2], #list of id's
days=["2020-07-03"], #list of str with isoformat date
activator=1, #activator id
value=1, #required depending activator config
comment="testing" #optional
)
# check result
added
See out...
[
{
"type": 6,
"dataObject": {
"_c_": "UsoActivadores",
"id": 3,
"name": "Testing summary activator",
"modified": "0001-01-01T00:00:00.0000000",
"createdBy": "Admin",
"rev": 40,
"created": "2020-08-05T19:21:16.8877146-03:00",
"numDays": 1,
"lastDay": "2020-07-03T00:00:00.0000000",
"firstDay": "2020-07-03T00:00:00.0000000",
"comment": "testing",
"employees": [2],
"activators": [{"value": 1, "activator": 1}],
"days": [6028],
"nodesSource": [],
"multiName": {"es-ES": "Testing summary activator"},
"validActvs": [1],
},
"message": "El elemento se ha creado correctamente.",
"showActions": True,
}
]
Activity monitor#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
monitor = client.get_activity_monitor(
employees=[2],
_from="2020-07-02",
to="2020-07-03"
)
# check result
monitor
See out...
[
{
"id": 2,
"days": [
{
"id": 6027,
"idAno": 2,
"mars": [
{"m": 540, "i": 0, "t": 18, "e": 268435457, "o": 8, "c": "009933"}
],
"horari": [
{"mi": 540, "mf": 720, "ia": False, "fa": True, "tv": 2, "idv": 5},
{"mi": 780, "mf": 1080, "ia": True, "fa": True, "tv": 2, "idv": 5},
{"mi": 720, "mf": 780, "ia": True, "fa": True, "tv": 2, "idv": 9},
],
"idJor": 5,
"bJor": [{"startTime": 0, "endTime": 1440}],
}
],
"planInfos": {},
},
{"info": {}},
]
Data structured like:
[{'id': employee_ID,
'days': [{
'id': offset_day_number #(settings.firstDate),
'idAno': anomaly_id,
'mars': [{ # Clockings
'm': minute_of_day,
'i': timtype_id,
't': type,
'e': state,
'o': origin,
'c': color}],
'horari': [{ # Jornada
'mi': start,
'mf': end,
'ia': False,
'fa': True,
'tv': 2,
'idv': 5},
{'mi': 780, 'mf': 1080, 'ia': True, 'fa': True, 'tv': 2, 'idv': 5},
{'mi': 720, 'mf': 780, 'ia': True, 'fa': True, 'tv': 2, 'idv': 9}],
'idJor': shift_id,
'bJor': [{'startTime': shift_start, 'endTime': shift_end}]}],
'planInfos': {}},
{'info': {}}]
Cube results (like results query window)#
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
cube = client.get_cube_results(
dateIni="2020-07-02",
dateEnd="2020-07-04",
dimensions=[
["id", "Apellidos_Nombre"],
["date"],
["ResultValue_C.Min.NORMALES", "ResultValue_S.Min.Jornada_teorica"]
]
)
# check result
cube
See out...
[
{
"dimKey": [1, "Lucyk, Lucas"],
"values": [0, 1440],
"children": [
{"dimKey": ["2020-07-02"], "values": [0, 480]},
{"dimKey": ["2020-07-03"], "values": [0, 480]},
{"dimKey": ["2020-07-04"], "values": [0, 480]},
],
},
{
"dimKey": [2, "Doe, John"],
"values": [480, 960],
"children": [
{"dimKey": ["2020-07-02"], "values": [0, 480]},
{"dimKey": ["2020-07-03"], "values": [480, 480]},
{"dimKey": ["2020-07-04"], "values": [0, 0]},
],
},
]
For more information, see the documentation for the get_cube_results method.
help(NT6Client.get_cube_results)
See out...
Help on function get_cube_results in module spec_utils.nettime6:
get_cube_results(self, dimensions: 'list', dateIni: 'str', dateEnd: 'str', interFilters: 'list' = [], filters: 'list' = [], ids: 'list' = [])
Gets nettime results using the "Results Query" window engine.
:param dimensions: List of list where each one contains the desired
fields or results. The order of the values does matter.
:param dateIni: Start day where you want to calculate.
:param dateIni: End day where you want to calculate.
:param interfilters: (Optional) If you use the "system" dimension,
specify the ids of the results in this parameter.
:param filters: (Optional) Nettime compatible filter expression.
:param ids: (Optional) List of employee ids in case you want to filter.
:return: :class:`list` object
:rtype: json
Another example#
- Get system results
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
system_results = client.get_elements("SystemResult")
# check result
system_results
See out...
{
"total": 13,
"items": [
{"id": 0, "name": "Productivas en el centro"},
{"id": 1, "name": "Productivas fuera del centro"},
{"id": 2, "name": "No productivas en el centro"},
{"id": 3, "name": "No productivas fuera del centro"},
{"id": 4, "name": "Ausencias justificadas"},
{"id": 5, "name": "Ausencias no justificadas"},
{"id": 6, "name": "Productivas"},
{"id": 7, "name": "No productivas"},
{"id": 8, "name": "Trabajadas"},
{"id": 9, "name": "Pausas"},
{"id": 10, "name": "Retrasos"},
{"id": 11, "name": "Jornada teórica"},
{"id": 12, "name": "Filtro día"},
],
}
- Get cube results
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
cube = get_cube_results(
dateIni="2020-07-02",
dateEnd="2020-07-04",
dimensions=[
["id", "Apellidos_Nombre"],
["date"],
["sistema"],
["interTotal"]
],
interFilters=[{
"dimension": "sistema",
"elements": [6, 11] # Productivas and Jornada teórica
}]
)
# check result
cube
See out...
[
{
"dimKey": [1, "Lucyk, Lucas"],
"values": [1440],
"children": [
{
"dimKey": ["2020-07-02"],
"values": [480],
"children": [{"dimKey": ["Jornada teórica"], "values": [480]}],
},
{
"dimKey": ["2020-07-03"],
"values": [480],
"children": [{"dimKey": ["Jornada teórica"], "values": [480]}],
},
{
"dimKey": ["2020-07-04"],
"values": [480],
"children": [{"dimKey": ["Jornada teórica"], "values": [480]}],
},
],
},
{
"dimKey": [2, "Doe, John"],
"values": [1475],
"children": [
{
"dimKey": ["2020-07-02"],
"values": [480],
"children": [{"dimKey": ["Jornada teórica"], "values": [480]}],
},
{
"dimKey": ["2020-07-03"],
"values": [995],
"children": [
{"dimKey": ["Productivas"], "values": [515]},
{"dimKey": ["Jornada teórica"], "values": [480]},
],
},
],
},
]
Set employee department#
path = ["SPEC SA", "Argentina", "CABA", "Information Technology", "Help Desk"]
with NT6Client(url=URL, username=USERNAME, pwd=PWD) as client:
edited = client.set_employee_department(employee=2, node_path=path)
# check node
edited[0].get('dataObject').get('Departments')
See out...
[{'id': 17}]