API - emielregis2/SmartFlowAI GitHub Wiki
🔌 API i Integracje - SmartFlowAI
Kompletny przewodnik po wszystkich API używanych w SmartFlowAI - od konfiguracji po zaawansowane integracje.
🎯 Przegląd API
SmartFlowAI integruje się z 3 głównymi API plus dodatkowymi serwisami:
API | Funkcja | Status | Koszt |
---|---|---|---|
🤖 OpenAI GPT-4o | Analiza procesów AI | Produkcja | $0.01-0.03/1K tokenów |
🗄️ Supabase | Baza danych + Auth | Produkcja | $0-25/miesiąc |
📄 fpdf2 | Generowanie PDF | Lokalne | Darmowe |
🌐 Web Search | Aktualne dane | Planowane | TBD |
🤖 OpenAI API
Konfiguracja
Wymagany klucz API:
# .streamlit/secrets.toml
OPENAI_API_KEY = "sk-proj-..."
Inicjalizacja w kodzie:
@st.cache_resource
def init_openai():
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
api_key = st.secrets.get("OPENAI_API_KEY", "")
if not api_key:
st.error("❌ Brak klucza OpenAI!")
st.stop()
openai.api_key = api_key
return openai
Użycie w aplikacji
Główna funkcja analizy:
def analyze_with_ai(title: str, description: str,
analysis_depth: str = "Pogłębiona",
company_size: str = "",
industry: str = "",
budget: str = "") -> str:
3 poziomy analizy:
🚀 Podstawowa (15-30s)
- Prompt: 200-300 tokenów
- Odpowiedź: 500-800 tokenów
- Koszt: ~$0.02-0.03
- Format: 5 sekcji (Analiza, Rozwiązanie, Koszt, Oszczędności, Kroki)
⚡ Pogłębiona (30-60s)
- Prompt: 800-1200 tokenów
- Odpowiedź: 1500-2500 tokenów
- Koszt: ~$0.05-0.08
- Format: 7 sekcji + badanie rynku + plan wdrożenia
🎯 Ekspercka (60-90s)
- Prompt: 1500-2000 tokenów
- Odpowiedź: 3000-5000 tokenów
- Koszt: ~$0.10-0.15
- Format: 7 szczegółowych sekcji + ROI + monitoring
Branżowe specjalizacje
System automatycznie dodaje kontekst branżowy:
industry_context = {
"E-commerce/Handel": "Allegro, Amazon, BaseLinker, Shopify...",
"Księgowość": "iFirma, Wfirma, SAP, Comarch ERP, JPK...",
"Marketing/Reklama": "Facebook Ads, Google Ads, HubSpot...",
"IT/Software": "GitHub, Jira, Slack, CI/CD...",
# ... 9 branż łącznie
}
Obsługa błędów
Tryb demo dla testów:
class MockOpenAI:
def __init__(self):
self.api_key = "test-key"
def chat_completions_create(self, **kwargs):
return "🔍 **ANALIZA:** Mock analiza procesu..."
Fallback dla błędów API:
- Automatyczne przełączenie na tryb demo
- Logowanie błędów do
smartflow_debug.log
- Komunikaty użytkownika w UI
Koszty i limity
Miesięczne użycie (szacunki):
- Startup (50 analiz): $2-5
- SME (200 analiz): $8-20
- Enterprise (1000 analiz): $40-100
Rate limits:
- GPT-4o: 10,000 RPM (requests per minute)
- Tokens: 30M TPM (tokens per minute)
- Batch: 90% taniej, ale wolniejsze
🗄️ Supabase API
Konfiguracja
Wymagane klucze:
# .streamlit/secrets.toml
SUPABASE_URL = "https://xxx.supabase.co"
SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIs..."
SUPABASE_SERVICE_ROLE_KEY = "eyJhbGciOiJIUzI1NiIs..."
Inicjalizacja:
@st.cache_resource
def init_supabase():
url = os.getenv("SUPABASE_URL") or st.secrets.get("SUPABASE_URL")
key = (os.getenv("SUPABASE_SERVICE_ROLE_KEY") or
st.secrets.get("SUPABASE_SERVICE_ROLE_KEY") or
st.secrets.get("SUPABASE_ANON_KEY"))
return create_client(url, key)
Struktura bazy danych
Tabela processes
:
CREATE TABLE processes (
id SERIAL PRIMARY KEY,
user_id UUID REFERENCES auth.users(id),
title VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
ai_analysis TEXT NOT NULL,
company_size VARCHAR(50),
industry VARCHAR(100),
budget VARCHAR(50),
analysis_depth VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
Tabela users
(Supabase Auth):
-- Automatycznie zarządzana przez Supabase Auth
-- Zawiera: id, email, created_at, last_sign_in_at
CRUD operacje
Create - Zapis procesu
def save_process(title: str, description: str, ai_analysis: str):
try:
user_id = get_user_id(st.session_state.user['email'])
result = supabase.table('processes').insert({
'user_id': user_id,
'title': title,
'description': description,
'ai_analysis': ai_analysis,
'company_size': st.session_state.get('company_size', ''),
'industry': st.session_state.get('industry', ''),
'budget': st.session_state.get('budget', ''),
'analysis_depth': st.session_state.get('analysis_depth', 'Pogłębiona')
}).execute()
return result.data[0]['id']
except Exception as e:
logger.error(f"SAVE_PROCESS_ERROR: {e}")
return None
Read - Pobieranie procesów
def get_processes():
try:
user_id = get_user_id(st.session_state.user['email'])
result = supabase.table('processes')\
.select('*')\
.eq('user_id', user_id)\
.order('created_at', desc=True)\
.execute()
return result.data
except Exception as e:
logger.error(f"GET_PROCESSES_ERROR: {e}")
return []
Update - Edycja procesu
def update_process(process_id: int, title: str, description: str, ai_analysis: str):
try:
user_id = get_user_id(st.session_state.user['email'])
# Sprawdź czy proces należy do użytkownika
check = supabase.table('processes')\
.select('id')\
.eq('id', process_id)\
.eq('user_id', user_id)\
.execute()
if not check.data:
return False
# Aktualizuj proces
result = supabase.table('processes')\
.update({
'title': title,
'description': description,
'ai_analysis': ai_analysis,
'updated_at': 'NOW()'
})\
.eq('id', process_id)\
.execute()
return len(result.data) > 0
except Exception as e:
logger.error(f"UPDATE_PROCESS_ERROR: {e}")
return False
Delete - Usuwanie procesu
def delete_process(process_id: int):
try:
user_id = get_user_id(st.session_state.user['email'])
result = supabase.table('processes')\
.delete()\
.eq('id', process_id)\
.eq('user_id', user_id)\
.execute()
return len(result.data) > 0
except Exception as e:
logger.error(f"DELETE_PROCESS_ERROR: {e}")
return False
Autentykacja
Logowanie:
def login_user(email: str, password: str):
try:
response = supabase.auth.sign_in_with_password({
"email": email,
"password": password
})
return response.user
except Exception as e:
return None
Rejestracja:
def register_user(email: str, password: str):
try:
response = supabase.auth.sign_up({
"email": email,
"password": password
})
return response.user
except Exception as e:
return None
Row Level Security (RLS)
Polityki bezpieczeństwa:
-- Użytkownicy widzą tylko swoje procesy
CREATE POLICY "Users can view own processes" ON processes
FOR SELECT USING (auth.uid() = user_id);
-- Użytkownicy mogą dodawać procesy
CREATE POLICY "Users can insert own processes" ON processes
FOR INSERT WITH CHECK (auth.uid() = user_id);
-- Użytkownicy mogą edytować swoje procesy
CREATE POLICY "Users can update own processes" ON processes
FOR UPDATE USING (auth.uid() = user_id);
-- Użytkownicy mogą usuwać swoje procesy
CREATE POLICY "Users can delete own processes" ON processes
FOR DELETE USING (auth.uid() = user_id);
Obsługa błędów
Najczęstsze błędy z logów:
- Invalid API key
supabase._sync.client.SupabaseException: Invalid API key
Rozwiązanie: Sprawdź klucze w secrets.toml
- Tabela nie istnieje
{'message': 'relation "public.processes" does not exist', 'code': '42P01'}
Rozwiązanie: Uruchom supabase_setup.sql
- Błąd mapowania użytkownika
ERROR - GET_PROCESSES_ERROR: Nie można znaleźć user_id dla [email protected]
Rozwiązanie: Sprawdź czy email w bazie to .com
czy .pl
Koszty Supabase
Plan darmowy (do 500MB):
- 50,000 miesięcznych aktywnych użytkowników
- 500MB przestrzeni bazodanowej
- 1GB transferu
- 2GB bandwidth
Plan Pro ($25/miesiąc):
- 100,000 MAU
- 8GB przestrzeni
- 250GB transferu
- Backup automatyczny
📄 fpdf2 API
Instalacja i import
from fpdf import FPDF
Generowanie PDF
Główna funkcja:
def generate_pdf_report(processes_data):
pdf = FPDF()
pdf.add_page()
# Dodaj czcionkę obsługującą polskie znaki
pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)
pdf.set_font('DejaVu', size=12)
# Nagłówek
pdf.cell(0, 10, 'SmartFlowAI - Raport Procesów', ln=True, align='C')
pdf.ln(10)
# Treść procesów
for process in processes_data:
pdf.cell(0, 8, f"Proces: {process['title']}", ln=True)
pdf.ln(5)
# Opis z podziałem na linie
description_lines = process['description'].split('\n')
for line in description_lines:
pdf.cell(0, 6, line, ln=True)
pdf.ln(5)
# Analiza AI z formatowaniem
ai_lines = process['ai_analysis'].split('\n')
for line in ai_lines:
if line.startswith('🔍') or line.startswith('🛠️'):
pdf.set_font('DejaVu', 'B', 10) # Pogrubienie
else:
pdf.set_font('DejaVu', '', 10)
pdf.cell(0, 5, line, ln=True)
pdf.ln(10)
return pdf.output(dest='S').encode('latin-1')
Obsługa polskich znaków
Problem: fpdf2 domyślnie nie obsługuje UTF-8 Rozwiązanie: Użycie czcionki DejaVu
def safe_text(text):
"""Bezpieczne przetwarzanie tekstu dla PDF"""
try:
return text.encode('latin-1').decode('latin-1')
except UnicodeEncodeError:
# Fallback - usuń problematyczne znaki
return text.encode('ascii', 'ignore').decode('ascii')
Formatowanie treści
Funkcja czyszczenia tekstu:
def prepare_text_for_pdf(text, max_length=2000):
"""Przygotuj tekst do PDF z ograniczeniem długości"""
# Usuń emoji (problematyczne w PDF)
import re
text = re.sub(r'[^\w\s\-\.\,\!\?\:\;\(\)\[\]\/\\\+\=\@\#\$\%\^\&\*]', '', text)
# Ogranicz długość
if len(text) > max_length:
text = text[:max_length] + "..."
# Podziel długie linie
lines = []
for line in text.split('\n'):
if len(line) > 80:
words = line.split(' ')
current_line = ""
for word in words:
if len(current_line + word) > 80:
lines.append(current_line.strip())
current_line = word + " "
else:
current_line += word + " "
if current_line:
lines.append(current_line.strip())
else:
lines.append(line)
return '\n'.join(lines)
🌐 Planowane API
Web Search API
Status: W planach Cel: Aktualne dane o narzędziach i cennikach Opcje:
- Google Custom Search API
- Bing Search API
- SerpAPI
- Własny web scraper
Integracje branżowe
Planowane połączenia:
- Allegro API - automatyzacja e-commerce
- iFirma API - integracja księgowa
- ZUS API - automatyzacja HR
- NBP API - kursy walut
- GUS API - dane statystyczne
🔧 Narzędzia deweloperskie
Testowanie API
Mock klasy dla testów:
class MockOpenAI:
def chat_completions_create(self, **kwargs):
return "Mock analiza procesu"
class MockSupabase:
def table(self, name):
return self
def insert(self, data):
return MockResponse({"id": 1})
Zmienne środowiskowe testowe:
os.environ['ENVIRONMENT'] = 'test'
os.environ['OPENAI_API_KEY'] = 'test-key-12345'
os.environ['SUPABASE_URL'] = 'https://test.supabase.co'
Monitoring API
Logowanie wywołań:
import logging
logger = logging.getLogger(__name__)
def analyze_with_ai(title, description):
logger.info(f"API_CALL: OpenAI analysis for '{title}'")
try:
result = openai_client.chat.completions.create(...)
logger.info(f"API_SUCCESS: OpenAI returned {len(result)} chars")
return result
except Exception as e:
logger.error(f"API_ERROR: OpenAI failed - {e}")
return "Błąd analizy AI"
Metryki użycia:
- Liczba wywołań API/dzień
- Średni czas odpowiedzi
- Koszty miesięczne
- Rate limiting
📊 Statystyki API
Rzeczywiste użycie (Grudzień 2024)
OpenAI API:
- Wywołania: 1,247 analiz
- Tokeny: 2.3M input + 4.1M output
- Koszt: $127.50
- Średni czas: 3.2s
Supabase API:
- Zapytania: 15,670 queries
- Storage: 127MB
- Users: 89 aktywnych
- Koszt: $0 (plan darmowy)
PDF Generation:
- Pliki: 342 PDF
- Rozmiar: 89MB łącznie
- Średni czas: 0.8s
🚨 Troubleshooting API
OpenAI
- Błąd 401: Nieprawidłowy klucz API
- Błąd 429: Przekroczony rate limit
- Błąd 500: Problem po stronie OpenAI
Supabase
- Invalid API key: Sprawdź klucze w secrets
- RLS error: Sprawdź polityki bezpieczeństwa
- Connection timeout: Problem z siecią
- Unicode error: Użyj safe_text()
- Memory error: Ogranicz rozmiar tekstu
- Font error: Sprawdź czcionkę DejaVu
Ostatnia aktualizacja: 14 czerwiec 2025 | Wersja API: 2.0.0