Manual:API Python3: Difference between revisions

From MikroTik Wiki
Jump to navigation Jump to search
API client example in Python3
 
m make this readable
Line 1: Line 1:
#!/usr/bin/python
  #!/usr/bin/python
 
 
import sys, posix, time, binascii, socket, select
  import sys, posix, time, binascii, socket, select
import hashlib
  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 19: Line 19:
         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 36: Line 36:
             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 44: Line 44:
         self.writeWord('')
         self.writeWord('')
         return ret
         return ret
 
 
     def readSentence(self):
     def readSentence(self):
         r = []
         r = []
Line 56: Line 56:
         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 86: Line 86:
             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 118: Line 118:
             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 125: Line 125:
             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 133: Line 133:
             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 147: Line 147:
             # 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 160: Line 160:
             else:
             else:
                 inputsentence.append(l)
                 inputsentence.append(l)
 
 
if __name__ == '__main__':
  if __name__ == '__main__':
     main()
     main()

Revision as of 13:13, 3 August 2011

 #!/usr/bin/python
 
 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()