You are an AI risk analyst. Extract structured information from the following code for downstream risk analysis. Focus on security, data handling, API usage, error handling, and AI-specific patterns.

CODE INPUT:
{code_text}

Return ONLY valid JSON matching this exact structure. No explanation, no markdown outside the JSON block.

{{
  "components": ["major components, classes, or modules identified, e.g. 'EmailFetcher class', 'summarize() function', 'Flask route /summarize'"],
  "api_calls": ["external API calls observed, e.g. 'openai.chat.completions.create', 'gmail.users.messages.list', 'requests.post to webhook URL'"],
  "data_access_patterns": ["how data is accessed, read, written, or transmitted, e.g. 'reads full email body including attachments', 'stores raw API responses to local file', 'passes user input directly into prompt'"],
  "error_handling": ["error handling patterns observed, e.g. 'no try/catch around OpenAI API calls', 'rate limit errors caught and retried', 'all exceptions silently swallowed'"],
  "security_controls": ["security controls present or notably absent, e.g. 'API key loaded from environment variable', 'no input sanitization before prompt construction', 'no output validation after LLM response'"],
  "notable_patterns": ["other patterns relevant to AI risk, e.g. 'user-controlled text concatenated directly into system prompt', 'all inbox emails fetched without date or sender filtering', 'model response used to make a database write without review'"]
}}

Rules:
- Include only information observable in the provided code
- Use empty lists for fields with no relevant observations
- Flag absent controls (e.g. 'no rate limiting', 'no output validation') only when clearly absent from the code shown
- Do NOT infer behavior not visible in the code
- Do NOT add generic code quality observations — focus exclusively on risk-relevant patterns
- data_access_patterns and security_controls are highest priority
