socialwifi / RouterOS-api

Python API to RouterBoard devices produced by MikroTik.
MIT License
251 stars 100 forks source link

hoe can I get 'count-only' for files? #79

Open SmartTransp opened 2 years ago

SmartTransp commented 2 years ago

I'm trying to get jsut the amount of files i ahve in the router on the CLI I'm running this command: :put [file print count-only ]

how can I do the same in the api? I have try this replay = api.get_resource('/file/') test_answer = replay.get(print='count-only') print('how many files? - ', test_answer but I get an empty response how many files? - []

I know I'm looking for txt files , so I have try this: try: test_answer = replay.get(type='.txt file') except Exception as r: print(r) print('how many files? - ', len(test_answer))

but if I ahve more then 1000 files , I get timeout (after 1 min of "thinking")

SmartTransp commented 2 years ago

I have also try this test = api.get_binary_resource('/').call('file', {'print': 'count-only'})

but I get error can't concat str to bytes

so I check the test command in the Readme file api.get_binary_resource('/').call('ping', { 'address': '192.168.56.1', 'count': '4' })

get the same error

so what is missing?

Thanks,

M0r13n commented 1 year ago

I also struggled with this issue. I wanted to get the number of connections - but not details about all connections. I messed around with this module and took a look at the source code. The important piece for me to understand was, that the API returns a list-like object. This is a custom attribute of the response class, which looks like a list and behaves like a list, but isn't a list :-)

Additionally, I noticed that the count is returned as the return-code from the Mikrotik device. This is why it is not part the result list.

import routeros_api

connection = routeros_api.RouterOsApiPool()
api = connection.get_api()

answer = api.get_binary_resource('/ip/firewall/connection/').call('print', {'count-only': b''})
# answer looks and feels like an empty list: [], but it has a special attribute `done_message`
done_message = answer.done_message

# `done_msg` is a dict with the return code as a key - which is the count that we are looking for
cnt = done_message['ret'].decode()
print(cnt)

You can adapt the example to your case, @SmartTransp.

akpw commented 2 months ago

this approach seems to work with api.get_resource as well, without the encoding/decoding:

answer = api.get_resource('/ip/firewall/connection/').call('print', {'count-only': ''})
print(answer.done_message)
akpw commented 2 months ago

this one does not work as expected though:

st = api.get_resource('/ip/route/').call('print', {'count-only':'', 'where': 'static'})            
print(st.done_message)

nor this:

st = api.get_resource('/ip/route/').call('print', {'count-only':''}, {'where': 'static'})            
print(st.done_message)

@jgoclawski by chance any advice on how to use this approach with the 'where' clause?