Async Usage
Worker threads with bounded concurrency. V2 methods return dictionaries with success, data, billing and meta; data holds the calculation payload.
Installation
python -m pip install "vedika-sdk==3.1.0"
Run the synchronous SDK in a worker
import asyncio, json
from vedika import VedikaClient
BIRTH = {"datetime": "1990-05-15T10:30:00+05:30", "latitude": 28.6139, "longitude": 77.2090, "timezone": "Asia/Kolkata"}
def fetch_chart(birth):
client = VedikaClient(timeout=15, max_retries=0, cache_enabled=True)
try:
return client.get_birth_chart_v2("birth-chart", birth)
finally:
client.session.close()
async def main():
envelope = await asyncio.to_thread(fetch_chart, BIRTH)
print(json.dumps(envelope["data"], ensure_ascii=False))
if __name__ == "__main__":
asyncio.run(main())
Concurrent Requests
# Reuse fetch_chart and BIRTH from above; each worker owns its session.
from concurrent.futures import ThreadPoolExecutor
async def fetch_many(workers, births):
loop = asyncio.get_running_loop()
return await asyncio.gather(*(loop.run_in_executor(workers, fetch_chart, b) for b in births))
with ThreadPoolExecutor(max_workers=2) as workers:
results = asyncio.run(fetch_many(workers, [BIRTH, BIRTH]))
print([envelope["data"] for envelope in results])
Rate Limiting with Semaphore
# A concurrency cap is an application limit, not an account rate allowance.
async def fetch_with_rate_limit(births, max_concurrent=2):
semaphore = asyncio.Semaphore(max_concurrent)
async def one(birth):
async with semaphore:
return await asyncio.to_thread(fetch_chart, birth)
return await asyncio.gather(*(one(b) for b in births))
# Valid dates only; select a small authorized batch before sending.
charts = asyncio.run(fetch_with_rate_limit([BIRTH, BIRTH]))
Async Streaming
def collect_stream():
client = VedikaClient(timeout=15, max_retries=0)
try:
return list(client.ask_question_stream("Explain the chart's main themes.", BIRTH))
finally:
client.session.close()
async def stream_response():
for payload in await asyncio.to_thread(collect_stream):
print(payload) # Raw SSE data strings, not typed event objects
# asyncio.run(stream_response()) # Sends a billable query when explicitly run
FastAPI Integration
# Reuse fetch_chart; install FastAPI separately in your server application.
from fastapi import FastAPI, HTTPException
from vedika import VedikaAPIError
app = FastAPI()
@app.post("/chart")
async def get_chart(birth: dict):
try:
return await asyncio.to_thread(fetch_chart, birth)
except VedikaAPIError:
raise HTTPException(502, "Calculation could not be completed.") from None
def fetch_match(male, female):
client = VedikaClient(timeout=15, max_retries=0)
try:
return client.get_guna_milan(male, female)
finally:
client.session.close()
@app.post("/match")
async def match_charts(male: dict, female: dict):
try:
return await asyncio.to_thread(fetch_match, male, female)
except VedikaAPIError:
raise HTTPException(502, "Matching could not be completed.") from None
Async Error Handling
from vedika import AuthenticationError, RateLimitError, VedikaAPIError
async def guarded_fetch(birth):
try:
return await asyncio.to_thread(fetch_chart, birth)
except (AuthenticationError, RateLimitError, VedikaAPIError):
# Keep upstream details in protected diagnostics; do not retry blindly.
print("Request failed; review the account configuration and limits.")
raise
Validation, stored charts and cache isolation
Authenticate the caller and verify stored-chart ownership before loading birth details. Validate required fields, datetime and coordinate ranges before scheduling a billable request. Scope application caches by owner, stored-chart id, inputs, options and language; never share results across owners. SDK cache_enabled controls prompt caching, not stored-chart storage. Workers close their own sessions; timeout and zero retries bound each call. Cancellation does not stop an already-running worker.