OBEXClient

## module lightblue.obex:

### class OBEXClient

        An OBEX client class. (Note this is not available on Python for Series 60.)

        For example, to connect to an OBEX server and send a file:
            >>> import lightblue
            >>> client = lightblue.obex.OBEXClient("aa:bb:cc:dd:ee:ff", 10)
            >>> client.connect()
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>> client.put({"name": "photo.jpg"}, file("photo.jpg", "rb"))
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>> client.disconnect()
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>>
        A client must call connect() to establish a connection before it can send
        any other requests.

        The connect(), disconnect(), put(), delete(), get() and setpath() methods
        all accept the request headers as a dictionary of header-value mappings. The
        request headers are used to provide the server with additional information
        for the request. For example, this sends a Put request that includes Name,
        Type and Length headers in the request headers, to provide details about
        the transferred file:
            >>> f = file("file.txt")
            >>> client.put({"name": "file.txt", "type": "text/plain",
            ...         "length": 5192}, f)
            >>>

        Here is a list of all the different string header keys that you can use in
        the request headers, and the expected type of the value for each header:

            - "name" -> a string
            - "type" -> a string
            - "length" -> an int
            - "time" -> a datetime object from the datetime module
            - "description" -> a string
            - "target" -> a string or buffer
            - "http" -> a string or buffer
            - "who" -> a string or buffer
            - "connection-id" -> an int
            - "application-parameters" -> a string or buffer
            - "authentication-challenge" -> a string or buffer
            - "authentication-response" -> a string or buffer
            - "creator-id" -> an int
            - "wan-uuid" -> a string or buffer
            - "object-class" -> a string or buffer
            - "session-parameters" -> a string or buffer
            - "session-sequence-number" -> an int less than 256

        (The string header keys are not case-sensitive.)

        Alternatively, you can use raw header ID values instead of the above
        convenience strings. So, the previous example can be rewritten as:
            >>> client.put({0x01: "file.txt", 0x42: "text/plain", 0xC3: 5192},
            ...     fileobject)
            >>>
        This is also useful for inserting custom headers. For example, a PutImage
        request for a Basic Imaging client requires the Img-Descriptor (0x71)
        header:
            >>> client.put({"type": "x-bt/img-img",
            ...     "name": "photo.jpg",
            ...     0x71: '<image-descriptor version="1.0"><image encoding="JPEG" pixel="160*120" size="37600"/></image-descriptor>'},
            ...     file('photo.jpg', 'rb'))
            >>>
        Notice that the connection-id header is not sent, because this is
        automatically included by OBEXClient in the request headers if a
        connection-id was received in a previous Connect response.

        See the included src/examples/obex_ftp_client.py for an example of using
        OBEXClient to implement a File Transfer client for browsing the files on a
        remote device.

## Methods

- __init__(address, channel)
- connect(headers={})
- disconnect(headers={})
- put(headers, fileobj)
- delete(headers)
- get(headers, fileobj)
- setpath(headers, cdtoparent=False, createdirs=False)

#### __init__(address, channel)

        Creates an OBEX client.

        Arguments:
            - address: the address of the remote device
            - channel: the RFCOMM channel of the remote OBEX service

#### connect(headers={})

        Establishes the Bluetooth connection to the remote OBEX server and sends
        a Connect request to open the OBEX session. Returns an OBEXResponse
        instance containing the server response.

        Raises lightblue.obex.OBEXError if the session is already connected, or if
        an error occurs during the request.

        If the server refuses the Connect request (i.e. if it sends a response code
        other than OK/Success), the Bluetooth connection will be closed.

        Arguments:
            - headers={}: the headers to send for the Connect request

#### disconnect(headers={})

        Sends a Disconnect request to end the OBEX session and closes the Bluetooth
        connection to the remote OBEX server. Returns an OBEXResponse
        instance containing the server response.

        Raises lightblue.obex.OBEXError if connect() has not been called, or if an
        error occurs during the request.

        Note that you don't need to send any connection-id headers - this is
        automatically included if the client received one in a Connect response.

        Arguments:
            - headers={}: the headers to send for the request

#### put(headers, fileobj)

        Sends a Put request. Returns an OBEXResponse instance containing the
        server response.

        Raises lightblue.obex.OBEXError if connect() has not been called, or if an
        error occurs during the request.

        Note that you don't need to send any connection-id headers - this is
        automatically included if the client received one in a Connect response.

        Arguments:
            - headers: the headers to send for the request
            - fileobj: a file-like object containing the file data to be sent for
              the request

        For example, to send a file named 'photo.jpg', using the request headers
        to notify the server of the file's name, MIME type and length:
            >>> client = lightblue.obex.OBEXClient("aa:bb:cc:dd:ee:ff", 10)
            >>> client.connect()
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>> client.put({"name": "photo.jpg", "type": "image/jpeg",
                    "length": 28566}, file("photo.jpg", "rb"))
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>>

#### delete(headers)

        Sends a Put-Delete request in order to delete a file or folder on the remote
        server. Returns an OBEXResponse instance containing the server response.

        Raises lightblue.obex.OBEXError if connect() has not been called, or if an
        error occurs during the request.

        Note that you don't need to send any connection-id headers - this is
        automatically included if the client received one in a Connect response.

        Arguments:
            - headers: the headers to send for the request - you should use the
              'name' header to specify the file you want to delete

        If the file on the server can't be deleted because it's a read-only file,
        you might get an 'Unauthorized' response, like this:
            >>> client = lightblue.obex.OBEXClient("aa:bb:cc:dd:ee:ff", 10)
            >>> client.connect()
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>> client.delete({"name": "random_file.txt"})
            <OBEXResponse reason='Unauthorized' code=0x41 (0xc1) headers={}>
            >>>

#### get(headers, fileobj)

        Sends a Get request. Returns an OBEXResponse instance containing the server
        response.

        Raises lightblue.obex.OBEXError if connect() has not been called, or if an
        error occurs during the request.

        Note that you don't need to send any connection-id headers - this is
        automatically included if the client received one in a Connect response.

        Arguments:
            - headers: the headers to send for the request - you should use these
              to specify the file you want to retrieve
            - fileobj: a file-like object, to which the received data will be
              written

        An example:
            >>> client.connect()
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>> f = file("received_file.txt", "w+")
            >>> client.get({"name": "testfile.txt"}, f)
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={'length':9}>
            >>> f.seek(0)
            >>> f.read()
            'test file'
            >>>

#### setpath(headers, cdtoparent=False, createdirs=False)

        Sends a SetPath request in order to set the "current path" on the remote
        server for file transfers. Returns an OBEXResponse instance containing the
        server response.

        Raises lightblue.obex.OBEXError if connect() has not been called, or if an
        error occurs during the request.

        Note that you don't need to send any connection-id headers - this is
        automatically included if the client received one in a Connect response.

        Arguments:
            - headers: the headers to send for the request - you should use the
              'name' header to specify the directory you want to change to
            - cdtoparent=False: True if the remote server should move up one
              directory before applying the specified directory (i.e. 'cd
              ../dirname')
            - createdirs=False: True if the specified directory should be created
              if it doesn't exist (if False, the server will return an error
              response if the directory doesn't exist)

        For example:
            # change to the "images" subdirectory
            >>> client.setpath({"name": "images"})
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>>
            # change to the parent directory
            >>> client.setpath({}, cdtoparent=True)
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>>
            # make a directory "My_Files"
            >>> client.setpath({"name": "My_Files"}, createdirs=True)
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>>
            # change to the root directory - you can use an empty "name" header
            # to specify this
            >>> client.setpath({"name": ""})
            <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
            >>>