Python bindings

Andrew Bird ajb at spheresystems.co.uk
Thu Nov 15 12:08:29 PST 2012


On Thursday 15 November 2012 10:18:00 Aleksander Morgado wrote:
> >>>>> 	Thanks, I'm getting further now. Seems I have to fix some missing
> >>>>> 
> >>>>> annotations now. I'll send patches later.
> >>>> 
> >>>> Great!
> >>> 
> >>> Hi Aleksander,
> >>> 
> >>> 	I sent the patches, can you check patches 2 and 3 before applying, as
> >>> 	I'm
> >>> 
> >>> not totally confident I got the modes and value correct?
> >> 
> >> I'll take a look at them, but I hope Dan can take a quick look at them
> >> too; I'm not expert in this area.
> >> 
> >> Just wondering, given you didn't change the autogenerated code, does it
> >> mean that the introspection tags in there are actually all ok?
> > 
> > Hi Aleksander,
> > 
> > 	The gir scanner didn't complain about anything other than the ones I
> > 
> > changed in the patches 2 / 3. As yet I haven't tested in Python, except
> > for
> > basic import. This is mainly due to my lack of knowledge on libqmi around
> > what's needed to do a simple call like get manufacturer or model etc.
> 
> For a simple call like Get Manufacturer, see e.g:
> http://www.lanedo.com/~aleksander/libqmi/html/libqmi-glib-DMS-Get-Manufactur
> er.html
> 
> So the flow would be:
>  * Create a QmiDevice.
>  * Request to allocate a QmiClient for service QMI_CLIENT_DMS.
>  * Call the get_manufacturer() method in the QmiClientDms.
>  * Get the response with the output bundle in get_manufacturer_finish().
>  * Check about errors in the bundle with output_get_result().
>  * Get the final string if no errors with output_get_manufacturer().
> 
> For each async operation, both the call and finish() use bundles to pack
> all possible input or output TLVs, so the bundles will also need proper
> introspection data.
> 
> I guess the same flow would apply in the case of a Python client. From
> what I can tell, the generated sources need additional annotations for a
> proper introspection (think I added some I knew of, but probably not
> all); or you won't be able to run the previous flow.
> 
> I would suggest to play with all this first, including:
>  * operations that need TLVs in output bundles
>  * operations that need TLVs in input bundles
>  * operations with different input/output types being passed (e.g. with
> integers, strings)
>  * operations with different containers (e.g. structs, arrays)

Hi Aleksander,
	Here's my first stab at the python, it's a little dirty in that I didn't 
bother releasing the cids etc.  I did need to tweak the build again so that we 
also added the generated files to the gir.

It almost works apart from:

1/ client.get_manufacturer() won't take None as the first argument, but looking 
at the gir I can't see why not. As a hack I passed in a function reference, 
knowing that its unused anyway.

2/ Where necessary, complex return values should be returned in a tuple. If 
you look at get_manufacturer_ready() you'll see that supposedly the value is 
returned in the string passed in to arg1. For me that's always empty, but I 
checked with qmicli, the value is populated properly. The page 
https://live.gnome.org/PyGObject/IntrospectionPorting suggests that it should 
be returning tuples in this case, and its certainly more pythonic.


from gi.repository import Gio                                                   
from gi.repository import GObject                                               
from gi.repository import libqmi as Qmi                                         
                                                                                
                                                                                
def get_manufacturer_ready(client, result, ignored):                            
    m = client.get_manufacturer_finish(result)                                  
                                                                                
    s = ''                                                                      
    v = m.get_manufacturer(s)                                                   
    print "get_manufacturer(): returned %d, '%s'" % (v, s)                      
                                                                                
    # We would ideally get a tuple like explained here                          
    # https://live.gnome.org/PyGObject/IntrospectionPorting                     
    # section entitled "Output arguments"                                       
    #(v,s) = m.get_manufacturer()                                               
    #print "get_manufacturer(): returned %d, '%s'" % (v, s)                     
                                                                                
                                                                                
def device_allocate_client_ready(device, result, arg):                          
    client = device.allocate_client_finish(result)                              
    print "allocated"                                                           
                                                                                
    def WontTakeNone():                                                         
        pass                                                                    
                                                                                
    client.get_manufacturer(WontTakeNone, 15, None, get_manufacturer_ready, 
None)
                                                                                
                                                                                
def device_open_ready(device, result, arg):                                     
    device.open_finish(result)                                                  
    print "device is open"                                                      
                                                                                
    service = Qmi.Service(Qmi.Service.DMS)                                      
    device.allocate_client(service, Qmi.CID_NONE, 15, None,                     
                            device_allocate_client_ready, None)                 
                                                                                
                                                                                
def device_new_ready(device, result, arg):                                      
    device.new_finish(result)                                                   
    print "device is ready"                                                     
    device.open(0, 15, None, device_open_ready, None)                           
                                                                                
dfile = Gio.file_parse_name("/dev/cdc-wdm0")                                    
Qmi.Device.new(dfile, None, device_new_ready, None)                             
                                                                                
                                                                                
loop = GObject.MainLoop()                                                       
loop.run()                                                                      

Andrew


More information about the libqmi-devel mailing list