tathaastu 0.1.0
tathaastu: ^0.1.0 copied to clipboard
Hindu calendar intelligence for Dart and Flutter: panchang, festivals and muhurat, with the rule and confidence behind every answer.
tathaastu #
Hindu calendar intelligence for Dart and Flutter: panchang, festivals and muhurat, with the rule and confidence behind every answer.
Generated from the OpenAPI 3.1 document that serves the API, so the client cannot drift from the endpoints it wraps. The namespaces and method names mirror the Python and TypeScript SDKs — a team using more than one should not have to learn more than one client.
Install #
flutter pub add tathaastu
Or for a plain Dart project:
dart pub add tathaastu
First call, no signup #
The /v1/demo/ endpoints are public. This runs the moment the package is
installed:
import 'package:tathaastu/tathaastu.dart';
Future<void> main() async {
final client = TathaAstu();
final day = await client.demo.panchangGet(date: '2026-11-08');
print(day['tithi']['name']); // Chaturdashi (14th)
client.close();
}
With a key #
Everything else needs one. It is read from TATHAASTU_API_KEY unless you pass
it — passing keys as literals is how they end up in git.
final client = TathaAstu(apiKey: 'sk_live_...');
final day = await client.panchang.get(date: '2026-11-08', locationId: 1);
final festivals = await client.festivals.list(date: '2026-11-08', locationId: 1);
Ask why #
The reason this SDK exists. Every festival carries the rule that produced it:
final why = await client.festivals.explain(
date: '2026-11-08',
festival: 'FESTIVAL_DIWALI',
);
print(why['human_readable']);
Errors #
Status codes map to distinct exceptions, because the fixes differ:
| Exception | Status | What to do |
|---|---|---|
AuthenticationException |
401 | Check TATHAASTU_API_KEY |
PlanException |
402 | The request was valid; your plan excludes this endpoint. Upgrade. |
ValidationException |
400, 422 | .fields names the offending parameters |
RateLimitException |
429 | .retryAfterSeconds when the server supplies it |
NotFoundException |
404 | No data for that input |
ServerException |
5xx | Retried automatically before it reaches you |
PlanException is deliberately not a subclass of
AuthenticationException. A 402 is not an auth problem, and treating it as one
sends you looking at the wrong thing.
try {
await client.timings.horaGet(date: '2026-11-08', lat: 28.6139, lon: 77.2090);
} on PlanException catch (e) {
print('Upgrade needed: ${e.message}');
} on RateLimitException catch (e) {
print('Back off for ${e.retryAfterSeconds}s');
} on TathaAstuException catch (e) {
print('${e.statusCode}: ${e.message}');
}
Every exception descends from TathaAstuException, so one on clause catches
the lot if that is all you need.
Flutter #
The package is pure Dart with one dependency (http), so it runs on Flutter
mobile, Flutter web and server-side Dart alike. It ships no widgets: what you
render is your design system's business, not this package's.
On Flutter web, do not embed an API key. Anything in a client bundle is public and a leaked key is billable to you. Call your own backend and let it hold the key:
final client = TathaAstu(baseUrl: 'https://your-app.example/api/tathaastu');
TathaAstu() reads TATHAASTU_API_KEY from the environment where one exists;
on web there is no environment to read, so the key stays empty and only the
public endpoints work — which is the safe default.
Configuration #
final client = TathaAstu(
apiKey: '...',
baseUrl: 'https://api.tathaastuapi.com',
timeout: const Duration(seconds: 15),
retry: const RetryPolicy(attempts: 3),
);
Retries apply to 5xx and 429 only, with exponential backoff, jitter, and
Retry-After honoured when the server sends it. Retrying a 4xx cannot
succeed and would just double the load caused by a bug.
Rate-limit headers from the last response are on client.rateLimit.
Call client.close() when you are done, or pass your own http.Client and
manage its lifetime yourself.
Responses #
Methods return decoded JSON as dynamic, matching Any in the Python SDK and
unknown in the TypeScript one. That is deliberate rather than lazy: the
OpenAPI document does not yet carry response schemas, and inventing model
classes would mean shipping types that can silently disagree with the API.
Typed models land when the spec does.
Request parameters are fully typed — they are in the spec, so they are generated.
Surface #
81 operations across 19 namespaces: panchang, calendar, festivals,
worldFestivals, muhurat, timings, calculators, astronomy, eclipses,
conditions, shastric, events, astrology, locations, i18n, bulk,
aggregated, system, demo.
Parity with the Python and TypeScript SDKs is enforced in CI.
Links #
- Documentation — https://docs.tathaastuapi.com
- Methodology, including what we still get wrong — https://tathaastuapi.com/methodology
- Support — https://tathaastuapi.com/company/contact/
License #
MIT