socialwifi / RouterOS-api

Python API to RouterBoard devices produced by MikroTik.
MIT License
255 stars 98 forks source link

TypeError: can't concat str to bytes? #39

Open Alnyz opened 5 years ago

Alnyz commented 5 years ago

I got this TypeError: can't concat str to bytes idk why,i just trying simple code like this

import routeros_api as routers

connection = routers.RouterOsApiPool('IP', username='username', password='password')
api = connection.get_api()
api.get_binary_resource('/').call('ping', { 'address': '192.168.56.1', 'count': '4' }) #this ip i got from example

This Example i Used

And full traceback:

Traceback (most recent call last):
  File "mikro.py", line 5, in <module>
    api.get_binary_resource('/').call('ping', { 'address': '192.168.56.1', 'count': '4' })
  File "/home/sengkunibot/.local/lib/python3.7/site-packages/routeros_api/resource.py", line 39, in call
    additional_queries=additional_queries).get()
  File "/home/sengkunibot/.local/lib/python3.7/site-packages/routeros_api/resource.py", line 45, in call_async
    additional_queries=additional_queries)
  File "/home/sengkunibot/.local/lib/python3.7/site-packages/routeros_api/api_communicator/encoding_decorator.py", line 12, in call
    path, command, arguments, queries, additional_queries)
  File "/home/sengkunibot/.local/lib/python3.7/site-packages/routeros_api/api_communicator/async_decorator.py", line 6, in call
    tag = self.inner.send(*args, **kwargs)
  File "/home/sengkunibot/.local/lib/python3.7/site-packages/routeros_api/api_communicator/exception_decorator.py", line 11, in send
    return self.inner.send(*args, **kwargs)
  File "/home/sengkunibot/.local/lib/python3.7/site-packages/routeros_api/api_communicator/key_cleaner_decorator.py", line 11, in send
    queries=encoded_queries, additional_queries=additional_queries)
  File "/home/sengkunibot/.local/lib/python3.7/site-packages/routeros_api/api_communicator/base.py", line 19, in send
    self.send_command(command)
  File "/home/sengkunibot/.local/lib/python3.7/site-packages/routeros_api/api_communicator/base.py", line 37, in send_command
    self.base.send_sentence(command.get_api_format())
  File "/home/sengkunibot/.local/lib/python3.7/site-packages/routeros_api/sentence.py", line 59, in get_api_format
    formated.append(b'=' + key + b'=' + value)
TypeError: can't concat str to bytes

My server:

kramarz commented 5 years ago

I guess it should be get_resource instead of get_binary_resource. Can you confirm that?

Alnyz commented 5 years ago

I guess it should be get_resource instead of get_binary_resource. Can you confirm that?

Idk, i just try This Example Maybe u can explain it

avloboda commented 5 years ago

I'm getting a similar error with api = connection.get_api() I'm not able to actually form a connection. import routeros_api connection = routeros_api.RouterOsApiPool('192.168.1.1', username='admin', password='password', plaintext_login=True) api = connection.get_api()

The below error appears after this last command. I am using Python3.4. Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python3.4/site-packages/routeros_api/api.py", line 51, in get_api self.api.login(self.username, self.password, self.plaintext_login) File "/usr/lib64/python3.4/site-packages/routeros_api/api.py", line 82, in login response = self.get_binary_resource('/').call('login',{ 'name': login, 'password': password }) File "/usr/lib64/python3.4/site-packages/routeros_api/resource.py", line 39, in call additional_queries=additional_queries).get() File "/usr/lib64/python3.4/site-packages/routeros_api/resource.py", line 45, in call_async additional_queries=additional_queries) File "/usr/lib64/python3.4/site-packages/routeros_api/api_communicator/encoding_decorator.py", line 12, in call path, command, arguments, queries, additional_queries) File "/usr/lib64/python3.4/site-packages/routeros_api/api_communicator/async_decorator.py", line 6, in call tag = self.inner.send(*args, **kwargs) File "/usr/lib64/python3.4/site-packages/routeros_api/api_communicator/exception_decorator.py", line 11, in send return self.inner.send(*args, **kwargs) File "/usr/lib64/python3.4/site-packages/routeros_api/api_communicator/key_cleaner_decorator.py", line 11, in send queries=encoded_queries, additional_queries=additional_queries) File "/usr/lib64/python3.4/site-packages/routeros_api/api_communicator/base.py", line 19, in send self.send_command(command) File "/usr/lib64/python3.4/site-packages/routeros_api/api_communicator/base.py", line 37, in send_command self.base.send_sentence(command.get_api_format()) File "/usr/lib64/python3.4/site-packages/routeros_api/sentence.py", line 59, in get_api_format formated.append(b'=' + key + b'=' + value) TypeError: can't concat bytes to str

I'm not sure if I am missing something, but I followed the wiki guide to as well.

stevehaskew commented 5 years ago

Two parts to the answer:

Simple way to make it work is to change the fields to bytes, like this:

import routeros_api as routers

connection = routers.RouterOsApiPool('IP', username='username', password='password')
api = connection.get_api()
api.get_binary_resource('/').call('ping', { 'address': b'192.168.56.1', 'count': b'4' }) #this ip i got from example

However, it does raise the question about whether under Python3 that we should be handling better.

okazdal commented 5 years ago

I had the same issue. I modified sentence.py file from library. Added lines with **. Seems to fix this but I don't know about any other side effects

def get_api_format(self):
    formated = [self.path + self.command]
    for key, value in self.attributes.items():
        **if type(value) == str:**
            **value = str.encode(value)**
        formated.append(b'=' + key + b'=' + value)
    for query in self.queries:
        formated.extend(query.get_api_format())
    if self.tag is not None:
        formated.append(b'.tag=' + self.tag)
    return formated
davidc commented 5 years ago

You're using Python 3. Use Python 2 or see #47 47

sukawatd commented 3 years ago

I modified sentence.py file from library. It's work for me. Check key or value type before concatenate. if it string type convert it to byte type.


from six import string_types

def get_api_format(self):
    formated = [self.path + self.command]
    for key, value in self.attributes.items():
        if isinstance(key, string_types):
            key = key.encode()
        if isinstance(value, string_types):
            value = value.encode()
        formated.append(b'=' + key + b'=' + value)
    for query in self.queries:
        formated.extend(query.get_api_format())
    if self.tag is not None:
        formated.append(b'.tag=' + self.tag)
    return formated```
sereykol commented 1 year ago

Two parts to the answer:

Simple way to make it work is to change the fields to bytes, like this:

import routeros_api as routers

connection = routers.RouterOsApiPool('IP', username='username', password='password')
api = connection.get_api()
api.get_binary_resource('/').call('ping', { 'address': b'192.168.56.1', 'count': b'4' }) #this ip i got from example

However, it does raise the question about whether under Python3 that we should be handling better.

Hi when I try writing the same it always load "routeros_api.exceptions.RouterOsApiConnectionError: [Errno 9] Bad file descriptor" What should I do?

AIT-AT commented 1 week ago

I modified sentence.py file from library. It's work for me. Check key or value type before concatenate. if it string type convert it to byte type.

from six import string_types

def get_api_format(self):
    formated = [self.path + self.command]
    for key, value in self.attributes.items():
        if isinstance(key, string_types):
            key = key.encode()
        if isinstance(value, string_types):
            value = value.encode()
        formated.append(b'=' + key + b'=' + value)
    for query in self.queries:
        formated.extend(query.get_api_format())
    if self.tag is not None:
        formated.append(b'.tag=' + self.tag)
    return formated```

That works for me too. But I use "str" instead of "string_types".