Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Alnyz opened this issue Feb 3, 2019 · 9 comments
Open

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

Alnyz opened this issue Feb 3, 2019 · 9 comments

Comments

@Alnyz
Copy link

Alnyz commented Feb 3, 2019

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:

  • Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-31-generic x86_64)
  • Python3.7
@kramarz
Copy link
Collaborator

kramarz commented Feb 3, 2019

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

@Alnyz
Copy link
Author

Alnyz commented Feb 4, 2019

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
Copy link

avloboda commented Apr 2, 2019

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
Copy link
Contributor

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
Copy link

okazdal commented Jul 8, 2019

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
Copy link

davidc commented Jul 11, 2019

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

@sukawatd
Copy link

sukawatd commented Oct 28, 2020

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
Copy link

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
Copy link

AIT-AT commented Aug 31, 2024

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".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants