├── api_key.txt ├── .gitignore ├── .vscode └── mcp.json ├── README.md └── openai_chat.c /api_key.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # API Keys and secrets 2 | *.key 3 | .env 4 | .env.local 5 | 6 | # Compiled binaries 7 | hello 8 | openai_chat 9 | test_request 10 | *.o 11 | *.exe 12 | 13 | # System files 14 | .DS_Store 15 | Thumbs.db -------------------------------------------------------------------------------- /.vscode/mcp.json: -------------------------------------------------------------------------------- 1 | { 2 | "servers": { 3 | "context7": { 4 | "type": "http", 5 | "url": "https://mcp.context7.com/mcp", 6 | "headers": { 7 | "CONTEXT7_API_KEY": "ctx7sk-2da0fccb-526c-4d9b-ae93-aa592b98f5b9" 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenAI Chat Client in C 2 | 3 | A simple C program that demonstrates how to make requests to the OpenAI API using libcurl. The program sends a "hello" message to the ChatGPT API and displays the response. 4 | 5 | ## Features 6 | 7 | - Makes HTTP POST requests to OpenAI's Chat Completions API 8 | - Supports multiple methods for API key configuration 9 | - JSON request/response handling 10 | - Dynamic memory allocation for responses 11 | - Error handling and validation 12 | 13 | ## Prerequisites 14 | 15 | - **libcurl**: Required for HTTP requests 16 | - **GCC**: For compilation 17 | - **OpenAI API Key**: Required for API access 18 | - **Context7 API Key**: Optional, for enhanced documentation access 19 | 20 | ## Installation 21 | 22 | ### macOS 23 | ```bash 24 | # libcurl is usually pre-installed on macOS 25 | # If not available, install via Homebrew: 26 | brew install curl 27 | ``` 28 | 29 | ### Linux (Ubuntu/Debian) 30 | ```bash 31 | sudo apt-get update 32 | sudo apt-get install libcurl4-openssl-dev build-essential 33 | ``` 34 | 35 | ### Linux (CentOS/RHEL) 36 | ```bash 37 | sudo yum install libcurl-devel gcc 38 | ``` 39 | 40 | ## API Key Setup 41 | 42 | ### Method 1: File-based Configuration (Recommended) 43 | 44 | 1. **OpenAI API Key**: 45 | ```bash 46 | echo "your-openai-api-key-here" > api_key.txt 47 | ``` 48 | 49 | 2. **Context7 API Key** (Optional - for enhanced documentation): 50 | - Edit `.vscode/mcp.json` and update the Context7 API key: 51 | ```json 52 | { 53 | "servers": { 54 | "context7": { 55 | "type": "http", 56 | "url": "https://mcp.context7.com/mcp", 57 | "headers": { 58 | "CONTEXT7_API_KEY": "your-context7-api-key-here" 59 | } 60 | } 61 | } 62 | } 63 | ``` 64 | 65 | ## Compilation and Usage 66 | 67 | 1. **Compile the program**: 68 | ```bash 69 | gcc -o openai_chat openai_chat.c -lcurl 70 | ``` 71 | 72 | 2. **Run the program**: 73 | ```bash 74 | ./openai_chat 75 | ``` 76 | 77 | ## Example Output 78 | 79 | ``` 80 | ✓ API key loaded from api_key.txt 81 | Sending request to OpenAI API with message: "hello" 82 | Request payload: {"model": "gpt-3.5-turbo","messages": [{"role": "user","content": "hello"}],"max_tokens": 100} 83 | 84 | Response from OpenAI API: 85 | { 86 | "id": "chatcmpl-xyz123", 87 | "object": "chat.completion", 88 | "created": 1699123456, 89 | "model": "gpt-3.5-turbo-0125", 90 | "choices": [ 91 | { 92 | "index": 0, 93 | "message": { 94 | "role": "assistant", 95 | "content": "Hello! How can I assist you today?", 96 | "refusal": null 97 | }, 98 | "finish_reason": "stop" 99 | } 100 | ], 101 | "usage": { 102 | "prompt_tokens": 8, 103 | "completion_tokens": 9, 104 | "total_tokens": 17 105 | } 106 | } 107 | ``` 108 | 109 | ## File Structure 110 | 111 | ``` 112 | Chaos-c-openAI/ 113 | ├── openai_chat.c # Main C source file 114 | ├── openai_chat # Compiled binary 115 | ├── api_key.txt # OpenAI API key (create this) 116 | ├── .vscode/ 117 | │ └── mcp.json # Context7 MCP configuration 118 | ├── README.md # This file 119 | └── .gitignore # Git ignore rules 120 | ``` 121 | -------------------------------------------------------------------------------- /openai_chat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // Structure to store response data 7 | struct Response { 8 | char *data; 9 | size_t size; 10 | }; 11 | 12 | // Callback function to write response data 13 | static size_t WriteCallback(void *contents, size_t size, size_t nmemb, struct Response *response) { 14 | size_t realsize = size * nmemb; 15 | char *ptr = realloc(response->data, response->size + realsize + 1); 16 | 17 | if (ptr == NULL) { 18 | printf("Not enough memory (realloc returned NULL)\n"); 19 | return 0; 20 | } 21 | 22 | response->data = ptr; 23 | memcpy(&(response->data[response->size]), contents, realsize); 24 | response->size += realsize; 25 | response->data[response->size] = 0; // null terminate 26 | 27 | return realsize; 28 | } 29 | 30 | int main() { 31 | CURL *curl; 32 | CURLcode res; 33 | struct Response response = {0}; 34 | struct curl_slist *headers = NULL; 35 | 36 | // Initialize libcurl 37 | res = curl_global_init(CURL_GLOBAL_ALL); 38 | if (res != CURLE_OK) { 39 | fprintf(stderr, "curl_global_init() failed: %s\n", curl_easy_strerror(res)); 40 | return 1; 41 | } 42 | 43 | curl = curl_easy_init(); 44 | if (curl) { 45 | // Set the URL 46 | curl_easy_setopt(curl, CURLOPT_URL, "https://api.openai.com/v1/chat/completions"); 47 | 48 | // Set headers 49 | headers = curl_slist_append(headers, "Content-Type: application/json"); 50 | 51 | // Try to get API key from file first, then fall back to environment variable 52 | char api_key_buffer[512] = {0}; 53 | const char *api_key = NULL; 54 | 55 | // Try to read API key from file 56 | FILE *key_file = fopen("api_key.txt", "r"); 57 | if (key_file != NULL) { 58 | if (fgets(api_key_buffer, sizeof(api_key_buffer), key_file) != NULL) { 59 | // Remove newline character if present 60 | char *newline = strchr(api_key_buffer, '\n'); 61 | if (newline) *newline = '\0'; 62 | // Remove carriage return if present 63 | char *carriage_return = strchr(api_key_buffer, '\r'); 64 | if (carriage_return) *carriage_return = '\0'; 65 | 66 | api_key = api_key_buffer; 67 | printf("✓ API key loaded from api_key.txt\n"); 68 | } 69 | fclose(key_file); 70 | } 71 | 72 | // Fall back to environment variable if file reading failed 73 | if (api_key == NULL || strlen(api_key) == 0) { 74 | api_key = getenv("OPENAI_API_KEY"); 75 | if (api_key != NULL) { 76 | printf("✓ API key loaded from environment variable\n"); 77 | } 78 | } 79 | 80 | // Check if we have an API key 81 | if (api_key == NULL || strlen(api_key) == 0) { 82 | fprintf(stderr, "Error: No API key found!\n"); 83 | fprintf(stderr, "Options:\n"); 84 | fprintf(stderr, "1. Create api_key.txt file with your API key\n"); 85 | fprintf(stderr, "2. Set OPENAI_API_KEY environment variable\n"); 86 | curl_easy_cleanup(curl); 87 | curl_global_cleanup(); 88 | return 1; 89 | } 90 | 91 | // Create authorization header 92 | char auth_header[512]; 93 | snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", api_key); 94 | headers = curl_slist_append(headers, auth_header); 95 | 96 | curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 97 | 98 | // JSON payload with "hello" message 99 | const char *json_data = 100 | "{" 101 | "\"model\": \"gpt-3.5-turbo\"," 102 | "\"messages\": [" 103 | "{" 104 | "\"role\": \"user\"," 105 | "\"content\": \"hello\"" 106 | "}" 107 | "]," 108 | "\"max_tokens\": 100" 109 | "}"; 110 | 111 | // Set POST data 112 | curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data); 113 | 114 | // Set callback function to capture response 115 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); 116 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); 117 | 118 | // Perform the request 119 | printf("Sending request to OpenAI API with message: \"hello\"\n"); 120 | printf("Request payload: %s\n\n", json_data); 121 | 122 | res = curl_easy_perform(curl); 123 | 124 | if (res != CURLE_OK) { 125 | fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); 126 | } else { 127 | printf("Response from OpenAI API:\n"); 128 | printf("%s\n", response.data ? response.data : "No response data"); 129 | } 130 | 131 | // Cleanup 132 | curl_slist_free_all(headers); 133 | curl_easy_cleanup(curl); 134 | } 135 | 136 | // Free response data 137 | if (response.data) { 138 | free(response.data); 139 | } 140 | 141 | curl_global_cleanup(); 142 | return (res == CURLE_OK) ? 0 : 1; 143 | } --------------------------------------------------------------------------------