Spaces:
Sleeping
Sleeping
Scheme Display API - Documentation
Overview
This document describes the new API endpoints for displaying government schemes on the frontend with filtering, pagination, and search capabilities.
π― New API Endpoints
1. GET /schemes/all - Get All Schemes with Filtering
Retrieves a paginated list of schemes with optional filtering.
Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page |
integer | No | 1 | Page number (starts from 1) |
page_size |
integer | No | 10 | Number of schemes per page (max: 100) |
state |
string | No | null | Filter by state name |
category |
string | No | null | Filter by scheme category |
level |
string | No | null | Filter by level (Central/State) |
search |
string | No | null | Search text (searches in name, details, benefits, tags) |
Response Format
{
"total": 3402,
"page": 1,
"page_size": 10,
"total_pages": 341,
"schemes": [
{
"scheme_name": "Scheme Name",
"slug": "scheme-slug",
"details": "Detailed description...",
"benefits": "Benefits offered...",
"eligibility": "Eligibility criteria...",
"application": "How to apply...",
"documents": "Required documents...",
"level": "State/Central",
"scheme_category": "Category name",
"tags": "tag1, tag2"
}
]
}
Example Requests
# Get first page of all schemes
GET http://127.0.0.1:8000/schemes/all
# Get schemes for specific state
GET http://127.0.0.1:8000/schemes/all?state=Karnataka&page=1&page_size=20
# Filter by category
GET http://127.0.0.1:8000/schemes/all?category=Agriculture
# Filter by level
GET http://127.0.0.1:8000/schemes/all?level=Central
# Search with text
GET http://127.0.0.1:8000/schemes/all?search=farmer
# Combined filters
GET http://127.0.0.1:8000/schemes/all?state=Maharashtra&category=Education&page=1&page_size=15
2. GET /schemes/{slug} - Get Scheme Details by Slug
Retrieves detailed information about a specific scheme.
Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
slug |
string | Yes | - | Unique scheme identifier |
language |
string | No | "en" | Language code for translation |
Response Format
{
"scheme_name": "Scheme Name",
"slug": "scheme-slug",
"details": "Full details...",
"benefits": "Complete benefits...",
"eligibility": "Full eligibility criteria...",
"application": "Complete application process...",
"documents": "All required documents...",
"level": "State/Central",
"scheme_category": "Category",
"tags": "tags"
}
Example Requests
# Get scheme in English
GET http://127.0.0.1:8000/schemes/astpss
# Get scheme in Hindi
GET http://127.0.0.1:8000/schemes/astpss?language=hi
# Get scheme in Telugu
GET http://127.0.0.1:8000/schemes/pmsfbcs?language=te
3. GET /schemes/categories - Get All Categories
Retrieves all unique scheme categories.
Response Format
{
"categories": [
"Agriculture,Rural & Environment",
"Business & Entrepreneurship",
"Education & Learning",
"Health & Wellness",
"Social welfare & Empowerment",
"Women and Child"
]
}
Example Request
GET http://127.0.0.1:8000/schemes/categories
4. GET /schemes/stats - Get Scheme Statistics
Retrieves statistics about all schemes.
Response Format
{
"total_schemes": 3402,
"by_level": {
"State": 2850,
"Central": 552
},
"by_category": {
"Social welfare & Empowerment": 856,
"Business & Entrepreneurship": 642,
"Education & Learning": 432,
"Agriculture,Rural & Environment": 389,
"Health & Wellness": 267
},
"total_categories": 24
}
Example Request
GET http://127.0.0.1:8000/schemes/stats
π¨ Frontend Implementation Examples
React/Next.js Example
// Fetch schemes with filters
const fetchSchemes = async (filters) => {
const params = new URLSearchParams({
page: filters.page || 1,
page_size: filters.pageSize || 10,
...(filters.state && { state: filters.state }),
...(filters.category && { category: filters.category }),
...(filters.level && { level: filters.level }),
...(filters.search && { search: filters.search })
});
const response = await fetch(
`http://127.0.0.1:8000/schemes/all?${params}`
);
return await response.json();
};
// Fetch single scheme
const fetchScheme = async (slug, language = 'en') => {
const response = await fetch(
`http://127.0.0.1:8000/schemes/${slug}?language=${language}`
);
return await response.json();
};
// Usage in component
const SchemesList = () => {
const [schemes, setSchemes] = useState([]);
const [filters, setFilters] = useState({
page: 1,
pageSize: 10,
state: '',
category: '',
search: ''
});
useEffect(() => {
fetchSchemes(filters).then(data => {
setSchemes(data.schemes);
});
}, [filters]);
return (
<div>
{/* Filter UI */}
{/* Scheme cards */}
</div>
);
};
π Search & Filter Recommendations
RECOMMENDATION: Implement Filters on BACKEND
β Why Backend Filtering is Better:
Performance
- Only sends required data over network
- Reduces bandwidth usage
- Faster page loads (10 schemes vs 3402 schemes)
Scalability
- Database can grow without affecting frontend performance
- Efficient pagination
- Optimized queries
Consistency
- Same filtering logic across all platforms (web, mobile, etc.)
- Centralized business logic
- Easier to maintain
User Experience
- Faster search results
- Real-time filtering without loading all data
- Better mobile experience
SEO Benefits
- Server-side rendering possible
- Better indexing of individual scheme pages
- Faster initial page load
β Why Avoid Frontend Filtering:
Performance Issues
- Loading 3402+ schemes slows down initial page load
- Memory consumption on client devices
- Poor mobile performance
Network Overhead
- Large JSON payload on every page load
- Wasted bandwidth for unused data
Maintenance
- Duplicate filtering logic on frontend and backend
- Harder to debug issues
π Backend Filtering Implementation
Current Implementation Features:
1. State Filtering
# Searches in details and eligibility fields
if state and state != "All States":
filtered_df = filtered_df[
filtered_df['details'].str.contains(state, case=False, na=False) |
filtered_df['eligibility'].str.contains(state, case=False, na=False)
]
2. Category Filtering
# Case-insensitive partial matching
if category:
filtered_df = filtered_df[
filtered_df['schemeCategory'].str.contains(category, case=False, na=False)
]
3. Level Filtering
# Exact match for Central/State
if level:
filtered_df = filtered_df[
filtered_df['level'].str.lower() == level.lower()
]
4. Text Search
# Searches across multiple fields
if search:
search_mask = (
filtered_df['scheme_name'].str.contains(search, case=False, na=False) |
filtered_df['details'].str.contains(search, case=False, na=False) |
filtered_df['benefits'].str.contains(search, case=False, na=False) |
filtered_df['tags'].str.contains(search, case=False, na=False)
)
5. Pagination
# Efficient slicing
start_idx = (page - 1) * page_size
end_idx = start_idx + page_size
paginated_df = filtered_df.iloc[start_idx:end_idx]
π― Recommended Frontend Architecture
Option 1: Server-Side Rendering (SSR) - Best for SEO
// Next.js Example
export async function getServerSideProps(context) {
const { page, state, category } = context.query;
const response = await fetch(
`http://127.0.0.1:8000/schemes/all?page=${page || 1}&state=${state || ''}&category=${category || ''}`
);
const data = await response.json();
return {
props: { schemes: data }
};
}
Option 2: Client-Side with Debouncing - Good UX
// React Hook for debounced search
import { useState, useEffect } from 'react';
import { debounce } from 'lodash';
const useSchemeSearch = () => {
const [filters, setFilters] = useState({});
const [schemes, setSchemes] = useState([]);
const [loading, setLoading] = useState(false);
const debouncedSearch = debounce(async (filters) => {
setLoading(true);
const data = await fetchSchemes(filters);
setSchemes(data.schemes);
setLoading(false);
}, 500); // Wait 500ms after user stops typing
useEffect(() => {
debouncedSearch(filters);
}, [filters]);
return { schemes, loading, setFilters };
};
Option 3: Hybrid Approach - Balanced
// Initial load: Server-side
// Filters: Client-side API calls
// Search: Debounced backend calls
const SchemeList = ({ initialSchemes }) => {
const [schemes, setSchemes] = useState(initialSchemes);
const handleFilterChange = async (newFilters) => {
const data = await fetchSchemes(newFilters);
setSchemes(data.schemes);
};
return (
<div>
<Filters onChange={handleFilterChange} />
<SchemeCards schemes={schemes} />
</div>
);
};
π Performance Optimization Tips
1. Caching
// Frontend caching with React Query
import { useQuery } from '@tanstack/react-query';
const useSchemes = (filters) => {
return useQuery({
queryKey: ['schemes', filters],
queryFn: () => fetchSchemes(filters),
staleTime: 5 * 60 * 1000, // Cache for 5 minutes
});
};
2. Lazy Loading
// Load more schemes on scroll
const SchemeList = () => {
const [page, setPage] = useState(1);
const handleScroll = () => {
if (/* bottom of page */) {
setPage(prev => prev + 1);
}
};
// Fetch next page and append
};
3. Virtual Scrolling
// Use react-window for large lists
import { FixedSizeList } from 'react-window';
<FixedSizeList
height={600}
itemCount={schemes.length}
itemSize={120}
>
{SchemeCard}
</FixedSizeList>
π± Mobile Optimization
Recommended Approach for Mobile:
- Smaller Page Size: Use
page_size=5orpage_size=10on mobile - Lazy Loading: Load more on scroll instead of pagination buttons
- Simplified Filters: Show essential filters only
- Backend Filtering: Critical for mobile performance
// Detect device and adjust
const isMobile = window.innerWidth < 768;
const pageSize = isMobile ? 5 : 10;
fetchSchemes({ page: 1, page_size: pageSize });
π Error Handling
Backend Errors
const fetchSchemes = async (filters) => {
try {
const response = await fetch(`/schemes/all?${params}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Failed to fetch schemes:', error);
// Show error toast/message to user
return { schemes: [], total: 0 };
}
};
π Testing the API
Using cURL
# Get all schemes
curl http://127.0.0.1:8000/schemes/all
# Filter by state
curl "http://127.0.0.1:8000/schemes/all?state=Karnataka"
# Search
curl "http://127.0.0.1:8000/schemes/all?search=farmer"
# Get specific scheme
curl http://127.0.0.1:8000/schemes/astpss
# Get statistics
curl http://127.0.0.1:8000/schemes/stats
Using Python
import requests
# Get schemes
response = requests.get(
'http://127.0.0.1:8000/schemes/all',
params={
'page': 1,
'page_size': 10,
'state': 'Karnataka',
'category': 'Agriculture'
}
)
data = response.json()
print(f"Found {data['total']} schemes")
π Summary
β What We Built:
- 4 new API endpoints for scheme management
- Backend filtering (state, category, level, search)
- Pagination support
- Multi-language scheme details
- Statistics endpoint
β Recommendations:
- Use BACKEND filtering - Better performance, scalability, UX
- Implement pagination - Don't load all 3402 schemes at once
- Add debouncing - For search input (500ms delay)
- Cache results - Use React Query or SWR
- Lazy load - For mobile and infinite scroll
π― Best Practice:
Backend handles filtering β Frontend displays results β User gets fast, smooth experience
π Support
For API documentation and interactive testing:
- Swagger UI: http://127.0.0.1:8000/docs
- ReDoc: http://127.0.0.1:8000/redoc