| Metadata | Value |
|---|---|
| Status | Archived |
| Version | 1.0.0 |
| Last Updated | 2026-09-10 |
| Author | Sangeetha Grantha Team |
| Document Type | Archive |
[!NOTE] Historical evidence: results, counts, commands, and observations below belong to the original work described here. The editorial update date is not a new test or corpus verification. For present behavior, use current ingestion guide.
| Date | 2026-01-20 |
|---|---|
| Status | Technical Analysis |
| Question | Why was Python suggested over existing project capabilities? |
The original consolidation summary suggested using Python for CSV parsing in Phase 1. This analysis compares Python against the project’s existing technical stack and recommends Rust (extending sangita-cli) as the optimal choice, with Kotlin as a viable alternative.
Recommendation: Use Rust to extend the existing sangita-cli tool rather than introducing Python as a new dependency.
The Python suggestion likely came from:
csv module makes CSV parsing trivialHowever, this approach introduces a new language dependency that doesn’t align with the project’s existing architecture.
| Component | Technology | Purpose |
|---|---|---|
| Backend API | Kotlin (JVM) + Ktor | REST API, business logic |
| CLI Tool | Rust (tools/sangita-cli) |
Database management, migrations, seeding |
| Database | PostgreSQL | Data persistence |
| Frontend | React + TypeScript | Admin UI |
| Build System | Gradle (Kotlin) | Backend dependencies |
sangita-cli)The Rust CLI tool (tools/sangita-cli) already handles:
cargo run -- db migrate)cargo run -- db seed)cargo run -- db reset)cargo run -- dev)cargo run -- test)Key Insight: The CLI is the canonical tool for database operations. Extending it for CSV ingestion aligns with existing patterns.
Pros:
csv module is built-in)Cons:
sangita-cli infrastructureExample Code:
# tools/scripts/ingest_csv_manifest.py
import csv
import uuid
def generate_sql(csv_file, source_id):
with open(csv_file, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
# Generate INSERT statements
...
sangita-cli) ✅ RECOMMENDEDPros:
cargo run -- db seed)Cons:
csv crate is well-maintained)Example Code:
// tools/sangita-cli/src/commands/import.rs
use csv::Reader;
use sqlx::PgPool;
pub async fn ingest_csv_manifest(
csv_path: &Path,
source_id: Uuid,
pool: &PgPool
) -> Result<()> {
let mut reader = Reader::from_path(csv_path)?;
for result in reader.records() {
let record = result?;
// Generate and execute INSERT statements
...
}
Ok(())
}
Integration:
// tools/sangita-cli/src/commands/db.rs
#[derive(Subcommand)]
enum DbCommands {
// ... existing commands
/// Ingest CSV manifest files
IngestCsv {
#[arg(long)]
csv_dir: PathBuf,
},
}
Pros:
ImportService, ImportRepository)Cons:
com.github.doyuchen:kotlin-csv)Example Code:
// modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/scripts/CsvIngestionScript.kt
import com.github.doyuchen.kotlin.csv.CsvReader
suspend fun ingestCsvManifest(csvPath: String, sourceId: Uuid): List<ImportedKrithiDto> {
val reader = CsvReader(csvPath)
val entries = reader.readAll()
// Use existing ImportService
return importService.submitImports(entries.map { ... })
}
Best Use Case: Phase 2+ (runtime CSV imports via API), not Phase 1 (seed file generation).
Pros:
Cons:
Example:
-- Limited: Requires pre-processing or staging table
COPY imported_krithis (source_key, raw_title, raw_raga)
FROM '/path/to/csv'
WITH (FORMAT csv, HEADER true);
Verdict: Not suitable for this use case (needs data transformation and validation).
| Criteria | Python | Rust (CLI) | Kotlin (Backend) | SQL COPY |
|---|---|---|---|---|
| Architecture Alignment | ❌ | ✅ | ⚠️ | ⚠️ |
| Existing Infrastructure | ❌ | ✅ | ✅ | ✅ |
| Integration with CLI | ❌ | ✅ | ❌ | ⚠️ |
| Type Safety | ❌ | ✅ | ✅ | N/A |
| Maintainability | ⚠️ | ✅ | ✅ | ❌ |
| Development Speed | ✅ | ⚠️ | ⚠️ | ❌ |
| Data Transformation | ✅ | ✅ | ✅ | ❌ |
| Validation Logic | ✅ | ✅ | ✅ | ❌ |
| Future Extensibility | ⚠️ | ✅ | ✅ | ❌ |
| Dependency Management | ❌ | ✅ | ⚠️ | ✅ |
sangita-cli)Architectural Consistency: The CLI tool is already the canonical interface for database operations. CSV ingestion is a database operation.
DatabaseManager)AppConfig)db seed workflow:
cargo run -- db seed # Runs all seed files including CSV-generated ones
Future-Proof: If CSV ingestion needs evolve (validation, transformation, API endpoints), the Rust CLI can be extended. Python would remain a separate tool.
csv = "1.3" to Cargo.toml is trivial.Step 1: Add CSV parsing dependency
# tools/sangita-cli/Cargo.toml
[dependencies]
csv = "1.3" # Add this
Step 2: Create new CLI command
// tools/sangita-cli/src/commands/import.rs
pub struct ImportArgs {
#[command(subcommand)]
command: ImportCommands,
}
#[derive(Subcommand)]
enum ImportCommands {
/// Generate SQL seed files from CSV manifests
GenerateSeed {
#[arg(long)]
csv_dir: PathBuf,
#[arg(long)]
output: PathBuf,
},
}
Step 3: Integrate with existing db seed workflow
database/seed_data/cargo run -- db seed will pick them up automaticallyStep 4: Add to CLI main
// tools/sangita-cli/src/main.rs
#[derive(Subcommand)]
enum Commands {
// ... existing commands
Import(import::ImportArgs), // Add this
}
While Rust is recommended for Phase 1 (seed file generation), Kotlin is the better choice for Phase 2+ when CSV imports become runtime operations:
POST /v1/admin/imports/csv/uploadImportService and WebScrapingServiceRecommendation: Use Rust for Phase 1 (seed generation), Kotlin for Phase 2+ (runtime imports).
If Python was already partially implemented, migration to Rust is straightforward:
std::fs and std::path are similar to Python’sEstimated Effort: 2-4 hours to port a Python script to Rust CLI command.
Primary Recommendation: Rust (extending sangita-cli) for Phase 1 CSV ingestion.
Rationale:
Secondary Recommendation: Kotlin for Phase 2+ runtime CSV imports via API.
Not Recommended: Python (introduces unnecessary dependency) or SQL COPY (insufficient for transformation needs).
Deliverables:
tools/sangita-cli/src/commands/import.rs
csv = "1.3" dependencydatabase/seed_data/04_initial_manifest_load.sqldatabase/seed_data/03_import_sources.sql
DbCommands to include CSV ingestion
cargo run -- import generate-seed \
--csv-dir database/for_import \
--output database/seed_data/04_initial_manifest_load.sql
cargo run -- db seed # Runs all seed files including CSV-generated ones
Success Criteria:
imported_krithis table