Skip to content

Instantly share code, notes, and snippets.

@rodrigobdz
Last active January 9, 2025 10:17
Show Gist options
  • Save rodrigobdz/8175885eb690f9bb5483ddabebc6a426 to your computer and use it in GitHub Desktop.
Save rodrigobdz/8175885eb690f9bb5483ddabebc6a426 to your computer and use it in GitHub Desktop.
Parse JSON response from OpenAI API containing content or refusal
import json
import logging
# Set up logger
logging.basicConfig(level=logging.WARNING)
logger = logging.getLogger(__name__)
# Modified JSON from https://platform.openai.com/docs/api-reference/chat/object
response_str = json.dumps({
"id": "chatcmpl-123456",
"object": "chat.completion",
"created": 1728933352,
"model": "gpt-4o-2024-08-06",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": None,
"refusal": "Refusing to answer"
},
"logprobs": None,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 19,
"completion_tokens": 10,
"total_tokens": 29,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"system_fingerprint": "fp_6b68a8204b"
})
class JSONObject:
def __init__(self, dictionary):
for key, value in dictionary.items():
if isinstance(value, dict):
setattr(self, key, JSONObject(value))
elif isinstance(value, list):
setattr(self, key, [JSONObject(item) if isinstance(item, dict) else item for item in value])
else:
setattr(self, key, value)
def __repr__(self):
return str(self.__dict__) # Provides a readable string representation of the object
# Convert JSON string to custom objects
response = json.loads(response_str, object_hook=lambda d: JSONObject(d))
# Parse content or refusal in API response
try:
# Ensure there are choices in the response
if not response.choices:
raise ValueError(f"The response does not contain any choices.")
# Extract the first choice and its message
first_choice = response.choices[0]
message = getattr(first_choice, "message", None)
# Ensure the message has the required attributes
if not message or not hasattr(message, "role"):
raise ValueError(f"The response message lacks the required 'role' field. Response:\n{response}")
# Use content if available, otherwise fallback to refusal
content = getattr(message, "content", None)
refusal = getattr(message, "refusal", None)
if not content and refusal:
logger.warning(f"Message content is empty. Using 'refusal' instead. Response:\n{response}")
if not content and not refusal:
raise ValueError(f"Content and refusal empty in response. Response:\n{response}")
print('Content or refusal: ', content or refusal)
except (AttributeError, IndexError, TypeError) as e:
raise ValueError(f"Invalid response structure. Response:\n{response}") from e
@rodrigobdz
Copy link
Author

Run snippet:

  1. Open Terminal
  2. Enter python
  3. Copy and paste the snippet and press Enter key

@rodrigobdz
Copy link
Author

Expected output:

WARNING:__main__:Message content is empty. Using 'refusal' instead. Response:
{'id': 'chatcmpl-123456', 'object': 'chat.completion', 'created': 1728933352, 'model': 'gpt-4o-2024-08-06', 'choices': [{'index': 0, 'message': {'role': 'assistant', 'content': None, 'refusal': 'Refusing to answer'}, 'logprobs': None, 'finish_reason': 'stop'}], 'usage': {'prompt_tokens': 19, 'completion_tokens': 10, 'total_tokens': 29, 'prompt_tokens_details': {'cached_tokens': 0}, 'completion_tokens_details': {'reasoning_tokens': 0, 'accepted_prediction_tokens': 0, 'rejected_prediction_tokens': 0}}, 'system_fingerprint': 'fp_6b68a8204b'}
Content or refusal:  Refusing to answer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment