Free lesson · GenAI Agent Engineering
Gemini API ని కాల్ చేసి structured responses ను తిరిగి ఇచ్చే Python app ను రాయండి
platform proxy ద్వారా Gemini API కి prompts పంపి, response ను format చేసే Python CLI application ను నిర్మించండి. ఈ chapter అంతటా మీరు containerize చేయబోయే app ఇదే.
Course: Kubernetes Essentials for GenAI Engineers · Chapter 1 · Containerizing LLM Applications
Free to read — no subscription required.
పరిచయం
మొదటిసారి ఒక Python సర్వీస్ను Gemini API కి కనెక్ట్ చేసేటప్పుడు, API కీని ఒక కాన్స్టంట్లో పెట్టి, రిక్వెస్ట్ను రూట్ హ్యాండ్లర్లో పేస్ట్ చేసి, షిప్ చేయాలనే ఆకర్షణ ఉంటుంది. అది ఒకసారి పనిచేస్తుంది — దాన్ని డిప్లాయ్ చేయవలసి వచ్చే వరకు. హార్డ్కోడ్ చేసిన సీక్రెట్లు కంటెయినరైజ్ చేసిన క్షణమే విరిగిపోతాయి, యాదృచ్ఛిక ఎర్రర్ హ్యాండ్లింగ్ Gemini లో వచ్చే ప్రతి చిన్న అంతరాయాన్నీ 500 లా కనిపించేలా చేస్తుంది, మరియు ప్రతి రిక్వెస్ట్కీ క్లయింట్ను కొత్తగా ఇనిషియలైజ్ చేయడం ప్రతి కాల్పై లేటెన్సీని వృథా చేస్తుంది. ఈ క్రమశిక్షణను దాటవేసే టీమ్లు చివరికి ఒక కీని రొటేట్ చేయడానికే ఇమేజ్ను మళ్లీ బిల్డ్ చేయవలసి వస్తుంది, మరియు స్థిరమైన ఎర్రర్ ఆకారం లేని అడపాదడపా వైఫల్యాల వెంట పరుగెత్తవలసి వస్తుంది.
ఈ పాఠం ముగిసేసరికి, మీరు ఎన్విరాన్మెంట్ వేరియబుల్స్ నుండి Gemini కాన్ఫిగరేషన్ను లోడ్ చేసే, FastAPI యొక్క lifespan హుక్ ద్వారా క్లయింట్ను ఖచ్చితంగా ఒకే సారి ఇనిషియలైజ్ చేసే, Gemini API కి ప్రాంప్ట్లను పంపే, మరియు ఊహించదగిన ఎర్రర్ సెమాంటిక్స్తో స్ట్రక్చర్డ్ JSON రెస్పాన్స్లను తిరిగి ఇచ్చే Python అప్లికేషన్ను రాయగలుగుతారు — తదుపరి పాఠంలో నేరుగా కంటెయినర్లో పెట్టడానికి సిద్ధంగా.
ముఖ్య పదజాలం
- Gemini API — Gemini కుటుంబానికి చెందిన లార్జ్ లాంగ్వేజ్ మోడల్స్ కోసం Google యొక్క HTTPS ఎండ్పాయింట్. ఈ పాఠంలోని అప్లికేషన్ దానికి ఒక ప్రాంప్ట్ పంపి, జనరేట్ అయిన టెక్స్ట్ను తిరిగి ఇస్తుంది; దాని రిక్వెస్ట్/రెస్పాన్స్ ఆకారం తెలుసుకోవడమే కింద ఉన్న ర్యాపర్ కోడ్ను అర్థవంతం చేస్తుంది.
- google-generativeai — Gemini HTTP API ని ర్యాప్ చేసే అధికారిక Python SDK, ప్రాంప్ట్-ఇన్ / టెక్స్ట్-అవుట్ కాల్స్ కోసం
GenerativeModel.generate_contentను అందిస్తుంది. కింద ఉన్నGeminiClientక్లాస్ దానిపై ఒక సన్నని పొర. - FastAPI — బాహ్య కాలర్లు Gemini SDK ని నేరుగా ఉపయోగించకుండా HTTP ద్వారా ప్రాంప్ట్లను సబ్మిట్ చేయగలిగేలా
/generateఎండ్పాయింట్ను ఎక్స్పోజ్ చేయడానికి ఇక్కడ ఉపయోగించిన async Python వెబ్ ఫ్రేమ్వర్క్. - Pydantic BaseSettings — ఎన్విరాన్మెంట్ వేరియబుల్స్ నుండి Gemini API కీ, మోడల్ పేరు, మరియు టైమ్అవుట్ను చదివే కాన్ఫిగరేషన్ లోడర్; ఏదైనా అవసరమైన విలువ లేకపోతే స్టార్టప్లోనే వెంటనే ఫెయిల్ అవుతుంది.
- lifespan context — యాప్ జీవితకాలం చుట్టూ సెటప్ మరియు టియర్డౌన్ను నడిపే FastAPI హుక్. ప్రతి రిక్వెస్ట్పై కాకుండా స్టార్టప్లో ఒకే సారి Gemini క్లయింట్ను నిర్మించడానికి ఇక్కడ ఉపయోగించబడింది.
భావనలు
లేయర్డ్ ఆర్కిటెక్చర్
సర్వీస్ మూడు లేయర్లుగా విడిపోతుంది, ప్రతి ఒక్కటికీ దాని సొంత కాన్ఫిగరేషన్ బాధ్యత ఉంటుంది. FastAPI HTTP మరియు Pydantic వాలిడేషన్ను నిర్వహిస్తుంది; ఒక GeminiClient క్లాస్ API కమ్యూనికేషన్ మరియు ఎర్రర్ అనువాదాన్ని సొంతం చేసుకుంటుంది; ఒక Settings మాడ్యూల్ ఎన్విరాన్మెంట్ వేరియబుల్స్ నుండి కాన్ఫిగరేషన్ను లోడ్ చేస్తుంది. ఈ విభజన సీక్రెట్ (API కీ) ను రిక్వెస్ట్-హ్యాండ్లింగ్ లాజిక్ నుండి వేరు చేస్తుంది, మరియు కోడ్ను తాకకుండానే కాల్ ఆకారాన్ని (టైమ్అవుట్, మాక్స్ టోకెన్లు) ట్యూన్ చేయడానికి అనుమతిస్తుంది.
వాలిడేషన్ ఇన్పుట్ను తిరస్కరిస్తే — ప్రాంప్ట్ లేకపోవడం, ఖాళీ స్ట్రింగ్, పరిమితిని మించిన ప్రాంప్ట్ — ఏ Gemini కాల్ జరగకముందే FastAPI 422 ను తిరిగి ఇస్తుంది, ఇది కోటా వినియోగాన్ని ఊహించదగినదిగా ఉంచుతుంది.
ఎన్విరాన్మెంట్ వేరియబుల్స్ ద్వారా కాన్ఫిగరేషన్
pydantic_settings నుండి వచ్చే BaseSettings ప్రతి కాన్ఫిగ్ ఫీల్డ్ను ఒక టైప్, ఒక డిఫాల్ట్, మరియు సంఖ్యా పరిధి వాలిడేటర్లతో డిక్లేర్ చేస్తుంది. స్టార్టప్లో ఇది ఎన్విరాన్మెంట్ వేరియబుల్స్ నుండి వాస్తవ విలువలను చదువుతుంది, డెవలప్మెంట్లో .env ఫైల్కు ఫాల్బ్యాక్ అవుతుంది. అవసరమైన ఫీల్డ్లు తమ డిఫాల్ట్గా ... ను ఉపయోగిస్తాయి, అందువల్ల GEMINI_API_KEY లేకపోతే మొదటి రిక్వెస్ట్పై అస్పష్టమైన రన్టైమ్ ఎర్రర్ ఇవ్వడానికి బదులు స్టార్టప్ వెంటనే ఫెయిల్ అవుతుంది. (కోడ్ వాక్త్రూ చూడండి.)
Lifespan-నిర్వహిత క్లయింట్ ఇనిషియలైజేషన్
FastAPI యొక్క lifespan async కాంటెక్స్ట్ మేనేజర్ యాప్ జీవితకాలం చుట్టూ ఒకే సారి నడుస్తుంది. ఉదాహరణ దీన్ని ఒక GeminiClient ను నిర్మించి app.state పై భద్రపరచడానికి ఉపయోగిస్తుంది. ప్రతి రిక్వెస్ట్ ప్రతి కాల్పై మళ్లీ ఇనిషియలైజ్ చేయడానికి బదులు ఆ క్లయింట్ను — మరియు SDK యొక్క అంతర్లీన కనెక్షన్ పూల్ను — తిరిగి ఉపయోగిస్తుంది. దీని అర్థం క్రెడెన్షియల్ వైఫల్యాలు యూజర్ ట్రాఫిక్ సమయంలో కాకుండా స్టార్టప్లోనే బయటపడతాయి.
సరిహద్దు వద్ద ఎర్రర్ అనువాదం
Gemini SDK నెట్వర్క్ టైమ్అవుట్లు, ఆథ్ వైఫల్యాలు, మరియు రేట్ లిమిట్లపై ఎక్సెప్షన్ త్రో చేయవచ్చు. generate మెథడ్ కాల్ను try/except లో ర్యాప్ చేసి HTTPException(502) గా మళ్లీ రైజ్ చేస్తుంది, ప్రతి SDK వైఫల్య రీతినీ ఒకే ఊహించదగిన HTTP రెస్పాన్స్కు మ్యాప్ చేస్తుంది. Gemini ఎలాంటి parts లేని రెస్పాన్స్ను తిరిగి ఇచ్చే సందర్భాన్ని (సాధారణంగా సేఫ్టీ-ఫిల్టర్ చేసిన అవుట్పుట్) ఒక ప్రత్యేక గార్డ్ నిర్వహిస్తుంది, మరియు SDK యొక్క అస్పష్టమైన ValueError కి బదులు స్పష్టమైన సందేశంతో అదే 502 ను ఇస్తుంది.
కోడ్ వాక్త్రూ
ఈ వాక్త్రూ నాలుగు భావనలను కలిపి ప్రదర్శిస్తుంది: BaseSettings ద్వారా ఎన్విరాన్మెంట్-ఆధారిత కాన్ఫిగరేషన్, lifespan-బూట్స్ట్రాప్ చేసిన క్లయింట్ ఇనిషియలైజేషన్, రిక్వెస్ట్ వాలిడేషన్, మరియు సరిహద్దు వద్ద ఎర్రర్ అనువాదం. మొదటి స్నిపెట్ Settings ను డిక్లేర్ చేస్తుంది; రెండవది దాన్ని ఒక GeminiClient తో FastAPI యాప్లోకి కనెక్ట్ చేస్తుంది.
Code snippetpython
1# settings.py 2from functools import lru_cache 3 4from pydantic import Field 5from pydantic_settings import BaseSettings, SettingsConfigDict 6 7class Settings(BaseSettings): 8 model_config = SettingsConfigDict(env_file=".env", case_sensitive=False) 9 10 gemini_api_key: str = Field(..., description="API key for Gemini") 11 gemini_model: str = Field(default="gemini-1.5-flash") 12 request_timeout: int = Field(default=30, ge=5, le=120) 13 max_output_tokens: int = Field(default=1024, ge=1, le=8192) 14 temperature: float = Field(default=0.7, ge=0.0, le=2.0) 15 16@lru_cache 17def get_settings() -> Settings: 18 return Settings()
gemini_api_key తన డిఫాల్ట్గా ... ను ఉపయోగిస్తుంది, ఇది దాన్ని అవసరమైనదిగా చేస్తుంది — GEMINI_API_KEY సెట్ చేయకపోతే యాప్ స్టార్టప్లోనే వెంటనే ఫెయిల్ అవుతుంది. ge/le వాలిడేటర్లు చెల్లని సంఖ్యా విలువలు Gemini కి చేరకముందే వాటిని నిరోధిస్తాయి. @lru_cache ప్రాసెస్ అంతటా ఒకే షేర్డ్ Settings ఇన్స్టాన్స్ ఉండేలా చూస్తుంది.
Code snippetpython
1# main.py 2from contextlib import asynccontextmanager 3 4import google.generativeai as genai 5from fastapi import FastAPI, HTTPException 6from pydantic import BaseModel, Field 7 8from settings import get_settings 9 10class PromptRequest(BaseModel): 11 prompt: str = Field(..., min_length=1, max_length=10000) 12 temperature: float | None = Field(default=None, ge=0.0, le=2.0) 13 14class GeminiClient: 15 def __init__(self, settings): 16 genai.configure(api_key=settings.gemini_api_key) 17 self._model = genai.GenerativeModel(settings.gemini_model) 18 self._settings = settings 19 20 def generate(self, prompt: str, temperature: float | None = None) -> dict: 21 config = genai.types.GenerationConfig( 22 max_output_tokens=self._settings.max_output_tokens, 23 temperature=temperature or self._settings.temperature, 24 ) 25 try: 26 response = self._model.generate_content( 27 prompt, 28 generation_config=config, 29 request_options={"timeout": self._settings.request_timeout}, 30 ) 31 except Exception as exc: 32 raise HTTPException(status_code=502, detail=str(exc)) from exc 33 34 if not response.parts: 35 raise HTTPException(status_code=502, detail="Empty response from Gemini") 36 37 return { 38 "model": self._settings.gemini_model, 39 "prompt": prompt, 40 "generated_text": response.text, 41 } 42 43@asynccontextmanager 44async def lifespan(app: FastAPI): 45 app.state.client = GeminiClient(get_settings()) 46 yield 47 48app = FastAPI(title="Gemini LLM Service", lifespan=lifespan) 49 50@app.post("/generate") 51async def generate_text(request: PromptRequest): 52 return app.state.client.generate( 53 prompt=request.prompt, 54 temperature=request.temperature, 55 ) 56 57@app.get("/health") 58async def health_check(): 59 return {"status": "healthy"}
PromptRequest అంచు వద్దనే 1 నుండి 10,000 అక్షరాల ప్రాంప్ట్ను అమలు చేస్తుంది, అందువల్ల ఖాళీ లేదా మితిమీరిన పరిమాణం గల రిక్వెస్ట్ ఎప్పుడూ Gemini కి చేరదు. lifespan కాంటెక్స్ట్ స్టార్టప్లో ఒకే సారి GeminiClient ను నిర్మించి app.state పై నిల్వ చేస్తుంది. generate లోపల, try/except ఏదైనా SDK ఎక్సెప్షన్ను HTTP 502 గా అనువదిస్తుంది, మరియు response.parts చెక్ .text ఎర్రర్ రైజ్ చేయకముందే సేఫ్టీ-ఫిల్టర్ చేసిన సందర్భాన్ని పట్టుకుంటుంది. /health ఎండ్పాయింట్ Gemini ని కాల్ చేయకుండా తిరిగి ఇస్తుంది, కంటెయినర్ ప్రోబ్లకు చౌకైన లక్ష్యాన్ని అందిస్తుంది.
GEMINI_API_KEY ను ఎక్స్పోర్ట్ చేసి uvicorn main:app --reload రన్ చేసిన తర్వాత, Content-Type: application/json మరియు బాడీ {"prompt":"Say hello in one short sentence."} తో http://localhost:8000/generate కి POST చేసినప్పుడు ఖాళీ కాని generated_text ఫీల్డ్తో 200 తిరిగి వస్తే, అది పనిచేస్తుందని మీకు తెలుస్తుంది.
కోసం ఆచరణలో
పైన ఉన్న నమూనా — ఎన్విరాన్మెంట్-ఆధారిత కాన్ఫిగ్, lifespan-బూట్స్ట్రాప్ చేసిన క్లయింట్, అంచు వద్ద వాలిడేషన్, సరిహద్దు వద్ద ఎర్రర్ అనువాదం — Gemini-ఆధారిత ఏ Python సర్వీస్కైనా వర్తిస్తుంది. దాన్ని ఎలా విస్తరిస్తారనేది మీరు ఏ రోల్ కోసం నిర్మిస్తున్నారనే దానిపై ఆధారపడి ఉంటుంది.
చేయవలసినవి మరియు చేయకూడనివి
చేయవలసినవి
- API కీని ఎన్విరాన్మెంట్ వేరియబుల్ నుండి లోడ్ చేయండి — సీక్రెట్ను సోర్స్ కంట్రోల్ బయట ఉంచుతుంది మరియు ఇమేజ్ను మళ్లీ బిల్డ్ చేయకుండా ప్రతి ఎన్విరాన్మెంట్కీ కీలను మార్చుకోవడానికి అనుమతిస్తుంది.
- Gemini క్లయింట్ను lifespan హుక్లో ఒకే సారి ఇనిషియలైజ్ చేయండి — SDK యొక్క కనెక్షన్ పూల్ను తిరిగి ఉపయోగిస్తుంది మరియు క్రెడెన్షియల్ వైఫల్యాలను ట్రాఫిక్ మధ్యలో కాకుండా స్టార్టప్లోనే బయటపెడుతుంది.
- SDK ఎక్సెప్షన్లను HTTP 502 గా అనువదించండి — అంతర్లీన సమస్య టైమ్అవుట్ అయినా, ఆథ్ వైఫల్యం అయినా, లేదా రేట్ లిమిట్ అయినా కాలర్లకు ఒకే ఊహించదగిన వైఫల్య రీతిని ఇస్తుంది.
చేయకూడనివి
- API కీని లేదా మోడల్ పేరును హార్డ్కోడ్ చేయకండి — ప్రతి ఎన్విరాన్మెంట్ మార్పూ ఇమేజ్ రీబిల్డ్ అవుతుంది, మరియు లీక్ అయిన ఇమేజ్ ప్రొడక్షన్ క్రెడెన్షియల్స్ను లీక్ చేస్తుంది.
- ముందుగా
response.partsను చెక్ చేయకుండాresponse.textను కాల్ చేయకండి — సేఫ్టీ-ఫిల్టర్ చేసిన Gemini రెస్పాన్స్ parts లేని చెల్లుబాటు అయ్యే ఆబ్జెక్ట్, మరియు.textఅస్పష్టమైనValueErrorను రైజ్ చేస్తుంది. - లైవ్నెస్ ప్రోబ్ల కోసం
/generateఎండ్పాయింట్ను తిరిగి ఉపయోగించకండి — ప్రతి ప్రోబ్ Gemini కోటాను వృథా చేస్తుంది; API ని కాల్ చేయకుండా తిరిగి ఇచ్చే ప్రత్యేక/healthరూట్ను ఎక్స్పోజ్ చేయండి.
A hands-on lab comes with this lesson — real code, in a cloud IDE. Create a free account to run it. No card.
Free account · no card · straight to the lab
Or get the full path — from
Listen to this lesson
Audio overviews of this lesson's labs and its chapter, from GenBodha Bytes.
- Structured Text Report GeneratorLab5 min
- Containerizing LLM ApplicationsChapter overview23 min
More free lessons in Kubernetes Essentials for GenAI Engineers
- Ch 1Write a Python app that calls the Gemini API and returns structured responsesYou are here
- Ch 1Write a Dockerfile and build a container image for the LLM app
- Ch 1Use Docker Compose to run the LLM app with supporting services
- Ch 2Deploy the LLM app as your first Kubernetes pod
- Ch 4Manage deployment lifecycle with kubectl rollout
- Ch 9Create a Helm chart for the LLM chat application
- Ch 9Use Kustomize bases and overlays for the LLM app