help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
weather-chatbot
/
utils
RSK World
weather-chatbot
Weather Chatbot - Python + Flask + OpenWeatherMap + OpenAI + Weather Forecast + Weather Alerts + Natural Language Processing
utils
  • __pycache__
  • __init__.py3.9 KB
  • advanced_nlp.py28.4 KB
  • analytics.py22 KB
  • auth.py17.8 KB
  • comparison.py24.2 KB
  • database.py24.6 KB
  • geolocation.py20.1 KB
  • multilang.py22 KB
  • notifications.py34.1 KB
  • rate_limiting.py24.3 KB
  • weather_maps.py29.6 KB
  • weather_utils.py12.9 KB
advanced_nlp.py
utils/advanced_nlp.py
Raw Download
Find: Go to:
#!/usr/bin/env python3
"""
Weather Chatbot Advanced NLP Module
====================================

Author: RSK World (https://rskworld.in)
Founded by: Molla Samser
Designer & Tester: Rima Khatun
Contact: +91 93305 39277, hello@rskworld.in, support@rskworld.in
Location: Nutanhat, Mongolkote, Purba Burdwan, West Bengal, India, 713147
Year: 2026

Description: Advanced natural language processing with sentiment analysis
"""

import re
import json
from typing import Dict, List, Optional, Tuple
from datetime import datetime, timedelta
import openai

# Optional dependencies - handle gracefully if not installed
try:
    from textblob import TextBlob
    TEXTBLOB_AVAILABLE = True
except ImportError:
    TextBlob = None
    TEXTBLOB_AVAILABLE = False
    print("Warning: TextBlob not available. Sentiment analysis will be limited.")

try:
    import spacy
    SPACY_AVAILABLE = True
except ImportError:
    spacy = None
    SPACY_AVAILABLE = False
    print("Warning: spaCy not available. Advanced NLP features will be limited.")

# Try to load spaCy model
nlp = None
if SPACY_AVAILABLE:
    try:
        nlp = spacy.load("en_core_web_sm")
    except OSError:
        nlp = None
        print("Warning: spaCy model 'en_core_web_sm' not found. Some NLP features will be limited.")

