<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_tokens_by_code(self, code, state):
 """Function to get access code for getting the user details from the OP. It is called after the user authorizes by visiting the auth URL. Parameters: * **code (string):
** code, parse from the callback URL querystring * **state (string):
** state value parsed from the callback URL Returns: **dict:** The tokens object with the following data structure. Example response:: { "access_token": "<token string>", "expires_in": 3600, "refresh_token": "<token string>", "id_token": "<token string>", "id_token_claims": { "iss": "https://server.example.com", "sub": "24400320", "aud": "s6BhdRkqt3", "nonce": "n-0S6_WzA2Mj", "exp": 1311281970, "iat": 1311280970, "at_hash": "MTIzNDU2Nzg5MDEyMzQ1Ng" } } Raises: **OxdServerError:** If oxd server throws an error OR if the params code and scopes are of improper data type. """

        params = dict(oxd_id=self.oxd_id, code=code, state=state)

        logger.debug("Sending command `get_tokens_by_code` with params %s",
                     params)
        response = self.msgr.request("get_tokens_by_code", **params)
        logger.debug("Received response: %s", response)

        if response['status'] == 'error':
            raise OxdServerError(response['data'])
        return response['data']