This commit is contained in:
root
2025-10-13 18:25:37 +05:00
parent e55eecd069
commit 3998095717
3 changed files with 175 additions and 2 deletions
+89
View File
@@ -0,0 +1,89 @@
# Настройка OpenAI API
## Проблема
Получена ошибка `401 Unauthorized` при обращении к OpenAI API. Это означает, что API ключ недействителен или истек.
## Решение
### 1. Получите новый API ключ OpenAI
1. Перейдите на [OpenAI Platform](https://platform.openai.com/)
2. Войдите в свой аккаунт или создайте новый
3. Перейдите в раздел "API Keys"
4. Создайте новый API ключ
5. Скопируйте ключ (он начинается с `sk-`)
### 2. Настройте API ключ
#### Вариант A: Переменная окружения (рекомендуется)
```bash
export OPENAI_API_KEY=sk-your-actual-api-key-here
```
#### Вариант B: Прямо в application.properties
Откройте файл `src/main/resources/application.properties` и замените:
```properties
openai.api.key=your-openai-api-key-here
```
на:
```properties
openai.api.key=sk-your-actual-api-key-here
```
### 3. Проверьте настройки
Убедитесь, что в `application.properties` правильно настроены:
```properties
# OpenAI Configuration
openai.api.key=${OPENAI_API_KEY:your-openai-api-key-here}
openai.api.url=https://api.openai.com/v1/chat/completions
openai.model.name=gpt-4o-mini
openai.timeoutMs=90000
```
### 4. Тестирование
После настройки API ключа:
1. Перезапустите приложение
2. Откройте `GET /api/openai/test` для проверки подключения
3. Проверьте логи на наличие ошибок
### 5. Возможные проблемы
- **401 Unauthorized**: Неверный или истекший API ключ
- **429 Rate Limit**: Превышен лимит запросов
- **500 Server Error**: Временная проблема с сервером OpenAI
### 6. Безопасность
⚠️ **Важно**: Никогда не коммитьте реальные API ключи в репозиторий!
- Используйте переменные окружения
- Добавьте `application.properties` в `.gitignore` если содержит секреты
- Используйте отдельные файлы конфигурации для продакшена
## Пример использования
После настройки API ключа сервис будет работать автоматически:
```java
@Autowired
private OpenAIAnalyticsService openAIAnalyticsService;
// Анализ текста
MarketItem.Analytics analytics = openAIAnalyticsService.analyzeText("Ваш текст здесь");
// Генерация контента
String result = openAIAnalyticsService.generateWithInstruction(
"Данные для анализа",
"Напиши краткий отчет"
);
```
@@ -37,6 +37,16 @@ public class OpenAIAnalyticsService {
private String apiKey; private String apiKey;
public OpenAIAnalyticsService(@Value("${openai.api.url:https://api.openai.com/v1/chat/completions}") String openaiUrl) { public OpenAIAnalyticsService(@Value("${openai.api.url:https://api.openai.com/v1/chat/completions}") String openaiUrl) {
// Проверяем API ключ при инициализации
if (apiKey == null || apiKey.trim().isEmpty() || apiKey.equals("your-openai-api-key-here")) {
logger.error("OpenAI API key is not configured properly. Please set OPENAI_API_KEY environment variable or update application.properties");
throw new IllegalStateException("OpenAI API key is not configured");
}
if (!apiKey.startsWith("sk-")) {
logger.warn("OpenAI API key does not start with 'sk-'. Please verify your API key is correct.");
}
HttpClient httpClient = HttpClient.create() HttpClient httpClient = HttpClient.create()
.compress(true) .compress(true)
.responseTimeout(Duration.ofMillis(timeoutMs)); .responseTimeout(Duration.ofMillis(timeoutMs));
@@ -46,6 +56,8 @@ public class OpenAIAnalyticsService {
.clientConnector(new ReactorClientHttpConnector(httpClient)) .clientConnector(new ReactorClientHttpConnector(httpClient))
.defaultHeader("Authorization", "Bearer " + apiKey) .defaultHeader("Authorization", "Bearer " + apiKey)
.build(); .build();
logger.info("OpenAIAnalyticsService initialized with model: {}", modelName);
} }
public MarketItem.Analytics analyzeText(String text) { public MarketItem.Analytics analyzeText(String text) {
@@ -135,7 +147,14 @@ public class OpenAIAnalyticsService {
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() { .bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
}) })
.onErrorResume(err -> { .onErrorResume(err -> {
logger.warn("OpenAI request failed: {}", err.getMessage()); logger.error("OpenAI request failed: {} - {}", err.getMessage(), err.getClass().getSimpleName());
if (err.getMessage().contains("401")) {
logger.error("OpenAI API key is invalid or expired. Please check your openai.api.key configuration.");
} else if (err.getMessage().contains("429")) {
logger.error("OpenAI API rate limit exceeded. Please try again later.");
} else if (err.getMessage().contains("500")) {
logger.error("OpenAI API server error. Please try again later.");
}
return Mono.empty(); return Mono.empty();
}) })
.block(Duration.ofMillis(timeoutMs)); .block(Duration.ofMillis(timeoutMs));
@@ -187,7 +206,14 @@ public class OpenAIAnalyticsService {
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() { .bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
}) })
.onErrorResume(err -> { .onErrorResume(err -> {
logger.warn("OpenAI request failed: {}", err.getMessage()); logger.error("OpenAI request failed: {} - {}", err.getMessage(), err.getClass().getSimpleName());
if (err.getMessage().contains("401")) {
logger.error("OpenAI API key is invalid or expired. Please check your openai.api.key configuration.");
} else if (err.getMessage().contains("429")) {
logger.error("OpenAI API rate limit exceeded. Please try again later.");
} else if (err.getMessage().contains("500")) {
logger.error("OpenAI API server error. Please try again later.");
}
return Mono.empty(); return Mono.empty();
}) })
.block(Duration.ofMillis(timeoutMs)); .block(Duration.ofMillis(timeoutMs));
+58
View File
@@ -0,0 +1,58 @@
#!/bin/bash
# Скрипт для тестирования OpenAI API ключа
echo "🔍 Тестирование OpenAI API ключа..."
# Проверяем, установлена ли переменная окружения
if [ -z "$OPENAI_API_KEY" ]; then
echo "❌ Переменная окружения OPENAI_API_KEY не установлена"
echo "Установите её командой: export OPENAI_API_KEY=sk-your-api-key-here"
exit 1
fi
# Проверяем формат ключа
if [[ ! $OPENAI_API_KEY =~ ^sk- ]]; then
echo "❌ API ключ должен начинаться с 'sk-'"
exit 1
fi
echo "✅ API ключ найден: ${OPENAI_API_KEY:0:10}..."
# Тестируем API
echo "🚀 Отправка тестового запроса к OpenAI API..."
response=$(curl -s -w "\n%{http_code}" -X POST "https://api.openai.com/v1/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Привет! Это тест API ключа. Ответь коротко."
}
],
"max_tokens": 50
}')
# Извлекаем HTTP код и тело ответа
http_code=$(echo "$response" | tail -n1)
response_body=$(echo "$response" | head -n -1)
echo "📊 HTTP код: $http_code"
if [ "$http_code" = "200" ]; then
echo "✅ API ключ работает корректно!"
echo "📝 Ответ от OpenAI:"
echo "$response_body" | jq -r '.choices[0].message.content' 2>/dev/null || echo "$response_body"
elif [ "$http_code" = "401" ]; then
echo "❌ Ошибка 401: API ключ недействителен или истек"
echo "📝 Ответ: $response_body"
elif [ "$http_code" = "429" ]; then
echo "⚠️ Ошибка 429: Превышен лимит запросов"
echo "📝 Ответ: $response_body"
else
echo "❌ Ошибка $http_code"
echo "📝 Ответ: $response_body"
fi