class AdvancedNLP:
    """Advanced natural language processing for weather queries"""
    
    def __init__(self, openai_api_key: str = None):
        self.openai_api_key = openai_api_key
        self.openai_client = None
        if openai_api_key:
            try:
                self.openai_client = openai.OpenAI(api_key=openai_api_key)
            except Exception:
                # Fallback to old API if new version not available
                openai.api_key = openai_api_key
        
        # Weather-related vocabulary
        self.weather_entities = {
            'cities': [
                'london', 'new york', 'paris', 'tokyo', 'delhi', 'mumbai', 'kolkata',
                'chennai', 'bangalore', 'sydney', 'moscow', 'beijing', 'dubai',
                'singapore', 'hong kong', 'los angeles', 'chicago', 'boston',
                'san francisco', 'seattle', 'toronto', 'vancouver', 'montreal'
            ],
            'weather_conditions': [
                'sunny', 'cloudy', 'rainy', 'snowy', 'stormy', 'windy', 'foggy',
                'clear', 'overcast', 'partly cloudy', 'mostly cloudy', 'drizzle',
                'thunderstorm', 'blizzard', 'hail', 'sleet', 'mist', 'haze'
            ],
            'time_expressions': [
                'today', 'tomorrow', 'yesterday', 'now', 'current', 'right now',
                'morning', 'afternoon', 'evening', 'night', 'tonight',
                'this week', 'next week', 'last week', 'weekend',
                'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday',
                'in 1 hour', 'in 2 hours', 'in 3 hours', 'in 6 hours', 'in 12 hours',
                'in 1 day', 'in 2 days', 'in 3 days', 'in 5 days', 'in a week'
            ],
            'query_types': [
                'weather', 'forecast', 'temperature', 'rain', 'snow', 'wind',
                'humidity', 'pressure', 'visibility', 'alerts', 'warnings',
                'conditions', 'climate', 'outlook', 'prediction'
            ],
            'comparative_words': [
                'compare', 'versus', 'vs', 'difference', 'better', 'worse',
                'hotter', 'colder', 'warmer', 'cooler', 'drier', 'wetter',
                'windier', 'calmer', 'sunnier', 'cloudier'
            ]
        }
        
        # Intent patterns
        self.intent_patterns = {
            'current_weather': [
                r'weather (?:in|at|for) (.+)',
                r'what(?:\'s| is) the weather (?:in|at|for) (.+)',
                r'current weather (?:in|for) (.+)',
                r'how(?:\'s| is) the weather (?:in|at) (.+)'
            ],
            'forecast': [
                r'forecast (?:for|in) (.+)',
                r'weather forecast (?:for|in) (.+)',
                r'what(?:\'s| is) the forecast (?:for|in) (.+)',
                r'will it (?:rain|snow) (?:in|at) (.+)',
                r'(?:temperature|temp) (?:in|for) (.+) (?:tomorrow|today|tonight)'
            ],
            'alerts': [
                r'weather alerts (?:for|in) (.+)',
                r'any (?:alerts|warnings) (?:for|in) (.+)',
                'severe weather (.+)',
                r'weather warnings (?:for|in) (.+)'
            ],
            'comparison': [
                r'compare (.+) (?:and|vs|versus) (.+)',
                r'(.+) (?:vs|versus) (.+) weather',
                r'difference between (.+) and (.+) weather',
                r'which (?:is|has) (?:better|worse) weather (.+) or (.+)'
            ],
            'historical': [
                r'weather history (?:for|in) (.+)',
                r'past weather (?:in|for) (.+)',
                r'weather (?:last|yesterday) (?:in|for) (.+)'
            ]
        }
    
    def analyze_query(self, query: str) -> Dict:
        """
        Comprehensive analysis of user query.
        
        Args:
            query: User's natural language query
            
        Returns:
            Detailed analysis result
        """
        try:
            # Basic preprocessing
            clean_query = self._preprocess_query(query)
            
            # Extract entities
            entities = self._extract_entities(clean_query)
            
            # Determine intent
            intent = self._determine_intent(clean_query)
            
            # Extract temporal information
            temporal_info = self._extract_temporal_info(clean_query)
            
            # Sentiment analysis
            sentiment = self._analyze_sentiment(clean_query)
            
            # Generate query context
            context = self._generate_query_context(entities, intent, temporal_info)
            
            # Confidence scoring
            confidence = self._calculate_confidence(entities, intent, temporal_info)
            
            return {
                'original_query': query,
                'cleaned_query': clean_query,
                'intent': intent,
                'entities': entities,
                'temporal_info': temporal_info,
                'sentiment': sentiment,
                'context': context,
                'confidence': confidence,
                'suggestions': self._generate_suggestions(entities, intent),
                'processed_at': datetime.now().isoformat()
            }
            
        except Exception as e:
            return {
                'error': f'Query analysis failed: {str(e)}',
                'original_query': query,
                'fallback_processed': True
            }
    
    def _preprocess_query(self, query: str) -> str:
        """Preprocess and clean the query"""
        # Convert to lowercase
        clean = query.lower().strip()
        
        # Remove extra whitespace
        clean = re.sub(r'\s+', ' ', clean)
        
        # Handle contractions
        contractions = {
            "what's": "what is",
            "how's": "how is",
            "it's": "it is",
            "that's": "that is",
            "there's": "there is",
            "where's": "where is",
            "when's": "when is",
            "why's": "why is",
            "who's": "who is",
            "let's": "let us",
            "don't": "do not",
            "doesn't": "does not",
            "didn't": "did not",
            "won't": "will not",
            "wouldn't": "would not",
            "can't": "cannot",
            "couldn't": "could not",
            "shouldn't": "should not",
            "mightn't": "might not",
            "mustn't": "must not"
        }
        
        for contraction, expansion in contractions.items():
            clean = clean.replace(contraction, expansion)
        
        # Remove punctuation except for meaningful ones
        clean = re.sub(r'[^\w\s\?\.\!\,\-]', '', clean)
        
        return clean
    
    def _extract_entities(self, query: str) -> Dict:
        """Extract entities from the query"""
        entities = {
            'cities': [],
            'weather_conditions': [],
            'time_expressions': [],
            'query_types': [],
            'comparative_words': [],
            'numbers': [],
            'unknown_locations': []
        }
        
        # Extract cities
        for city in self.weather_entities['cities']:
            if city in query:
                entities['cities'].append(city)
        
        # Extract weather conditions
        for condition in self.weather_entities['weather_conditions']:
            if condition in query:
                entities['weather_conditions'].append(condition)
        
        # Extract time expressions
        for time_expr in self.weather_entities['time_expressions']:
            if time_expr in query:
                entities['time_expressions'].append(time_expr)
        
        # Extract query types
        for query_type in self.weather_entities['query_types']:
            if query_type in query:
                entities['query_types'].append(query_type)
        
        # Extract comparative words
        for comp_word in self.weather_entities['comparative_words']:
            if comp_word in query:
                entities['comparative_words'].append(comp_word)
        
        # Extract numbers
        numbers = re.findall(r'\b\d+\b', query)
        entities['numbers'] = [int(n) for n in numbers]
        
        # Use spaCy for advanced entity extraction if available
        if SPACY_AVAILABLE and nlp is not None:
            try:
                doc = nlp(query)
                
                # Extract GPE (Geopolitical Entity) for cities
                for ent in doc.ents:
                    if ent.label_ == 'GPE' and ent.text.lower() not in entities['cities']:
                        entities['unknown_locations'].append(ent.text)
            except Exception as e:
                # Silently fail if spaCy processing fails
                pass
        
        return entities
    
    def _determine_intent(self, query: str) -> Dict:
        """Determine the primary intent of the query"""
        intent_scores = {}
        
        for intent_name, patterns in self.intent_patterns.items():
            score = 0
            for pattern in patterns:
                if re.search(pattern, query, re.IGNORECASE):
                    score += 1
            intent_scores[intent_name] = score
        
        # Find the intent with highest score
        if intent_scores:
            primary_intent = max(intent_scores, key=intent_scores.get)
            confidence = intent_scores[primary_intent] / len(self.intent_patterns[primary_intent])
        else:
            primary_intent = 'general_query'
            confidence = 0.5
        
        return {
            'primary_intent': primary_intent,
            'confidence': confidence,
            'all_scores': intent_scores
        }
    
    def _extract_temporal_info(self, query: str) -> Dict:
        """Extract temporal information from the query"""
        temporal_info = {
            'time_reference': 'current',
            'specific_time': None,
            'relative_time': None,
            'duration': None,
            'time_range': None
        }
        
        # Check for time references
        if any(word in query for word in ['current', 'now', 'right now', 'today']):
            temporal_info['time_reference'] = 'current'
        elif 'tomorrow' in query:
            temporal_info['time_reference'] = 'tomorrow'
        elif 'yesterday' in query:
            temporal_info['time_reference'] = 'yesterday'
        elif any(word in query for word in ['forecast', 'future', 'next']):
            temporal_info['time_reference'] = 'forecast'
        elif any(word in query for word in ['past', 'history', 'last', 'previous']):
            temporal_info['time_reference'] = 'historical'
        
        # Extract specific times
        time_patterns = [
            (r'(\d{1,2})\s*(am|pm)', 'specific_time'),
            (r'(\d{1,2}):(\d{2})\s*(am|pm)?', 'specific_time'),
            (r'(morning|afternoon|evening|night|tonight)', 'specific_time'),
        ]
        
        for pattern, time_type in time_patterns:
            match = re.search(pattern, query)
            if match:
                temporal_info[time_type] = match.group(0)
                break
        
        # Extract durations
        duration_patterns = [
            (r'(\d+)\s*(hour|hours|hr|hrs)', 'hours'),
            (r'(\d+)\s*(day|days)', 'days'),
            (r'(\d+)\s*(week|weeks)', 'weeks')
        ]
        
        for pattern, unit in duration_patterns:
            match = re.search(pattern, query)
            if match:
                temporal_info['duration'] = {
                    'value': int(match.group(1)),
                    'unit': unit
                }
                break
        
        return temporal_info
    
    def _analyze_sentiment(self, query: str) -> Dict:
        """Analyze sentiment of the query"""
        try:
            if not TEXTBLOB_AVAILABLE or TextBlob is None:
                # Fallback sentiment analysis without TextBlob
                return {
                    'polarity': 0.0,
                    'subjectivity': 0.5,
                    'sentiment_label': 'neutral',
                    'emotional_tone': 'neutral',
                    'confidence': 0.5
                }
            
            # Use TextBlob for sentiment analysis
            blob = TextBlob(query)
            polarity = blob.sentiment.polarity
            subjectivity = blob.sentiment.subjectivity
            
            # Categorize sentiment
            if polarity > 0.1:
                sentiment_label = 'positive'
            elif polarity < -0.1:
                sentiment_label = 'negative'
            else:
                sentiment_label = 'neutral'
            
            # Determine emotional tone
            emotional_tone = self._determine_emotional_tone(query, polarity)
            
            return {
                'polarity': polarity,
                'subjectivity': subjectivity,
                'sentiment_label': sentiment_label,
                'emotional_tone': emotional_tone,
                'confidence': abs(polarity)
            }
            
        except Exception as e:
            return {
                'error': f'Sentiment analysis failed: {str(e)}',
                'polarity': 0,
                'subjectivity': 0,
                'sentiment_label': 'neutral',
                'emotional_tone': 'neutral',
                'confidence': 0
            }
    
    def _determine_emotional_tone(self, query: str, polarity: float) -> str:
        """Determine emotional tone based on keywords and polarity"""
        positive_words = ['great', 'excellent', 'perfect', 'beautiful', 'nice', 'good', 'wonderful', 'amazing']
        negative_words = ['terrible', 'awful', 'horrible', 'bad', 'worst', 'hate', 'dislike', 'ugly']
        urgent_words = ['urgent', 'emergency', 'immediately', 'asap', 'critical', 'important']
        
        query_lower = query.lower()
        
        if any(word in query_lower for word in urgent_words):
            return 'urgent'
        elif polarity > 0.3 and any(word in query_lower for word in positive_words):
            return 'enthusiastic'
        elif polarity < -0.3 and any(word in query_lower for word in negative_words):
            return 'concerned'
        elif polarity > 0.1:
            return 'positive'
        elif polarity < -0.1:
            return 'negative'
        else:
            return 'neutral'
    
    def _generate_query_context(self, entities: Dict, intent: Dict, temporal_info: Dict) -> Dict:
        """Generate comprehensive query context"""
        context = {
            'primary_location': None,
            'secondary_locations': [],
            'weather_focus': None,
            'time_frame': temporal_info['time_reference'],
            'query_complexity': 'simple',
            'expected_response_type': 'weather_data'
        }
        
        # Determine primary location
        if entities['cities']:
            context['primary_location'] = entities['cities'][0]
            context['secondary_locations'] = entities['cities'][1:]
        elif entities['unknown_locations']:
            context['primary_location'] = entities['unknown_locations'][0]
        
        # Determine weather focus
        if entities['weather_conditions']:
            context['weather_focus'] = entities['weather_conditions'][0]
        
        # Determine query complexity
        if len(entities['cities']) > 1 or entities['comparative_words']:
            context['query_complexity'] = 'complex'
            context['expected_response_type'] = 'comparison'
        elif intent['primary_intent'] == 'forecast':
            context['query_complexity'] = 'moderate'
            context['expected_response_type'] = 'forecast'
        elif intent['primary_intent'] == 'alerts':
            context['query_complexity'] = 'moderate'
            context['expected_response_type'] = 'alerts'
        
        return context
    
    def _calculate_confidence(self, entities: Dict, intent: Dict, temporal_info: Dict) -> float:
        """Calculate overall confidence in the analysis"""
        confidence_factors = []
        
        # Entity extraction confidence
        entity_confidence = 0
        total_entities = sum(len(v) for v in entities.values())
        if total_entities > 0:
            entity_confidence = min(total_entities / 3, 1.0)  # Cap at 1.0
        confidence_factors.append(entity_confidence)
        
        # Intent confidence
        confidence_factors.append(intent['confidence'])
        
        # Temporal information confidence
        temporal_confidence = 0.5  # Base confidence
        if temporal_info['time_reference'] != 'current':
            temporal_confidence = 0.8
        confidence_factors.append(temporal_confidence)
        
        # Overall confidence (average of factors)
        overall_confidence = sum(confidence_factors) / len(confidence_factors)
        
        return round(overall_confidence, 2)
    
    def _generate_suggestions(self, entities: Dict, intent: Dict) -> List[str]:
        """Generate suggestions for improving the query"""
        suggestions = []
        
        # Location suggestions
        if not entities['cities'] and not entities['unknown_locations']:
            suggestions.append("Please specify a city name for weather information")
        
        # Intent suggestions
        if intent['confidence'] < 0.5:
            suggestions.append("Try being more specific about what weather information you need")
        
        # Time suggestions
        if intent['primary_intent'] == 'forecast' and not any(
            word in ' '.join(entities['time_expressions']) 
            for word in ['tomorrow', 'today', 'week', 'day']
        ):
            suggestions.append("Specify when you want the forecast (e.g., 'tomorrow', 'this week')")
        
        return suggestions
    
    def enhance_with_openai(self, query: str, analysis: Dict) -> Dict:
        """Enhance analysis using OpenAI GPT"""
        if not self.openai_api_key:
            return analysis
        
        try:
            prompt = f"""
            Analyze this weather query and provide enhanced understanding:
            
            Query: "{query}"
            
            Current Analysis: {json.dumps(analysis, indent=2)}
            
            Please provide:
            1. Enhanced intent classification
            2. Better entity extraction
            3. Contextual understanding
            4. Suggested follow-up questions
            5. Query improvement suggestions
            
            Respond in JSON format with these keys:
            - enhanced_intent
            - refined_entities
            - contextual_understanding
            - follow_up_questions
            - improvement_suggestions
            """
            
            # Use new API client if available, otherwise fallback to old API
            if self.openai_client:
                response = self.openai_client.chat.completions.create(
                    model="gpt-3.5-turbo",
                    messages=[
                        {"role": "system", "content": "You are an expert weather query analyzer."},
                        {"role": "user", "content": prompt}
                    ],
                    max_tokens=500,
                    temperature=0.3
                )
                content = response.choices[0].message.content.strip()
            else:
                # Fallback to old OpenAI API format
                try:
                    response = openai.ChatCompletion.create(
                        model="gpt-3.5-turbo",
                        messages=[
                            {"role": "system", "content": "You are an expert weather query analyzer."},
                            {"role": "user", "content": prompt}
                        ],
                        max_tokens=500,
                        temperature=0.3
                    )
                    content = response.choices[0].message.content.strip()
                except AttributeError:
                    # Old API format might be different
                    analysis['enhancement_error'] = 'OpenAI API format not supported'
                    return analysis
            
            # Try to parse JSON response
            try:
                enhanced_data = json.loads(content)
                
                # Merge enhanced data with original analysis
                analysis['enhanced'] = enhanced_data
                analysis['enhanced_at'] = datetime.now().isoformat()
            except json.JSONDecodeError:
                # If response is not JSON, store raw response
                analysis['enhancement_error'] = 'Could not parse OpenAI response as JSON'
                analysis['enhanced_raw'] = content
            
            return analysis
            
        except Exception as e:
            analysis['enhancement_error'] = str(e)
            return analysis
    
    def generate_conversation_response(self, query: str, weather_data: Dict, analysis: Dict) -> str:
        """Generate natural conversation response based on analysis"""
        try:
            intent = analysis.get('intent', {}).get('primary_intent', 'general_query')
            sentiment = analysis.get('sentiment', {})
            emotional_tone = sentiment.get('emotional_tone', 'neutral')
            
            # Base response based on intent
            if intent == 'current_weather':
                response = self._generate_current_weather_response(weather_data, emotional_tone)
            elif intent == 'forecast':
                response = self._generate_forecast_response(weather_data, emotional_tone)
            elif intent == 'alerts':
                response = self._generate_alerts_response(weather_data, emotional_tone)
            elif intent == 'comparison':
                response = self._generate_comparison_response(weather_data, emotional_tone)
            else:
                response = self._generate_general_response(weather_data, emotional_tone)
            
            # Add contextual elements
            if emotional_tone == 'enthusiastic':
                response = "Great question! " + response
            elif emotional_tone == 'concerned':
                response = "I understand your concern. " + response
            elif emotional_tone == 'urgent':
                response = "I'll help you right away. " + response
            
            # Add follow-up suggestions
            suggestions = self._generate_follow_up_suggestions(analysis, weather_data)
            if suggestions:
                response += "\n\n" + " ".join(suggestions)
            
            return response
            
        except Exception as e:
            return f"I apologize, but I encountered an error while generating my response: {str(e)}"
    
    def _generate_current_weather_response(self, weather_data: Dict, emotional_tone: str) -> str:
        """Generate response for current weather queries"""
        if 'error' in weather_data:
            return f"I'm sorry, I couldn't get the weather information. {weather_data['error']}"
        
        city = weather_data.get('city', 'Unknown')
        temp = weather_data.get('temperature', 0)
        description = weather_data.get('description', 'unknown conditions')
        humidity = weather_data.get('humidity', 0)
        wind_speed = weather_data.get('wind_speed', 0)
        
        response = f"Currently in {city}, it's {temp}°C with {description}. "
        response += f"The humidity is {humidity}% and wind speed is {wind_speed} m/s."
        
        return response
    
    def _generate_forecast_response(self, weather_data: Dict, emotional_tone: str) -> str:
        """Generate response for forecast queries"""
        if 'forecasts' not in weather_data:
            return "I'm sorry, I couldn't get the forecast information."
        
        city = weather_data.get('city', 'Unknown')
        forecasts = weather_data['forecasts'][:3]  # First 3 forecasts
        
        response = f"Here's the forecast for {city}:\n"
        
        for forecast in forecasts:
            datetime_str = forecast.get('datetime', '')
            temp = forecast.get('temperature', 0)
            desc = forecast.get('description', '')
            
            # Format datetime
            try:
                dt = datetime.fromisoformat(datetime_str.replace('Z', '+00:00'))
                time_str = dt.strftime('%A, %I %p')
            except:
                time_str = datetime_str
            
            response += f"• {time_str}: {temp}°C, {desc}\n"
        
        return response
    
    def _generate_alerts_response(self, weather_data: Dict, emotional_tone: str) -> str:
        """Generate response for weather alerts queries"""
        if not weather_data.get('alerts'):
            return f"Good news! There are no active weather alerts."
        
        alerts = weather_data['alerts']
        response = f"There are {len(alerts)} active weather alerts:\n"
        
        for alert in alerts:
            event = alert.get('event', 'Weather Alert')
            description = alert.get('description', '')
            response += f"• {event}: {description}\n"
        
        return response
    
    def _generate_comparison_response(self, weather_data: Dict, emotional_tone: str) -> str:
        """Generate response for comparison queries"""
        # This would need to be implemented based on comparison data structure
        return "Here's the weather comparison between the cities you requested."
    
    def _generate_general_response(self, weather_data: Dict, emotional_tone: str) -> str:
        """Generate general weather response"""
        if 'error' in weather_data:
            return f"I'm sorry, I couldn't process your weather request. {weather_data['error']}"
        
        return self._generate_current_weather_response(weather_data, emotional_tone)
    
    def _generate_follow_up_suggestions(self, analysis: Dict, weather_data: Dict) -> List[str]:
        """Generate follow-up suggestions based on context"""
        suggestions = []
        
        intent = analysis.get('intent', {}).get('primary_intent', 'general_query')
        entities = analysis.get('entities', {})
        
        if intent == 'current_weather':
            suggestions.append("Would you like to see the forecast for tomorrow?")
            suggestions.append("Are there any weather alerts for this area?")
        elif intent == 'forecast':
            suggestions.append("Would you like to compare this with another city?")
            suggestions.append("Do you need historical weather data?")
        elif entities['cities']:
            city = entities['cities'][0] if entities['cities'] else 'this location'
            suggestions.append(f"Would you like to save {city.title()} to your favorites?")
        
        return suggestions[:2]  # Limit to 2 suggestions
703 lines•28.4 KB
python

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer