Manual:API Python3: Difference between revisions

From MikroTik Wiki
Jump to navigation Jump to search
(made sure wiki syntax does not interefere with python spacing)
Line 4: Line 4:


==Code for Python3==
==Code for Python3==
====code===
====code====
  #!/usr/bin/python
<pre>
 
#!/usr/bin/python3
  import sys, posix, time, binascii, socket, select
 
  import hashlib
import sys, posix, time, binascii, socket, select
 
import hashlib
  class ApiRos:
 
class ApiRos:
     "Routeros api"
     "Routeros api"
     def __init__(self, sk):
     def __init__(self, sk):
         self.sk = sk
         self.sk = sk
         self.currenttag = 0
         self.currenttag = 0
 
       
     def login(self, username, pwd):
     def login(self, username, pwd):
         for repl, attrs in self.talk(["/login"]):
         for repl, attrs in self.talk(["/login"]):
Line 25: Line 26:
         self.talk(["/login", "=name=" + username,
         self.talk(["/login", "=name=" + username,
                   "=response=00" + binascii.hexlify(md.digest()).decode('UTF-8') ])
                   "=response=00" + binascii.hexlify(md.digest()).decode('UTF-8') ])
 
 
     def talk(self, words):
     def talk(self, words):
         if self.writeSentence(words) == 0: return
         if self.writeSentence(words) == 0: return
Line 42: Line 43:
             r.append((reply, attrs))
             r.append((reply, attrs))
             if reply == '!done': return r
             if reply == '!done': return r
 
 
     def writeSentence(self, words):
     def writeSentence(self, words):
         ret = 0
         ret = 0
Line 50: Line 51:
         self.writeWord('')
         self.writeWord('')
         return ret
         return ret
 
 
     def readSentence(self):
     def readSentence(self):
         r = []
         r = []
Line 62: Line 63:
         self.writeLen(len(w))
         self.writeLen(len(w))
         self.writeStr(w)
         self.writeStr(w)
 
 
     def readWord(self):
     def readWord(self):
         ret = self.readStr(self.readLen())
         ret = self.readStr(self.readLen())
         print((">>> " + ret))
         print((">>> " + ret))
         return ret
         return ret
 
 
     def writeLen(self, l):
     def writeLen(self, l):
         if l < 0x80:
         if l < 0x80:
Line 92: Line 93:
             self.writeStr(chr((l >> 8) & 0xFF))
             self.writeStr(chr((l >> 8) & 0xFF))
             self.writeStr(chr(l & 0xFF))
             self.writeStr(chr(l & 0xFF))
 
 
     def readLen(self):               
     def readLen(self):               
         c = ord(self.readStr(1))     
         c = ord(self.readStr(1))     
Line 124: Line 125:
             c += ord(self.readStr(1))     
             c += ord(self.readStr(1))     
         return c                     
         return c                     
 
 
     def writeStr(self, str):         
     def writeStr(self, str):         
         n = 0;                       
         n = 0;                       
Line 131: Line 132:
             if r == 0: raise RuntimeError("connection closed by remote end")
             if r == 0: raise RuntimeError("connection closed by remote end")
             n += r                   
             n += r                   
 
 
     def readStr(self, length):       
     def readStr(self, length):       
         ret = ''                     
         ret = ''                     
Line 139: Line 140:
             ret += s
             ret += s
         return ret
         return ret
 
 
  def main():
def main():
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     s.connect((sys.argv[1], 8728))   
     s.connect((sys.argv[1], 8728))   
     apiros = ApiRos(s);             
     apiros = ApiRos(s);             
     apiros.login(sys.argv[2], sys.argv[3]);
     apiros.login(sys.argv[2], sys.argv[3]);
 
 
     inputsentence = []
     inputsentence = []
 
 
     while 1:
     while 1:
         r = select.select([s, sys.stdin], [], [], None)
         r = select.select([s, sys.stdin], [], [], None)
Line 153: Line 154:
             # something to read in socket, read sentence
             # something to read in socket, read sentence
             x = apiros.readSentence()
             x = apiros.readSentence()
 
 
         if sys.stdin in r[0]:
         if sys.stdin in r[0]:
             # read line from input and strip off newline
             # read line from input and strip off newline
             l = sys.stdin.readline()
             l = sys.stdin.readline()
             l = l[:-1]
             l = l[:-1]
 
 
             # if empty line, send sentence and start with new
             # if empty line, send sentence and start with new
             # otherwise append to input sentence
             # otherwise append to input sentence
Line 166: Line 167:
             else:
             else:
                 inputsentence.append(l)
                 inputsentence.append(l)
 
 
  if __name__ == '__main__':
if __name__ == '__main__':
     main()
     main()
</pre>


==file==
==file==

Revision as of 05:40, 4 August 2011

Summary

Since python language have introduced changes to syntax when going from 2.x to 3.x some adjustments had to be made for old code from API.

Code for Python3

code

#!/usr/bin/python3

import sys, posix, time, binascii, socket, select
import hashlib

class ApiRos:
    "Routeros api"
    def __init__(self, sk):
        self.sk = sk
        self.currenttag = 0
        
    def login(self, username, pwd):
        for repl, attrs in self.talk(["/login"]):
            chal = binascii.unhexlify((attrs['=ret']).encode('UTF-8'))
        md = hashlib.md5()
        md.update(b'\x00')
        md.update(pwd.encode('UTF-8'))
        md.update(chal)
        self.talk(["/login", "=name=" + username,
                   "=response=00" + binascii.hexlify(md.digest()).decode('UTF-8') ])

    def talk(self, words):
        if self.writeSentence(words) == 0: return
        r = []
        while 1:
            i = self.readSentence();
            if len(i) == 0: continue
            reply = i[0]
            attrs = {}
            for w in i[1:]:
                j = w.find('=', 1)
                if (j == -1):
                    attrs[w] = ''
                else:
                    attrs[w[:j]] = w[j+1:]
            r.append((reply, attrs))
            if reply == '!done': return r

    def writeSentence(self, words):
        ret = 0
        for w in words:
            self.writeWord(w)
            ret += 1
        self.writeWord('')
        return ret

    def readSentence(self):
        r = []
        while 1:
            w = self.readWord()
            if w == '': return r
            r.append(w)
            
    def writeWord(self, w):
        print(("<<< " + w))
        self.writeLen(len(w))
        self.writeStr(w)

    def readWord(self):
        ret = self.readStr(self.readLen())
        print((">>> " + ret))
        return ret

    def writeLen(self, l):
        if l < 0x80:
            self.writeStr(chr(l))
        elif l < 0x4000:
            l |= 0x8000
            self.writeStr(chr((l >> 8) & 0xFF))
            self.writeStr(chr(l & 0xFF))
        elif l < 0x200000:
            l |= 0xC00000
            self.writeStr(chr((l >> 16) & 0xFF))
            self.writeStr(chr((l >> 8) & 0xFF))
            self.writeStr(chr(l & 0xFF))
        elif l < 0x10000000:        
            l |= 0xE0000000         
            self.writeStr(chr((l >> 24) & 0xFF))
            self.writeStr(chr((l >> 16) & 0xFF))
            self.writeStr(chr((l >> 8) & 0xFF))
            self.writeStr(chr(l & 0xFF))
        else:                       
            self.writeStr(chr(0xF0))
            self.writeStr(chr((l >> 24) & 0xFF))
            self.writeStr(chr((l >> 16) & 0xFF))
            self.writeStr(chr((l >> 8) & 0xFF))
            self.writeStr(chr(l & 0xFF))

    def readLen(self):              
        c = ord(self.readStr(1))    
        if (c & 0x80) == 0x00:      
            pass                    
        elif (c & 0xC0) == 0x80:    
            c &= ~0xC0              
            c <<= 8                 
            c += ord(self.readStr(1))    
        elif (c & 0xE0) == 0xC0:    
            c &= ~0xE0              
            c <<= 8                 
            c += ord(self.readStr(1))    
            c <<= 8                 
            c += ord(self.readStr(1))    
        elif (c & 0xF0) == 0xE0:    
            c &= ~0xF0              
            c <<= 8                 
            c += ord(self.readStr(1))    
            c <<= 8                 
            c += ord(self.readStr(1))    
            c <<= 8                 
            c += ord(self.readStr(1))    
        elif (c & 0xF8) == 0xF0:    
            c = ord(self.readStr(1))     
            c <<= 8                 
            c += ord(self.readStr(1))    
            c <<= 8                 
            c += ord(self.readStr(1))    
            c <<= 8                 
            c += ord(self.readStr(1))    
        return c                    

    def writeStr(self, str):        
        n = 0;                      
        while n < len(str):         
            r = self.sk.send(bytes(str[n:], 'UTF-8'))
            if r == 0: raise RuntimeError("connection closed by remote end")
            n += r                  

    def readStr(self, length):      
        ret = ''                    
        while len(ret) < length:    
            s = self.sk.recv(length - len(ret)).decode('UTF-8')
            if s == '': raise RuntimeError("connection closed by remote end")
            ret += s
        return ret

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((sys.argv[1], 8728))  
    apiros = ApiRos(s);             
    apiros.login(sys.argv[2], sys.argv[3]);

    inputsentence = []

    while 1:
        r = select.select([s, sys.stdin], [], [], None)
        if s in r[0]:
            # something to read in socket, read sentence
            x = apiros.readSentence()

        if sys.stdin in r[0]:
            # read line from input and strip off newline
            l = sys.stdin.readline()
            l = l[:-1]

            # if empty line, send sentence and start with new
            # otherwise append to input sentence
            if l == '':
                apiros.writeSentence(inputsentence)
                inputsentence = []
            else:
                inputsentence.append(l)

if __name__ == '__main__':
    main()

file

File:Api.txt

See also

API