This commit is contained in:
Kevin Carter 2025-11-14 14:47:19 +00:00
parent 2a85845835
commit 3758c7572a
137 changed files with 365654 additions and 11147 deletions

4
.gitignore vendored
View File

@ -5,6 +5,4 @@ __pycache__
.env
data/init_data/
logs/
.archive/*

212
README_GAIS_IMPORT.md Normal file
View File

@ -0,0 +1,212 @@
# GAIS Data Import for ClassroomCopilot
This document describes the GAIS (Get All Information from Schools) data import functionality for ClassroomCopilot, which allows you to import publicly available school databases into the Neo4j database.
## Overview
The GAIS data import system is designed to import publicly available educational data from various sources, starting with Edubase All Data. The system follows Neo4j naming conventions and creates a comprehensive graph structure representing schools and their relationships.
## Neo4j Naming Conventions
The import system adheres to the following Neo4j naming conventions:
- **Node Labels**: PascalCase (e.g., `Establishment`, `LocalAuthority`, `EstablishmentType`)
- **Relationships**: `HAS_` prefix followed by the target node label (e.g., `HAS_LOCAL_AUTHORITY`, `HAS_ESTABLISHMENT_TYPE`)
- **Properties**: camelCase (e.g., `establishmentName`, `schoolCapacity`, `numberOfPupils`)
## Data Structure
### Main Nodes
1. **Establishment** - The primary school/educational institution node
- Properties: URN, name, address, capacity, pupil counts, etc.
- Unique identifier: `urn` property
2. **LocalAuthority** - Local authority governing the establishment
- Properties: code, name
- Relationship: `HAS_LOCAL_AUTHORITY`
3. **EstablishmentType** - Type of educational establishment
- Properties: code, name
- Relationship: `HAS_ESTABLISHMENT_TYPE`
4. **EstablishmentTypeGroup** - Group classification of establishment types
- Properties: code, name
- Relationship: `HAS_ESTABLISHMENT_TYPE_GROUP`
5. **PhaseOfEducation** - Educational phase (Primary, Secondary, etc.)
- Properties: code, name
- Relationship: `HAS_PHASE_OF_EDUCATION`
6. **GenderType** - Gender classification of the establishment
- Properties: code, name
- Relationship: `HAS_GENDER_TYPE`
7. **ReligiousCharacter** - Religious character of the establishment
- Properties: code, name
- Relationship: `HAS_RELIGIOUS_CHARACTER`
8. **Diocese** - Religious diocese (if applicable)
- Properties: code, name
- Relationship: `HAS_DIOCESE`
9. **GovernmentOfficeRegion** - Government office region
- Properties: code, name
- Relationship: `HAS_GOVERNMENT_OFFICE_REGION`
10. **DistrictAdministrative** - Administrative district
- Properties: code, name
- Relationship: `HAS_DISTRICT_ADMINISTRATIVE`
11. **MSOA** - Middle Super Output Area
- Properties: code, name
- Relationship: `HAS_MSOA`
12. **LSOA** - Lower Super Output Area
- Properties: code, name
- Relationship: `HAS_LSOA`
13. **Country** - Country of the establishment
- Properties: name
- Relationship: `HAS_COUNTRY`
## Usage
### Command Line
You can run the GAIS data import using the startup script:
```bash
# Import GAIS data
./start.sh gais-data
# Or directly with Python
python main.py --mode gais-data
```
### Programmatic Usage
```python
from run.initialization.gais_data import import_gais_data
# Import the data
result = import_gais_data()
if result["success"]:
print(f"Successfully imported {result['total_rows']} records")
print(f"Processing time: {result['processing_time']:.2f} seconds")
print(f"Nodes created: {result['nodes_created']}")
print(f"Relationships created: {result['relationships_created']}")
else:
print(f"Import failed: {result['message']}")
```
## Data Sources
### Edubase All Data
The primary data source is the Edubase All Data CSV file, which contains information about all educational establishments in England and Wales.
**File Location**: `run/initialization/import/edubasealldata20250828.csv`
**Data Volume**: Approximately 51,900 records
**Key Fields**:
- URN (Unique Reference Number)
- Establishment details (name, type, status)
- Geographic information (address, coordinates, administrative areas)
- Educational characteristics (phase, gender, religious character)
- Capacity and pupil numbers
- Contact information
- Inspection details
## Data Processing
### Batch Processing
The import system processes data in batches to optimize performance and memory usage:
- **Batch Size**: 1,000 records per batch
- **Processing**: Nodes are created first, then relationships
- **Error Handling**: Individual record failures don't stop the entire import
### Data Validation
The system automatically handles:
- Empty/blank values (excluded from node properties)
- "Not applicable" values (treated as empty)
- Date format conversion (DD-MM-YYYY to ISO format)
- Numeric value parsing
- Duplicate node prevention
### Relationship Creation
Relationships are created using a two-pass approach:
1. **First Pass**: Create all nodes and build a mapping of keys to node objects
2. **Second Pass**: Create relationships between nodes using the mapping
## Performance Considerations
- **Memory Usage**: Data is processed in batches to minimize memory footprint
- **Database Connections**: Uses connection pooling for efficient database access
- **Duplicate Prevention**: Tracks created nodes to avoid duplicates
- **Error Resilience**: Continues processing even if individual records fail
## Future Enhancements
The GAIS import system is designed to be extensible for additional data sources:
1. **Governance Data** - School governance and management information
2. **Links Data** - Relationships between schools and other entities
3. **Groups Data** - Multi-academy trusts and federations
4. **Additional Sources** - Other publicly available educational datasets
## Troubleshooting
### Common Issues
1. **File Not Found**: Ensure the Edubase CSV file is in the correct location
2. **Database Connection**: Verify Neo4j is running and accessible
3. **Memory Issues**: Reduce batch size if processing large datasets
4. **Permission Errors**: Check file permissions for the CSV data file
### Logging
The system provides comprehensive logging:
- Import progress updates
- Error details for failed records
- Performance metrics
- Node and relationship creation counts
### Testing
Use the test script to verify functionality:
```bash
python test_gais_import.py
```
## Data Quality
The import system maintains data quality by:
- Filtering out invalid or empty values
- Converting data types appropriately
- Maintaining referential integrity
- Providing detailed error reporting
## Schema Compatibility
The imported data is compatible with the existing ClassroomCopilot schema and can be integrated with:
- Calendar structures
- User management systems
- Educational content management
- Analytics and reporting tools
## Support
For issues or questions related to the GAIS data import:
1. Check the logs for detailed error information
2. Verify data file format and content
3. Ensure database connectivity and permissions
4. Review the Neo4j schema constraints and indexes

View File

@ -0,0 +1,66 @@
# Auto-Processing Code Archive
This directory contains the complex auto-processing system that was previously used for automatic document processing after file upload.
## Archived Components
### Core Processing Files
- `files_with_auto_processing.py` - Original files.py router with automatic processing
- `pipeline_controller.py` - Complex multi-phase pipeline orchestration
- `task_processors.py` - Document processing task handlers
### Advanced Queue Management (Created but not deployed)
- `memory_aware_queue.py` - Memory-based intelligent queue management
- `enhanced_upload_handler.py` - Advanced upload handler with queuing
- `enhanced_upload.py` - API endpoints for advanced upload system
## What This System Did
### Automatic Processing Pipeline
1. **File Upload** → Immediate processing trigger
2. **PDF Conversion** (synchronous, blocking)
3. **Phase 1**: Structure discovery (Tika, Page Images, Document Analysis, Split Map)
4. **Phase 2**: Docling processing (NO_OCR → OCR → VLM pipelines)
5. **Complex Dependencies**: Phase coordination, task sequencing
6. **Redis Queue Management**: Service limits, rate limits, dependency tracking
### Features
- Multi-phase processing pipelines
- Complex task dependency management
- Memory-aware queue limits
- Multi-user capacity management
- Real-time processing status
- WebSocket status updates
- Service-specific resource limits
- Task recovery on restart
## Why Archived
The system was overly complex for the current needs:
- **Complexity**: Multi-phase pipelines with complex dependencies
- **Blocking Operations**: Synchronous PDF conversion causing timeouts
- **Resource Management**: Over-engineered for single-user scenarios
- **User Experience**: Users had to wait for processing to complete
## New Simplified Approach
The new system focuses on:
- **Simple Upload**: Just store files and create database records
- **No Auto-Processing**: Users manually trigger processing when needed
- **Directory Support**: Upload entire folders with manifest tracking
- **Immediate Response**: Users get instant confirmation without waiting
## If You Need to Restore
To restore the auto-processing functionality:
1. Copy `files_with_auto_processing.py` back to `routers/database/files/files.py`
2. Ensure `pipeline_controller.py` and `task_processors.py` are in `modules/`
3. Update imports and dependencies
4. Re-enable background processing in upload handlers
## Migration Notes
The database schema and Redis structure remain compatible. The new simplified system can coexist with the archived processing logic if needed.
Date Archived: $(date)
Reason: Simplification for directory upload implementation

View File

@ -0,0 +1,142 @@
"""
Enhanced Upload Router with Memory-Aware Queuing
===============================================
Provides intelligent upload endpoints with capacity checking,
queue management, and real-time status updates.
Endpoints:
- POST /upload/check-capacity - Pre-check if upload is possible
- POST /upload/with-queue - Upload with intelligent queuing
- GET /upload/status/{file_id} - Get processing status
- GET /upload/queue-status - Get overall queue status
- WebSocket /ws/upload-status - Real-time status updates
"""
import os
import uuid
import json
import logging
from typing import Dict, List, Optional, Any
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, WebSocket, WebSocketDisconnect
from fastapi.responses import JSONResponse
from modules.auth.supabase_bearer import SupabaseBearer
from modules.enhanced_upload_handler import get_upload_handler
from modules.memory_aware_queue import get_memory_queue
from modules.logger_tool import initialise_logger
router = APIRouter()
auth = SupabaseBearer()
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
# WebSocket connection manager for real-time updates
class ConnectionManager:
def __init__(self):
self.active_connections: Dict[str, List[WebSocket]] = {}
async def connect(self, websocket: WebSocket, file_id: str):
await websocket.accept()
if file_id not in self.active_connections:
self.active_connections[file_id] = []
self.active_connections[file_id].append(websocket)
def disconnect(self, websocket: WebSocket, file_id: str):
if file_id in self.active_connections:
self.active_connections[file_id].remove(websocket)
if not self.active_connections[file_id]:
del self.active_connections[file_id]
async def broadcast_to_file(self, file_id: str, message: dict):
if file_id in self.active_connections:
for connection in self.active_connections[file_id].copy():
try:
await connection.send_json(message)
except:
self.active_connections[file_id].remove(connection)
manager = ConnectionManager()
@router.post("/upload/check-capacity")
async def check_upload_capacity(
file_size: int = Form(...),
mime_type: str = Form(...),
payload: Dict[str, Any] = Depends(auth)
):
"""
Check if user can upload a file of given size and type.
Returns capacity information and recommendations.
"""
try:
user_id = payload.get('sub') or payload.get('user_id', 'anonymous')
# Determine environment
environment = 'dev' if os.getenv('BACKEND_DEV_MODE', 'true').lower() == 'true' else 'prod'
upload_handler = get_upload_handler(environment)
eligible, message, details = upload_handler.check_upload_eligibility(
user_id, file_size, mime_type
)
response = {
'eligible': eligible,
'message': message,
'details': details,
'timestamp': time.time()
}
status_code = 200 if eligible else 429 # Too Many Requests if not eligible
logger.info(f"📋 Capacity check for user {user_id}: {eligible} - {message}")
return JSONResponse(content=response, status_code=status_code)
except Exception as e:
logger.error(f"Capacity check error: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.post("/upload/with-queue")
async def upload_with_queue(
cabinet_id: str = Form(...),
path: str = Form(...),
scope: str = Form(...),
priority: int = Form(1),
file: UploadFile = File(...),
payload: Dict[str, Any] = Depends(auth)
):
"""
Upload file with intelligent queuing and capacity management.
Returns queue information and processing status.
"""
try:
user_id = payload.get('sub') or payload.get('user_id', 'anonymous')
# Read file content
file_bytes = await file.read()
file_size = len(file_bytes)
mime_type = file.content_type or 'application/octet-stream'
filename = file.filename or path
logger.info(f"📤 Upload request: {filename} ({file_size} bytes) for user {user_id}")
# Determine environment
environment = 'dev' if os.getenv('BACKEND_DEV_MODE', 'true').lower() == 'true' else 'prod'
upload_handler = get_upload_handler(environment)
# Check if upload queuing is enabled
if os.getenv('UPLOAD_QUEUE_ENABLED', 'true').lower() == 'true':
# Use new queue-based upload
file_id = str(uuid.uuid4())
result = await upload_handler.handle_upload_with_queue(
file_id=file_id,
user_id=user_id,
filename=filename,
file_bytes=file_bytes,
mime_type=mime_type,
cabinet_id=cabinet_id,
priority=priority
)\n \n return result\n \n else:\n # Fall back to immediate processing (legacy mode)\n logger.warning(\"Using legacy immediate processing mode\")\n # TODO: Call original upload_file function\n raise HTTPException(status_code=501, detail=\"Legacy mode not implemented in this endpoint\")\n \n except HTTPException:\n raise\n except Exception as e:\n logger.error(f\"Upload error: {e}\")\n raise HTTPException(status_code=500, detail=str(e))\n\n@router.get(\"/upload/status/{file_id}\")\nasync def get_upload_status(\n file_id: str,\n payload: Dict[str, Any] = Depends(auth)\n):\n \"\"\"\n Get current processing status for an uploaded file.\n \"\"\"\n try:\n # Determine environment\n environment = 'dev' if os.getenv('BACKEND_DEV_MODE', 'true').lower() == 'true' else 'prod'\n upload_handler = get_upload_handler(environment)\n \n status = upload_handler.get_processing_status(file_id)\n \n if status.get('status') == 'not_found':\n raise HTTPException(status_code=404, detail=\"File not found\")\n \n return status\n \n except HTTPException:\n raise\n except Exception as e:\n logger.error(f\"Status check error for {file_id}: {e}\")\n raise HTTPException(status_code=500, detail=str(e))\n\n@router.get(\"/upload/queue-status\")\nasync def get_queue_status(\n payload: Dict[str, Any] = Depends(auth)\n):\n \"\"\"\n Get overall queue status and system capacity information.\n \"\"\"\n try:\n # Determine environment\n environment = 'dev' if os.getenv('BACKEND_DEV_MODE', 'true').lower() == 'true' else 'prod'\n memory_queue = get_memory_queue(environment)\n \n system_status = memory_queue.get_system_status()\n \n return {\n 'system_status': system_status,\n 'timestamp': time.time(),\n 'environment': environment\n }\n \n except Exception as e:\n logger.error(f\"Queue status error: {e}\")\n raise HTTPException(status_code=500, detail=str(e))\n\n@router.websocket(\"/ws/upload-status/{file_id}\")\nasync def websocket_upload_status(websocket: WebSocket, file_id: str):\n \"\"\"\n WebSocket endpoint for real-time upload status updates.\n \"\"\"\n await manager.connect(websocket, file_id)\n \n try:\n # Send initial status\n environment = 'dev' if os.getenv('BACKEND_DEV_MODE', 'true').lower() == 'true' else 'prod'\n upload_handler = get_upload_handler(environment)\n initial_status = upload_handler.get_processing_status(file_id)\n \n await websocket.send_json({\n 'type': 'status_update',\n 'data': initial_status\n })\n \n # Keep connection alive and listen for updates\n while True:\n # In a real implementation, you'd have a background task\n # that pushes updates when file status changes\n await asyncio.sleep(5)\n \n # Check for status updates\n current_status = upload_handler.get_processing_status(file_id)\n await websocket.send_json({\n 'type': 'status_update', \n 'data': current_status\n })\n \n except WebSocketDisconnect:\n manager.disconnect(websocket, file_id)\n except Exception as e:\n logger.error(f\"WebSocket error for {file_id}: {e}\")\n manager.disconnect(websocket, file_id)\n\n# Background task to process upload queue\n@router.on_event(\"startup\")\nasync def start_queue_processor():\n \"\"\"Start background queue processor.\"\"\"\n \n if os.getenv('UPLOAD_QUEUE_ENABLED', 'true').lower() != 'true':\n logger.info(\"📋 Upload queue disabled, skipping queue processor\")\n return\n \n import asyncio\n \n environment = 'dev' if os.getenv('BACKEND_DEV_MODE', 'true').lower() == 'true' else 'prod'\n upload_handler = get_upload_handler(environment)\n \n # Start background processor\n asyncio.create_task(upload_handler.process_queued_files(\"document_processor\"))\n \n logger.info(\"🚀 Upload queue processor started\")\n\nimport time\nimport asyncio"

View File

@ -0,0 +1,362 @@
"""
Enhanced Upload Handler with Memory-Aware Queuing
=================================================
Replaces the immediate processing model with intelligent queue management.
Provides user feedback about capacity, queue position, and processing status.
Features:
- Pre-upload capacity checking
- Memory-aware queuing with user quotas
- Real-time status updates via WebSocket/SSE
- Graceful degradation under load
- Fair queuing across multiple users
"""
import os
import uuid
import time
import logging
import asyncio
from typing import Dict, List, Optional, Any, Tuple
from fastapi import HTTPException, BackgroundTasks
from dataclasses import asdict
from .memory_aware_queue import get_memory_queue, QueuedFile
from .redis_manager import get_redis_manager
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
from modules.database.tools.storage.storage_admin import StorageAdmin
logger = logging.getLogger(__name__)
class EnhancedUploadHandler:
"""Enhanced upload handler with memory-aware queuing."""
def __init__(self, environment: str = "dev"):
self.memory_queue = get_memory_queue(environment)
self.redis_manager = get_redis_manager(environment)
self.redis_client = self.redis_manager.client
# Processing status tracking
self.processing_status_key = "file_processing_status"
def check_upload_eligibility(self, user_id: str, file_size: int,
mime_type: str) -> Tuple[bool, str, Dict[str, Any]]:
"""
Check if user can upload a file right now.
Returns:
(eligible, message, details)
"""
# Check system capacity
can_accept, message, queue_info = self.memory_queue.check_upload_capacity(
user_id, file_size, mime_type
)
if not can_accept:
return False, message, {
'reason': 'capacity_exceeded',
'queue_info': queue_info,
'recommendations': self._get_recommendations(queue_info)
}
return True, message, {
'status': 'ready_for_upload',
'queue_info': queue_info,
'processing_estimate': self._estimate_processing_time(file_size, mime_type)
}
async def handle_upload_with_queue(self, file_id: str, user_id: str,
filename: str, file_bytes: bytes,
mime_type: str, cabinet_id: str,
priority: int = 1) -> Dict[str, Any]:
"""
Handle file upload with intelligent queuing.
Steps:
1. Store file immediately (cheap operation)
2. Add to processing queue
3. Return queue status to user
4. Process asynchronously when capacity available
"""
# Store file immediately (this is fast)
storage = StorageAdmin()
client = SupabaseServiceRoleClient()
# Create database record
bucket = f"{cabinet_id}-files" # or your bucket naming convention
storage_path = f"{cabinet_id}/{file_id}/{filename}"
try:
# Store file
storage.upload_file(bucket, storage_path, file_bytes, mime_type, upsert=True)
# Create file record
insert_res = client.supabase.table('files').insert({
'id': file_id,
'name': filename,
'cabinet_id': cabinet_id,
'bucket': bucket,
'path': storage_path,
'mime_type': mime_type,
'uploaded_by': user_id,
'size_bytes': len(file_bytes),
'source': 'classroomcopilot-web',
'status': 'queued_for_processing' # New status
}).execute()
if not insert_res.data:
raise HTTPException(status_code=500, detail="Failed to create file record")
except Exception as e:
logger.error(f"Failed to store file {file_id}: {e}")
raise HTTPException(status_code=500, detail=f"Storage failed: {str(e)}")
# Add to processing queue
try:
queue_result = self.memory_queue.enqueue_file(
file_id=file_id,
user_id=user_id,
filename=filename,
size_bytes=len(file_bytes),
mime_type=mime_type,
cabinet_id=cabinet_id,
priority=priority
)
# Update file status in database
client.supabase.table('files').update({
'status': 'queued_for_processing',
'extra': {
'queue_position': queue_result['queue_position'],
'estimated_wait_seconds': queue_result['estimated_wait_seconds'],
'memory_estimate_mb': queue_result['memory_estimate_mb']
}
}).eq('id', file_id).execute()
logger.info(f"📋 File {file_id} queued at position {queue_result['queue_position']}")
return {
'status': 'upload_successful',
'message': 'File uploaded and queued for processing',
'file_id': file_id,
'queue_info': queue_result,
'next_steps': {
'poll_status_endpoint': f'/database/files/{file_id}/processing-status',
'websocket_updates': f'/ws/file-processing/{file_id}'
}
}
except Exception as e:
logger.error(f"Failed to queue file {file_id}: {e}")
# Clean up stored file
try:
storage.delete_file(bucket, storage_path)
client.supabase.table('files').delete().eq('id', file_id).execute()
except:
pass
raise HTTPException(status_code=500, detail=f"Queue failed: {str(e)}")
async def process_queued_files(self, service_name: str = "document_processor"):
"""
Background service to process queued files.
This runs continuously as a background task.
"""
logger.info(f"🚀 Started queue processor for {service_name}")
while True:
try:
# Get next file from queue
queued_file = self.memory_queue.dequeue_next_file(service_name)
if not queued_file:
# No files ready for processing
await asyncio.sleep(5)
continue
# Update file status
await self._update_processing_status(queued_file.file_id, 'processing')
# Process the file
try:
await self._process_file(queued_file, service_name)
await self._update_processing_status(queued_file.file_id, 'completed')
except Exception as e:
logger.error(f"Failed to process file {queued_file.file_id}: {e}")
await self._update_processing_status(queued_file.file_id, 'failed', str(e))
finally:
# Always free memory
self.memory_queue.complete_processing(
service_name,
queued_file.file_id,
queued_file.memory_estimate_mb
)
except Exception as e:
logger.error(f"Queue processor error: {e}")
await asyncio.sleep(10) # Back off on errors
async def _process_file(self, queued_file: QueuedFile, service_name: str):
"""Process a single file from the queue."""
logger.info(f"🔄 Processing file {queued_file.file_id} in {service_name}")
# Import here to avoid circular imports
from modules.pipeline_controller import get_pipeline_controller
client = SupabaseServiceRoleClient()
controller = get_pipeline_controller()
# Get file record
file_result = client.supabase.table('files').select('*').eq('id', queued_file.file_id).single().execute()
file_row = file_result.data
if not file_row:
raise Exception(f"File record not found: {queued_file.file_id}")
# Update status to processing
client.supabase.table('files').update({
'status': 'processing'
}).eq('id', queued_file.file_id).execute()
# Convert to PDF if needed (this is where the bottleneck was before)
processing_path = await self._handle_pdf_conversion(file_row)
# Enqueue Phase 1 tasks
phase1_tasks = controller.enqueue_phase1_tasks(
file_id=queued_file.file_id,
file_row={**file_row, 'path': processing_path},
processing_path=processing_path,
processing_mime=file_row['mime_type']
)
# Update database with task IDs
client.supabase.table('files').update({
'status': 'phase1_processing',
'extra': {
**file_row.get('extra', {}),
'phase1_tasks': phase1_tasks,
'processing_started_at': time.time()
}
}).eq('id', queued_file.file_id).execute()
logger.info(f"✅ File {queued_file.file_id} processing initiated")
async def _handle_pdf_conversion(self, file_row: Dict[str, Any]) -> str:
"""Handle PDF conversion asynchronously."""
if file_row['mime_type'] == 'application/pdf':
return file_row['path']
# TODO: Implement async PDF conversion
# For now, return original path and handle conversion in pipeline
logger.info(f"PDF conversion queued for file {file_row['id']}")
return file_row['path']
async def _update_processing_status(self, file_id: str, status: str, error: str = None):
"""Update file processing status."""
status_data = {
'file_id': file_id,
'status': status,
'timestamp': time.time(),
'error': error
}
# Store in Redis for real-time updates
status_key = f"{self.processing_status_key}:{file_id}"
self.redis_client.setex(status_key, 86400, json.dumps(status_data)) # 24h expiry
# Update database
client = SupabaseServiceRoleClient()
client.supabase.table('files').update({
'status': status,
'error_message': error
}).eq('id', file_id).execute()
logger.info(f"📊 Status update for {file_id}: {status}")
def get_processing_status(self, file_id: str) -> Dict[str, Any]:
"""Get current processing status for a file."""
status_key = f"{self.processing_status_key}:{file_id}"
status_json = self.redis_client.get(status_key)
if status_json:
return json.loads(status_json)
# Fallback to database
client = SupabaseServiceRoleClient()
result = client.supabase.table('files').select('status, error_message, extra').eq('id', file_id).single().execute()
if result.data:
return {
'file_id': file_id,
'status': result.data['status'],
'error': result.data.get('error_message'),
'extra': result.data.get('extra', {})
}
return {'file_id': file_id, 'status': 'not_found'}
def _estimate_processing_time(self, file_size: int, mime_type: str) -> Dict[str, Any]:
"""Estimate processing time for a file."""
# Base time estimates (in seconds)
base_times = {
'application/pdf': 60, # 1 minute per MB
'application/msword': 120, # 2 minutes per MB
'image/': 30 # 30 seconds per MB
}
# Find matching mime type
time_per_mb = 60 # default
for mime_prefix, time_val in base_times.items():
if mime_type.startswith(mime_prefix):
time_per_mb = time_val
break
file_size_mb = file_size / (1024 * 1024)
estimated_seconds = int(file_size_mb * time_per_mb)
return {
'estimated_seconds': estimated_seconds,
'estimated_minutes': estimated_seconds / 60,
'phases': {
'pdf_conversion': estimated_seconds * 0.2,
'metadata_extraction': estimated_seconds * 0.3,
'docling_processing': estimated_seconds * 0.5
}
}
def _get_recommendations(self, queue_info: Dict[str, Any]) -> List[str]:
"""Get recommendations for user when upload is rejected."""
recommendations = []
if queue_info.get('reason') == 'file_too_large':
recommendations.append("Try compressing your file or splitting it into smaller parts")
if queue_info.get('utilization', 0) > 0.9:
recommendations.append("System is currently overloaded. Try uploading during off-peak hours")
recommendations.append("Consider uploading smaller files first")
if queue_info.get('user_current', 0) > 0:
recommendations.append("Wait for your current uploads to complete before uploading more")
if not recommendations:
recommendations.append("Please try again in a few minutes")
return recommendations
# Convenience functions
def get_upload_handler(environment: str = "dev") -> EnhancedUploadHandler:
"""Get enhanced upload handler instance."""
return EnhancedUploadHandler(environment)
import json

View File

@ -0,0 +1,997 @@
import os
import io
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, BackgroundTasks
from typing import Any, Dict, Optional
import uuid
import re
import requests
import os
import tempfile
from pathlib import Path
from modules.auth.supabase_bearer import SupabaseBearer, verify_supabase_jwt_str
from modules.logger_tool import initialise_logger
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
from modules.database.supabase.utils.storage import StorageAdmin
from modules.document_processor import DocumentProcessor
from modules.queue_system import (
enqueue_tika_task, enqueue_docling_task, enqueue_split_map_task,
enqueue_document_analysis_task, enqueue_page_images_task,
TaskPriority, get_queue, QueueConnectionError
)
from fastapi.responses import Response
from fastapi import Body
router = APIRouter()
auth = SupabaseBearer()
doc_processor = DocumentProcessor()
DEFAULT_BUCKET = os.getenv('DEFAULT_FILES_BUCKET', 'cc.users')
# Timeout configurations (in seconds)
TIKA_TIMEOUT = int(os.getenv('TIKA_TIMEOUT', '300')) # 5 minutes default
DOCLING_FRONTMATTER_TIMEOUT = int(os.getenv('DOCLING_FRONTMATTER_TIMEOUT', '1800')) # 30 minutes default
DOCLING_NOOCR_TIMEOUT = int(os.getenv('DOCLING_NOOCR_TIMEOUT', '3600')) # 1 hour default
# (Legacy feature flags removed - using new three-phase system)
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
def _safe_filename(name: str) -> str:
base = os.path.basename(name or 'file')
return re.sub(r"[^A-Za-z0-9._-]+", "_", base)
def _choose_bucket(scope: str, user_id: str, school_id: Optional[str]) -> str:
scope = (scope or 'teacher').lower()
if scope == 'school' and school_id:
return f"cc.institutes.{school_id}.private"
# teacher / student fall back to users bucket for now
return 'cc.users'
@router.post("/files/upload")
async def upload_file(
cabinet_id: str = Form(...),
path: str = Form(...),
scope: str = Form('teacher'),
school_id: Optional[str] = Form(default=None),
file: UploadFile = File(...),
payload: Dict[str, Any] = Depends(auth),
background_tasks: BackgroundTasks = None
):
user_id = payload.get('sub') or payload.get('user_id')
if not user_id:
raise HTTPException(status_code=401, detail="Invalid token payload")
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
# Determine target bucket by scope
bucket = _choose_bucket(scope, user_id, school_id)
# Stage DB row to get file_id
staged_path = f"{cabinet_id}/staging/{uuid.uuid4()}"
name = _safe_filename(path or file.filename)
file_bytes = await file.read()
insert_res = client.supabase.table('files').insert({
'cabinet_id': cabinet_id,
'name': name,
'path': staged_path,
'bucket': bucket,
'mime_type': file.content_type,
'uploaded_by': user_id,
'size_bytes': len(file_bytes),
'source': 'classroomcopilot-web'
}).execute()
if not insert_res.data:
raise HTTPException(status_code=500, detail="Failed to create file record")
file_row = insert_res.data[0]
file_id = file_row['id']
# Final storage path: bucket/cabinet_id/file_id/file
final_storage_path = f"{cabinet_id}/{file_id}/{name}"
try:
storage.upload_file(bucket, final_storage_path, file_bytes, file.content_type or 'application/octet-stream', upsert=True)
except Exception as e:
# cleanup staged row
client.supabase.table('files').delete().eq('id', file_id).execute()
raise HTTPException(status_code=500, detail=f"Storage upload failed: {str(e)}")
# Update DB path to final
update_res = client.supabase.table('files').update({
'path': final_storage_path
}).eq('id', file_id).execute()
# Kick off initial artefacts generation in background (Tika + Docling frontmatter + no-OCR)
try:
if background_tasks is not None:
logger.info(f"Scheduling initial artefacts generation for file_id={file_id}")
background_tasks.add_task(generate_initial_artefacts, file_id, payload)
else:
logger.info(f"Running initial artefacts generation synchronously for file_id={file_id}")
generate_initial_artefacts(file_id, payload)
except Exception as e:
logger.error(f"Failed to schedule initial artefacts for file_id={file_id}: {e}")
return update_res.data
@router.get("/files")
def list_files(cabinet_id: str, payload: Dict[str, Any] = Depends(auth)):
client = SupabaseServiceRoleClient()
res = client.supabase.table('files').select('*').eq('cabinet_id', cabinet_id).execute()
return res.data
@router.post("/files/{file_id}/move")
def move_file(file_id: str, body: Dict[str, Any], payload: Dict[str, Any] = Depends(auth)):
client = SupabaseServiceRoleClient()
updates = {}
if 'cabinet_id' in body:
updates['cabinet_id'] = body['cabinet_id']
if 'path' in body:
updates['path'] = body['path']
if not updates:
raise HTTPException(status_code=400, detail="No changes provided")
res = client.supabase.table('files').update(updates).eq('id', file_id).execute()
return res.data
@router.delete("/files/{file_id}")
def delete_file(file_id: str, payload: Dict[str, Any] = Depends(auth)):
client = SupabaseServiceRoleClient()
res = client.supabase.table('files').delete().eq('id', file_id).execute()
return res.data
@router.get("/files/{file_id}/artefacts")
def list_artefacts(file_id: str, payload: Dict[str, Any] = Depends(auth)):
client = SupabaseServiceRoleClient()
res = client.supabase.table('document_artefacts').select('*').eq('file_id', file_id).order('created_at', desc=True).execute()
return res.data
@router.get("/files/{file_id}/viewer-artefacts")
def list_viewer_artefacts(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""
Get artefacts organized for UI viewer display, including frontmatter JSON,
processing bundles, and analysis data with proper display metadata.
"""
client = SupabaseServiceRoleClient()
# Get all artefacts for the file
res = client.supabase.table('document_artefacts').select('*').eq('file_id', file_id).order('created_at', desc=True).execute()
all_artefacts = res.data or []
# Organize artefacts by category for UI display
viewer_artefacts = {
'document_analysis': [],
'processing_bundles': [],
'raw_data': []
}
for artefact in all_artefacts:
artefact_type = artefact.get('type', '')
extra = artefact.get('extra', {})
# Enhanced artefact info for UI display
artefact_info = {
'id': artefact['id'],
'type': artefact_type,
'display_name': extra.get('display_name'),
'bundle_label': extra.get('bundle_label'),
'section_title': extra.get('section_title'),
'page_range': extra.get('page_range'),
'page_count': extra.get('page_count'),
'pipeline': extra.get('pipeline'),
'processing_mode': extra.get('processing_mode'),
'ui_order': extra.get('ui_order', 999),
'description': extra.get('description'),
'viewer_type': extra.get('viewer_type', 'json'),
'created_at': artefact['created_at'],
'status': artefact.get('status', 'unknown')
}
# Categorize artefacts for UI organization
if artefact_type == 'docling_frontmatter_json':
artefact_info.update({
'display_name': artefact_info['display_name'] or 'Document Frontmatter',
'bundle_label': artefact_info['bundle_label'] or 'Frontmatter Analysis',
'description': artefact_info['description'] or 'OCR analysis of document structure and metadata',
'ui_order': 1,
'viewer_type': 'json'
})
viewer_artefacts['document_analysis'].append(artefact_info)
elif artefact_type == 'split_map_json':
artefact_info.update({
'display_name': 'Document Structure Map',
'bundle_label': 'Split Map',
'description': 'Document section boundaries and organization structure',
'ui_order': 2,
'viewer_type': 'json'
})
viewer_artefacts['document_analysis'].append(artefact_info)
elif artefact_type == 'tika_json':
artefact_info.update({
'display_name': 'Document Metadata',
'bundle_label': 'Tika Analysis',
'description': 'Raw document metadata and properties extracted by Apache Tika',
'ui_order': 3,
'viewer_type': 'json'
})
viewer_artefacts['raw_data'].append(artefact_info)
elif artefact_type in ['canonical_docling_json', 'docling_bundle_split', 'docling_bundle', 'docling_standard', 'docling_bundle_split_pages']:
# Processing bundles (OCR, No-OCR, VLM) - use original_pipeline for proper differentiation
pipeline_name = extra.get('original_pipeline', extra.get('pipeline', 'Unknown'))
bundle_label = artefact_info['bundle_label'] or f"{pipeline_name.upper().replace('_', '-')} Bundle"
display_name = artefact_info['display_name'] or f"{pipeline_name.upper().replace('_', '-')} Processing Result"
# Special handling for master manifests
if artefact_type == 'docling_bundle_split_pages':
display_name = f"{pipeline_name.upper().replace('_', '-')} Document Pages"
bundle_label = f"{pipeline_name.upper().replace('_', '-')} Pages Bundle"
artefact_info.update({
'viewer_type': 'bundle_collection',
'is_master_manifest': True,
'ui_order': 10 # Show master manifests before individual pages
})
elif artefact_type == 'docling_standard':
# Individual page bundles - lower UI priority
artefact_info.update({
'viewer_type': 'page_bundle',
'is_individual_page': True,
'ui_order': extra.get('split_order', 999) + 100 # Show after master manifests
})
artefact_info.update({
'display_name': display_name,
'bundle_label': bundle_label,
'description': f"Docling processing result using {pipeline_name.replace('_', '-')} pipeline",
'pipeline_type': pipeline_name # Add explicit pipeline type for UI
})
viewer_artefacts['processing_bundles'].append(artefact_info)
elif artefact_type.startswith('docling_') and artefact_type.endswith('_json'):
# Other docling JSON results
pipeline_name = artefact_type.replace('docling_', '').replace('_json', '').upper()
artefact_info.update({
'display_name': f"{pipeline_name} Analysis",
'bundle_label': f"{pipeline_name} Result",
'description': f"Docling {pipeline_name.lower()} processing result",
'viewer_type': 'json'
})
viewer_artefacts['processing_bundles'].append(artefact_info)
elif artefact_type == 'page_images':
artefact_info.update({
'display_name': 'Page Images',
'bundle_label': 'Visual Pages',
'description': 'Generated page images for document visualization',
'viewer_type': 'images'
})
viewer_artefacts['raw_data'].append(artefact_info)
# Sort each category by ui_order
for category in viewer_artefacts.values():
category.sort(key=lambda x: (x['ui_order'], x['created_at']))
return {
'file_id': file_id,
'categories': viewer_artefacts,
'total_artefacts': len(all_artefacts)
}
@router.post("/files/{file_id}/artefacts/initial")
def generate_initial_artefacts(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""
Generate initial artefacts using the new three-phase pipeline architecture.
Phase 1: Document Structure Discovery & Analysis
- Tika metadata extraction
- Page images generation
- Document structure analysis (LLM-enhanced)
- Split map generation
Phase 2: Triggered automatically after Phase 1 completion
"""
logger.info(f"Three-phase pipeline: Starting Phase 1 for file_id={file_id}")
from modules.pipeline_controller import get_pipeline_controller
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
controller = get_pipeline_controller()
# Load file row
fr = client.supabase.table('files').select('*').eq('id', file_id).single().execute()
file_row = fr.data
if not file_row:
raise HTTPException(status_code=404, detail="File not found")
bucket = file_row['bucket']
storage_path = file_row['path']
cabinet_id = file_row['cabinet_id']
mime = file_row.get('mime_type') or 'application/octet-stream'
filename = file_row.get('name', 'file')
# Step 1: Convert to PDF if not already a PDF (synchronous for now)
processing_path = storage_path
processing_mime = mime
if mime != 'application/pdf':
logger.info(f"Converting non-PDF file to PDF: file_id={file_id} mime={mime}")
try:
file_bytes = storage.download_file(bucket, storage_path)
with tempfile.TemporaryDirectory() as temp_dir:
# Save original file to temp location
temp_input = Path(temp_dir) / filename
with open(temp_input, 'wb') as f:
f.write(file_bytes)
# Convert to PDF
pdf_bytes = doc_processor.convert_to_pdf(temp_input)
# Store PDF as artefact
pdf_artefact_id = str(uuid.uuid4())
pdf_rel_path = f"{cabinet_id}/{file_id}/{pdf_artefact_id}/document.pdf"
storage.upload_file(bucket, pdf_rel_path, pdf_bytes, 'application/pdf', upsert=True)
pdf_ar = client.supabase.table('document_artefacts').insert({
'file_id': file_id,
'type': 'document_pdf',
'rel_path': pdf_rel_path,
'extra': {'converted_from': mime, 'original_filename': filename},
'status': 'completed'
}).execute()
# Use converted PDF for subsequent processing
processing_path = pdf_rel_path
processing_mime = 'application/pdf'
logger.info(f"PDF conversion: completed file_id={file_id} rel_path={pdf_rel_path}")
except Exception as e:
logger.error(f"PDF conversion: error processing file_id={file_id}: {e}")
# Continue with original file if conversion fails
else:
logger.info(f"File is already PDF, skipping conversion: file_id={file_id}")
# Step 2: Enqueue Phase 1 tasks using the new pipeline controller
user_id = payload.get('sub') or payload.get('user_id')
priority = TaskPriority.HIGH if user_id else TaskPriority.NORMAL
try:
# Update file row with processing path
updated_file_row = {**file_row, 'path': processing_path, 'mime_type': processing_mime}
# Enqueue Phase 1 tasks
phase1_tasks = controller.enqueue_phase1_tasks(
file_id=file_id,
file_row=updated_file_row,
processing_path=processing_path,
processing_mime=processing_mime,
priority=priority
)
total_tasks = sum(len(task_list) for task_list in phase1_tasks.values())
logger.info(f"Three-phase pipeline: Enqueued {total_tasks} Phase 1 tasks for file_id={file_id}")
return {
'message': f'Three-phase pipeline: Enqueued {total_tasks} Phase 1 tasks. Phase 2 will trigger automatically after completion.',
'phase1_tasks': {k: v for k, v in phase1_tasks.items()},
'file_id': file_id,
'pipeline_mode': 'three_phase',
'bundle_architecture_enabled': True
}
except QueueConnectionError as e:
logger.error(f"Queue system unavailable for file_id={file_id}: {e}")
logger.error("Redis is not running. Please start the API server with './start.sh dev' to auto-start Redis.")
return {
'message': 'File uploaded successfully, but processing tasks could not be queued (Redis unavailable)',
'file_id': file_id,
'queue_status': 'unavailable',
'error': 'Queue system unavailable. Please restart the API server with Redis enabled.'
}
except Exception as e:
logger.error(f"Unexpected error enqueueing Phase 1 tasks for file_id={file_id}: {e}")
return {
'message': 'File uploaded successfully, but processing tasks failed to queue',
'file_id': file_id,
'queue_status': 'failed',
'error': str(e)
}
@router.get("/files/{file_id}/page-images/manifest")
def get_page_images_manifest(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Return the page_images manifest JSON for a file via service-role access."""
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
# Find file row to get bucket
fr = client.supabase.table('files').select('id,bucket,cabinet_id').eq('id', file_id).single().execute()
file_row = fr.data or {}
if not file_row:
raise HTTPException(status_code=404, detail="File not found")
bucket = file_row['bucket']
cabinet_id = file_row['cabinet_id']
# Find page_images artefact
arts = client.supabase.table('document_artefacts') \
.select('id,type,rel_path,extra') \
.eq('file_id', file_id).eq('type', 'page_images') \
.order('created_at', desc=True).limit(1).execute().data or []
if not arts:
raise HTTPException(status_code=404, detail="page_images artefact not found")
art = arts[0]
# Manifest path
manifest_rel_path = (art.get('extra') or {}).get('manifest') or f"{art['rel_path'].rstrip('/')}/page_images.json"
try:
raw = storage.download_file(bucket, manifest_rel_path)
import json as _json
manifest = _json.loads(raw.decode('utf-8'))
# Ensure bucket and base prefix are present for the UI
manifest.setdefault('bucket', bucket)
manifest.setdefault('base_dir', art['rel_path'])
return manifest
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to load manifest: {e}")
def json_dumps(obj: Any) -> str:
try:
import json
return json.dumps(obj, ensure_ascii=False)
except Exception:
return "{}"
@router.get("/files/{file_id}/artefacts/{artefact_id}/json")
def get_artefact_json(file_id: str, artefact_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Return the JSON content of a document artefact using service-role storage access."""
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
# Look up artefact to get rel_path and validate it belongs to file
ar = client.supabase.table('document_artefacts').select('id,file_id,rel_path').eq('id', artefact_id).single().execute()
artefact = ar.data
if not artefact:
raise HTTPException(status_code=404, detail="Artefact not found")
if artefact.get('file_id') != file_id:
raise HTTPException(status_code=400, detail="Artefact does not belong to file")
# Look up file to get bucket
fr = client.supabase.table('files').select('bucket').eq('id', file_id).single().execute()
file_row = fr.data
if not file_row:
raise HTTPException(status_code=404, detail="File not found")
bucket = file_row['bucket']
rel_path = artefact['rel_path']
try:
raw = storage.download_file(bucket, rel_path)
import json as _json
data = _json.loads(raw.decode('utf-8'))
return data
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to load artefact JSON: {str(e)}")
@router.get("/files/{file_id}/artefacts/{artefact_id}/vlm-section-manifest")
def get_vlm_section_manifest(file_id: str, artefact_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Return the VLM section page bundle manifest JSON for a VLM section bundle artefact."""
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
ar = client.supabase.table('document_artefacts').select('id,file_id,rel_path,type,extra').eq('id', artefact_id).single().execute().data
if not ar:
raise HTTPException(status_code=404, detail="Artefact not found")
if ar.get('file_id') != file_id:
raise HTTPException(status_code=400, detail="Artefact does not belong to file")
if ar.get('type') != 'vlm_section_page_bundle':
raise HTTPException(status_code=400, detail="Artefact is not a VLM section page bundle")
fr = client.supabase.table('files').select('bucket').eq('id', file_id).single().execute().data
if not fr:
raise HTTPException(status_code=404, detail="File not found")
bucket = fr['bucket']
# The rel_path directly points to the manifest JSON file
manifest_rel_path = ar['rel_path']
try:
raw = storage.download_file(bucket, manifest_rel_path)
import json as _json
data = _json.loads(raw.decode('utf-8'))
# ensure bucket present for client use
data.setdefault('bucket', bucket)
return data
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to load VLM section manifest: {e}")
@router.post("/files/{file_id}/artefacts/outline")
def enqueue_outline_structure(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""
Manually enqueue the fast document outline (headings-only) analysis for an existing file.
Returns the queued task id.
"""
client = SupabaseServiceRoleClient()
fr = client.supabase.table('files').select('id,bucket,cabinet_id,path,mime_type').eq('id', file_id).single().execute()
file_row = fr.data
if not file_row:
raise HTTPException(status_code=404, detail="File not found")
bucket = file_row['bucket']
storage_path = file_row['path']
cabinet_id = file_row['cabinet_id']
mime = file_row.get('mime_type') or 'application/pdf'
# Prefer converted PDF artefact if available
arts = client.supabase.table('document_artefacts').select('type,rel_path').eq('file_id', file_id).order('created_at', desc=True).execute().data or []
pdf_art = next((a for a in arts if a.get('type') == 'document_pdf'), None)
processing_path = pdf_art['rel_path'] if pdf_art else storage_path
try:
task_id = enqueue_docling_task(
file_id=file_id,
task_type='document_structure_analysis',
payload={
'bucket': bucket,
'file_path': processing_path,
'cabinet_id': cabinet_id,
'mime_type': mime,
'config': {
'target_type': 'inbody',
'to_formats': 'json',
'do_ocr': False,
'force_ocr': False
}
},
priority=TaskPriority.NORMAL,
timeout=300
)
return { 'message': 'outline task enqueued', 'task_id': task_id, 'file_id': file_id }
except QueueConnectionError as e:
raise HTTPException(status_code=503, detail=f"Queue unavailable: {e}")
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to enqueue outline task: {e}")
@router.get("/files/proxy")
def proxy_storage_file(bucket: str, path: str, payload: Dict[str, Any] = Depends(auth)):
"""Proxy a storage file (service-role), useful for private image access in the UI."""
storage = StorageAdmin()
try:
data = storage.download_file(bucket, path)
media = 'application/octet-stream'
lp = path.lower()
if lp.endswith('.png'):
media = 'image/png'
elif lp.endswith('.webp'):
media = 'image/webp'
elif lp.endswith('.jpg') or lp.endswith('.jpeg'):
media = 'image/jpeg'
elif lp.endswith('.json'):
media = 'application/json'
return Response(content=data, media_type=media)
except Exception as e:
raise HTTPException(status_code=404, detail=f"File not found or inaccessible: {e}")
# Signed proxy for iframe/img tags without Authorization header
@router.get("/files/proxy_signed")
def proxy_storage_file_signed(bucket: str, path: str, token: str):
"""Proxy using a signed bearer token passed as query param 'token'."""
try:
payload = verify_supabase_jwt_str(token)
if not payload:
raise HTTPException(status_code=403, detail="Invalid token")
except Exception as e:
raise HTTPException(status_code=403, detail=f"Invalid token: {e}")
storage = StorageAdmin()
try:
data = storage.download_file(bucket, path)
media = 'application/octet-stream'
lp = path.lower()
if lp.endswith('.png'):
media = 'image/png'
elif lp.endswith('.webp'):
media = 'image/webp'
elif lp.endswith('.jpg') or lp.endswith('.jpeg'):
media = 'image/jpeg'
elif lp.endswith('.json'):
media = 'application/json'
return Response(content=data, media_type=media)
except Exception as e:
raise HTTPException(status_code=404, detail=f"File not found or inaccessible: {e}")
# -------- Canonical bundle manifest ---------
@router.get("/files/{file_id}/artefacts/{artefact_id}/manifest")
def get_canonical_manifest(file_id: str, artefact_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Return the manifest.json for a canonical_docling_bundle artefact."""
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
ar = client.supabase.table('document_artefacts').select('id,file_id,rel_path,extra').eq('id', artefact_id).single().execute().data
if not ar:
raise HTTPException(status_code=404, detail="Artefact not found")
if ar.get('file_id') != file_id:
raise HTTPException(status_code=400, detail="Artefact does not belong to file")
extra = ar.get('extra') or {}
manifest_rel_path = extra.get('manifest')
if not manifest_rel_path:
raise HTTPException(status_code=404, detail="Manifest path not recorded on artefact")
fr = client.supabase.table('files').select('bucket').eq('id', file_id).single().execute().data
if not fr:
raise HTTPException(status_code=404, detail="File not found")
bucket = fr['bucket']
try:
raw = storage.download_file(bucket, manifest_rel_path)
import json as _json
data = _json.loads(raw.decode('utf-8'))
# ensure bucket present for client use
data.setdefault('bucket', bucket)
return data
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to load manifest: {e}")
# -------- Canonical Docling generation ---------
def _load_split_map(client: SupabaseServiceRoleClient, storage: StorageAdmin, bucket: str, file_id: str) -> Optional[Dict[str, Any]]:
try:
arts = client.supabase.table('document_artefacts') \
.select('id,type,rel_path') \
.eq('file_id', file_id).eq('type', 'split_map_json') \
.order('created_at', desc=True).limit(1).execute().data or []
if not arts:
return None
art = arts[0]
raw = storage.download_file(bucket, art['rel_path'])
import json as _json
return _json.loads(raw.decode('utf-8'))
except Exception:
return None
@router.post("/files/{file_id}/artefacts/canonical-docling")
def enqueue_canonical_docling(
file_id: str,
body: Dict[str, Any] = Body(default={}),
payload: Dict[str, Any] = Depends(auth)
):
"""Enqueue generation of canonical Docling JSON(s) for a file.
If a split_map is available and the document is large, this will enqueue
multiple Docling jobs using page ranges per section. Otherwise a single
job is created for the whole document.
"""
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
fr = client.supabase.table('files').select('*').eq('id', file_id).single().execute()
file_row = fr.data
if not file_row:
raise HTTPException(status_code=404, detail="File not found")
bucket = file_row['bucket']
cabinet_id = file_row['cabinet_id']
mime = file_row.get('mime_type') or 'application/pdf'
storage_path = file_row['path']
# Prefer converted PDF if available
try:
arts = client.supabase.table('document_artefacts').select('type,rel_path').eq('file_id', file_id).order('created_at', desc=True).execute().data or []
a_pdf = next((a for a in arts if a.get('type') == 'document_pdf'), None)
processing_path = a_pdf['rel_path'] if a_pdf else storage_path
processing_mime = 'application/pdf' if a_pdf else mime
except Exception:
processing_path = storage_path
processing_mime = mime
# Determine page_count (prefer Tika; fallback to PDF parser if needed)
page_count = None
try:
arts_pc = client.supabase.table('document_artefacts').select('type,rel_path').eq('file_id', file_id).execute().data or []
a_tika_pc = next((a for a in arts_pc if a.get('type') == 'tika_json'), None)
if a_tika_pc:
raw = storage.download_file(bucket, a_tika_pc['rel_path'])
import json as _json
tj = _json.loads(raw.decode('utf-8'))
for k in ("xmpTPg:NPages", "Page-Count", "pdf:PageCount"):
v = tj.get(k) or tj.get(k.lower())
if v is not None:
page_count = int(v)
break
except Exception as e:
logger.debug(f"[canonical-docling] Tika page_count read failed: {e}")
pass
# Fallback: compute page_count from PDF if Tika did not provide it
if page_count is None:
try:
pdf_bytes = storage.download_file(bucket, processing_path)
try:
import fitz # PyMuPDF
doc = fitz.open(stream=pdf_bytes, filetype='pdf')
page_count = int(doc.page_count)
doc.close()
logger.info(f"[canonical-docling] page_count via PyMuPDF: {page_count}")
except Exception:
try:
from PyPDF2 import PdfReader
reader = PdfReader(io.BytesIO(pdf_bytes))
page_count = int(len(reader.pages))
logger.info(f"[canonical-docling] page_count via PyPDF2: {page_count}")
except Exception:
page_count = None
except Exception:
page_count = None
else:
logger.info(f"[canonical-docling] page_count via Tika: {page_count}")
# Optional custom range from caller
custom_range = body.get('custom_range')
custom_label = body.get('custom_label') or ''
selected_section_id = body.get('selected_section_id')
selected_section_title = body.get('selected_section_title')
# Load split map if requested and document is large enough
use_split_requested = bool(body.get('use_split_map', True))
split_threshold = int(body.get('threshold') or os.getenv('DOCLING_SPLIT_THRESHOLD', '50'))
ranges = [] # list of (start,end)
split_map = None
sections = [] # list of dicts: {start,end,title}
logger.info(f"[canonical-docling] use_split_map={use_split_requested} threshold={split_threshold} page_count={page_count}")
# If custom range provided, honor it and bypass split map
if isinstance(custom_range, list) and len(custom_range) >= 2:
try:
cs = int(custom_range[0]); ce = int(custom_range[1])
if page_count is not None:
cs = max(1, min(cs, page_count))
ce = max(cs, min(ce, page_count))
ranges = [(cs, ce)]
sections = [{'start': cs, 'end': ce, 'title': custom_label or 'Custom range'}]
use_split_requested = False
logger.info(f"[canonical-docling] using custom_range start={cs} end={ce} label='{custom_label}'")
except Exception as _e:
logger.warning(f"[canonical-docling] invalid custom_range; falling back. err={_e}")
if not ranges and use_split_requested and (page_count is None or page_count >= split_threshold):
split_map = _load_split_map(client, storage, bucket, file_id)
entries = (split_map or {}).get('entries') if split_map else []
logger.info(f"[canonical-docling] split_map loaded entries={len(entries) if isinstance(entries, list) else 0}")
if split_map and isinstance(entries, list) and len(entries) > 0:
# Normalize and sort entries by start_page to enforce correct order
norm: list[dict] = []
for e in entries:
try:
s = int(e.get('start_page', 1))
t = int(e.get('end_page', s))
if t < s:
t = s
title = e.get('title') or e.get('label') or ''
norm.append({'start': s, 'end': t, 'title': title})
except Exception:
continue
norm.sort(key=lambda x: x['start'])
# Deduplicate identical or overlapping starts by keeping the earliest occurrence
ordered: list[dict] = []
last_end = 0
for e in norm:
s, t = int(e['start']), int(e['end'])
if ordered and s <= last_end:
# Clamp to prevent inversion and maintain order
s = last_end + 1
if s > (page_count or s):
continue
if t < s:
t = s
last_end = max(last_end, t)
ordered.append({'start': s, 'end': t, 'title': e['title']})
for e in ordered:
ranges.append((e['start'], e['end']))
sections.append(e)
# Fallback: if no split_map ranges... we shouldn't be here
if not ranges:
# If document is large, split into fixed windows to protect Docling server
if page_count is not None and page_count >= split_threshold:
chunk = int(os.getenv('DOCLING_FALLBACK_CHUNK_PAGES', '25'))
chunk = max(5, min(100, chunk))
for i in range(1, (page_count or 1) + 1, chunk):
end = min(i + chunk - 1, page_count or i)
ranges.append((i, end))
sections.append({'start': i, 'end': end, 'title': f"Pages {i}-{end}"})
logger.warning(f"[canonical-docling] using fallback chunking ranges={len(ranges)} chunk={chunk}")
else:
ranges = [(1, page_count or 9223372036854775807)]
logger.warning(f"[canonical-docling] using single-range fallback (small doc)")
# Build config
cfg = body.get('config', {})
pipeline = cfg.get('pipeline', 'standard')
config: Dict[str, Any] = {
# target_type is computed in processor based on to_formats unless explicitly provided by user
'to_formats': cfg.get('to_formats', 'json'),
'do_ocr': bool(cfg.get('do_ocr', True)),
'force_ocr': bool(cfg.get('force_ocr', False)),
'image_export_mode': cfg.get('image_export_mode', 'embedded'),
'ocr_engine': cfg.get('ocr_engine', 'easyocr'),
'ocr_lang': cfg.get('ocr_lang', 'en'),
'pdf_backend': cfg.get('pdf_backend', 'dlparse_v4'),
'table_mode': cfg.get('table_mode', 'fast'),
'pipeline': pipeline,
'do_picture_classification': bool(cfg.get('do_picture_classification', False)),
'do_picture_description': bool(cfg.get('do_picture_description', False)),
}
# If user explicitly set target_type, pass it through
if 'target_type' in cfg:
config['target_type'] = cfg['target_type']
# Optional VLM settings (only include API fields if provided as JSON by caller)
if config['do_picture_description']:
pd_api = cfg.get('picture_description_api')
if isinstance(pd_api, (dict, list)):
config['picture_description_api'] = pd_api
elif isinstance(pd_api, str) and pd_api.strip().startswith(('{', '[')):
config['picture_description_api'] = pd_api
if cfg.get('picture_description_prompt'):
config['picture_description_prompt'] = cfg['picture_description_prompt']
if pipeline == 'vlm':
# Provider presets mapping
provider = (cfg.get('vlm_provider') or '').strip().lower()
provider_model = (cfg.get('vlm_provider_model') or '').strip()
provider_base = (cfg.get('vlm_provider_base_url') or '').strip()
if provider in ('ollama', 'openai') and provider_model:
if provider == 'ollama':
base_url = provider_base or os.getenv('OLLAMA_BASE_URL') or os.getenv('VLM_OLLAMA_BASE_URL')
if base_url:
endpoint = f"{base_url.rstrip('/')}/v1/chat/completions"
# Use OpenAI provider schema against Ollama's OpenAI-compatible endpoint
cfg_api = {
'provider': 'openai',
'url': endpoint,
'model': provider_model,
'response_format': 'markdown',
'request_params': {'model': provider_model}
}
logger.info(f"[canonical-docling] VLM provider=ollama mapped to openai-compatible url={endpoint} model={provider_model}")
config['vlm_pipeline_model_api'] = cfg_api
# Also wire picture_description_api if picture description is enabled
if config.get('do_picture_description'):
config['picture_description_api'] = {
'url': endpoint,
'headers': {},
'params': {'model': provider_model}
}
elif provider == 'openai':
base_url = provider_base or os.getenv('OPENAI_BASE_URL') or 'https://api.openai.com/v1'
api_key = os.getenv('OPENAI_API_KEY') or os.getenv('OPENAI_API_KEY_READONLY')
# Do not inline key if not present; server may have default
model_cfg: Dict[str, Any] = {
'provider': 'openai',
'url': f"{base_url.rstrip('/')}/chat/completions",
'model': provider_model,
'response_format': 'markdown',
'request_params': {'model': provider_model}
}
if api_key:
model_cfg['api_key'] = api_key
# Also pass explicit Authorization header for servers that expect it
model_cfg['headers'] = {
'Authorization': f"Bearer {api_key}"
}
logger.info(f"[canonical-docling] VLM provider=openai url={model_cfg['url']} model={provider_model} api_key={'yes' if api_key else 'no'}")
config['vlm_pipeline_model_api'] = model_cfg
# Also wire picture_description_api if picture description is enabled
if config.get('do_picture_description'):
headers = {'Authorization': f"Bearer {api_key}"} if api_key else {}
config['picture_description_api'] = {
'url': f"{base_url.rstrip('/')}/chat/completions",
'headers': headers,
'params': {'model': provider_model}
}
else:
# Pass through explicit API/local JSON if provided by caller
vpa = cfg.get('vlm_pipeline_model_api')
if isinstance(vpa, (dict, list)):
config['vlm_pipeline_model_api'] = vpa
elif isinstance(vpa, str) and vpa.strip().startswith(('{', '[')):
config['vlm_pipeline_model_api'] = vpa
# Enqueue tasks for each range
priority = TaskPriority.HIGH
task_ids = []
multi = len(ranges) > 1
logger.info(f"[canonical-docling] final ranges={len(ranges)} multi={multi} pipeline={pipeline} producer={body.get('producer', 'manual')}")
# Create a group id for split bundles (used for UI grouping)
# Use provided group_id if present (for two-pass auto system), otherwise generate new
group_id = body.get('group_id') or (str(uuid.uuid4()) if multi else None)
if multi and not sections:
# Build sections from ranges if titles were not captured
for (start, end) in ranges:
sections.append({'start': int(start), 'end': int(end), 'title': ''})
idx = 0
for (start, end) in ranges:
# Locate title for this range if available
title = ''
if multi and sections and idx < len(sections):
title = sections[idx].get('title') or ''
idx += 1
cfg_range = dict(config)
# Ensure 1-based inclusive range is passed through
cfg_range['page_range'] = [max(1, int(start)), max(int(start), int(end))]
extra = {
'is_subdoc': multi,
'page_range': [int(start), int(end)],
'label': (title or f"subdoc p{int(start)}-{int(end)}") if multi else 'canonical'
}
# Attach selected section metadata if provided by caller
if selected_section_id:
extra['selected_section_id'] = selected_section_id
if selected_section_title or custom_label:
extra['selected_section_title'] = selected_section_title or custom_label
# For split processing, force split bundle artefact type and add grouping/order metadata
if multi:
extra.update({
# UI grouping metadata
'split_order': idx,
'split_heading': title,
'split_total': len(ranges)
})
if group_id:
extra['group_id'] = group_id
extra['group_pack_type'] = 'docling_standard_auto_split'
else:
# Single-bundle case: allow caller to override type (defaults to canonical bundle)
if 'artefact_type_override' in body and body.get('artefact_type_override'):
extra['artefact_type_override'] = body.get('artefact_type_override')
# Mark producer and selection metadata
extra['producer'] = body.get('producer') or ('auto_split' if (multi and body.get('use_split_map')) else 'manual')
if selected_section_id:
extra['selected_section_id'] = selected_section_id
if selected_section_title or custom_label:
extra['selected_section_title'] = selected_section_title or custom_label
# Enhanced logging for canonical operations
if multi:
logger.info(f"[canonical-docling] enqueue range idx={idx}/{len(ranges)} start={start} end={end} title='{title}' group_id={group_id} producer={extra.get('producer')} pipeline={pipeline}")
else:
logger.info(f"[canonical-docling] enqueue single range start={start} end={end} producer={extra.get('producer')} pipeline={pipeline}")
tid = enqueue_docling_task(
file_id=file_id,
task_type='canonical_docling_subdoc_json' if multi else 'canonical_docling_json',
payload={
'bucket': bucket,
'file_path': processing_path,
'cabinet_id': cabinet_id,
'mime_type': processing_mime,
'config': cfg_range,
'artefact_extra': extra,
# Ensure canonical tasks respect upstream dependencies (e.g., Frontmatter)
'depends_on': body.get('depends_on', []),
# Pass through grouping info if provided by caller (kept for backward-compat)
'group_pack_type': body.get('group_pack_type')
},
priority=priority,
timeout=int(body.get('timeout', DOCLING_NOOCR_TIMEOUT))
)
task_ids.append(tid)
logger.info(f"[canonical-docling] completed enqueue file_id={file_id} tasks={len(task_ids)} ranges={len(ranges)} pipeline={pipeline} producer={body.get('producer','manual')} group_id={group_id if multi else 'single'}")
return {
'message': f'enqueued {len(task_ids)} canonical docling job(s)',
'task_ids': task_ids,
'ranges': ranges,
'used_split_map': bool(split_map),
'group_id': group_id,
'pipeline': pipeline,
'producer': body.get('producer', 'manual')
}

View File

@ -0,0 +1,411 @@
"""
Memory-Aware Queue Management System
====================================
Provides intelligent queue management based on memory usage and file sizes
rather than simple task count limits. Supports multiple users with fair
queuing and capacity management.
Features:
- Memory-based queue limits (not just task count)
- Fair queuing across multiple users
- Upload capacity checking with user feedback
- Graceful degradation under load
- Service-specific memory tracking
"""
import os
import time
import json
import uuid
import logging
from typing import Dict, List, Optional, Any, Tuple
from dataclasses import dataclass, asdict
from enum import Enum
import redis
from .redis_manager import get_redis_manager
import psutil
logger = logging.getLogger(__name__)
class QueueStatus(Enum):
ACCEPTING = "accepting" # Normal operation
BUSY = "busy" # High load, warn users
OVERLOADED = "overloaded" # Reject new uploads
MAINTENANCE = "maintenance" # Manual override
@dataclass
class MemoryConfig:
"""Memory configuration for queue management."""
max_total_memory_mb: int = 2048 # 2GB total queue memory
max_user_memory_mb: int = 512 # 512MB per user
max_file_size_mb: int = 100 # 100MB max file size
memory_warning_threshold: float = 0.8 # Warn at 80%
memory_reject_threshold: float = 0.95 # Reject at 95%
@dataclass
class QueuedFile:
"""Represents a file waiting in the queue."""
file_id: str
user_id: str
filename: str
size_bytes: int
mime_type: str
cabinet_id: str
priority: int = 1
queued_at: float = 0
estimated_processing_time: int = 300 # seconds
memory_estimate_mb: float = 0
def __post_init__(self):
if self.queued_at == 0:
self.queued_at = time.time()
# Estimate memory usage (rough heuristic)
self.memory_estimate_mb = self._estimate_memory_usage()
def _estimate_memory_usage(self) -> float:
"""Estimate memory usage for this file during processing."""
base_mb = self.size_bytes / (1024 * 1024)
# Processing multipliers based on operations
if self.mime_type == 'application/pdf':
# PDF: original + extracted text + images + thumbnails
return base_mb * 3.5
elif self.mime_type.startswith('image/'):
# Images: original + resized variants + OCR text
return base_mb * 2.5
else:
# Other docs: original + PDF conversion + processing
return base_mb * 4.0
class MemoryAwareQueue:
"""Memory-aware queue management system."""
def __init__(self, environment: str = "dev"):
self.redis_manager = get_redis_manager(environment)
self.redis_client = self.redis_manager.client
self.config = self._load_config()
# Redis keys
self.upload_queue_key = "upload_queue"
self.processing_memory_key = "processing_memory"
self.user_quota_key = "user_quotas"
self.system_status_key = "system_status"
logger.info(f"🧠 Memory-aware queue initialized (max: {self.config.max_total_memory_mb}MB)")
def _load_config(self) -> MemoryConfig:
"""Load memory configuration from environment."""
return MemoryConfig(
max_total_memory_mb=int(os.getenv('QUEUE_MAX_MEMORY_MB', '2048')),
max_user_memory_mb=int(os.getenv('QUEUE_MAX_USER_MEMORY_MB', '512')),
max_file_size_mb=int(os.getenv('MAX_FILE_SIZE_MB', '100')),
memory_warning_threshold=float(os.getenv('MEMORY_WARNING_THRESHOLD', '0.8')),
memory_reject_threshold=float(os.getenv('MEMORY_REJECT_THRESHOLD', '0.95'))
)
def check_upload_capacity(self, user_id: str, file_size_bytes: int,
mime_type: str) -> Tuple[bool, str, Dict[str, Any]]:
"""
Check if system can accept a new upload.
Returns:
(can_accept, message, queue_info)
"""
# Create temporary QueuedFile to estimate memory
temp_file = QueuedFile(
file_id="temp",
user_id=user_id,
filename="temp",
size_bytes=file_size_bytes,
mime_type=mime_type,
cabinet_id="temp"
)
file_memory_mb = temp_file.memory_estimate_mb
# Check file size limit
if file_size_bytes > (self.config.max_file_size_mb * 1024 * 1024):
return False, f"File too large (max: {self.config.max_file_size_mb}MB)", {}
# Get current memory usage
current_memory = self._get_current_memory_usage()
user_memory = self._get_user_memory_usage(user_id)
# Check user quota
if user_memory + file_memory_mb > self.config.max_user_memory_mb:
return False, f"User quota exceeded (limit: {self.config.max_user_memory_mb}MB)", {
'user_current': user_memory,
'user_limit': self.config.max_user_memory_mb
}
# Check system capacity
total_after = current_memory + file_memory_mb
max_memory = self.config.max_total_memory_mb
if total_after > (max_memory * self.config.memory_reject_threshold):
queue_info = self._get_queue_info()
return False, "System overloaded. Please try again later.", {
'current_memory': current_memory,
'max_memory': max_memory,
'utilization': current_memory / max_memory,
'queue_position': queue_info['total_queued'] + 1
}
# Calculate wait time estimate
wait_estimate = self._estimate_wait_time(user_id)
status = "ready"
message = "Upload accepted"
if total_after > (max_memory * self.config.memory_warning_threshold):
status = "busy"
message = f"System busy. Estimated wait: {wait_estimate // 60}m {wait_estimate % 60}s"
return True, message, {
'status': status,
'estimated_wait_seconds': wait_estimate,
'memory_usage': {
'current': current_memory,
'after_upload': total_after,
'limit': max_memory,
'utilization': total_after / max_memory
},
'user_quota': {
'used': user_memory,
'after_upload': user_memory + file_memory_mb,
'limit': self.config.max_user_memory_mb
}
}
def enqueue_file(self, file_id: str, user_id: str, filename: str,
size_bytes: int, mime_type: str, cabinet_id: str,
priority: int = 1) -> Dict[str, Any]:
"""
Add file to upload queue.
Returns:
Queue information including position and estimated wait time
"""
queued_file = QueuedFile(
file_id=file_id,
user_id=user_id,
filename=filename,
size_bytes=size_bytes,
mime_type=mime_type,
cabinet_id=cabinet_id,
priority=priority
)
# Serialize and add to Redis queue (priority queue: higher priority = lower score)
score = time.time() - (priority * 1000000) # Priority affects score significantly
self.redis_client.zadd(
self.upload_queue_key,
{json.dumps(asdict(queued_file)): score}
)
# Update user quota tracking
self._update_user_quota(user_id, queued_file.memory_estimate_mb, increment=True)
# Get queue position and wait estimate
position = self._get_queue_position(file_id)
wait_estimate = self._estimate_wait_time(user_id)
logger.info(f"📋 Queued file {file_id} for user {user_id} (pos: {position}, wait: {wait_estimate}s)")
return {
'queued': True,
'file_id': file_id,
'queue_position': position,
'estimated_wait_seconds': wait_estimate,
'memory_estimate_mb': queued_file.memory_estimate_mb
}
def dequeue_next_file(self, service_name: str) -> Optional[QueuedFile]:
"""
Get next file from queue for processing.
Args:
service_name: The service requesting work (for capacity management)
"""
# Check if service has capacity
service_memory = self._get_service_memory_usage(service_name)
service_limit = self._get_service_memory_limit(service_name)
if service_memory >= service_limit:
logger.debug(f"Service {service_name} at capacity ({service_memory}/{service_limit}MB)")
return None
# Get next item from priority queue (lowest score first)
items = self.redis_client.zrange(self.upload_queue_key, 0, 0, withscores=True)
if not items:
return None
file_data_json, score = items[0]
file_data = json.loads(file_data_json)
queued_file = QueuedFile(**file_data)
# Check if this file would exceed service memory limit
if service_memory + queued_file.memory_estimate_mb > service_limit:
# Skip this file for now, try smaller ones later
logger.debug(f"File {queued_file.file_id} too large for {service_name} capacity")
return None
# Remove from queue
self.redis_client.zrem(self.upload_queue_key, file_data_json)
# Update tracking
self._update_user_quota(queued_file.user_id, queued_file.memory_estimate_mb, increment=False)
self._update_service_memory(service_name, queued_file.memory_estimate_mb, increment=True)
logger.info(f"🎯 Dequeued file {queued_file.file_id} for {service_name} processing")
return queued_file
def complete_processing(self, service_name: str, file_id: str, memory_used_mb: float):
"""Mark file processing as complete and free memory."""
self._update_service_memory(service_name, memory_used_mb, increment=False)
logger.info(f"✅ Completed processing {file_id} in {service_name} (freed {memory_used_mb}MB)")
def _get_current_memory_usage(self) -> float:
"""Get current total memory usage across all services."""
services = ['docling', 'tika', 'llm', 'document_analysis']
total = 0
for service in services:
service_key = f"{self.processing_memory_key}:{service}"
memory = float(self.redis_client.get(service_key) or 0)
total += memory
return total
def _get_user_memory_usage(self, user_id: str) -> float:
"""Get current memory usage for a specific user."""
user_key = f"{self.user_quota_key}:{user_id}"
return float(self.redis_client.get(user_key) or 0)
def _get_service_memory_usage(self, service_name: str) -> float:
"""Get current memory usage for a service."""
service_key = f"{self.processing_memory_key}:{service_name}"
return float(self.redis_client.get(service_key) or 0)
def _get_service_memory_limit(self, service_name: str) -> float:
"""Get memory limit for a service."""
# Service-specific memory limits as percentage of total
limits = {
'docling': 0.4, # 40% for Docling (memory-intensive)
'tika': 0.2, # 20% for Tika
'llm': 0.3, # 30% for LLM processing
'document_analysis': 0.1 # 10% for document analysis
}
percentage = limits.get(service_name, 0.1)
return self.config.max_total_memory_mb * percentage
def _update_user_quota(self, user_id: str, memory_mb: float, increment: bool):
"""Update user memory quota tracking."""
user_key = f"{self.user_quota_key}:{user_id}"
if increment:
self.redis_client.incrbyfloat(user_key, memory_mb)
else:
current = float(self.redis_client.get(user_key) or 0)
new_value = max(0, current - memory_mb)
self.redis_client.set(user_key, new_value)
# Set expiration for cleanup
self.redis_client.expire(user_key, 86400) # 24 hours
def _update_service_memory(self, service_name: str, memory_mb: float, increment: bool):
"""Update service memory usage tracking."""
service_key = f"{self.processing_memory_key}:{service_name}"
if increment:
self.redis_client.incrbyfloat(service_key, memory_mb)
else:
current = float(self.redis_client.get(service_key) or 0)
new_value = max(0, current - memory_mb)
self.redis_client.set(service_key, new_value)
# Set expiration for cleanup
self.redis_client.expire(service_key, 3600) # 1 hour
def _get_queue_position(self, file_id: str) -> int:
"""Get position of file in queue."""
items = self.redis_client.zrange(self.upload_queue_key, 0, -1)
for i, item in enumerate(items):
file_data = json.loads(item)
if file_data['file_id'] == file_id:
return i + 1
return 0
def _estimate_wait_time(self, user_id: str) -> int:
"""Estimate wait time for user's next file."""
# Simple estimation based on queue position and average processing time
queue_size = self.redis_client.zcard(self.upload_queue_key)
avg_processing_time = 300 # 5 minutes average
return int(queue_size * avg_processing_time * 0.5) # Assume parallel processing
def _get_queue_info(self) -> Dict[str, Any]:
"""Get comprehensive queue information."""
total_queued = self.redis_client.zcard(self.upload_queue_key)
current_memory = self._get_current_memory_usage()
max_memory = self.config.max_total_memory_mb
return {
'total_queued': total_queued,
'memory_usage': {
'current_mb': current_memory,
'max_mb': max_memory,
'utilization': current_memory / max_memory if max_memory > 0 else 0
},
'status': self._determine_system_status(current_memory, max_memory)
}
def _determine_system_status(self, current_memory: float, max_memory: float) -> str:
"""Determine current system status based on memory usage."""
utilization = current_memory / max_memory if max_memory > 0 else 0
if utilization >= self.config.memory_reject_threshold:
return "overloaded"
elif utilization >= self.config.memory_warning_threshold:
return "busy"
else:
return "ready"
def get_system_status(self) -> Dict[str, Any]:
"""Get comprehensive system status for monitoring."""
queue_info = self._get_queue_info()
# Service-specific info
services = {}
for service_name in ['docling', 'tika', 'llm', 'document_analysis']:
services[service_name] = {
'memory_used_mb': self._get_service_memory_usage(service_name),
'memory_limit_mb': self._get_service_memory_limit(service_name),
'utilization': self._get_service_memory_usage(service_name) / self._get_service_memory_limit(service_name)
}
return {
'status': queue_info['status'],
'queue': queue_info,
'services': services,
'config': asdict(self.config)
}
# Convenience functions
def get_memory_queue(environment: str = "dev") -> MemoryAwareQueue:
"""Get memory-aware queue instance."""
return MemoryAwareQueue(environment)
def check_upload_capacity(user_id: str, file_size: int, mime_type: str, environment: str = "dev") -> Tuple[bool, str, Dict]:
"""Quick capacity check for upload."""
queue = get_memory_queue(environment)
return queue.check_upload_capacity(user_id, file_size, mime_type)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

111
clear_stuck_tasks.py Normal file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env python3
"""
Clear stuck tasks from Redis queue after worker restart.
This script identifies tasks that are marked as "active" but have no
corresponding worker processing them, and returns them to the queue.
"""
import redis
import json
import os
import sys
from typing import List, Dict, Any
def get_redis_client():
"""Get Redis client using the same config as the main app."""
try:
from modules.redis_config import get_redis_url
return redis.from_url(get_redis_url())
except:
redis_url = os.getenv('REDIS_URL', 'redis://localhost:6379')
return redis.from_url(redis_url)
def check_stuck_tasks():
"""Check for stuck tasks in Redis."""
client = get_redis_client()
print("=== REDIS QUEUE STATUS ===")
processing_count = client.llen("document_processing")
failed_count = client.llen("document_processing:failed")
active_count = client.scard("active_tasks")
print(f"Processing queue: {processing_count} tasks")
print(f"Failed queue: {failed_count} tasks")
print(f"Active tasks: {active_count} tasks")
if active_count > 0:
print(f"\n⚠️ WARNING: {active_count} tasks marked as 'active' but workers may have been restarted!")
return True
elif processing_count > 0:
print(f"\n{processing_count} tasks waiting in queue (normal)")
return False
else:
print("\n✅ No stuck tasks found")
return False
def clear_stuck_tasks():
"""Move stuck 'active' tasks back to processing queue."""
client = get_redis_client()
# Get all active task IDs
active_tasks = client.smembers("active_tasks")
if not active_tasks:
print("No active tasks to clear")
return
cleared = 0
for task_id in active_tasks:
task_id_str = task_id.decode('utf-8')
try:
# Try to get the task data
task_data = client.get(f"task:{task_id_str}")
if task_data:
# Parse task to determine priority queue
task_obj = json.loads(task_data.decode('utf-8'))
priority = task_obj.get('priority', 'normal')
queue_key = {
'high': 'document_processing:high',
'normal': 'document_processing',
'low': 'document_processing:low'
}.get(priority, 'document_processing')
# Move task back to processing queue
client.lpush(queue_key, task_id_str)
client.srem("active_tasks", task_id_str)
cleared += 1
print(f"✅ Cleared stuck task: {task_id_str} ({task_obj.get('service', 'unknown')}/{task_obj.get('task_type', 'unknown')})")
else:
# Task data not found, just remove from active set
client.srem("active_tasks", task_id_str)
cleared += 1
print(f"🗑️ Removed orphaned active task: {task_id_str}")
except Exception as e:
print(f"❌ Failed to clear task {task_id_str}: {e}")
print(f"\n✅ Cleared {cleared} stuck tasks")
def main():
"""Main function."""
print("🔍 Checking for stuck tasks in Redis...")
try:
has_stuck = check_stuck_tasks()
if has_stuck:
response = input("\n❓ Clear stuck tasks? (y/N): ")
if response.lower() in ['y', 'yes']:
print("\n🧹 Clearing stuck tasks...")
clear_stuck_tasks()
print("\n✅ Done! Tasks should now be processed by workers.")
else:
print("Skipped clearing tasks.")
except Exception as e:
print(f"❌ Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()

View File

@ -1,624 +0,0 @@
URN,LA (code),LA (name),EstablishmentNumber,EstablishmentName,TypeOfEstablishment (name),EstablishmentTypeGroup (name),EstablishmentStatus (name),ReasonEstablishmentOpened (name),OpenDate,ReasonEstablishmentClosed (name),CloseDate,PhaseOfEducation (name),StatutoryLowAge,StatutoryHighAge,Boarders (name),NurseryProvision (name),OfficialSixthForm (name),Gender (name),ReligiousCharacter (name),ReligiousEthos (name),Diocese (name),AdmissionsPolicy (name),SchoolCapacity,SpecialClasses (name),CensusDate,NumberOfPupils,NumberOfBoys,NumberOfGirls,PercentageFSM,TrustSchoolFlag (name),Trusts (name),SchoolSponsorFlag (name),SchoolSponsors (name),FederationFlag (name),Federations (name),UKPRN,FEHEIdentifier,FurtherEducationType (name),OfstedLastInsp,LastChangedDate,Street,Locality,Address3,Town,County (name),Postcode,SchoolWebsite,TelephoneNum,HeadTitle (name),HeadFirstName,HeadLastName,HeadPreferredJobTitle,BSOInspectorateName (name),InspectorateReport,DateOfLastInspectionVisit,NextInspectionVisit,TeenMoth (name),TeenMothPlaces,CCF (name),SENPRU (name),EBD (name),PlacesPRU,FTProv (name),EdByOther (name),Section41Approved (name),SEN1 (name),SEN2 (name),SEN3 (name),SEN4 (name),SEN5 (name),SEN6 (name),SEN7 (name),SEN8 (name),SEN9 (name),SEN10 (name),SEN11 (name),SEN12 (name),SEN13 (name),TypeOfResourcedProvision (name),ResourcedProvisionOnRoll,ResourcedProvisionCapacity,SenUnitOnRoll,SenUnitCapacity,GOR (name),DistrictAdministrative (name),AdministrativeWard (name),ParliamentaryConstituency (name),UrbanRural (name),GSSLACode (name),Easting,Northing,MSOA (name),LSOA (name),InspectorateName (name),SENStat,SENNoStat,PropsName,OfstedRating (name),RSCRegion (name),Country (name),UPRN,SiteName,QABName (name),EstablishmentAccredited (name),QABReport,CHNumber,MSOA (code),LSOA (code),FSM,AccreditationExpiryDate
118229,886,Kent,1001,Northfleet Nursery School,Local authority nursery school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Nursery,2.0,5,No boarders,Has Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,,Not applicable,19-01-2023,91.0,57.0,34.0,0.0,Not applicable,,Not applicable,,Not under a federation,,,,Not applicable,19-07-2022,16-05-2024,140 London Road,Northfleet,,Gravesend,Kent,DA11 9JS,www.northfleetnursery.co.uk,1474533950.0,Mrs,Neerasha,Singh,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Gravesham,Rosherville,Gravesham,(England/Wales) Urban major conurbation,E10000016,563365.0,174145.0,Gravesham 001,Gravesham 001D,,,,,Outstanding,South-East England and South London,,10012024908.0,,Not applicable,Not applicable,,,E02005055,E01024279,0.0,
118254,886,Kent,2088,Crockenhill Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,187.0,83.0,104.0,29.4,Not applicable,,Not applicable,,Not under a federation,,10072997.0,,Not applicable,27-03-2019,04-12-2023,The Green,Crockenhill,,,Kent,BR8 8JG,http://www.crockenhill.kent.sch.uk,3000658300.0,Mrs,Karen,Dodd,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Sevenoaks,Crockenhill and Well Hill,Sevenoaks,(England/Wales) Urban city and town,E10000016,550590.0,167367.0,Sevenoaks 003,Sevenoaks 003A,,,,,Good,South-East England and South London,,,,Not applicable,Not applicable,,,E02005089,E01024421,55.0,
118255,886,Kent,2089,The Anthony Roper Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,315.0,No Special Classes,19-01-2023,307.0,151.0,156.0,9.8,Not supported by a trust,,Not applicable,,Not under a federation,,10069650.0,,Not applicable,27-06-2019,16-04-2024,High Street,Eynsford,,Dartford,Kent,DA4 0AA,www.anthony-roper.kent.sch.uk/,1322863680.0,Mr,Adam,Nicholls,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Eynsford,Sevenoaks,(England/Wales) Rural town and fringe,E10000016,554368.0,165949.0,Sevenoaks 005,Sevenoaks 005A,,,,,Good,South-East England and South London,,100060999084.0,,Not applicable,Not applicable,,,E02005091,E01024431,30.0,
118257,886,Kent,2094,Cobham Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,219.0,No Special Classes,19-01-2023,218.0,109.0,109.0,7.3,Not applicable,,Not applicable,,Not under a federation,,10073366.0,,Not applicable,15-11-2012,07-05-2024,The Street,Cobham,,Gravesend,Kent,DA12 3BN,www.cobham.kent.sch.uk/,1474814373.0,Mrs,Jacqui,Saunders,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,"Istead Rise, Cobham & Luddesdown",Gravesham,(England/Wales) Rural village,E10000016,567152.0,168444.0,Gravesham 013,Gravesham 013D,,,,,Outstanding,South-East England and South London,,100062312570.0,,Not applicable,Not applicable,,,E02005067,E01024302,16.0,
118258,886,Kent,2095,Cecil Road Primary and Nursery School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,378.0,No Special Classes,19-01-2023,444.0,228.0,216.0,16.2,Supported by a trust,Northfleet Schools Co-Operative Trust,Not applicable,,Not under a federation,,10069334.0,,Not applicable,05-12-2019,23-04-2024,Cecil Road,Northfleet,,Gravesend,Kent,DA11 7BT,www.cecilroad.co.uk,1474534544.0,Mrs,C,Old,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Gravesham,Coldharbour & Perry Street,Gravesham,(England/Wales) Urban major conurbation,E10000016,563896.0,173124.0,Gravesham 004,Gravesham 004E,,,,,Good,South-East England and South London,,100062310705.0,,Not applicable,Not applicable,,,E02005058,E01024284,64.0,
118262,886,Kent,2109,Higham Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,208.0,101.0,107.0,11.5,Not applicable,,Not applicable,,Not under a federation,,10073365.0,,Not applicable,25-01-2024,20-05-2024,School Lane,Higham,,Rochester,Kent,ME3 7JL,www.higham.kent.sch.uk,1474822535.0,Mrs,Catherine,Grattan,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Higham & Shorne,Gravesham,(England/Wales) Rural village,E10000016,571349.0,172256.0,Gravesham 010,Gravesham 010C,,,,,Good,South-East England and South London,,100062390148.0,,Not applicable,Not applicable,,,E02005064,E01024267,24.0,
118264,886,Kent,2116,Lawn Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,262.0,No Special Classes,19-01-2023,230.0,117.0,113.0,52.7,Supported by a trust,Northfleet Schools Co-Operative Trust,Not applicable,,Not under a federation,,10077449.0,,Not applicable,11-01-2023,08-01-2024,High Street,Northfleet,,Gravesend,Kent,DA11 9HB,http://www.lawnprimary.co.uk,1474365303.0,Mrs,A,Wilson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Northfleet & Springhead,Gravesham,(England/Wales) Urban major conurbation,E10000016,562102.0,174368.0,Gravesham 001,Gravesham 001C,,,,,Requires improvement,South-East England and South London,,100062311102.0,,Not applicable,Not applicable,,,E02005055,E01024278,108.0,
118266,886,Kent,2120,Bean Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,190.0,88.0,102.0,22.1,Not applicable,,Not applicable,,Not under a federation,,10073364.0,,Not applicable,06-11-2019,21-05-2024,School Lane,Bean,,Dartford,Kent,DA2 8AW,https://www.bean.kent.sch.uk/,1474833225.0,Mr,Graham,Reilly,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Dartford,Bean & Village Park,Dartford,(England/Wales) Rural town and fringe,E10000016,558989.0,172058.0,Dartford 012,Dartford 012B,,,,,Good,South-East England and South London,,100060855655.0,,Not applicable,Not applicable,,,E02005039,E01024134,42.0,
118271,886,Kent,2128,Capel Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,212.0,No Special Classes,19-01-2023,207.0,113.0,94.0,15.9,Not applicable,,Not applicable,,Not under a federation,,10073362.0,,Not applicable,15-01-2019,24-04-2024,Five Oak Green Road,Five Oak Green,,Tonbridge,Kent,TN12 6RP,www.capelschool.com/,1892833919.0,Mrs,Suzanne,Farr,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Capel,Tunbridge Wells,(England/Wales) Rural hamlet and isolated dwellings,E10000016,563919.0,145118.0,Tunbridge Wells 001,Tunbridge Wells 001A,,,,,Good,South-East England and South London,,10008670848.0,,Not applicable,Not applicable,,,E02005162,E01024798,33.0,
118272,886,Kent,2130,Dunton Green Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,187.0,90.0,97.0,31.6,Not applicable,,Not applicable,,Not under a federation,,10069525.0,,Not applicable,18-07-2018,08-04-2024,London Road,Dunton Green,,Sevenoaks,Kent,TN13 2UP,www.dunton-green.kent.sch.uk/,1732462221.0,Mr,Ben,Hulme,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Dunton Green and Riverhead,Sevenoaks,(England/Wales) Urban city and town,E10000016,551173.0,157352.0,Sevenoaks 008,Sevenoaks 008F,,,,,Good,South-East England and South London,United Kingdom,100062547929.0,,Not applicable,Not applicable,,,E02005094,E01035000,59.0,
118273,886,Kent,2132,Hadlow Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,187.0,107.0,80.0,38.5,Not applicable,,Not applicable,,Supported by a federation,The Bourne Partnership,10073361.0,,Not applicable,02-10-2019,13-04-2024,Hadlow,,,Tonbridge,Kent,TN11 0EH,www.hadlow.kent.sch.uk,1732850349.0,Miss,Nicole,Chapman,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Bourne,Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,563334.0,149843.0,Tonbridge and Malling 008,Tonbridge and Malling 008D,,,,,Good,South-East England and South London,,200000967219.0,,Not applicable,Not applicable,,,E02005156,E01024747,72.0,
118277,886,Kent,2136,Kemsing Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,184.0,99.0,85.0,14.7,Not applicable,,Not applicable,,Not under a federation,,10069522.0,,Not applicable,20-07-2022,19-01-2024,West End,Kemsing,,Sevenoaks,Kent,TN15 6PU,http://www.kemsing.kent.sch.uk,1732761236.0,Mr,Tom,Hardwick,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Kemsing,Sevenoaks,(England/Wales) Rural town and fringe,E10000016,555461.0,158873.0,Sevenoaks 009,Sevenoaks 009C,,,,,Good,South-East England and South London,,50002002944.0,,Not applicable,Not applicable,,,E02005095,E01024450,27.0,
118278,886,Kent,2137,Leigh Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,171.0,No Special Classes,19-01-2023,161.0,77.0,84.0,18.0,Not applicable,,Not applicable,,Not under a federation,,10073359.0,,Not applicable,08-02-2024,20-05-2024,The Green,Leigh,,Tonbridge,Kent,TN11 8QP,www.leighprimaryschool.com,1732832660.0,Mrs,Jenna,Halfhide,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Leigh and Chiddingstone Causeway,Tonbridge and Malling,(England/Wales) Rural village,E10000016,554871.0,146478.0,Sevenoaks 015,Sevenoaks 015B,,,,,Good,South-East England and South London,,50002001763.0,,Not applicable,Not applicable,,,E02005101,E01024451,29.0,
118279,886,Kent,2138,Otford Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,332.0,172.0,160.0,13.3,Not applicable,,Not applicable,,Not under a federation,,10069521.0,,Not applicable,18-10-2023,23-04-2024,High Street,Otford,,Sevenoaks,Kent,TN14 5PG,www.otford.kent.sch.uk,1959523145.0,Mrs,Helen,Roberts,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Otford and Shoreham,Sevenoaks,(England/Wales) Rural hamlet and isolated dwellings,E10000016,552632.0,159289.0,Sevenoaks 008,Sevenoaks 008E,,,,,Good,South-East England and South London,,100062548574.0,,Not applicable,Not applicable,,,E02005094,E01024452,44.0,
118280,886,Kent,2139,Pembury School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,510.0,No Special Classes,19-01-2023,404.0,199.0,205.0,11.6,Not applicable,,Not applicable,,Not under a federation,,10073358.0,,Not applicable,26-02-2019,04-04-2024,Lower Green Road,Pembury,,Tunbridge Wells,Kent,TN2 4EB,http://www.pembury.kent.sch.uk,1892822259.0,Mrs,Hannah,Walters,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Pembury,Tunbridge Wells,(England/Wales) Rural town and fringe,E10000016,562858.0,141702.0,Tunbridge Wells 004,Tunbridge Wells 004D,,,,,Good,South-East England and South London,,100062554668.0,,Not applicable,Not applicable,,,E02005165,E01024827,47.0,
118282,886,Kent,2142,Sandhurst Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,191.0,No Special Classes,19-01-2023,154.0,74.0,80.0,25.3,Not applicable,,Not applicable,,Not under a federation,,10069520.0,,Not applicable,06-02-2019,07-05-2024,Rye Road,Sandhurst,Sandhurst Primary School,Cranbrook,Kent,TN18 5JE,www.sandhurst.kent.sch.uk,1580850288.0,Mrs,Amanda,Norman,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Hawkhurst and Sandhurst,Tunbridge Wells,(England/Wales) Rural village,E10000016,580082.0,128340.0,Tunbridge Wells 014,Tunbridge Wells 014D,,,,,Good,South-East England and South London,,10000069892.0,,Not applicable,Not applicable,,,E02005175,E01024809,39.0,
118283,886,Kent,2147,Weald Community Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,175.0,No Special Classes,19-01-2023,126.0,55.0,71.0,11.9,Not applicable,,Not applicable,,Not under a federation,,10069519.0,,Not applicable,04-03-2020,27-03-2024,Long Barn Road,Weald,,Sevenoaks,Kent,TN14 6PY,www.weald.kent.sch.uk,1732463307.0,Mr,David,Pyle,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Seal and Weald,Sevenoaks,(England/Wales) Rural village,E10000016,552697.0,150900.0,Sevenoaks 012,Sevenoaks 012B,,,,,Good,South-East England and South London,,100062548945.0,,Not applicable,Not applicable,,,E02005098,E01024459,15.0,
118284,886,Kent,2148,Shoreham Village School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,105.0,No Special Classes,19-01-2023,84.0,40.0,44.0,21.4,Not applicable,,Not applicable,,Not under a federation,,10073357.0,,Not applicable,26-03-2019,25-04-2024,Church Street,Shoreham,,Sevenoaks,Kent,TN14 7SN,www.shorehamvillageschool.net,1959522228.0,Mrs,Gillian,Lovatt-Young,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Otford and Shoreham,Sevenoaks,(England/Wales) Rural village,E10000016,551878.0,161599.0,Sevenoaks 008,Sevenoaks 008E,,,,,Good,South-East England and South London,,50002000337.0,,Not applicable,Not applicable,,,E02005094,E01024452,18.0,
118285,886,Kent,2155,Slade Primary School and Attached Unit for Children with Hearing Impairment,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,418.0,223.0,195.0,13.2,Not applicable,,Not applicable,,Not under a federation,,10072996.0,,Not applicable,06-03-2024,22-05-2024,The Slade,,,Tonbridge,Kent,TN9 1HR,www.slade.kent.sch.uk,1732350354.0,Mrs,Karen,Slade,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,HI - Hearing Impairment,,,,,,,,,,,,,Resourced provision,10.0,10.0,,,South East,Tonbridge and Malling,Judd,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,558843.0,146765.0,Tonbridge and Malling 012,Tonbridge and Malling 012A,,,,,Good,South-East England and South London,,200000962234.0,,Not applicable,Not applicable,,,E02005160,E01024732,55.0,
118286,886,Kent,2156,Sussex Road Community Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,418.0,209.0,209.0,13.9,Not applicable,,Not applicable,,Not under a federation,,10072995.0,,Not applicable,24-11-2021,08-05-2024,Sussex Road,,,Tonbridge,Kent,TN9 2TP,http://www.sussex-road.kent.sch.uk/,1732352367.0,Mrs,Sarah,Miles,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tonbridge and Malling,Judd,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,558245.0,145866.0,Tonbridge and Malling 013,Tonbridge and Malling 013A,,,,,Good,South-East England and South London,,200000961981.0,,Not applicable,Not applicable,,,E02005161,E01024757,58.0,
118288,886,Kent,2161,Boughton Monchelsea Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,206.0,102.0,104.0,19.4,Not applicable,,Not applicable,,Not under a federation,,10073356.0,,Not applicable,29-09-2023,22-04-2024,Church Hill,Boughton Monchelsea,,Maidstone,Kent,ME17 4HP,http://www.boughton-monchelsea.kent.sch.uk,1622743596.0,Mrs,Mandy,Gibbs,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Maidstone,Boughton Monchelsea and Chart Sutton,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,576889.0,150785.0,Maidstone 012,Maidstone 012A,,,,,Good,South-East England and South London,,200003674284.0,,Not applicable,Not applicable,,,E02005079,E01024331,40.0,
118289,886,Kent,2163,East Farleigh Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,208.0,104.0,104.0,13.0,Not applicable,,Not applicable,,Not under a federation,,10073355.0,,Not applicable,22-06-2022,23-04-2024,Vicarage Lane,East Farleigh,,Maidstone,Kent,ME15 0LY,www.east-farleigh.kent.sch.uk,1622726364.0,Mr,Peter,Goodman,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Coxheath and Hunton,Maidstone and The Weald,(England/Wales) Rural village,E10000016,573555.0,152821.0,Maidstone 016,Maidstone 016B,,,,,Good,South-East England and South London,,200003673168.0,,Not applicable,Not applicable,,,E02005083,E01024343,27.0,
118290,886,Kent,2164,East Peckham Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,175.0,99.0,76.0,14.3,Not applicable,,Not applicable,,Not under a federation,,10073354.0,,Not applicable,04-07-2023,14-05-2024,130 Pound Road,East Peckham,,Tonbridge,Kent,TN12 5LH,http://www.east-peckham.kent.sch.uk/,1622871268.0,Mrs,Kate,Elliott,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,"East and West Peckham, Mereworth & Wateringbury",Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,566468.0,149067.0,Tonbridge and Malling 008,Tonbridge and Malling 008B,,,,,Requires improvement,South-East England and South London,,100062628528.0,,Not applicable,Not applicable,,,E02005156,E01024744,25.0,
118291,886,Kent,2165,Headcorn Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,392.0,210.0,182.0,20.2,Not applicable,,Not applicable,,Not under a federation,,10073353.0,,Not applicable,05-05-2022,02-05-2024,Kings Road,,,Headcorn,Kent,TN27 9QT,www.headcorn.kent.sch.uk,1622891289.0,Miss,Sarah,Symonds,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Headcorn,Faversham and Mid Kent,(England/Wales) Rural town and fringe,E10000016,583351.0,144445.0,Maidstone 017,Maidstone 017B,,,,,Requires improvement,South-East England and South London,,200003698713.0,,Not applicable,Not applicable,,,E02005084,E01024365,79.0,
118292,886,Kent,2166,Hollingbourne Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,105.0,No Special Classes,19-01-2023,96.0,48.0,48.0,24.0,Not applicable,,Not applicable,,Not under a federation,,10073352.0,,Not applicable,01-03-2022,12-03-2024,Eyhorne Street,Hollingbourne,,Maidstone,Kent,ME17 1UA,www.hollingbourne.kent.sch.uk/,1622880270.0,Mrs,Helen,Bradley-Wyatt,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,North Downs,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,584016.0,154881.0,Maidstone 011,Maidstone 011D,,,,,Good,South-East England and South London,,200003719238.0,,Not applicable,Not applicable,,,E02005078,E01024387,23.0,
118293,886,Kent,2167,Ightham Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,209.0,105.0,104.0,3.3,Not applicable,,Not applicable,,Not under a federation,,10073351.0,,Not applicable,04-03-2020,07-05-2024,Oldbury Lane,Ightham,,Sevenoaks,Kent,TN15 9DD,www.ightham.kent.sch.uk,1732882405.0,Mr,David,Sherhod,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Pilgrims with Ightham,Tonbridge and Malling,(England/Wales) Rural village,E10000016,558908.0,156539.0,Tonbridge and Malling 006,Tonbridge and Malling 006E,,,,,Outstanding,South-East England and South London,,100062551218.0,,Not applicable,Not applicable,,,E02005154,E01024755,7.0,
118294,886,Kent,2168,Lenham Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Non-selective,210.0,No Special Classes,19-01-2023,213.0,104.0,109.0,21.1,Not applicable,,Not applicable,,Not under a federation,,10075877.0,,Not applicable,06-12-2023,13-05-2024,Ham Lane,Lenham,,Maidstone,Kent,ME17 2LL,http://www.lenham.kent.sch.uk,1622858260.0,Mrs,Andrea,McCluskey,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Harrietsham and Lenham,Faversham and Mid Kent,(England/Wales) Rural town and fringe,E10000016,589472.0,152164.0,Maidstone 011,Maidstone 011B,,,,,Good,South-East England and South London,,200003719333.0,,Not applicable,Not applicable,,,E02005078,E01024362,45.0,
118295,886,Kent,2169,Platts Heath Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,91.0,No Special Classes,19-01-2023,62.0,32.0,30.0,29.0,Not applicable,,Not applicable,,Not under a federation,,10073350.0,,Not applicable,21-04-2022,21-05-2024,Headcorn Road,Platts Heath,,Maidstone,Kent,ME17 2NH,https://plattsheathkentsch.co.uk/,1622850316.0,Mr,Darren,Waters,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Harrietsham and Lenham,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,587729.0,150533.0,Maidstone 011,Maidstone 011B,,,,,Good,South-East England and South London,,200003703748.0,,Not applicable,Not applicable,,,E02005078,E01024362,18.0,
118297,886,Kent,2171,Brunswick House Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,421.0,No Special Classes,19-01-2023,421.0,207.0,214.0,25.2,Not applicable,,Not applicable,,Not under a federation,,10069518.0,,Not applicable,19-07-2023,21-05-2024,Leafy Lane,,,Maidstone,Kent,ME16 0QQ,http://www.brunswick-house.kent.sch.uk,1622752102.0,Mrs,Wendy,Skinner,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Bridge,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,575123.0,156195.0,Maidstone 006,Maidstone 006B,,,,,Good,South-East England and South London,,200003659753.0,,Not applicable,Not applicable,,,E02005073,E01024340,106.0,
118301,886,Kent,2175,North Borough Junior School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,360.0,No Special Classes,19-01-2023,353.0,201.0,152.0,28.6,Not applicable,,Not applicable,,Supported by a federation,St Paul's and North Borough Schools Federation,10079035.0,,Not applicable,19-10-2023,25-04-2024,"North Borough Junior School, Peel Street",,,Maidstone,Kent,ME14 2BP,www.north-borough.kent.sch.uk/,1622754708.0,Mrs,Dawn,Wakefield,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,North,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,576137.0,156985.0,Maidstone 004,Maidstone 004C,,,,,Good,South-East England and South London,,200003704716.0,,Not applicable,Not applicable,,,E02005071,E01024382,101.0,
118302,886,Kent,2176,Park Way Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,315.0,No Special Classes,19-01-2023,316.0,153.0,163.0,26.3,Not applicable,,Not applicable,,Not under a federation,,10073349.0,,Not applicable,13-11-2018,12-09-2023,Park Way,,,Maidstone,Kent,ME15 7AH,http://www.park-way.kent.sch.uk,1622753651.0,Mrs,Karen,Dhanecha,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Shepway North,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,576965.0,154343.0,Maidstone 010,Maidstone 010B,,,,,Good,South-East England and South London,,200003686775.0,,Not applicable,Not applicable,,,E02005077,E01024392,83.0,
118307,886,Kent,2185,Mereworth Community Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,218.0,No Special Classes,19-01-2023,203.0,117.0,86.0,16.7,Not applicable,,Not applicable,,Not under a federation,,10069517.0,,Not applicable,07-07-2022,21-05-2024,39 the Street,Mereworth,,Maidstone,Kent,ME18 5ND,www.mereworth.kent.sch.uk,1622812569.0,Miss,Amanda,Lavelle,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,"East and West Peckham, Mereworth & Wateringbury",Tonbridge and Malling,(England/Wales) Rural hamlet and isolated dwellings,E10000016,565535.0,153533.0,Tonbridge and Malling 007,Tonbridge and Malling 007A,,,,,Good,South-East England and South London,,100062386957.0,,Not applicable,Not applicable,,,E02005155,E01024746,34.0,
118308,886,Kent,2187,Offham Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,205.0,100.0,105.0,5.9,Not applicable,,Not applicable,,Not under a federation,,10073347.0,,Not applicable,20-05-2015,23-01-2024,Church Road,Offham,,West Malling,Kent,ME19 5NX,http://www.offham.kent.sch.uk,1732842355.0,Mrs,Emily,John,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,"East Malling, West Malling & Offham",Tonbridge and Malling,(England/Wales) Rural hamlet and isolated dwellings,E10000016,565935.0,157744.0,Tonbridge and Malling 014,Tonbridge and Malling 014E,,,,,Outstanding,South-East England and South London,,10002907519.0,,Not applicable,Not applicable,,,E02006833,E01032620,12.0,
118309,886,Kent,2188,Plaxtol Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,109.0,No Special Classes,19-01-2023,98.0,49.0,49.0,10.2,Not applicable,,Not applicable,,Not under a federation,,10073346.0,,Not applicable,21-03-2023,21-05-2024,School Lane,Plaxtol,,Sevenoaks,Kent,TN15 0QD,http://www.plaxtol.kent.sch.uk/,1732810200.0,Mrs,Claire,Rowley,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Bourne,Tonbridge and Malling,(England/Wales) Rural village,E10000016,560235.0,153454.0,Tonbridge and Malling 006,Tonbridge and Malling 006A,,,,,Good,South-East England and South London,,200000959103.0,,Not applicable,Not applicable,,,E02005154,E01024723,10.0,
118310,886,Kent,2189,Ryarsh Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,210.0,107.0,103.0,8.1,Not applicable,,Not applicable,,Not under a federation,,10073345.0,,Not applicable,26-04-2012,03-06-2024,Birling Road,Ryarsh,,West Malling,Kent,ME19 5LS,www.ryarsh.kent.sch.uk/,1732870600.0,Mr,Daniel,Childs,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,"Birling, Leybourne & Ryarsh",Tonbridge and Malling,(England/Wales) Rural village,E10000016,567182.0,159943.0,Tonbridge and Malling 014,Tonbridge and Malling 014F,,,,,Outstanding,South-East England and South London,,200000959182.0,,Not applicable,Not applicable,,,E02006833,E01032829,17.0,
118311,886,Kent,2190,Shipbourne School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,59.0,No Special Classes,19-01-2023,60.0,28.0,32.0,18.3,Not applicable,,Not applicable,,Supported by a federation,The Bourne Partnership,10073344.0,,Not applicable,28-03-2019,25-04-2024,Stumble Hill,Shipbourne,,Tonbridge,Kent,TN11 9PB,http://www.shipbourne.kent.sch.uk,1732810344.0,Mrs,Terri,Daters,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Bourne,Tonbridge and Malling,(England/Wales) Rural hamlet and isolated dwellings,E10000016,559185.0,151948.0,Tonbridge and Malling 006,Tonbridge and Malling 006A,,,,,Good,South-East England and South London,,200000966854.0,,Not applicable,Not applicable,,,E02005154,E01024723,11.0,
118313,886,Kent,2192,Staplehurst School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,525.0,No Special Classes,19-01-2023,406.0,194.0,212.0,19.5,Not applicable,,Not applicable,,Not under a federation,,10073343.0,,Not applicable,26-01-2022,17-04-2024,Gybbon Rise,Staplehurst,,Tonbridge,Kent,TN12 0LZ,www.staplehurstschool.co.uk/,1580891765.0,Miss,Lucy,Davenport,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Staplehurst,Maidstone and The Weald,(England/Wales) Rural town and fringe,E10000016,578439.0,143382.0,Maidstone 019,Maidstone 019D,,,,,Good,South-East England and South London,,200003679143.0,,Not applicable,Not applicable,,,E02005086,E01024409,79.0,
118314,886,Kent,2193,Sutton Valence Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,205.0,100.0,105.0,20.5,Not applicable,,Not applicable,,Not under a federation,,10073342.0,,Not applicable,29-03-2023,09-05-2024,North Street,Sutton Valence,,Maidstone,Kent,ME17 3HT,http://www.sutton-valence.kent.sch.uk,1622842188.0,Mrs,Rebecca,Latham-Parsons,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Sutton Valence and Langley,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,581028.0,149379.0,Maidstone 017,Maidstone 017D,,,,,Good,South-East England and South London,,200003720509.0,,Not applicable,Not applicable,,,E02005084,E01024411,42.0,
118336,886,Kent,2226,Eastling Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,105.0,No Special Classes,19-01-2023,101.0,39.0,62.0,20.8,Not applicable,,Not applicable,,Not under a federation,,10073341.0,,Not applicable,20-10-2021,04-06-2024,Kettle Hill Road,Eastling,,Faversham,Kent,ME13 0BA,http://www.eastling.kent.sch.uk,1795890252.0,Mrs,Melanie,Dale,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,East Downs,Faversham and Mid Kent,(England/Wales) Rural hamlet and isolated dwellings,E10000016,596524.0,156325.0,Swale 016,Swale 016B,,,,,Good,South-East England and South London,,200002532821.0,,Not applicable,Not applicable,,,E02005130,E01024566,21.0,
118337,886,Kent,2227,Ethelbert Road Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,209.0,108.0,101.0,5.7,Not applicable,,Not applicable,,Not under a federation,,10073340.0,,Not applicable,01-10-2014,29-05-2024,Ethelbert Road,,,Faversham,Kent,ME13 8SQ,www.ethelbert-road.kent.sch.uk,1795533124.0,Mrs,Michele,Kirkbride,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Watling,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,601072.0,160785.0,Swale 014,Swale 014E,,,,,Outstanding,South-East England and South London,,10035063205.0,,Not applicable,Not applicable,,,E02005128,E01024626,12.0,
118338,886,Kent,2228,Davington Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,417.0,208.0,209.0,21.8,Not applicable,,Not applicable,,Not under a federation,,10069515.0,,Not applicable,22-06-2023,18-03-2024,Priory Row,Davington,,Faversham,Kent,ME13 7EQ,www.davington.kent.sch.uk/,1795532401.0,Mr,Chilton,Saint,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Priory,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,601089.0,161986.0,Swale 015,Swale 015D,,,,,Good,South-East England and South London,,100062379818.0,,Not applicable,Not applicable,,,E02005129,E01024563,91.0,
118341,886,Kent,2231,Lower Halstow Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,188.0,94.0,94.0,13.3,Not applicable,,Not applicable,,Supported by a federation,The Federation of Lower Halstow Primary and Newington CofE Primary School,10073339.0,,Not applicable,14-03-2019,04-06-2024,School Lane,Lower Halstow,,Sittingbourne,Kent,ME9 7ES,www.lower-halstow.kent.sch.uk,1795842344.0,Mrs,Tara,Deevoy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,"Bobbing, Iwade and Lower Halstow",Sittingbourne and Sheppey,(England/Wales) Rural village,E10000016,585951.0,166826.0,Swale 008,Swale 008E,,,,,Good,South-East England and South London,,200002532824.0,,Not applicable,Not applicable,,,E02005122,E01024575,25.0,
118346,886,Kent,2239,Rodmersham School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,70.0,No Special Classes,19-01-2023,117.0,59.0,58.0,3.4,Not applicable,,Not applicable,,Not under a federation,,10073338.0,,Not applicable,22-09-2011,24-04-2024,Rodmersham Green,,,Sittingbourne,Kent,ME9 0PS,www.rodmersham.kent.sch.uk/,1795423776.0,Mrs,Nicola,McMullon,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,West Downs,Sittingbourne and Sheppey,(England/Wales) Rural village,E10000016,591601.0,161273.0,Swale 013,Swale 013C,,,,,Outstanding,South-East England and South London,,100062397234.0,,Not applicable,Not applicable,,,E02005127,E01024628,4.0,
118348,886,Kent,2245,Rose Street Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,438.0,225.0,213.0,59.6,Not applicable,,Not applicable,,Supported by a federation,Sheerness West Federation,10076228.0,,Not applicable,30-11-2022,14-05-2024,Rose Street,,,Sheerness,Kent,ME12 1AW,www.swfed.co.uk,1795663012.0,Mrs,Samantha,Mackay,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Sheerness,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,591895.0,174664.0,Swale 002,Swale 002A,,,,,Requires improvement,South-East England and South London,,100062377402.0,,Not applicable,Not applicable,,,E02005116,E01024613,249.0,
118354,886,Kent,2254,Canterbury Road Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,208.0,103.0,105.0,32.7,Not applicable,,Not applicable,,Not under a federation,,10073337.0,,Not applicable,06-03-2024,22-05-2024,School Road,,,Sittingbourne,Kent,ME10 4SE,http://www.canterbury-road.kent.sch.uk,1795423818.0,Mr,Timothy,Pye,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Roman,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,591591.0,163352.0,Swale 010,Swale 010D,,,,,Good,South-East England and South London,,200002531732.0,,Not applicable,Not applicable,,,E02005124,E01024599,68.0,
118356,886,Kent,2258,Blean Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,469.0,Not applicable,19-01-2023,431.0,215.0,216.0,6.7,Not applicable,,Not applicable,,Not under a federation,,10073336.0,,Not applicable,09-03-2022,07-05-2024,Whitstable Road,Blean,,Canterbury,Kent,CT2 9ED,www.bleanprimary.org.uk/,1227471254.0,Mr,Ian,Rowden,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Blean Forest,Canterbury,(England/Wales) Urban city and town,E10000016,612837.0,159932.0,Canterbury 012,Canterbury 012H,,,,,Outstanding,South-East England and South London,,200000683406.0,,Not applicable,Not applicable,,,E02005021,E01035309,29.0,
118359,886,Kent,2263,Herne Bay Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,2.0,7,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,360.0,No Special Classes,19-01-2023,304.0,154.0,150.0,35.7,Not applicable,,Not applicable,,Not under a federation,,10074072.0,,Not applicable,04-12-2019,17-01-2024,Stanley Road,,,Herne Bay,Kent,CT6 5SH,www.herne-bay.kent.sch.uk/,1227372245.0,Ms,Nicky,Brown,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Heron,North Thanet,(England/Wales) Urban city and town,E10000016,617893.0,167868.0,Canterbury 003,Canterbury 003D,,,,,Good,South-East England and South London,,200000682558.0,,Not applicable,Not applicable,,,E02005012,E01024083,99.0,
118361,886,Kent,2265,Hoath Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,105.0,No Special Classes,19-01-2023,103.0,45.0,58.0,16.5,Not applicable,,Not applicable,,Supported by a federation,The Federation of Chislet CE and Hoath Primary Schools,10073335.0,,Not applicable,18-01-2022,12-01-2024,School Lane,Hoath,,Canterbury,Kent,CT3 4LA,www.chislethoathfederation.co.uk,1227860249.0,Mr,Tim,Whitehouse,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Reculver,North Thanet,(England/Wales) Rural hamlet and isolated dwellings,E10000016,620491.0,164365.0,Canterbury 010,Canterbury 010C,,,,,Good,South-East England and South London,,10033152360.0,,Not applicable,Not applicable,,,E02005019,E01024086,17.0,
118363,886,Kent,2268,Westmeads Community Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,180.0,No Special Classes,19-01-2023,156.0,84.0,72.0,23.1,Not applicable,,Not applicable,,Not under a federation,,10074071.0,,Not applicable,18-05-2022,03-06-2024,Cromwell Road,,,Whitstable,Kent,CT5 1NA,www.westmeads.kent.sch.uk/,1227272995.0,Ms,Kirsty,White,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Gorrell,Canterbury,(England/Wales) Urban city and town,E10000016,611013.0,166711.0,Canterbury 008,Canterbury 008D,,,,,Requires improvement,South-East England and South London,,100062300538.0,,Not applicable,Not applicable,,,E02005017,E01024072,36.0,
118364,886,Kent,2269,Whitstable Junior School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,255.0,No Special Classes,19-01-2023,232.0,126.0,106.0,28.9,Supported by a trust,The Coastal Alliance Co-operative Trust,Not applicable,,Not under a federation,,10077448.0,,Not applicable,18-06-2019,02-04-2024,Oxford Street,,,Whitstable,Kent,CT5 1DB,www.whitstable-junior.kent.sch.uk/,1227272385.0,Ms,Sarah,Kent,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Gorrell,Canterbury,(England/Wales) Urban city and town,E10000016,610711.0,166216.0,Canterbury 008,Canterbury 008C,,,,,Good,South-East England and South London,,100062300650.0,,Not applicable,Not applicable,,,E02005017,E01024070,67.0,
118365,886,Kent,2270,Aldington Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,191.0,112.0,79.0,11.0,Supported by a trust,CARE Foundation Trust,Not applicable,,Not under a federation,,10073112.0,,Not applicable,07-02-2024,22-05-2024,Roman Road,Aldington,,Ashford,Kent,TN25 7EE,http://www.aldington.kent.sch.uk/,1233720247.0,Mr,Ben,Dawson.,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Saxon Shore,Folkestone and Hythe,(England/Wales) Rural village,E10000016,606435.0,136475.0,Ashford 010,Ashford 010A,,,,,Good,South-East England and South London,,100062562493.0,,Not applicable,Not applicable,,,E02005005,E01024013,21.0,
118369,886,Kent,2275,Victoria Road Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,206.0,No Special Classes,19-01-2023,211.0,113.0,98.0,25.6,Not applicable,,Not applicable,,Not under a federation,,10069513.0,,Not applicable,15-01-2019,25-04-2024,Victoria Road,,,Ashford,Kent,TN23 7HQ,http://www.victoriaroad.co.uk/,1233620044.0,Mrs,Kelly,Collens,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Ashford,Victoria,Ashford,(England/Wales) Urban city and town,E10000016,600804.0,142343.0,Ashford 005,Ashford 005F,,,,,Good,South-East England and South London,,100062048541.0,,Not applicable,Not applicable,,,E02005000,E01034985,54.0,
118370,886,Kent,2276,Willesborough Infant School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,390.0,No Special Classes,19-01-2023,357.0,177.0,180.0,15.7,Not supported by a trust,,Not applicable,,Supported by a federation,The Willesborough Schools,10080431.0,,Not applicable,15-09-2022,08-05-2024,Church Road,Willesborough,,Ashford,Kent,TN24 0JZ,www.willesborough-infant.kent.sch.uk/,1233624165.0,Mr,Tom,Head,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,PD - Physical Disability,,,,,,,,,,,,,Resourced provision,,,,,South East,Ashford,Highfield,Ashford,(England/Wales) Urban city and town,E10000016,603174.0,141786.0,Ashford 006,Ashford 006B,,,,,Good,South-East England and South London,,100062560396.0,,Not applicable,Not applicable,,,E02005001,E01023995,56.0,
118371,886,Kent,5226,Willesborough Junior School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,510.0,No Special Classes,19-01-2023,511.0,249.0,262.0,18.8,Not supported by a trust,,Not applicable,,Supported by a federation,The Willesborough Schools,10069649.0,,Not applicable,22-03-2023,12-09-2023,Highfield Road,Willesborough,,Ashford,Kent,TN24 0JU,www.willesborough-js.kent.sch.uk/,1233620405.0,Mr,Tom,Head,Interim Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Highfield,Ashford,(England/Wales) Urban city and town,E10000016,603107.0,141715.0,Ashford 006,Ashford 006B,,,,,Good,South-East England and South London,,200002904249.0,,Not applicable,Not applicable,,,E02005001,E01023995,96.0,
118372,886,Kent,2278,Bethersden Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,140.0,No Special Classes,19-01-2023,131.0,70.0,61.0,25.4,Not applicable,,Not applicable,,Not under a federation,,10073334.0,,Not applicable,08-06-2023,21-05-2024,School Road,Bethersden,,Ashford,Kent,TN26 3AH,www.bethersden.kent.sch.uk/,1233820479.0,Ms,Rebecca,Heaton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Ashford,Weald Central,Ashford,(England/Wales) Rural village,E10000016,592556.0,140108.0,Ashford 012,Ashford 012B,,,,,Good,South-East England and South London,,100062563194.0,,Not applicable,Not applicable,,,E02005007,E01024031,33.0,
118373,886,Kent,2279,Brook Community Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,105.0,No Special Classes,19-01-2023,71.0,40.0,31.0,12.7,Supported by a trust,CARE Foundation Trust,Not applicable,,Not under a federation,,10073111.0,,Not applicable,11-05-2023,22-04-2024,Spelders Hill,Brook,,Ashford,Kent,TN25 5PB,www.brook-ashford.kent.sch.uk,1233812614.0,Mrs,Ellen,Ranson-McCabe,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Bircholt,Folkestone and Hythe,(England/Wales) Rural village,E10000016,606030.0,143546.0,Ashford 010,Ashford 010C,,,,,Good,South-East England and South London,,100062561999.0,,Not applicable,Not applicable,,,E02005005,E01024015,9.0,
118374,886,Kent,2280,Challock Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,210.0,100.0,110.0,7.6,Supported by a trust,CARE Foundation Trust,Not applicable,,Not under a federation,,10073110.0,,Not applicable,12-07-2023,13-05-2024,Church Lane,Challock,,Ashford,Kent,TN25 4BU,www.challockprimaryschool.co.uk,1233740286.0,Mrs,Susan,Sweet,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Downs West,Ashford,(England/Wales) Rural village,E10000016,600941.0,150288.0,Ashford 002,Ashford 002C,,,,,Outstanding,South-East England and South London,,100062561620.0,,Not applicable,Not applicable,,,E02004997,E01023989,16.0,
118375,886,Kent,2282,Great Chart Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,420.0,219.0,201.0,17.6,Not applicable,,Not applicable,,Not under a federation,,10073333.0,,Not applicable,07-06-2023,03-06-2024,Hoxton Close,Singleton,,Ashford,Kent,TN23 5LB,www.great-chart.kent.sch.uk/,1233620040.0,Mrs,Wendy,Pang,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Singleton East,Ashford,(England/Wales) Urban city and town,E10000016,598848.0,141528.0,Ashford 007,Ashford 007E,,,,,Outstanding,South-East England and South London,,100062617920.0,,Not applicable,Not applicable,,,E02005002,E01024017,74.0,
118377,886,Kent,2285,Mersham Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,181.0,93.0,88.0,14.4,Supported by a trust,CARE Foundation Trust,Not applicable,,Not under a federation,,10073109.0,,Not applicable,23-02-2022,12-04-2024,Church Road,Mersham,,Ashford,Kent,TN25 6NU,www.mersham.kent.sch.uk/,1233720449.0,Mrs,Cheryl,Chalkley,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,"Mersham, Sevington South with Finberry",Ashford,(England/Wales) Rural village,E10000016,605060.0,139253.0,Ashford 010,Ashford 010F,,,,,Good,South-East England and South London,,100062562340.0,,Not applicable,Not applicable,,,E02005005,E01034988,26.0,
118381,886,Kent,2289,Smeeth Community Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,140.0,No Special Classes,19-01-2023,122.0,66.0,56.0,13.1,Supported by a trust,CARE Foundation Trust,Not applicable,,Not under a federation,,10073108.0,,Not applicable,04-07-2023,03-11-2023,Caroland Close,Smeeth,,Ashford,Kent,TN25 6RX,www.smeeth.kent.sch.uk,1303813128.0,Ms,Jennifer,Payne,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Ashford,Bircholt,Folkestone and Hythe,(England/Wales) Rural hamlet and isolated dwellings,E10000016,607714.0,140096.0,Ashford 010,Ashford 010A,,,,,Good,South-East England and South London,,100062562341.0,,Not applicable,Not applicable,,,E02005005,E01024013,16.0,
118385,886,Kent,2298,Hawkinge Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,396.0,189.0,207.0,17.9,Not supported by a trust,,Not applicable,,Not under a federation,,10073107.0,,Not applicable,12-06-2019,03-05-2024,Canterbury Road,Hawkinge,,Folkestone,Kent,CT18 7BN,www.hawkingeprimaryschool.co.uk/,1303892224.0,Miss,Aly,Ward,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,North Downs East,Folkestone and Hythe,(England/Wales) Rural town and fringe,E10000016,621648.0,139892.0,Folkestone and Hythe 002,Folkestone and Hythe 002B,,,,,Outstanding,South-East England and South London,,50034845.0,,Not applicable,Not applicable,,,E02005103,E01024541,71.0,
118387,886,Kent,2300,Sellindge Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,142.0,61.0,81.0,13.4,Not applicable,,Not applicable,,Not under a federation,,10073331.0,,Not applicable,03-02-2023,22-03-2024,Main Road,Sellindge,,Ashford,Kent,TN25 6JY,www.sellindge-ashford.co.uk/,1303812073.0,Miss,Joanne,Wren,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,North Downs West,Folkestone and Hythe,(England/Wales) Rural village,E10000016,610305.0,138188.0,Folkestone and Hythe 009,Folkestone and Hythe 009D,,,,,Good,South-East England and South London,,50010667.0,,Not applicable,Not applicable,,,E02005110,E01024546,19.0,
118393,886,Kent,2312,River Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,427.0,Not applicable,19-01-2023,413.0,210.0,203.0,18.4,Not applicable,,Not applicable,,Supported by a federation,Lydden and River Primary Schools Federation,10072994.0,,Not applicable,29-11-2013,24-01-2024,Lewisham Road,River,,Dover,Kent,CT17 0PP,www.river.kent.sch.uk/,1304822516.0,Mr,Neil,Brinicombe,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,12.0,12.0,,,South East,Dover,Dover Downs & River,Dover,(England/Wales) Urban city and town,E10000016,629160.0,143403.0,Dover 010,Dover 010C,,,,,Outstanding,South-East England and South London,,100062290036.0,,Not applicable,Not applicable,,,E02005050,E01024233,76.0,
118398,886,Kent,2318,Langdon Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,105.0,No Special Classes,19-01-2023,86.0,51.0,35.0,22.1,Not applicable,,Not applicable,,Not under a federation,,10073330.0,,Not applicable,28-01-2020,07-05-2024,East Langdon,,The Street,Dover,Kent,CT15 5JQ,www.langdonprimaryschool.co.uk,1304852600.0,Mrs,Lynn,Paylor Sutton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,"Guston, Kingsdown & St Margaret's-at-Cliffe",Dover,(England/Wales) Rural village,E10000016,633397.0,146333.0,Dover 012,Dover 012B,,,,,Good,South-East England and South London,,100062287609.0,,Not applicable,Not applicable,,,E02005052,E01024238,19.0,
118399,886,Kent,2320,Eythorne Elvington Community Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,140.0,No Special Classes,19-01-2023,107.0,47.0,60.0,52.3,Not applicable,,Not applicable,,Supported by a federation,The Federation of Shepherdswell Church of England and Eythorne Elvington,10069511.0,,Not applicable,14-12-2022,17-05-2024,Adelaide Road,Eythorne,,Dover,Kent,CT15 4AN,www.eythorne-elvington.kent.sch.uk,1304830376.0,Mr,N,Garvey,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,"Aylesham, Eythorne & Shepherdswell",Dover,(England/Wales) Rural town and fringe,E10000016,628011.0,149789.0,Dover 006,Dover 006D,,,,,Outstanding,South-East England and South London,,10034882456.0,,Not applicable,Not applicable,,,E02005046,E01024204,56.0,
118400,886,Kent,2321,Lydden Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,84.0,No Special Classes,19-01-2023,78.0,37.0,41.0,11.7,Not applicable,,Not applicable,,Supported by a federation,Lydden and River Primary Schools Federation,10073329.0,,Not applicable,05-02-2019,26-03-2024,Stonehall,Lydden,,Dover,Kent,CT15 7LA,http://www.lydden.kent.sch.uk,1304822887.0,Mr,Neil,Brinicombe,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Dover Downs & River,Dover,(England/Wales) Rural village,E10000016,626743.0,145568.0,Dover 010,Dover 010G,,,,,Good,South-East England and South London,,100062288383.0,,Not applicable,Not applicable,,,E02005050,E01033210,9.0,
118401,886,Kent,2322,Preston Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,133.0,No Special Classes,19-01-2023,117.0,58.0,59.0,7.7,Not applicable,,Not applicable,,Supported by a federation,The Federation of Preston and Wingham,10073328.0,,Not applicable,01-02-2024,20-05-2024,Mill Lane,Preston,,Canterbury,Kent,CT3 1HB,www.prestonprimary.org.uk,1227722235.0,Mrs,Helen,Clements,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Little Stour & Ashstone,South Thanet,(England/Wales) Rural village,E10000016,625140.0,160901.0,Dover 001,Dover 001A,,,,,Good,South-East England and South London,,100062298104.0,,Not applicable,Not applicable,,,E02005041,E01024206,9.0,
118403,886,Kent,2326,Wingham Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,191.0,97.0,94.0,15.7,Not applicable,,Not applicable,,Supported by a federation,The Federation of Preston and Wingham,10073327.0,,Not applicable,17-11-2021,18-04-2024,School Lane,Wingham,,Canterbury,Kent,CT3 1BD,www.winghamprimary.org.uk/,1227720277.0,Mrs,Helen,Clements,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Little Stour & Ashstone,South Thanet,(England/Wales) Rural town and fringe,E10000016,624160.0,157221.0,Dover 001,Dover 001D,,,,,Good,South-East England and South London,,100062298256.0,,Not applicable,Not applicable,,,E02005041,E01024209,30.0,
118405,886,Kent,2328,St Mildred's Primary Infant School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,269.0,135.0,134.0,21.9,Supported by a trust,Thanet Endeavour Learning Trust,Not applicable,,Supported by a federation,The Federation of Bromstone Primary School and St.Mildred's Primary Infant School,10074070.0,,Not applicable,24-11-2021,30-04-2024,St Mildred's Avenue,,,Broadstairs,Kent,CT10 2BX,http://www.st-mildreds.kent.sch.uk,1843862035.0,Headteacher,James,Williams,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Viking,South Thanet,(England/Wales) Urban city and town,E10000016,639125.0,167790.0,Thanet 010,Thanet 010C,,,,,Outstanding,South-East England and South London,,200002882176.0,,Not applicable,Not applicable,,,E02005141,E01024706,59.0,
118406,886,Kent,2329,Callis Grange Nursery and Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,7,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,296.0,No Special Classes,19-01-2023,288.0,159.0,129.0,21.2,Not applicable,,Not applicable,,Not under a federation,,10074069.0,,Not applicable,21-04-2022,15-05-2024,Beacon Road,,,Broadstairs,Kent,CT10 3DG,http://www.callis-grange.kent.sch.uk,1843862531.0,Mrs,Vikki,Bowman,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Beacon Road,South Thanet,(England/Wales) Urban city and town,E10000016,638675.0,169146.0,Thanet 006,Thanet 006A,,,,,Good,South-East England and South London,,100062281748.0,,Not applicable,Not applicable,,,E02005137,E01024633,61.0,
118411,886,Kent,2337,St Crispin's Community Primary Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,254.0,128.0,126.0,28.3,Not applicable,,Not applicable,,Not under a federation,,10074068.0,,Not applicable,11-09-2019,22-04-2024,St Crispin's Road,,,Westgate-on-Sea,Kent,CT8 8EB,http://www.st-crispinsinfants.org.uk,1843832040.0,Mrs,Louise,Davidson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Westgate-on-Sea,North Thanet,(England/Wales) Urban city and town,E10000016,632291.0,169367.0,Thanet 007,Thanet 007E,,,,,Good,South-East England and South London,,200001851326.0,,Not applicable,Not applicable,,,E02005138,E01024716,72.0,
118414,886,Kent,2340,Ellington Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,180.0,No Special Classes,19-01-2023,134.0,71.0,63.0,47.8,Not applicable,,Not applicable,,Not under a federation,,10074067.0,,Not applicable,19-07-2022,23-04-2024,High Street,St Lawrence,,Ramsgate,Kent,CT11 0QH,www.ellington-infant.kent.sch.uk,1843591638.0,Mr,Adnan,Ahmet,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Central Harbour,South Thanet,(England/Wales) Urban city and town,E10000016,637175.0,165319.0,Thanet 015,Thanet 015A,,,,,Good,South-East England and South London,,200003079680.0,,Not applicable,Not applicable,,,E02005146,E01024645,64.0,
118416,886,Kent,2345,Priory Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,180.0,No Special Classes,19-01-2023,155.0,76.0,79.0,38.1,Not applicable,,Not applicable,,Not under a federation,,10074066.0,,Not applicable,21-06-2023,05-06-2024,Cannon Road,,,Ramsgate,Kent,CT11 9XT,www.priory.kent.sch.uk,1843593105.0,Ms,Tracey,Sandy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Central Harbour,South Thanet,(England/Wales) Urban city and town,E10000016,637770.0,165232.0,Thanet 016,Thanet 016A,,,,,Good,South-East England and South London,,100062283791.0,,Not applicable,Not applicable,,,E02005147,E01024646,59.0,
118436,886,Kent,2431,Shears Green Junior School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,480.0,No Special Classes,19-01-2023,483.0,232.0,251.0,28.0,Supported by a trust,Northfleet Schools Co-Operative Trust,Not applicable,,Not under a federation,,10073106.0,,Not applicable,19-01-2023,03-05-2024,White Avenue,Northfleet,,Gravesend,Kent,DA11 7JB,www.shearsgreenjuniorschool.co.uk,1474567359.0,Mr,Matthew,Paterson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Coldharbour & Perry Street,Gravesham,(England/Wales) Urban major conurbation,E10000016,563816.0,172261.0,Gravesham 009,Gravesham 009A,,,,,Good,South-East England and South London,,100062310707.0,,Not applicable,Not applicable,,,E02005063,E01024264,135.0,
118438,886,Kent,2434,West Minster Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,570.0,Has Special Classes,19-01-2023,508.0,253.0,255.0,56.6,Not applicable,,Not applicable,,Supported by a federation,Sheerness West Federation,10076225.0,,Not applicable,01-12-2021,14-05-2024,St George's Avenue,,,Sheerness,Kent,ME12 1ET,www.swfed.co.uk,1795662178.0,Ms,Hazel,Brewer,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Sheerness,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,591524.0,173868.0,Swale 002,Swale 002C,,,,,Good,South-East England and South London,,100062626557.0,,Not applicable,Not applicable,,,E02005116,E01024615,269.0,
118449,886,Kent,2454,Aycliffe Community Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,135.0,No Special Classes,19-01-2023,93.0,54.0,39.0,61.3,Not applicable,,Not applicable,,Not under a federation,,10073325.0,,Not applicable,01-12-2022,19-04-2024,St David's Avenue,,,Dover,Kent,CT17 9HJ,www.aycliffecpschool.co.uk,1304202651.0,Mrs,Jacky,Cox,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Town & Castle,Dover,(England/Wales) Urban city and town,E10000016,630152.0,139911.0,Dover 013,Dover 013E,,,,,Good,South-East England and South London,,200001851339.0,,Not applicable,Not applicable,,,E02005053,E01024249,57.0,
118453,886,Kent,2459,Riverhead Infants' School,Community school,Local authority maintained schools,Open,Not applicable,26-02-1997,Not applicable,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,268.0,140.0,128.0,4.5,Not applicable,,Not applicable,,Not under a federation,,10080749.0,,Not applicable,22-03-2023,24-01-2024,Worships Hill,,,Riverhead,Kent,TN13 2AS,http://www.riverhead.kent.sch.uk,1732452475.0,Mr,Andrew,King,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Dunton Green and Riverhead,Sevenoaks,(England/Wales) Urban city and town,E10000016,551308.0,156016.0,Sevenoaks 011,Sevenoaks 011C,,,,,Good,South-East England and South London,,50002018912.0,,Not applicable,Not applicable,,,E02005097,E01024424,12.0,
118456,886,Kent,2465,Claremont Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,436.0,No Special Classes,19-01-2023,438.0,239.0,199.0,2.7,Not applicable,,Not applicable,,Not under a federation,,10069510.0,,Not applicable,12-01-2023,24-05-2024,Banner Farm Road,,,Tunbridge Wells,Kent,TN2 5EB,www.claremont.kent.sch.uk,1892531395.0,Mrs,Candi,Roberts,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Pantiles and St Mark's,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558955.0,138862.0,Tunbridge Wells 012,Tunbridge Wells 012E,,,,,Good,South-East England and South London,,100062554871.0,,Not applicable,Not applicable,,,E02005173,E01024820,12.0,
118459,886,Kent,2471,Whitfield Aspen School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,591.0,Has Special Classes,19-01-2023,585.0,329.0,256.0,36.1,Not applicable,,Not applicable,,Not under a federation,,10072993.0,,Not applicable,12-09-2019,02-05-2024,Mayfield Road,Whitfield,,Dover,Kent,CT16 3LJ,www.whitfieldaspenschool.co.uk/,1304821526.0,Mr,Jason,Cook,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,PMLD - Profound and Multiple Learning Difficulty,,,,,,,,,,,,,Resourced provision,168.0,168.0,,,South East,Dover,Whitfield,Dover,(England/Wales) Urban city and town,E10000016,630324.0,145151.0,Dover 010,Dover 010F,,,,,Good,South-East England and South London,,100062289581.0,,Not applicable,Not applicable,,,E02005050,E01024256,211.0,
118461,886,Kent,2474,St Paul's Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,261.0,120.0,141.0,30.3,Not applicable,,Not applicable,,Supported by a federation,St Paul's and North Borough Schools Federation,10074064.0,,Not applicable,15-01-2020,24-04-2024,Hillary Road,,,Maidstone,Kent,ME14 2BS,www.stpaulsmaidstone.co.uk,1622753322.0,Mrs,Sarah,Aldridge,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,North,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,576222.0,157046.0,Maidstone 004,Maidstone 004D,,,,,Good,South-East England and South London,,200003707812.0,,Not applicable,Not applicable,,,E02005071,E01024383,79.0,
118465,886,Kent,2482,Langton Green Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,414.0,209.0,205.0,5.1,Not applicable,,Not applicable,,Not under a federation,,10073324.0,,Not applicable,20-06-2012,21-05-2024,Lampington Row,Langton Green,,Tunbridge Wells,Kent,TN3 0JG,www.langton-green-school.org,1892862648.0,Mr,Alex,Cornelius,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Speldhurst and Bidborough,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,554343.0,139529.0,Tunbridge Wells 006,Tunbridge Wells 006D,,,,,Outstanding,South-East England and South London,,100062566427.0,,Not applicable,Not applicable,,,E02005167,E01024853,21.0,
118468,886,Kent,2490,Bishops Down Primary and Nursery School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,233.0,121.0,112.0,11.7,Not applicable,,Not applicable,,Not under a federation,,10077232.0,,Not applicable,02-11-2023,16-04-2024,Rydal Drive,,,Tunbridge Wells,Kent,TN4 9SU,www.bishopsdownprimary.org/,1892520114.0,Mrs,Laura,Johnson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,PD - Physical Disability,,,,,,,,,,,,,Resourced provision,7.0,8.0,,,South East,Tunbridge Wells,Culverden,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,556995.0,140187.0,Tunbridge Wells 007,Tunbridge Wells 007B,,,,,Requires improvement,South-East England and South London,,100062586163.0,,Not applicable,Not applicable,,,E02005168,E01024800,25.0,
118479,886,Kent,2509,Singlewell Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,390.0,No Special Classes,19-01-2023,392.0,178.0,214.0,18.4,Not applicable,,Not applicable,,Not under a federation,,10069509.0,,Not applicable,25-01-2023,03-05-2024,Mackenzie Way,,,Gravesend,Kent,DA12 5TY,www.singlewell.kent.sch.uk,1474569859.0,Mrs,Michelle,Brown,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Singlewell,Gravesham,(England/Wales) Urban major conurbation,E10000016,565793.0,170786.0,Gravesham 011,Gravesham 011B,,,,,Good,South-East England and South London,,100062312820.0,,Not applicable,Not applicable,,,E02005065,E01024304,72.0,
118480,886,Kent,2510,Cheriton Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,389.0,203.0,186.0,24.9,Not supported by a trust,,Not applicable,,Not under a federation,,10073105.0,,Not applicable,30-10-2019,24-04-2024,Church Road,,,Folkestone,Kent,CT20 3EP,http://www.cheritonprimary.org.uk/,1303276112.0,Ms,Sophia,Dover,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Cheriton,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,619394.0,136651.0,Folkestone and Hythe 005,Folkestone and Hythe 005C,,,,,Good,South-East England and South London,,50025272.0,,Not applicable,Not applicable,,,E02005106,E01024494,97.0,
118484,886,Kent,2514,Brookfield Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,180.0,No Special Classes,19-01-2023,180.0,85.0,95.0,18.9,Not applicable,,Not applicable,,Supported by a federation,Flourish,10074062.0,,Not applicable,20-04-2023,23-04-2024,Swallow Road,Larkfield,,Aylesford,Kent,ME20 6PY,https://flourish-federation.secure-primarysite.net/,1732840955.0,Miss,C,Smith,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Larkfield,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,570115.0,158700.0,Tonbridge and Malling 003,Tonbridge and Malling 003F,,,,,Good,South-East England and South London,,10002912773.0,,Not applicable,Not applicable,,,E02005151,E01024765,34.0,
118487,886,Kent,2519,Vigo Village School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,142.0,78.0,64.0,15.5,Not applicable,,Not applicable,,Not under a federation,,10073323.0,,Not applicable,06-11-2019,16-05-2024,Erskine Road,Vigo Village,Meopham,Gravesend,Kent,DA13 0RL,http://www.vigo.kent.sch.uk,1732823144.0,Mr,Roger,Barber,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Meopham South & Vigo,Gravesham,(England/Wales) Rural town and fringe,E10000016,564387.0,161691.0,Gravesham 013,Gravesham 013C,,,,,Good,South-East England and South London,,100062312944.0,,Not applicable,Not applicable,,,E02005067,E01024275,22.0,
118488,886,Kent,2520,Madginford Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,654.0,No Special Classes,19-01-2023,642.0,353.0,289.0,10.1,Not applicable,,Not applicable,,Not under a federation,,10073322.0,,Not applicable,20-04-2023,12-09-2023,Egremont Road,Bearsted,,Maidstone,Kent,ME15 8LH,www.madginfordprimaryschool.co.uk,1622734539.0,Mrs,Amanda,Woolcombe,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Bearsted,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,579076.0,154708.0,Maidstone 007,Maidstone 007B,,,,,Good,South-East England and South London,,200003691655.0,,Not applicable,Not applicable,,,E02005074,E01024327,65.0,
118490,886,Kent,2524,Palmarsh Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,140.0,No Special Classes,19-01-2023,191.0,82.0,109.0,30.9,Not applicable,,Not applicable,,Not under a federation,,10073321.0,,Not applicable,02-10-2019,04-06-2024,St George's Place,,,Hythe,Kent,CT21 6NE,http://www.palmarsh.kent.sch.uk,1303260212.0,Mr,Jamie,Leach,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Hythe Rural,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,613796.0,133711.0,Folkestone and Hythe 010,Folkestone and Hythe 010D,,,,,Good,South-East England and South London,,50013151.0,,Not applicable,Not applicable,,,E02005111,E01024529,59.0,
118491,886,Kent,2525,Painters Ash Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,406.0,203.0,203.0,22.4,Supported by a trust,Northfleet Schools Co-Operative Trust,Not applicable,,Not under a federation,,10073104.0,,Not applicable,01-03-2023,23-05-2024,Masefield Road,Northfleet,,Gravesend,Kent,DA11 8EL,www.paintersashprimary.co.uk,1474568991.0,,Georgina,Salter,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Painters Ash,Gravesham,(England/Wales) Urban major conurbation,E10000016,562691.0,172101.0,Gravesham 006,Gravesham 006E,,,,,Good,South-East England and South London,,100062310909.0,,Not applicable,Not applicable,,,E02005060,E01024288,91.0,
118493,886,Kent,2530,Tunbury Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,19-01-2023,587.0,292.0,295.0,7.8,Not applicable,,Not applicable,,Not under a federation,,10073320.0,,Not applicable,08-06-2023,14-05-2024,Tunbury Avenue,Walderslade,,Chatham,Kent,ME5 9HY,www.tunbury.kent.sch.uk,1634863085.0,Mrs,Ruth,Austin,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Walderslade,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,575737.0,162426.0,Tonbridge and Malling 001,Tonbridge and Malling 001D,,,,,Good,South-East England and South London,,100062393390.0,,Not applicable,Not applicable,,,E02005149,E01024722,46.0,
118495,886,Kent,2532,St Margaret's-at-Cliffe Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,189.0,96.0,93.0,9.0,Not applicable,,Not applicable,,Not under a federation,,10069508.0,,Not applicable,03-07-2015,03-06-2024,Sea Street,St Margaret's-At-Cliffe,,Dover,Kent,CT15 6SS,http://www.stmargaretsprimary.co.uk,1304852639.0,Ms,Helen,Comfort,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,"Guston, Kingsdown & St Margaret's-at-Cliffe",Dover,(England/Wales) Rural town and fringe,E10000016,636125.0,144710.0,Dover 009,Dover 009B,,,,,Outstanding,South-East England and South London,,100062288026.0,,Not applicable,Not applicable,,,E02005049,E01024236,17.0,
118501,886,Kent,2539,Stocks Green Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,218.0,No Special Classes,19-01-2023,216.0,115.0,101.0,5.1,Not applicable,,Not applicable,,Not under a federation,,10069507.0,,Not applicable,07-03-2024,22-05-2024,Leigh Road,Hildenborough,,Tonbridge,Kent,TN11 9AE,www.stocksgreenprimary.co.uk,1732832758.0,Mr,P,Hipkiss,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Hildenborough,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,557065.0,148064.0,Tonbridge and Malling 010,Tonbridge and Malling 010B,,,,,Good,South-East England and South London,,100062628569.0,,Not applicable,Not applicable,,,E02005158,E01024752,11.0,
118505,886,Kent,2545,Sandgate Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,418.0,206.0,212.0,9.8,Not applicable,,Not applicable,,Not under a federation,,10073318.0,,Not applicable,16-09-2021,12-09-2023,Coolinge Lane,,,Folkestone,Kent,CT20 3QU,www.sandgateprimaryschool.co.uk/,1303257280.0,Mr,Matthew,Green,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Sandgate & West Folkestone,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,620849.0,135894.0,Folkestone and Hythe 006,Folkestone and Hythe 006H,,,,,Good,South-East England and South London,,50027156.0,,Not applicable,Not applicable,,,E02005107,E01024521,41.0,
118511,886,Kent,2552,Sandling Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,421.0,226.0,195.0,4.8,Not applicable,,Not applicable,,Not under a federation,,10073317.0,,Not applicable,05-02-2020,07-05-2024,Ashburnham Road,Penenden Heath,,Maidstone,Kent,ME14 2JG,http://www.sandling.kent.sch.uk/,1622763297.0,Miss,Claire,Coombes,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Maidstone,North,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,576624.0,157776.0,Maidstone 002,Maidstone 002D,,,,,Good,South-East England and South London,,10014308132.0,,Not applicable,Not applicable,,,E02005069,E01024385,20.0,
118515,886,Kent,2559,Capel-le-Ferne Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,177.0,99.0,78.0,22.6,Not applicable,,Not applicable,,Not under a federation,,10071996.0,,Not applicable,30-03-2022,21-05-2024,Capel Street,Capel-le-Ferne,,Folkestone,Kent,CT18 7HB,www.capelleferneprimary.co.uk,1303251353.0,Mr,Anthony,Richards,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Dover,Alkham & Capel-le-Ferne,Dover,(England/Wales) Rural hamlet and isolated dwellings,E10000016,625026.0,139092.0,Dover 014,Dover 014A,,,,,Good,South-East England and South London,,100062290850.0,,Not applicable,Not applicable,,,E02005054,E01024198,40.0,
118516,886,Kent,2562,Lunsford Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,208.0,104.0,104.0,20.7,Not applicable,,Not applicable,,Not under a federation,,10073316.0,,Not applicable,14-06-2023,01-04-2024,Swallow Road,Larkfield,,Aylesford,Kent,ME20 6PY,http://www.lunsford.kent.sch.uk,1732843352.0,Mr,Gary,Anscombe,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Larkfield,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,570068.0,158786.0,Tonbridge and Malling 003,Tonbridge and Malling 003F,,,,,Good,South-East England and South London,,200000966558.0,,Not applicable,Not applicable,,,E02005151,E01024765,43.0,
118523,886,Kent,2574,Downs View Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,260.0,138.0,122.0,16.2,Not applicable,,Not applicable,,Not under a federation,,10080430.0,,Not applicable,18-10-2023,21-05-2024,Ball Lane,Kennington,,Ashford,Kent,TN25 4PJ,www.downs-view.kent.sch.uk/,1233632339.0,Mrs,Tracy Kent,Mrs Sarah Collins,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Ashford,Kennington,Ashford,(England/Wales) Urban city and town,E10000016,602119.0,145227.0,Ashford 003,Ashford 003B,,,,,Good,South-East England and South London,,100062561615.0,,Not applicable,Not applicable,,,E02004998,E01023999,42.0,
118524,886,Kent,2578,Kingswood Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,140.0,No Special Classes,19-01-2023,129.0,70.0,59.0,10.1,Not applicable,,Not applicable,,Not under a federation,,10073315.0,,Not applicable,19-07-2022,20-11-2023,Cayser Drive,Kingswood,,Maidstone,Kent,ME17 3QF,www.kingswoodkentsch.co.uk,1622842674.0,Mrs,Lynsey,Sanchez Daviu,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Leeds,Faversham and Mid Kent,(England/Wales) Rural town and fringe,E10000016,584054.0,150831.0,Maidstone 015,Maidstone 015C,,,,,Good,South-East England and South London,,10022897422.0,,Not applicable,Not applicable,,,E02005082,E01024375,13.0,
118526,886,Kent,2586,Senacre Wood Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,212.0,109.0,103.0,32.1,Not applicable,,Not applicable,,Not under a federation,,10073314.0,,Not applicable,04-12-2019,27-02-2024,Graveney Road,Senacre,,Maidstone,Kent,ME15 8QQ,www.senacre-wood.kent.sch.uk/,3000658430.0,Mrs,Emily,Sweeney,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Shepway South,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,578633.0,153076.0,Maidstone 013,Maidstone 013F,,,,,Good,South-East England and South London,,200003717450.0,,Not applicable,Not applicable,,,E02005080,E01024399,68.0,
118534,886,Kent,2603,"Bromstone Primary School, Broadstairs",Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,Has Special Classes,19-01-2023,406.0,221.0,185.0,38.9,Supported by a trust,Thanet Endeavour Learning Trust,Not applicable,,Supported by a federation,The Federation of Bromstone Primary School and St.Mildred's Primary Infant School,10073313.0,,Not applicable,27-03-2019,21-05-2024,Rumfields Road,,,Broadstairs,Kent,CT10 2PW,www.bromstoneschool.com/,1843867010.0,Mr,James,Williams,Executive Head,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,VI - Visual Impairment,HI - Hearing Impairment,"SLCN - Speech, language and Communication",,,,,,,,,,,Resourced provision,35.0,35.0,,,South East,Thanet,St Peters,South Thanet,(England/Wales) Urban city and town,E10000016,637928.0,167475.0,Thanet 011,Thanet 011D,,,,,Good,South-East England and South London,,200003079311.0,,Not applicable,Not applicable,,,E02005142,E01024690,158.0,
118536,886,Kent,2607,Parkside Community Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,168.0,84.0,84.0,75.6,Supported by a trust,Thanet Endeavour Learning Trust,Not applicable,,Not under a federation,,10073312.0,,Not applicable,26-04-2023,30-04-2024,Tennyson Avenue,,,Canterbury,Kent,CT1 1EP,www.parksidecommunityprimaryschool.co.uk,1227464956.0,Mr,James,Williams,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Northgate,Canterbury,(England/Wales) Urban city and town,E10000016,616671.0,158965.0,Canterbury 014,Canterbury 014C,,,,,Good,South-East England and South London,,100062279371.0,,Not applicable,Not applicable,,,E02005023,E01024090,127.0,
118541,886,Kent,2615,High Firs Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,206.0,98.0,108.0,13.6,Not applicable,,Not applicable,,Not under a federation,,10073311.0,,Not applicable,12-10-2023,23-04-2024,Court Crescent,,,Swanley,Kent,BR8 8NR,www.high-firs.kent.sch.uk/,1322669721.0,Mr,Andrew,Kilbride,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Swanley Christchurch and Swanley Village,Sevenoaks,(England/Wales) Urban major conurbation,E10000016,551435.0,168115.0,Sevenoaks 003,Sevenoaks 003C,,,,,Good,South-East England and South London,,50002001954.0,,Not applicable,Not applicable,,,E02005089,E01024474,28.0,
118548,886,Kent,2627,Sandwich Junior School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,240.0,No Special Classes,19-01-2023,210.0,104.0,106.0,22.4,Not applicable,,Not applicable,,Not under a federation,,10079030.0,,Not applicable,24-03-2022,12-09-2023,St Bart's Road,,,Sandwich,Kent,CT13 0AS,www.sandwich-junior.kent.sch.uk/,1304612227.0,Mr,Martin,Dyson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Sandwich,South Thanet,(England/Wales) Rural town and fringe,E10000016,632790.0,157449.0,Dover 002,Dover 002C,,,,,Outstanding,South-East England and South London,,200001851331.0,,Not applicable,Not applicable,,,E02005042,E01024243,47.0,
118551,886,Kent,2632,Sevenoaks Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,19-01-2023,587.0,312.0,275.0,15.2,Not applicable,,Not applicable,,Not under a federation,,10073310.0,,Not applicable,19-04-2023,15-04-2024,Bradbourne Park Road,,,Sevenoaks,Kent,TN13 3LB,www.sevenoaks.kent.sch.uk,1732453952.0,Mrs,Cassandra,Malone,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Sevenoaks Town and St John's,Sevenoaks,(England/Wales) Urban city and town,E10000016,552671.0,156229.0,Sevenoaks 010,Sevenoaks 010F,,,,,Good,South-East England and South London,,100062548252.0,,Not applicable,Not applicable,,,E02005096,E01024468,89.0,
118558,886,Kent,2643,Swalecliffe Community Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,660.0,No Special Classes,19-01-2023,581.0,320.0,261.0,18.2,Supported by a trust,The Coastal Alliance Co-operative Trust,Not applicable,,Not under a federation,,10073102.0,,Not applicable,14-09-2023,24-01-2024,Bridgefield Road,Swalecliffe,,Whitstable,Kent,CT5 2PH,http://www.swalecliffeprimary.org,1227272101.0,Mrs,Sarah,Watson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Swalecliffe,Canterbury,(England/Wales) Urban city and town,E10000016,613028.0,166878.0,Canterbury 005,Canterbury 005E,,,,,Good,South-East England and South London,,100062301012.0,,Not applicable,Not applicable,,,E02005014,E01024115,106.0,
118563,886,Kent,2648,Aylesham Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,391.0,191.0,200.0,39.1,Not applicable,,Not applicable,,Not under a federation,,10073309.0,,Not applicable,08-06-2023,16-04-2024,Attlee Avenue,Aylesham,,Canterbury,Kent,CT3 3BS,www.aylesham.kent.sch.uk,1304840392.0,Mr,Darran,Callaghan,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,"Aylesham, Eythorne & Shepherdswell",Dover,(England/Wales) Rural town and fringe,E10000016,623337.0,152432.0,Dover 006,Dover 006E,,,,,Good,South-East England and South London,,10034883661.0,,Not applicable,Not applicable,,,E02005046,E01035314,153.0,
118566,886,Kent,2651,Broadwater Down Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,148.0,69.0,79.0,34.5,Not applicable,,Not applicable,,Not under a federation,,10073308.0,,Not applicable,09-03-2023,17-04-2024,Broadwater Lane,,,Tunbridge Wells,Kent,TN2 5RP,www.broadwater-down.kent.sch.uk,1892527588.0,Mr,Alex,Cornelius,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Broadwater,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,557682.0,138106.0,Tunbridge Wells 010,Tunbridge Wells 010A,,,,,Good,South-East England and South London,,100062555286.0,,Not applicable,Not applicable,,,E02005171,E01024795,51.0,
118568,886,Kent,2653,West Borough Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,510.0,No Special Classes,19-01-2023,503.0,257.0,246.0,22.2,Not applicable,,Not applicable,,Not under a federation,,10076223.0,,Not applicable,19-10-2022,20-02-2024,Greenway,,,Maidstone,Kent,ME16 8TL,http://www.west-borough.kent.sch.uk/,1622726391.0,Mrs,Lisa,Edinburgh,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Heath,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,573885.0,155150.0,Maidstone 008,Maidstone 008C,,,,,Good,South-East England and South London,,10014309300.0,,Not applicable,Not applicable,,,E02005075,E01024367,102.0,
118575,886,Kent,2662,Long Mead Community Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,128.0,50.0,78.0,54.7,Not supported by a trust,,Not applicable,,Not under a federation,,10073101.0,,Not applicable,18-09-2019,31-03-2024,Waveney Road,,,Tonbridge,Kent,TN10 3JU,www.long-mead.kent.sch.uk/,1732350601.0,Mrs,Karen,Follows,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Trench,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,558754.0,148444.0,Tonbridge and Malling 009,Tonbridge and Malling 009C,,,,,Good,South-East England and South London,,200000961885.0,,Not applicable,Not applicable,,,E02005157,E01024775,64.0,
118585,886,Kent,2674,King's Farm Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,492.0,No Special Classes,19-01-2023,437.0,237.0,200.0,53.2,Not applicable,,Not applicable,,Supported by a federation,Ifield School & King's Farm Primary School Federation,10069504.0,,Not applicable,28-02-2024,22-05-2024,Cedar Avenue,,,Gravesend,Kent,DA12 5JT,www.kings-farm.kent.sch.uk,1474566979.0,Mr,Chris,Jackson,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,13.0,15.0,,,South East,Gravesham,Singlewell,Gravesham,(England/Wales) Urban major conurbation,E10000016,565269.0,171511.0,Gravesham 011,Gravesham 011D,,,,,Good,South-East England and South London,,100062312756.0,,Not applicable,Not applicable,,,E02005065,E01024306,216.0,
118590,886,Kent,3010,St Pauls' Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,105.0,No Special Classes,19-01-2023,107.0,52.0,55.0,10.3,Not applicable,,Not applicable,,Supported by a federation,The Compass Federation,10070335.0,,Not applicable,28-01-2020,01-05-2024,School Lane,,,Swanley Village,Kent,BR8 7PJ,www.st-pauls-swanley.kent.sch.uk,1322664324.0,Mr,Benjamin,Hulme,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Swanley Christchurch and Swanley Village,Sevenoaks,(England/Wales) Urban major conurbation,E10000016,552800.0,169829.0,Sevenoaks 001,Sevenoaks 001D,,,,,Good,South-East England and South London,,100062076900.0,,Not applicable,Not applicable,,,E02005087,E01024472,11.0,
118592,886,Kent,3015,Fawkham Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,105.0,No Special Classes,19-01-2023,102.0,50.0,52.0,5.9,Not applicable,,Not applicable,,Not under a federation,,10078483.0,,Not applicable,22-11-2023,15-04-2024,Valley Road,Fawkham,,LONGFIELD,Kent,DA3 8NA,http://fawkhamschool.com,1474702312.0,Miss,Mandy,Bridges,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Fawkham and West Kingsdown,Sevenoaks,(England/Wales) Rural hamlet and isolated dwellings,E10000016,558819.0,166693.0,Sevenoaks 007,Sevenoaks 007C,,,,,Good,South-East England and South London,,10035185497.0,,Not applicable,Not applicable,,,E02005093,E01024437,6.0,
118597,886,Kent,3022,Benenden Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,211.0,96.0,115.0,11.4,Not applicable,,Not applicable,,Supported by a federation,The 10:10 Primary Federation,10074253.0,,Not applicable,24-02-2022,20-05-2024,Rolvenden Road,,,Cranbrook,,TN17 4EH,http://www.benenden-cep.kent.sch.uk,1580240565.0,Mrs,Lindsay,Roberts,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tunbridge Wells,Benenden and Cranbrook,Maidstone and The Weald,(England/Wales) Rural village,E10000016,580826.0,132744.0,Tunbridge Wells 014,Tunbridge Wells 014A,,,,,Good,South-East England and South London,United Kingdom,10000069843.0,,Not applicable,Not applicable,,,E02005175,E01024789,24.0,
118598,886,Kent,3023,Bidborough Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,207.0,109.0,98.0,6.3,Not applicable,,Not applicable,,Not under a federation,,10070333.0,,Not applicable,10-11-2022,20-05-2024,Spring Lane,Bidborough,,Tunbridge Wells,Kent,TN3 0UE,http://www.bidborough.kent.sch.uk,1892529333.0,Mrs,Julie,Burton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Speldhurst and Bidborough,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,556545.0,143127.0,Tunbridge Wells 006,Tunbridge Wells 006E,,,,,Good,South-East England and South London,,100062566429.0,,Not applicable,Not applicable,,,E02005167,E01024854,13.0,
118600,886,Kent,3027,Cranbrook Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,199.0,93.0,106.0,32.2,Not applicable,,Not applicable,,Not under a federation,,10070332.0,,Not applicable,22-06-2022,21-05-2024,Carriers Road,,,Cranbrook,Kent,TN17 3JZ,http://www.cranbrook-cep.kent.sch.uk,1580713249.0,Miss,Francesca,Shaw,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Benenden and Cranbrook,Maidstone and The Weald,(England/Wales) Rural town and fringe,E10000016,577605.0,136487.0,Tunbridge Wells 013,Tunbridge Wells 013C,,,,,Good,South-East England and South London,,100062552228.0,,Not applicable,Not applicable,,,E02005174,E01024790,64.0,
118601,886,Kent,3029,Goudhurst and Kilndown Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,211.0,107.0,104.0,15.6,Not applicable,,Not applicable,,Supported by a federation,The 10:10 Primary Federation,10078482.0,,Not applicable,20-03-2014,20-05-2024,Beaman Close,Cranbrook Road,Goudhurst,Cranbrook,Kent,TN17 1DZ,www.goudhurst-kilndown.kent.sch.uk,1580211365.0,Mrs,Lindsay,Roberts,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Goudhurst and Lamberhurst,Tunbridge Wells,(England/Wales) Rural village,E10000016,572817.0,137814.0,Tunbridge Wells 011,Tunbridge Wells 011C,,,,,Outstanding,South-East England and South London,,10008665566.0,,Not applicable,Not applicable,,,E02005172,E01024804,33.0,
118602,886,Kent,3032,Hawkhurst Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,183.0,100.0,83.0,42.1,Not applicable,,Not applicable,,Not under a federation,,10070331.0,,Not applicable,25-01-2023,15-04-2024,Fowlers Park,Rye Road,Hawkhurst,Cranbrook,Kent,TN18 4JJ,www.hawkhurst.kent.sch.uk,1580753254.0,Mrs,Jodi,Hacker,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Hawkhurst and Sandhurst,Tunbridge Wells,(England/Wales) Rural town and fringe,E10000016,576506.0,130526.0,Tunbridge Wells 014,Tunbridge Wells 014B,,,,,Good,South-East England and South London,,10000066322.0,,Not applicable,Not applicable,,,E02005175,E01024807,77.0,
118603,886,Kent,3033,Hildenborough Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,190.0,92.0,98.0,8.4,Not applicable,,Not applicable,,Not under a federation,,10069124.0,,Not applicable,01-03-2023,23-01-2024,Riding Lane,Hildenborough,,Tonbridge,Kent,TN11 9HY,http://www.hildenborough.kent.sch.uk,1732833394.0,Miss,Ruth,Ardrey,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Hildenborough,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,556585.0,148896.0,Tonbridge and Malling 010,Tonbridge and Malling 010D,,,,,Good,South-East England and South London,,200000966230.0,,Not applicable,Not applicable,,,E02005158,E01024754,16.0,
118604,886,Kent,3034,Lamberhurst St Mary's CofE (Voluntary Controlled) Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,206.0,95.0,111.0,8.7,Not applicable,,Not applicable,,Not under a federation,,10069123.0,,Not applicable,08-03-2023,01-05-2024,Pearse Place,Lamberhurst,,Tunbridge Wells,Kent,TN3 8EJ,www.lamberhurst.kent.sch.uk,1892890281.0,Mrs,Caroline,Bromley,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Goudhurst and Lamberhurst,Tunbridge Wells,(England/Wales) Rural village,E10000016,567565.0,136008.0,Tunbridge Wells 011,Tunbridge Wells 011D,,,,,Good,South-East England and South London,,10000067311.0,,Not applicable,Not applicable,,,E02005172,E01024805,18.0,
118606,886,Kent,3037,"St John's Church of England Primary School, Sevenoaks",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,202.0,90.0,112.0,10.9,Not applicable,,Not applicable,,Not under a federation,,10078481.0,,Not applicable,26-04-2023,19-04-2024,Bayham Road,,,Sevenoaks,Kent,TN13 3XD,www.stjohnssevenoaks.co.uk,1732453944.0,Mrs,Therese,Pullan,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Sevenoaks Eastern,Sevenoaks,(England/Wales) Urban city and town,E10000016,553550.0,155884.0,Sevenoaks 010,Sevenoaks 010C,,,,,Good,South-East England and South London,,10035184681.0,,Not applicable,Not applicable,,,E02005096,E01024461,22.0,
118607,886,Kent,3042,Speldhurst Church of England Voluntary Aided Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,213.0,106.0,107.0,8.5,Not applicable,,Not applicable,,Not under a federation,,10069121.0,,Not applicable,07-02-2014,19-03-2024,Langton Road,Speldhurst,,Tunbridge Wells,Kent,TN3 0NP,http://www.speldhurst.kent.sch.uk,1892863044.0,Mrs,Stephanie,Hayward,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tunbridge Wells,Speldhurst and Bidborough,Tunbridge Wells,(England/Wales) Rural hamlet and isolated dwellings,E10000016,555310.0,141309.0,Tunbridge Wells 006,Tunbridge Wells 006D,,,,,Outstanding,South-East England and South London,,100062566310.0,,Not applicable,Not applicable,,,E02005167,E01024853,18.0,
118608,886,Kent,3043,Sundridge and Brasted Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,105.0,No Special Classes,19-01-2023,60.0,32.0,28.0,38.3,Not applicable,,Not applicable,,Not under a federation,,10078480.0,,Not applicable,12-10-2023,16-04-2024,Church Road,Sundridge,,Sevenoaks,Kent,TN14 6EA,http://www.sundridge.kent.sch.uk,1959562694.0,Mr,Tom,Hardwick,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Brasted, Chevening and Sundridge",Sevenoaks,(England/Wales) Rural village,E10000016,548465.0,154940.0,Sevenoaks 013,Sevenoaks 013A,,,,,Good,South-East England and South London,,100062548784.0,,Not applicable,Not applicable,,,E02005099,E01024417,23.0,
118611,886,Kent,3050,St John's Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,630.0,No Special Classes,19-01-2023,631.0,314.0,317.0,11.6,Not applicable,,Not applicable,,Not under a federation,,10069120.0,,Not applicable,22-03-2023,16-05-2024,Cunningham Road,,St John's Cep,Tunbridge Wells,Kent,TN4 9EW,www.st-johns-school.org.uk/,1892678980.0,Mr,Niall,Dossad,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,St John's,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558728.0,141298.0,Tunbridge Wells 003,Tunbridge Wells 003A,,,,,Good,South-East England and South London,,100062586186.0,,Not applicable,Not applicable,,,E02005164,E01024836,73.0,
118613,886,Kent,3052,St Mark's Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,420.0,No Special Classes,19-01-2023,360.0,193.0,167.0,23.1,Not applicable,,Not applicable,,Not under a federation,,10069119.0,,Not applicable,29-06-2022,21-05-2024,Ramslye Road,,,Tunbridge Wells,Kent,TN4 8LN,http://www.st-marks.kent.sch.uk,1892525402.0,Mr,Simon,Bird,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Broadwater,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,556979.0,138070.0,Tunbridge Wells 010,Tunbridge Wells 010B,,,,,Good,South-East England and South London,,100062585738.0,,Not applicable,Not applicable,,,E02005171,E01024796,83.0,
118614,886,Kent,3053,St Peter's Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,213.0,116.0,97.0,13.1,Not applicable,,Not applicable,,Not under a federation,,10078479.0,,Not applicable,20-03-2014,27-09-2023,Hawkenbury Road,,,Tunbridge Wells,,TN2 5BW,http://www.st-peters.kent.sch.uk,1892525727.0,Mrs,Joanna,Langton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Park,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,559229.0,139204.0,Tunbridge Wells 009,Tunbridge Wells 009C,,,,,Outstanding,South-East England and South London,United Kingdom,10090053470.0,,Not applicable,Not applicable,,,E02005170,E01024824,28.0,
118615,886,Kent,3054,Crockham Hill Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,140.0,No Special Classes,19-01-2023,137.0,70.0,67.0,0.7,Not applicable,,Not applicable,,Not under a federation,,10069118.0,,Not applicable,26-04-2023,23-05-2024,Crockham Hill,,,Edenbridge,Kent,TN8 6RP,http://www.crockhamhill.kent.sch.uk,1732866374.0,Mrs,Lisa,Higgs,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Sevenoaks,Westerham and Crockham Hill,Sevenoaks,(England/Wales) Rural hamlet and isolated dwellings,E10000016,544353.0,150691.0,Sevenoaks 013,Sevenoaks 013D,,,,,Good,South-East England and South London,,10035185257.0,,Not applicable,Not applicable,,,E02005099,E01024484,1.0,
118616,886,Kent,3055,Churchill Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,420.0,No Special Classes,19-01-2023,201.0,94.0,107.0,28.4,Not applicable,,Not applicable,,Not under a federation,,10078478.0,,Not applicable,05-12-2019,12-09-2023,Rysted Lane,,,Westerham,Kent,TN16 1EZ,www.churchill.kent.sch.uk,1959562197.0,Mrs,Kathy,Jax,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Westerham and Crockham Hill,Sevenoaks,(England/Wales) Rural town and fringe,E10000016,544398.0,154520.0,Sevenoaks 013,Sevenoaks 013D,,,,,Good,South-East England and South London,,10035185216.0,,Not applicable,Not applicable,,,E02005099,E01024484,57.0,
118617,886,Kent,3057,St Peter's Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,194.0,102.0,92.0,14.4,Not applicable,,Not applicable,,Not under a federation,,10069117.0,,Not applicable,20-03-2019,03-06-2024,Mount Pleasant,,,Aylesford,Kent,ME20 7BE,www.stpetersaylesford.kent.sch.uk,1622717335.0,Mr,Jim,Holditch,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Aylesford North & North Downs,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,573064.0,159050.0,Tonbridge and Malling 001,Tonbridge and Malling 001A,,,,,Good,South-East England and South London,,100062628349.0,,Not applicable,Not applicable,,,E02005149,E01024719,28.0,
118619,886,Kent,3061,Bredhurst Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,140.0,No Special Classes,19-01-2023,130.0,70.0,60.0,5.4,Not applicable,,Not applicable,,Not under a federation,,10069116.0,,Not applicable,24-01-2024,20-05-2024,The Street,Bredhurst,,Gillingham,Kent,ME7 3JY,www.bredhurst.kent.sch.uk/,1634231271.0,Mrs,Michelle,Cox,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Boxley,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,579632.0,162276.0,Maidstone 001,Maidstone 001C,,,,,Good,South-East England and South London,,200003720400.0,,Not applicable,Not applicable,,,E02005068,E01024335,7.0,
118620,886,Kent,3062,Burham Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,196.0,No Special Classes,19-01-2023,144.0,74.0,70.0,8.3,Not applicable,,Not applicable,,Not under a federation,,10069115.0,,Not applicable,05-12-2018,14-05-2024,Bell Lane,Burham,,Rochester,Kent,ME1 3SY,http://www.burham.kent.sch.uk,1634861691.0,Mrs,Holly,Goddon,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Aylesford North & North Downs,Chatham and Aylesford,(England/Wales) Rural village,E10000016,572942.0,161845.0,Tonbridge and Malling 001,Tonbridge and Malling 001F,,,,,Good,South-East England and South London,,200000961192.0,,Not applicable,Not applicable,,,E02005149,E01024728,12.0,
118622,886,Kent,3067,Harrietsham Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,390.0,No Special Classes,19-01-2023,309.0,148.0,161.0,19.2,Not applicable,,Not applicable,,Not under a federation,,10070328.0,,Not applicable,21-02-2024,20-05-2024,West Street,Harrietsham,,Maidstone,Kent,ME17 1JZ,www.harrietsham.kent.sch.uk,1622859261.0,Mrs,Jackie,Chambers,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Harrietsham and Lenham,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,586070.0,152776.0,Maidstone 011,Maidstone 011F,,,,,Good,South-East England and South London,,10022893860.0,,Not applicable,Not applicable,,,E02005078,E01034994,59.0,
118623,886,Kent,3069,Leeds and Broomfield Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,84.0,40.0,44.0,23.8,Not applicable,,Not applicable,,Not under a federation,,10069114.0,,Not applicable,19-10-2021,17-01-2024,Lower Street,Leeds,,Maidstone,Kent,ME17 1RL,www.leedsandbroomfieldkentsch.co.uk,1622861398.0,Mrs,Fiona,Steer,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Leeds,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,582467.0,153353.0,Maidstone 015,Maidstone 015C,,,,,Good,South-East England and South London,,200003698499.0,,Not applicable,Not applicable,,,E02005082,E01024375,20.0,
118625,886,Kent,3072,"Maidstone, St Michael's Church of England Junior School",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,178.0,No Special Classes,19-01-2023,178.0,89.0,89.0,18.5,Not applicable,,Not applicable,,Supported by a federation,St Michael's Church of England Federated Infant and Junior School,10078477.0,,Not applicable,22-11-2023,23-04-2024,Douglas Road,,,Maidstone,Kent,ME16 8ER,www.st-michaels-junior.kent.sch.uk,1622751502.0,Mrs,Lisa,Saunders,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Fant,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,575266.0,155120.0,Maidstone 006,Maidstone 006G,,,,,Good,South-East England and South London,,200003668897.0,,Not applicable,Not applicable,,,E02005073,E01033091,33.0,
118626,886,Kent,3073,St Michael's Church of England Infant School Maidstone,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,120.0,No Special Classes,19-01-2023,121.0,63.0,58.0,17.4,Not applicable,,Not applicable,,Supported by a federation,St Michael's Church of England Federated Infant and Junior School,10079671.0,,Not applicable,29-01-2014,17-04-2024,Douglas Road,,,Maidstone,Kent,ME16 8ER,http://www.st-michaels-infant.kent.sch.uk,1622751398.0,Mrs,Lisa,Saunders,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Fant,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,575266.0,155120.0,Maidstone 006,Maidstone 006G,,,,,Outstanding,South-East England and South London,,200003668897.0,,Not applicable,Not applicable,,,E02005073,E01033091,21.0,
118629,886,Kent,3081,Thurnham Church of England Infant School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,270.0,No Special Classes,19-01-2023,270.0,140.0,130.0,1.9,Not applicable,,Not applicable,,Not under a federation,,10079670.0,,Not applicable,22-02-2023,25-04-2024,The Landway,Bearsted,,Maidstone,Kent,ME14 4BL,www.thurnham-infant.kent.sch.uk,1622737685.0,Mr,Tony,Pring,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Bearsted,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,579425.0,155670.0,Maidstone 005,Maidstone 005A,,,,,Good,South-East England and South London,,200003691727.0,,Not applicable,Not applicable,,,E02005072,E01024330,5.0,
118630,886,Kent,3082,Trottiscliffe Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,84.0,No Special Classes,19-01-2023,81.0,39.0,42.0,2.5,Not applicable,,Not applicable,,Not under a federation,,10069113.0,,Not applicable,15-09-2022,21-05-2024,Church Lane,Trottiscliffe,,West Malling,Kent,ME19 5EB,http://www.trottiscliffe.kent.sch.uk/,1732822803.0,Miss,Lucy,Henderson,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Pilgrims with Ightham,Tonbridge and Malling,(England/Wales) Rural village,E10000016,564298.0,160200.0,Tonbridge and Malling 014,Tonbridge and Malling 014F,,,,,Good,South-East England and South London,,200000963789.0,,Not applicable,Not applicable,,,E02006833,E01032829,2.0,
118631,886,Kent,3083,Ulcombe Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,63.0,31.0,32.0,50.8,Not applicable,,Not applicable,,Not under a federation,,10069112.0,,Not applicable,27-11-2019,03-06-2024,The Street,Ulcombe,,Maidstone,Kent,ME17 1DU,https://ulcombekentsch.co.uk/,1622842903.0,Ms,Emma,Masters,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",ASD - Autistic Spectrum Disorder,"SEMH - Social, Emotional and Mental Health",MLD - Moderate Learning Difficulty,,,,,,,,,,Resourced provision,6.0,15.0,,,South East,Maidstone,Headcorn,Faversham and Mid Kent,(England/Wales) Rural hamlet and isolated dwellings,E10000016,584797.0,148979.0,Maidstone 017,Maidstone 017C,,,,,Good,South-East England and South London,,10014312333.0,,Not applicable,Not applicable,,,E02005084,E01024366,32.0,
118632,886,Kent,3084,Wateringbury Church of England Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,175.0,74.0,101.0,16.6,Not applicable,,Not applicable,,Not under a federation,,10078476.0,,Not applicable,08-03-2023,30-11-2023,147 Bow Road,Wateringbury,,Maidstone,Kent,ME18 5EA,www.wateringbury.kent.sch.uk/,1622812199.0,Miss,Debbie,Johnson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,"East and West Peckham, Mereworth & Wateringbury",Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,569089.0,152864.0,Tonbridge and Malling 007,Tonbridge and Malling 007D,,,,,Requires improvement,South-East England and South London,,10014312449.0,,Not applicable,Not applicable,,,E02005155,E01024781,29.0,
118634,886,Kent,3088,"Wouldham, All Saints Church of England Voluntary Controlled Primary School",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Non-selective,420.0,No Special Classes,19-01-2023,401.0,196.0,205.0,13.7,Not applicable,,Not applicable,,Not under a federation,,10075829.0,,Not applicable,26-04-2023,10-10-2023,1 Worrall Drive,Wouldham,,Rochester,,ME1 3GE,http://www.wouldham.kent.sch.uk,1634861434.0,Mrs,Victoria,Baldwin,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Aylesford North & North Downs,Chatham and Aylesford,(England/Wales) Rural hamlet and isolated dwellings,E10000016,571413.0,163394.0,Tonbridge and Malling 001,Tonbridge and Malling 001H,,,,,Good,South-East England and South London,United Kingdom,10092972751.0,,Not applicable,Not applicable,,,E02005149,E01035003,55.0,
118635,886,Kent,3089,St George's Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,203.0,103.0,100.0,18.7,Not applicable,,Not applicable,,Not under a federation,,10078871.0,,Not applicable,14-12-2022,03-06-2024,Old London Road,Wrotham,,Sevenoaks,Kent,TN15 7DL,http://www.st-georges-wrotham.kent.sch.uk/,1732882401.0,Mrs,Elizabeth,Rye,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tonbridge and Malling,Pilgrims with Ightham,Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,560941.0,159482.0,Tonbridge and Malling 006,Tonbridge and Malling 006F,,,,,Good,South-East England and South London,,200000964122.0,,Not applicable,Not applicable,,,E02005154,E01024786,38.0,
118636,886,Kent,3090,"St Margaret's, Collier Street Church of England Voluntary Controlled School",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,120.0,No Special Classes,19-01-2023,123.0,58.0,65.0,4.1,Not applicable,,Not applicable,,Not under a federation,,10069111.0,,Not applicable,04-05-2022,07-05-2024,Collier Street,Marden,,Tonbridge,Kent,TN12 9RR,www.collier-street.kent.sch.uk/,1892730264.0,Mr,Paul,Ryan,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Marden and Yalding,Maidstone and The Weald,(England/Wales) Rural hamlet and isolated dwellings,E10000016,571630.0,146064.0,Maidstone 018,Maidstone 018C,,,,,Good,South-East England and South London,,200003662059.0,,Not applicable,Not applicable,,,E02005085,E01024380,5.0,
118637,886,Kent,3091,Laddingford St Mary's Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,101.0,No Special Classes,19-01-2023,81.0,37.0,44.0,25.0,Not applicable,,Not applicable,,Not under a federation,,10069110.0,,Not applicable,08-03-2023,30-04-2024,Darman Lane,Laddingford,,Maidstone,Kent,ME18 6BL,http://www.laddingford.kent.sch.uk,1622871270.0,Mrs,Lucy,Clark,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Maidstone,Marden and Yalding,Maidstone and The Weald,(England/Wales) Rural hamlet and isolated dwellings,E10000016,568865.0,147811.0,Maidstone 018,Maidstone 018B,,,,,Good,South-East England and South London,,200003718886.0,,Not applicable,Not applicable,,,E02005085,E01024379,20.0,
118638,886,Kent,3092,"Yalding, St Peter and St Paul Church of England Voluntary Controlled Primary School",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,168.0,No Special Classes,19-01-2023,173.0,87.0,86.0,10.4,Not applicable,,Not applicable,,Not under a federation,,10078475.0,,Not applicable,30-01-2019,05-06-2024,Vicarage Road,Yalding,,Maidstone,Kent,ME18 6DP,http://www.yalding.kent.sch.uk,1622814298.0,Mrs,Sarah,Friend,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Marden and Yalding,Maidstone and The Weald,(England/Wales) Rural town and fringe,E10000016,570095.0,150173.0,Maidstone 014,Maidstone 014D,,,,,Good,South-East England and South London,,200003718898.0,,Not applicable,Not applicable,,,E02005081,E01024378,18.0,
118646,886,Kent,3108,Ospringe Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,213.0,113.0,100.0,30.5,Not applicable,,Not applicable,,Not under a federation,,10069108.0,,Not applicable,07-06-2023,16-04-2024,Water Lane,Ospringe,,Faversham,Kent,ME13 8TX,www.ospringeprimary.co.uk/,1795532004.0,Mrs,Amanda,Ralph,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Watling,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,600216.0,160694.0,Swale 014,Swale 014F,,,,,Good,South-East England and South London,,100062380290.0,,Not applicable,Not applicable,,,E02005128,E01024627,65.0,
118647,886,Kent,3109,Hernhill Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,212.0,105.0,107.0,10.4,Not applicable,,Not applicable,,Not under a federation,,10078474.0,,Not applicable,07-03-2024,22-05-2024,Fostall,Hernhill,,Faversham,Kent,ME13 9JG,www.hernhill.kent.sch.uk,1227751322.0,Mrs,Sarah,Alexander,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Boughton and Courtenay,Faversham and Mid Kent,(England/Wales) Rural hamlet and isolated dwellings,E10000016,606692.0,161491.0,Swale 017,Swale 017B,,,,,Outstanding,South-East England and South London,,10023196116.0,,Not applicable,Not applicable,,,E02005131,E01024556,22.0,
118649,886,Kent,3111,Newington Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,236.0,No Special Classes,19-01-2023,252.0,139.0,113.0,33.3,Not applicable,,Not applicable,,Supported by a federation,The Federation of Lower Halstow Primary and Newington CofE Primary School,10069107.0,,Not applicable,15-05-2019,19-04-2024,School Lane,Newington,,Sittingbourne,Kent,ME9 7LB,www.newington.kent.sch.uk,1795842300.0,Mrs,Tara,Deevoy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,"Hartlip, Newington and Upchurch",Sittingbourne and Sheppey,(England/Wales) Rural town and fringe,E10000016,585949.0,165334.0,Swale 008,Swale 008B,,,,,Good,South-East England and South London,,100062626974.0,,Not applicable,Not applicable,,,E02005122,E01024571,84.0,
118651,886,Kent,3117,Teynham Parochial Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,202.0,105.0,97.0,31.2,Not applicable,,Not applicable,,Not under a federation,,10078473.0,,Not applicable,29-03-2023,23-05-2024,Station Road,Teynham,,Sittingbourne,Kent,ME9 9BQ,www.teynham.kent.sch.uk,1795521217.0,Mrs,Elizabeth,Pearson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Teynham and Lynsted,Sittingbourne and Sheppey,(England/Wales) Rural town and fringe,E10000016,595417.0,162735.0,Swale 016,Swale 016D,,,,,Requires improvement,South-East England and South London,,100062627014.0,,Not applicable,Not applicable,,,E02005130,E01024623,63.0,
118653,886,Kent,3120,Barham Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,210.0,102.0,108.0,12.4,Not applicable,,Not applicable,,Not under a federation,,10069106.0,,Not applicable,25-01-2023,15-04-2024,Valley Road,Barham,Barham C of E Primary School,CANTERBURY,Kent,CT4 6NX,www.barham.kent.sch.uk/,1227831312.0,Mrs,Alison Higgins,Jo Duhig,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Nailbourne,Canterbury,(England/Wales) Rural village,E10000016,620612.0,150003.0,Canterbury 018,Canterbury 018B,,,,,Good,South-East England and South London,,100062299377.0,,Not applicable,Not applicable,,,E02005027,E01024043,26.0,
118654,886,Kent,3122,Bridge and Patrixbourne Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,407.0,199.0,208.0,3.4,Not applicable,,Not applicable,,Not under a federation,,10078472.0,,Not applicable,04-10-2023,18-04-2024,Conyngham Lane,Bridge,,Canterbury,Kent,CT4 5JX,www.bridge.kent.sch.uk,1227830276.0,Mr,James,Tibbles,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Nailbourne,Canterbury,(England/Wales) Rural town and fringe,E10000016,618239.0,154550.0,Canterbury 018,Canterbury 018C,,,,,Good,South-East England and South London,,100062298950.0,,Not applicable,Not applicable,,,E02005027,E01024088,14.0,
118655,886,Kent,3123,Chislet Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,95.0,50.0,45.0,12.6,Not applicable,,Not applicable,,Supported by a federation,The Federation of Chislet CE and Hoath Primary Schools,10078870.0,,Not applicable,24-11-2022,18-04-2024,Church Lane,Chislet,,Canterbury,Kent,CT3 4DU,www.chislethoathfederation.co.uk,1227860295.0,Mr,Tim,Whitehouse,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Canterbury,Reculver,North Thanet,(England/Wales) Rural village,E10000016,622377.0,164226.0,Canterbury 010,Canterbury 010D,,,,,Good,South-East England and South London,,10033152283.0,,Not applicable,Not applicable,,,E02005019,E01024087,12.0,
118657,886,Kent,3126,Littlebourne Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,99.0,47.0,52.0,26.3,Not applicable,,Not applicable,,Not under a federation,,10069105.0,,Not applicable,23-05-2019,30-05-2024,Church Road,Littlebourne,,Canterbury,Kent,CT3 1XS,http://www.littlebourne.kent.sch.uk,1227721671.0,Mrs,Samantha,Killick,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Little Stour & Adisham,Canterbury,(England/Wales) Rural town and fringe,E10000016,620956.0,157780.0,Canterbury 010,Canterbury 010A,,,,,Good,South-East England and South London,,200000681653.0,,Not applicable,Not applicable,,,E02005019,E01024084,26.0,
118659,886,Kent,3129,St Alphege Church of England Infant School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,7,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,232.0,No Special Classes,19-01-2023,206.0,105.0,101.0,16.3,Not applicable,,Not applicable,,Not under a federation,,10079668.0,,Not applicable,03-02-2023,03-06-2024,Oxford Street,,,Whitstable,Kent,CT5 1DA,http://www.st-alphege.kent.sch.uk,1227272977.0,Mrs,Liz,Thomas-Friend,Executive Head,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Gorrell,Canterbury,(England/Wales) Urban city and town,E10000016,610681.0,166250.0,Canterbury 008,Canterbury 008C,,,,,Good,South-East England and South London,,100062300537.0,,Not applicable,Not applicable,,,E02005017,E01024070,30.0,
118660,886,Kent,3130,Wickhambreaux Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,115.0,No Special Classes,19-01-2023,118.0,55.0,63.0,11.0,Not applicable,,Not applicable,,Not under a federation,,10065385.0,,Not applicable,26-02-2015,20-05-2024,The Street,Wickhambreaux,,Canterbury,Kent,CT3 1RN,www.wickhambreaux-school.ik.org/,1227721300.0,Mrs,Lisa,Crosbie,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Little Stour & Adisham,Canterbury,(England/Wales) Rural hamlet and isolated dwellings,E10000016,622169.0,158684.0,Canterbury 010,Canterbury 010B,,,,,Outstanding,South-East England and South London,,100062298259.0,,Not applicable,Not applicable,,,E02005019,E01024085,13.0,
118663,886,Kent,3136,Brabourne Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,104.0,49.0,55.0,11.5,Not applicable,,Not applicable,,Not under a federation,,10078471.0,,Not applicable,19-06-2018,06-06-2024,School Lane,Brabourne,,Ashford,Kent,TN25 5LQ,www.brabourne.kent.sch.uk,1303813276.0,Mr,Andrew,Stapley,Acting Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Bircholt,Folkestone and Hythe,(England/Wales) Rural hamlet and isolated dwellings,E10000016,609183.0,141706.0,Ashford 010,Ashford 010C,,,,,Good,South-East England and South London,,100062561998.0,,Not applicable,Not applicable,,,E02005005,E01024015,12.0,
118664,886,Kent,3137,Brookland Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,87.0,43.0,44.0,16.1,Not applicable,,Not applicable,,Not under a federation,,10078470.0,,Not applicable,03-02-2023,14-05-2024,High Street,Brookland,,Romney Marsh,Kent,TN29 9QR,http://www.brookland.kent.sch.uk,1797344317.0,Mr,Martin,Hacker,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Walland & Denge Marsh,Folkestone and Hythe,(England/Wales) Rural hamlet and isolated dwellings,E10000016,599003.0,125887.0,Folkestone and Hythe 011,Folkestone and Hythe 011D,,,,,Good,South-East England and South London,,50000252.0,,Not applicable,Not applicable,,,E02005112,E01024548,14.0,
118665,886,Kent,3138,"Chilham, St Mary's Church of England Primary School",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,79.0,36.0,43.0,24.1,Not applicable,,Not applicable,,Not under a federation,,10069103.0,,Not applicable,02-02-2022,08-05-2024,School Hill,Chilham,,Canterbury,Kent,CT4 8DE,www.chilham.kent.sch.uk,1227730442.0,Mrs,Delia,Cooper,Interim Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Downs North,Ashford,(England/Wales) Rural village,E10000016,606875.0,153533.0,Ashford 001,Ashford 001B,,,,,Good,South-East England and South London,,10012840696.0,,Not applicable,Not applicable,,,E02004996,E01023987,19.0,
118666,886,Kent,3139,High Halden Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,102.0,45.0,57.0,17.6,Not applicable,,Not applicable,,Supported by a federation,Flourish Together Federation,10069102.0,,Not applicable,24-02-2022,19-04-2024,Church Hill,High Halden,,Ashford,Kent,TN26 3JB,http://www.high-halden.kent.sch.uk/,1233850285.0,Mrs,Kelly,Burlton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Weald Central,Ashford,(England/Wales) Rural village,E10000016,590169.0,137144.0,Ashford 011,Ashford 011C,,,,,Good,South-East England and South London,,100062617661.0,,Not applicable,Not applicable,,,E02005006,E01024032,18.0,
118672,886,Kent,3145,Woodchurch Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,182.0,No Special Classes,19-01-2023,157.0,88.0,69.0,26.1,Not applicable,,Not applicable,,Supported by a federation,Flourish Together Federation,10069101.0,,Not applicable,17-05-2023,07-05-2024,Bethersden Road,Woodchurch,,Ashford,Kent,TN26 3QJ,http://www.woodchurch.kent.sch.uk,1233860232.0,Mrs,Kelly,Burlton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Weald South,Ashford,(England/Wales) Rural village,E10000016,594165.0,134993.0,Ashford 012,Ashford 012C,,,,,Good,South-East England and South London,,10012848908.0,,Not applicable,Not applicable,,,E02005007,E01024038,41.0,
118673,886,Kent,3146,Bodsham Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,103.0,No Special Classes,19-01-2023,82.0,43.0,39.0,6.1,Not applicable,,Not applicable,,Supported by a federation,The Federation of Bodsham Church of England Primary School and Saltwood Church of England Primary School,10069100.0,,Not applicable,26-05-2022,23-04-2024,School Hill,Bodsham,,Ashford,Kent,TN25 5JQ,www.bodsham.kent.sch.uk,1233750374.0,Mr,Paul,Newton,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Folkestone and Hythe,North Downs West,Folkestone and Hythe,(England/Wales) Rural hamlet and isolated dwellings,E10000016,611020.0,145724.0,Folkestone and Hythe 001,Folkestone and Hythe 001C,,,,,Good,South-East England and South London,,50010714.0,,Not applicable,Not applicable,,,E02005102,E01024545,5.0,
118675,886,Kent,3149,"Folkestone, St Martin's Church of England Primary School",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,202.0,90.0,112.0,18.3,Not applicable,,Not applicable,,Supported by a federation,The Federation of St Martin's and Seabrook CEP Schools,10069099.0,,Not applicable,24-04-2015,17-04-2024,Horn Street,,,Folkestone,Kent,CT20 3JJ,http://www.stmartinsfolkestone.com,1303238888.0,Mrs,Elizabeth,Carter,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Cheriton,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,618951.0,136429.0,Folkestone and Hythe 005,Folkestone and Hythe 005C,,,,,Outstanding,South-East England and South London,,50023003.0,,Not applicable,Not applicable,,,E02005106,E01024494,37.0,
118676,886,Kent,3150,"Folkestone, St Peter's Church of England Primary School",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,104.0,47.0,57.0,43.3,Not applicable,,Not applicable,,Not under a federation,,10078469.0,,Not applicable,26-06-2019,13-05-2024,The Durlocks,,,Folkestone,Kent,CT19 6AL,www.stpetersfolkestone.com/,1303255400.0,Mrs,Toni,Browne,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Folkestone Harbour,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,623352.0,136165.0,Folkestone and Hythe 014,Folkestone and Hythe 014A,,,,,Good,South-East England and South London,,,,Not applicable,Not applicable,,,E02006879,E01024504,45.0,
118678,886,Kent,3153,Seabrook Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,104.0,45.0,59.0,13.5,Not applicable,,Not applicable,,Supported by a federation,The Federation of St Martin's and Seabrook CEP Schools,10078468.0,,Not applicable,08-11-2023,17-04-2024,Seabrook Road,,,Hythe,Kent,CT21 5RL,www.seabrookprimaryschool.co.uk/,1303238429.0,Mrs,Elizabeth,Carter,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Hythe,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,618674.0,134958.0,Folkestone and Hythe 005,Folkestone and Hythe 005F,,,,,Good,South-East England and South London,,50022207.0,,Not applicable,Not applicable,,,E02005106,E01024528,14.0,
118679,886,Kent,3154,Lyminge Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,196.0,97.0,99.0,8.7,Not applicable,,Not applicable,,Not under a federation,,10069098.0,,Not applicable,09-11-2023,04-06-2024,Church Road,Lyminge,,Folkestone,Kent,CT18 8JA,www.lymingeprimaryschool.co.uk/,1303862367.0,Mr,Matt,Day,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,North Downs West,Folkestone and Hythe,(England/Wales) Rural town and fringe,E10000016,616220.0,141085.0,Folkestone and Hythe 001,Folkestone and Hythe 001D,,,,,Good,South-East England and South London,,50021153.0,,Not applicable,Not applicable,,,E02005102,E01024547,17.0,
118680,886,Kent,3155,Lympne Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,203.0,104.0,99.0,6.4,Not applicable,,Not applicable,,Not under a federation,,10070327.0,,Not applicable,14-10-2021,24-05-2024,Octavian Drive,Lympne,,Hythe,Kent,CT21 4JG,www.lympne.kent.sch.uk,1303268041.0,Mrs,Melanie,Nash,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Hythe Rural,Folkestone and Hythe,(England/Wales) Rural town and fringe,E10000016,612226.0,135150.0,Folkestone and Hythe 009,Folkestone and Hythe 009C,,,,,Good,South-East England and South London,,50012208.0,,Not applicable,Not applicable,,,E02005110,E01024536,13.0,
118681,886,Kent,3158,Stelling Minnis Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,83.0,48.0,35.0,18.1,Not applicable,,Not applicable,,Not under a federation,,10078467.0,,Not applicable,09-06-2022,03-06-2024,Bossingham Road,Stelling Minnis,,Canterbury,Kent,CT4 6DU,www.stelling-minnis.kent.sch.uk,1227709218.0,Mrs,Julie,Simmons,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,North Downs West,Folkestone and Hythe,(England/Wales) Rural hamlet and isolated dwellings,E10000016,614898.0,148564.0,Folkestone and Hythe 001,Folkestone and Hythe 001A,,,,,Good,South-East England and South London,,50014408.0,,Not applicable,Not applicable,,,E02005102,E01024490,15.0,
118682,886,Kent,3159,Stowting Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,103.0,52.0,51.0,7.8,Not applicable,,Not applicable,,Not under a federation,,10069097.0,,Not applicable,13-11-2019,20-03-2024,Stowting,Stowting Hill,,Ashford,Kent,TN25 6BE,http://www.stowting.kent.sch.uk,1303862375.0,Mrs,Sarah,Uden,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,North Downs West,Folkestone and Hythe,(England/Wales) Rural hamlet and isolated dwellings,E10000016,612365.0,142429.0,Folkestone and Hythe 001,Folkestone and Hythe 001C,,,,,Good,South-East England and South London,,50012509.0,,Not applicable,Not applicable,,,E02005102,E01024545,8.0,
118683,886,Kent,3160,Selsted Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,99.0,54.0,45.0,9.1,Not applicable,,Not applicable,,Not under a federation,,10069096.0,,Not applicable,02-11-2022,15-05-2024,Selsted,"Wootton Lane, Selsted",Wootton Lane,Dover,Kent,CT15 7HH,www.selstedschool.org/,1303844286.0,Mrs,Angela,Woodgate,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,North Downs East,Folkestone and Hythe,(England/Wales) Rural hamlet and isolated dwellings,E10000016,622244.0,144587.0,Folkestone and Hythe 001,Folkestone and Hythe 001B,,,,,Good,South-East England and South London,,50044106.0,,Not applicable,Not applicable,,,E02005102,E01024544,9.0,
118685,886,Kent,3167,Eastry Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,218.0,No Special Classes,19-01-2023,165.0,87.0,78.0,26.8,Not applicable,,Not applicable,,Not under a federation,,10069095.0,,Not applicable,14-06-2023,08-05-2024,Cooks Lea,Eastry,,Sandwich,Kent,CT13 0LR,www.eastry.kent.sch.uk/,1304611360.0,Mrs,Sarah,Moss,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Dover,Eastry Rural,Dover,(England/Wales) Rural town and fringe,E10000016,630665.0,154869.0,Dover 002,Dover 002A,,,,,Good,South-East England and South London,,100062284627.0,,Not applicable,Not applicable,,,E02005042,E01024202,44.0,
118686,886,Kent,3168,Goodnestone Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,70.0,No Special Classes,19-01-2023,53.0,21.0,32.0,9.4,Not applicable,,Not applicable,,Not under a federation,,10069094.0,,Not applicable,17-01-2019,14-05-2024,The Street,Goodnestone,,Canterbury,Kent,CT3 1PQ,www.goodnestone.kent.sch.uk/,1304840329.0,Mrs,Victoria,Solly,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Little Stour & Ashstone,South Thanet,(England/Wales) Rural village,E10000016,625516.0,154670.0,Dover 001,Dover 001B,,,,,Good,South-East England and South London,,100062298258.0,,Not applicable,Not applicable,,,E02005041,E01024207,5.0,
118687,886,Kent,3169,Guston Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Non-selective,180.0,No Special Classes,19-01-2023,151.0,81.0,70.0,9.3,Not applicable,,Not applicable,,Not under a federation,,10075828.0,,Not applicable,21-10-2021,16-04-2024,Burgoyne Heights,Guston,,Dover,Kent,CT15 5LR,www.guston.kent.sch.uk/,1304206847.0,Mrs,Deby,Day,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,"Guston, Kingsdown & St Margaret's-at-Cliffe",Dover,(England/Wales) Rural village,E10000016,632307.0,143088.0,Dover 012,Dover 012B,,,,,Good,South-East England and South London,,100062620447.0,,Not applicable,Not applicable,,,E02005052,E01024238,14.0,
118688,886,Kent,3171,Nonington Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,86.0,No Special Classes,19-01-2023,38.0,19.0,19.0,57.9,Not applicable,,Not applicable,,Not under a federation,,10078869.0,,Not applicable,21-04-2022,14-05-2024,Church Street,Nonington,,Dover,Kent,CT15 4LB,www.noningtonprimary.co.uk/,1304840348.0,Mrs,Victoria,Solly,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SEMH - Social, Emotional and Mental Health",,,,,,,,,,,,,Resourced provision,,8.0,,,South East,Dover,"Aylesham, Eythorne & Shepherdswell",Dover,(England/Wales) Rural hamlet and isolated dwellings,E10000016,625273.0,152175.0,Dover 006,Dover 006A,,,,,Requires improvement,South-East England and South London,,100062287271.0,,Not applicable,Not applicable,,,E02005046,E01024190,22.0,
118691,886,Kent,3175,Shepherdswell Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,202.0,104.0,98.0,11.4,Not applicable,,Not applicable,,Supported by a federation,The Federation of Shepherdswell Church of England and Eythorne Elvington,10069093.0,,Not applicable,20-10-2021,02-05-2024,Coldred Road,Shepherdswell,,DOVER,Kent,CT15 7LH,www.shepherdswell.kent.sch.uk/,1304830312.0,Mr,Mark,Lamb,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,"Aylesham, Eythorne & Shepherdswell",Dover,(England/Wales) Rural town and fringe,E10000016,626077.0,147755.0,Dover 006,Dover 006D,,,,,Good,South-East England and South London,United Kingdom,100062288370.0,,Not applicable,Not applicable,,,E02005046,E01024204,23.0,
118693,886,Kent,3178,Birchington Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,570.0,No Special Classes,19-01-2023,475.0,235.0,240.0,25.3,Not applicable,,Not applicable,,Not under a federation,,10078464.0,,Not applicable,25-09-2019,05-06-2024,Park Lane,,,Birchington,Kent,CT7 0AS,www.birchington-primary.com/,1843841046.0,Ms,Kathleen,Barham,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Birchington South,North Thanet,(England/Wales) Urban city and town,E10000016,630372.0,168670.0,Thanet 007,Thanet 007A,,,,,Good,South-East England and South London,,100062303819.0,,Not applicable,Not applicable,,,E02005138,E01024641,120.0,
118694,886,Kent,3179,"Margate, Holy Trinity and St John's Church of England Primary School",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,407.0,208.0,199.0,55.3,Not applicable,,Not applicable,,Not under a federation,,10069092.0,,Not applicable,29-03-2023,21-05-2024,St John's Road,,,Margate,Kent,CT9 1LU,www.holytrinitymargate.co.uk/,1843223237.0,Mr,Rob,Garratt,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,16.0,16.0,,,South East,Thanet,Margate Central,North Thanet,(England/Wales) Urban city and town,E10000016,635618.0,170614.0,Thanet 001,Thanet 001G,,,,,Good,South-East England and South London,,200003082079.0,,Not applicable,Not applicable,,,E02005132,E01035317,225.0,
118695,886,Kent,3181,St Saviour's Church of England Junior School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,Not applicable,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,384.0,Not applicable,19-01-2023,375.0,196.0,179.0,30.9,Not applicable,,Not applicable,,Not under a federation,,10078463.0,,Not applicable,18-10-2023,13-12-2023,Elm Grove,,St. Saviour's C.E Junior School Elm Grove,Westgate on Sea,Kent,CT8 8LD,www.stsavioursjunior.com,1843831707.0,Mr,Nick,Bonell,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Westgate-on-Sea,North Thanet,(England/Wales) Urban city and town,E10000016,632054.0,169794.0,Thanet 007,Thanet 007C,,,,,Good,South-East England and South London,,100062304387.0,,Not applicable,Not applicable,,,E02005138,E01024714,116.0,
118696,886,Kent,3182,Minster Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,389.0,212.0,177.0,22.1,Not applicable,,Not applicable,,Not under a federation,,10069091.0,,Not applicable,18-01-2023,23-04-2024,Molineux Road,Minster-in-Thanet,,Ramsgate,Kent,CT12 4PS,http://www.minster-ramsgate.kent.sch.uk/,1843821384.0,Mr,Paul,McCarthy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Thanet Villages,North Thanet,(England/Wales) Rural town and fringe,E10000016,630821.0,164492.0,Thanet 014,Thanet 014B,,,,,Good,South-East England and South London,,200001487980.0,,Not applicable,Not applicable,,,E02005145,E01024702,86.0,
118697,886,Kent,3183,Monkton Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,106.0,49.0,57.0,23.6,Not applicable,,Not applicable,,Not under a federation,,10069090.0,,Not applicable,30-01-2024,20-05-2024,Monkton Street,Monkton,,Ramsgate,Kent,CT12 4JQ,http://www.monkton.kent.sch.uk,1843821394.0,Mr,Paul,McCarthy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Thanet Villages,North Thanet,(England/Wales) Rural village,E10000016,628701.0,165070.0,Thanet 014,Thanet 014C,,,,,Good,South-East England and South London,,10022964433.0,,Not applicable,Not applicable,,,E02005145,E01024703,25.0,
118698,886,Kent,3186,St Nicholas At Wade Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,195.0,86.0,109.0,15.9,Not applicable,,Not applicable,,Not under a federation,,10078462.0,,Not applicable,02-10-2019,21-05-2024,Down Barton Road,St Nicholas-At-Wade,,Birchington,Kent,CT7 0PY,www.st-nicholas-birchington.kent.sch.uk/,1843847253.0,Mrs,Taralee,Kennedy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Thanet Villages,North Thanet,(England/Wales) Rural village,E10000016,626348.0,166666.0,Thanet 014,Thanet 014C,,,,,Good,South-East England and South London,,100062303823.0,,Not applicable,Not applicable,,,E02005145,E01024703,31.0,
118701,886,Kent,3198,Frittenden Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,98.0,44.0,54.0,23.5,Not applicable,,Not applicable,,Not under a federation,,10069089.0,,Not applicable,24-11-2022,26-04-2024,Frittenden Primary School,,Frittenden,Cranbrook,Kent,TN17 2DD,http://www.frittenden.kent.sch.uk,1580852250.0,Ms,nichola,costello,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Frittenden and Sissinghurst,Maidstone and The Weald,(England/Wales) Rural village,E10000016,581389.0,140963.0,Tunbridge Wells 013,Tunbridge Wells 013E,,,,,Requires improvement,South-East England and South London,,10008667029.0,,Not applicable,Not applicable,,,E02005174,E01024803,23.0,
118702,886,Kent,3199,Egerton Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,188.0,103.0,85.0,20.7,Not applicable,,Not applicable,,Not under a federation,,10069088.0,,Not applicable,12-10-2023,16-04-2024,Stisted Way,Egerton,,Ashford,Kent,TN27 9DR,http://www.egerton.kent.sch.uk,1233756274.0,Mrs,Julia,Walker,Interim Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Ashford,Weald North,Ashford,(England/Wales) Rural village,E10000016,590598.0,147325.0,Ashford 002,Ashford 002F,,,,,Good,South-East England and South London,,100062563941.0,,Not applicable,Not applicable,,,E02004997,E01024035,39.0,
118704,886,Kent,3201,St Lawrence Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,84.0,No Special Classes,19-01-2023,76.0,35.0,41.0,3.9,Not applicable,,Not applicable,,Not under a federation,,10078461.0,,Not applicable,28-09-2022,05-02-2024,Church Road,Stone Street,,Sevenoaks,Kent,TN15 0LN,http://www.st-lawrence-sevenoaks.kent.sch.uk,1732761393.0,Mr,Daniel,Eaton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Seal and Weald,Sevenoaks,(England/Wales) Rural hamlet and isolated dwellings,E10000016,557394.0,154844.0,Sevenoaks 012,Sevenoaks 012A,,,,,Good,South-East England and South London,,10035185576.0,,Not applicable,Not applicable,,,E02005098,E01024458,3.0,
118705,886,Kent,3282,Boughton-under-Blean and Dunkirk Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Methodist,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,203.0,100.0,103.0,24.1,Not applicable,,Not applicable,,Not under a federation,,10078141.0,,Not applicable,11-07-2019,03-06-2024,School Lane,Boughton-under-Blean,,Faversham,Kent,ME13 9AW,www.bad.kent.sch.uk,1227751431.0,Mr,Simon,Way,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Boughton and Courtenay,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,605832.0,159483.0,Swale 017,Swale 017C,,,,,Good,South-East England and South London,,200002540885.0,,Not applicable,Not applicable,,,E02005131,E01024557,49.0,
118706,886,Kent,3284,Lady Joanna Thornhill Endowed Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,418.0,198.0,220.0,11.2,Not applicable,,Not applicable,,Not under a federation,,10078140.0,,Not applicable,05-02-2015,18-04-2024,Bridge Street,Wye,,Ashford,Kent,TN25 5EA,www.ladyj.kent.sch.uk/,1233812781.0,Mrs,Rachael,Foster,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Wye with Hinxhill,Ashford,(England/Wales) Rural town and fringe,E10000016,605082.0,146710.0,Ashford 001,Ashford 001D,,,,,Outstanding,South-East England and South London,,10012868707.0,,Not applicable,Not applicable,,,E02004996,E01024040,47.0,
118707,886,Kent,3289,St Peter's Methodist Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Methodist,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,209.0,108.0,101.0,21.5,Not applicable,,Not applicable,,Not under a federation,,10078139.0,,Not applicable,12-12-2018,01-05-2024,St Peter's Grove,,,Canterbury,Kent,CT1 2DH,http://www.st-peters-canterbury.kent.sch.uk,1227464392.0,Mrs,Kristina,Dyer,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Westgate,Canterbury,(England/Wales) Urban city and town,E10000016,614679.0,157910.0,Canterbury 020,Canterbury 020F,,,,,Good,South-East England and South London,,200000676740.0,,Not applicable,Not applicable,,,E02006856,E01032807,45.0,
118709,886,Kent,3294,St Matthew's High Brooms Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,420.0,No Special Classes,19-01-2023,354.0,178.0,176.0,43.2,Not applicable,,Not applicable,,Not under a federation,,10069087.0,,Not applicable,19-07-2018,15-04-2024,Powder Mill Lane,High Brooms,,Tunbridge Wells,Kent,TN4 9DY,www.st-matthews-school.org,1892528098.0,Mrs,Claire,Harris,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Southborough and High Brooms,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558927.0,141801.0,Tunbridge Wells 003,Tunbridge Wells 003D,,,,,Good,South-East England and South London,,100062586205.0,,Not applicable,Not applicable,,,E02005164,E01024847,153.0,
118710,886,Kent,3295,Herne Church of England Infant and Nursery School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,7,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,270.0,No Special Classes,19-01-2023,316.0,171.0,145.0,7.8,Not applicable,,Not applicable,,Not under a federation,,10079667.0,,Not applicable,29-09-2021,21-05-2024,Palmer Close,Herne,,Herne Bay,Kent,CT6 7AH,www.herne-infant.kent.sch.uk/,1227740793.0,Mrs,E,Thomas-Friend,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Herne & Broomfield,North Thanet,(England/Wales) Urban city and town,E10000016,618672.0,165903.0,Canterbury 006,Canterbury 006C,,,,,Outstanding,South-East England and South London,,200000680285.0,,Not applicable,Not applicable,,,E02005015,E01024075,21.0,
118711,886,Kent,3296,Langafel Church of England Voluntary Controlled Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,331.0,No Special Classes,19-01-2023,325.0,175.0,150.0,32.0,Not applicable,,Not applicable,,Not under a federation,,10078868.0,,Not applicable,03-10-2018,26-02-2024,Main Road,,,Longfield,Kent,DA3 7PW,www.langafel.kent.sch.uk/,1474703398.0,Mrs,Catherine,Maynard,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,30.0,29.0,,,South East,Dartford,"Longfield, New Barn & Southfleet",Dartford,(England/Wales) Urban city and town,E10000016,561395.0,168619.0,Dartford 013,Dartford 013D,,,,,Good,South-East England and South London,,200000538032.0,,Not applicable,Not applicable,,,E02005040,E01024160,104.0,
118712,886,Kent,3297,Southborough CofE Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,630.0,No Special Classes,19-01-2023,615.0,309.0,306.0,17.6,Not applicable,,Not applicable,,Not under a federation,,10074251.0,,Not applicable,21-06-2018,30-04-2024,Broomhill Park Road,Southborough,,Tunbridge Wells,Kent,TN4 0JY,http://www.southborough.kent.sch.uk,1892529682.0,Mrs,Emma,Savage,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tunbridge Wells,Southborough and High Brooms,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,557592.0,141923.0,Tunbridge Wells 002,Tunbridge Wells 002C,,,,,Good,South-East England and South London,,100062585335.0,,Not applicable,Not applicable,,,E02005163,E01024846,108.0,
118713,886,Kent,3303,St Katharine's Knockholt Church of England Voluntary Aided Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,201.0,No Special Classes,19-01-2023,170.0,80.0,90.0,4.7,Not applicable,,Not applicable,,Not under a federation,,10069086.0,,Not applicable,16-11-2022,12-09-2023,Main Road,Knockholt,,Sevenoaks,Kent,TN14 7LS,www.knockholt.kent.sch.uk/,1959532237.0,Miss,Sarah-Jane,Tormey,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Halstead, Knockholt and Badgers Mount",Sevenoaks,(England/Wales) Rural hamlet and isolated dwellings,E10000016,546750.0,158787.0,Sevenoaks 008,Sevenoaks 008D,,,,,Good,South-East England and South London,,100061014242.0,,Not applicable,Not applicable,,,E02005094,E01024440,8.0,
118715,886,Kent,3307,"Chevening, St Botolph's Church of England Voluntary Aided Primary School",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,179.0,87.0,92.0,2.8,Not applicable,,Not applicable,,Not under a federation,,10078460.0,,Not applicable,27-11-2019,18-04-2024,Chevening Road,Chipstead,,Sevenoaks,Kent,TN13 2SA,http://www.chevening.kent.sch.uk,1732452895.0,Miss,Karen,Minnis,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Brasted, Chevening and Sundridge",Sevenoaks,(England/Wales) Urban city and town,E10000016,549789.0,156509.0,Sevenoaks 011,Sevenoaks 011A,,,,,Good,South-East England and South London,,10013771396.0,,Not applicable,Not applicable,,,E02005097,E01024416,5.0,
118716,886,Kent,3308,Colliers Green Church of England Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,112.0,No Special Classes,19-01-2023,112.0,52.0,60.0,4.5,Not applicable,,Not applicable,,Not under a federation,,10069085.0,,Not applicable,07-03-2019,11-01-2024,Colliers Green,,,Cranbrook,Kent,TN17 2LR,www.colliers-green.kent.sch.uk/,1580211335.0,Dr,Josephine,Hopkins,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Goudhurst and Lamberhurst,Maidstone and The Weald,(England/Wales) Rural hamlet and isolated dwellings,E10000016,575881.0,138768.0,Tunbridge Wells 011,Tunbridge Wells 011E,,,,,Good,South-East England and South London,,10000064641.0,,Not applicable,Not applicable,,,E02005172,E01024806,5.0,
118717,886,Kent,3309,Sissinghurst Voluntary Aided Church of England Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,175.0,No Special Classes,19-01-2023,171.0,88.0,83.0,16.4,Not applicable,,Not applicable,,Not under a federation,,10073480.0,,Not applicable,01-03-2023,03-06-2024,Common Road,Sissinghurst,,Cranbrook,Kent,TN17 2BH,www.sissinghurst.kent.sch.uk/,1580713895.0,Mrs,Sarah,Holman,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tunbridge Wells,Frittenden and Sissinghurst,Maidstone and The Weald,(England/Wales) Rural village,E10000016,578960.0,137839.0,Tunbridge Wells 013,Tunbridge Wells 013E,,,,,Requires improvement,South-East England and South London,,10000070036.0,,Not applicable,Not applicable,,,E02005174,E01024803,28.0,
118718,886,Kent,3312,Hever Church of England Voluntary Aided Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,205.0,No Special Classes,19-01-2023,152.0,66.0,86.0,17.1,Not applicable,,Not applicable,,Not under a federation,,10069084.0,,Not applicable,23-03-2022,29-04-2024,Hever Road,Hever,,Edenbridge,Kent,TN8 7NH,www.hever.kent.sch.uk/,1732862304.0,Mrs,Helene,Bligh,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Cowden and Hever,Tonbridge and Malling,(England/Wales) Rural hamlet and isolated dwellings,E10000016,547634.0,144758.0,Sevenoaks 015,Sevenoaks 015A,,,,,Requires improvement,South-East England and South London,,100062593515.0,,Not applicable,Not applicable,,,E02005101,E01024420,26.0,
118720,886,Kent,3314,Penshurst Church of England Voluntary Aided Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,105.0,No Special Classes,19-01-2023,84.0,46.0,38.0,13.1,Not applicable,,Not applicable,,Not under a federation,,10069082.0,,Not applicable,17-11-2022,04-06-2024,High Street,Penshurst,,Tonbridge,Kent,TN11 8BX,www.penshurstschool.org.uk,1892870446.0,Mrs,Susan,Elliott,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Penshurst, Fordcombe and Chiddingstone",Tonbridge and Malling,(England/Wales) Rural village,E10000016,552486.0,143627.0,Sevenoaks 015,Sevenoaks 015D,,,,,Good,South-East England and South London,,10035181676.0,,Not applicable,Not applicable,,,E02005101,E01024456,11.0,
118721,886,Kent,3317,"Lady Boswell's Church of England Voluntary Aided Primary School, Sevenoaks",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,436.0,No Special Classes,19-01-2023,425.0,203.0,222.0,4.9,Not applicable,,Not applicable,,Not under a federation,,10079894.0,,Not applicable,25-05-2022,24-05-2024,Plymouth Drive,,,Sevenoaks,Kent,TN13 3RW,http://www.ladyboswells.kent.sch.uk,1732452851.0,Mrs,"Hannah Pullen,",Mrs Sharon Saunders,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Sevenoaks Town and St John's,Sevenoaks,(England/Wales) Urban city and town,E10000016,553202.0,155064.0,Sevenoaks 012,Sevenoaks 012F,,,,,Outstanding,South-East England and South London,,10035184700.0,,Not applicable,Not applicable,,,E02005098,E01024471,21.0,
118722,886,Kent,3318,Ide Hill Church of England Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,154.0,No Special Classes,19-01-2023,153.0,85.0,68.0,5.9,Not applicable,,Not applicable,,Not under a federation,,10069081.0,,Not applicable,04-04-2019,13-05-2024,Sundridge Road,Ide Hill,,Sevenoaks,Kent,TN14 6JT,https://idehill.eschools.co.uk/,1732750389.0,Miss,Elizabeth,Alexander,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Sevenoaks,"Brasted, Chevening and Sundridge",Sevenoaks,(England/Wales) Rural village,E10000016,548483.0,151962.0,Sevenoaks 013,Sevenoaks 013B,,,,,Good,South-East England and South London,,50002011896.0,,Not applicable,Not applicable,,,E02005099,E01024419,9.0,
118724,886,Kent,3320,St Barnabas CofE VA Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,202.0,96.0,106.0,34.2,Not applicable,,Not applicable,,Not under a federation,,10069080.0,,Not applicable,24-01-2024,20-05-2024,Quarry Road,,,Tunbridge Wells,Kent,TN1 2EY,www.st-barnabas.kent.sch.uk/,1892522958.0,Mrs,Moira,Duncombe,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,St James',Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558893.0,140276.0,Tunbridge Wells 008,Tunbridge Wells 008D,,,,,Good,South-East England and South London,,100062543182.0,,Not applicable,Not applicable,,,E02005169,E01024833,69.0,
118725,886,Kent,3322,St James' Church of England Voluntary Aided Primary School,Voluntary aided school,Local authority maintained schools,Open,Not Recorded,01-01-1900,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,630.0,No Special Classes,19-01-2023,631.0,302.0,329.0,7.8,Not applicable,,Not applicable,,Not under a federation,,10079666.0,,Not applicable,06-03-2024,22-05-2024,Sandrock Road,,,Tunbridge Wells,Kent,TN2 3PR,https://st-james.kent.sch.uk,1892523006.0,Mr,John,Tutt,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Park,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,559230.0,139720.0,Tunbridge Wells 008,Tunbridge Wells 008C,,,,,Good,South-East England and South London,,10000066049.0,,Not applicable,Not applicable,,,E02005169,E01024823,49.0,
118726,886,Kent,3323,Hunton Church of England Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,105.0,No Special Classes,19-01-2023,102.0,41.0,61.0,17.6,Not applicable,,Not applicable,,Not under a federation,,10069079.0,,Not applicable,12-05-2021,15-04-2024,Bishops Lane,Hunton,,Maidstone,Kent,ME15 0SJ,http://www.hunton.kent.sch.uk,1622820360.0,Mrs,Anita,Makey,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Coxheath and Hunton,Maidstone and The Weald,(England/Wales) Rural hamlet and isolated dwellings,E10000016,571802.0,149308.0,Maidstone 018,Maidstone 018A,,,,,Good,South-East England and South London,,200003720206.0,,Not applicable,Not applicable,,,E02005085,E01024345,18.0,
118728,886,Kent,3325,Platt Church of England Voluntary Aided Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,173.0,85.0,88.0,16.2,Not applicable,,Not applicable,,Not under a federation,,10069078.0,,Not applicable,24-04-2019,22-02-2024,Platinum Way,St Mary's Platt,,Sevenoaks,Kent,TN15 8FH,http://www.platt.kent.sch.uk,1732882596.0,Mrs,Emma,Smith,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Borough Green & Platt,Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,562312.0,157440.0,Tonbridge and Malling 006,Tonbridge and Malling 006B,,,,,Good,South-East England and South London,United Kingdom,10094697223.0,,Not applicable,Not applicable,,,E02005154,E01024724,28.0,
118730,886,Kent,3328,Bapchild and Tonge Church of England Primary School and Nursery,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,245.0,136.0,109.0,11.4,Not applicable,,Not applicable,,Not under a federation,,10069077.0,,Not applicable,17-07-2019,07-05-2024,School Lane,Bapchild,,Sittingbourne,Kent,ME9 9NL,www.bapchildprimary.co.uk,1795424143.0,Mr,Christian,Kelly,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,West Downs,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,592811.0,163003.0,Swale 013,Swale 013D,,,,,Good,South-East England and South London,,10035063550.0,,Not applicable,Not applicable,,,E02005127,E01024629,28.0,
118734,886,Kent,3332,Hartlip Endowed Church of England Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,108.0,59.0,49.0,15.7,Not applicable,,Not applicable,,Not under a federation,,10069076.0,,Not applicable,21-04-2022,05-03-2024,The Street,Hartlip,,Sittingbourne,Kent,ME9 7TL,www.hartlip.kent.sch.uk,1795842473.0,Mrs,Tracey,Jerome,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,"Hartlip, Newington and Upchurch",Sittingbourne and Sheppey,(England/Wales) Rural village,E10000016,583965.0,164247.0,Swale 008,Swale 008A,,,,,Good,South-East England and South London,,200002532833.0,,Not applicable,Not applicable,,,E02005122,E01024570,17.0,
118735,886,Kent,3337,Tunstall Church of England (Aided) Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,422.0,200.0,222.0,2.1,Not applicable,,Not applicable,,Not under a federation,,10069075.0,,Not applicable,24-05-2023,23-05-2024,Tunstall Road,,,Sittingbourne,Kent,ME10 1YG,http://www.tunstall.kent.sch.uk/,1795472895.0,Mrs,Rebecca,Andrews,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Woodstock,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,589964.0,161884.0,Swale 013,Swale 013E,,,,,Outstanding,South-East England and South London,,,,Not applicable,Not applicable,,,E02005127,E01024631,9.0,
118736,886,Kent,3338,Herne Church of England Junior School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,360.0,No Special Classes,19-01-2023,360.0,184.0,176.0,13.6,Not applicable,,Not applicable,,Not under a federation,,10073479.0,,Not applicable,01-11-2023,25-03-2024,School Lane,Herne,,Herne Bay,Kent,CT6 7AL,http://www.herne-junior.kent.sch.uk,1227374069.0,Mr,Mal,Saunders,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Herne & Broomfield,North Thanet,(England/Wales) Urban city and town,E10000016,618444.0,165965.0,Canterbury 006,Canterbury 006C,,,,,Outstanding,South-East England and South London,,200000683363.0,,Not applicable,Not applicable,,,E02005015,E01024075,49.0,
118737,886,Kent,3339,Whitstable and Seasalter Endowed Church of England Junior School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,228.0,No Special Classes,19-01-2023,210.0,107.0,103.0,16.7,Not applicable,,Not applicable,,Not under a federation,,10073478.0,,Not applicable,07-12-2022,15-04-2024,High Street,,,Whitstable,Kent,CT5 1AY,http://www.whitstable-endowed.kent.sch.uk,1227273630.0,Miss,Ellen,Taylor,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Gorrell,Canterbury,(England/Wales) Urban city and town,E10000016,610765.0,166471.0,Canterbury 008,Canterbury 008C,,,,,Outstanding,South-East England and South London,,100062619665.0,,Not applicable,Not applicable,,,E02005017,E01024070,35.0,
118738,886,Kent,3340,"Ashford, St Mary's Church of England Primary School",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,420.0,215.0,205.0,25.0,Not applicable,,Not applicable,,Not under a federation,,10069074.0,,Not applicable,29-01-2020,25-01-2024,Western Avenue,,,Ashford,Kent,TN23 1ND,www.st-marys-ashford.kent.sch.uk/,1233625531.0,Mrs,Nicola,Hirst,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Victoria,Ashford,(England/Wales) Urban city and town,E10000016,600448.0,143067.0,Ashford 016,Ashford 016C,,,,,Good,South-East England and South London,,100062559492.0,,Not applicable,Not applicable,,,E02007047,E01023992,105.0,
118740,886,Kent,3346,Wittersham Church of England Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,140.0,No Special Classes,19-01-2023,141.0,66.0,75.0,17.0,Not applicable,,Not applicable,,Not under a federation,,10069073.0,,Not applicable,28-01-2020,24-04-2024,The Street,Wittersham,,Tenterden,Kent,TN30 7EA,www.wittersham.kent.sch.uk,1797270329.0,Mr,George,Hawkins,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Isle of Oxney,Ashford,(England/Wales) Rural village,E10000016,589703.0,126905.0,Ashford 014,Ashford 014B,,,,,Good,South-East England and South London,,100062567595.0,,Not applicable,Not applicable,,,E02005009,E01023998,24.0,
118741,886,Kent,3347,Elham Church of England Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,140.0,No Special Classes,19-01-2023,127.0,58.0,69.0,18.1,Not applicable,,Not applicable,,Not under a federation,,10069072.0,,Not applicable,19-07-2022,25-04-2024,Vicarage Lane,Elham,,Canterbury,Kent,CT4 6TT,http://www.elhamprimary.co.uk,1303840325.0,Mr,Dan,File,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,North Downs East,Folkestone and Hythe,(England/Wales) Rural village,E10000016,617633.0,143734.0,Folkestone and Hythe 001,Folkestone and Hythe 001A,,,,,Good,South-East England and South London,,50021810.0,,Not applicable,Not applicable,,,E02005102,E01024490,23.0,
118744,886,Kent,3350,Saltwood CofE Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,222.0,No Special Classes,19-01-2023,208.0,105.0,103.0,7.7,Not applicable,,Not applicable,,Supported by a federation,The Federation of Bodsham Church of England Primary School and Saltwood Church of England Primary School,10069071.0,,Not applicable,11-05-2022,29-01-2024,Grange Road,Saltwood,,Hythe,Kent,CT21 4QS,http://www.saltwood.kent.sch.uk,1303266058.0,Mr,Paul,Newton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Folkestone and Hythe,Hythe,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,615799.0,135758.0,Folkestone and Hythe 008,Folkestone and Hythe 008D,,,,,Good,South-East England and South London,,50017103.0,,Not applicable,Not applicable,,,E02005109,E01024550,16.0,
118745,886,Kent,3351,Ash Cartwright and Kelsey Church of England Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,158.0,89.0,69.0,31.5,Not applicable,,Not applicable,,Not under a federation,,10073477.0,,Not applicable,25-09-2019,15-04-2024,School Road,Ash,,Canterbury,Kent,CT3 2JD,www.ashckschool.org,1304812539.0,Mrs,Fiona,Crascall,Interim Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Little Stour & Ashstone,South Thanet,(England/Wales) Rural town and fringe,E10000016,628453.0,158532.0,Dover 001,Dover 001A,,,,,Good,South-East England and South London,,100062298485.0,,Not applicable,Not applicable,,,E02005041,E01024206,45.0,
118748,886,Kent,3356,"Dover, St Mary's Church of England Primary School",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,155.0,75.0,80.0,66.5,Not applicable,,Not applicable,,Not under a federation,,10069069.0,,Not applicable,16-11-2022,06-06-2024,Laureston Place,,,Dover,Kent,CT16 1QX,www.st-marys-dover.kent.sch.uk/,1304206887.0,Ms,Helen,Comfort,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Town & Castle,Dover,(England/Wales) Urban city and town,E10000016,632228.0,141684.0,Dover 012,Dover 012E,,,,,Requires improvement,South-East England and South London,,100062288992.0,,Not applicable,Not applicable,,,E02005052,E01033209,103.0,
118750,886,Kent,3360,St Peter-in-Thanet CofE Junior School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,360.0,No Special Classes,19-01-2023,365.0,190.0,175.0,32.3,Not applicable,,Not applicable,,Not under a federation,,10073476.0,,Not applicable,11-05-2023,05-06-2024,Grange Road,St Peter's,,Broadstairs,Kent,CT10 3EP,www.stpetersthanet.co.uk,1843861430.0,Mr,Tim,Whitehouse,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Beacon Road,South Thanet,(England/Wales) Urban city and town,E10000016,638767.0,169105.0,Thanet 009,Thanet 009A,,,,,Outstanding,South-East England and South London,,200003081114.0,,Not applicable,Not applicable,,,E02005140,E01024635,118.0,
118751,886,Kent,3364,"Ramsgate, Holy Trinity Church of England Primary School",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,210.0,113.0,97.0,12.4,Not applicable,,Not applicable,,Not under a federation,,10073475.0,,Not applicable,29-09-2021,21-05-2024,Dumpton Park Drive,,,Broadstairs,Kent,CT10 1RR,www.ramsgateholytrinity.co.uk,1843860744.0,Mrs,Erin,Price,Interim Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Viking,South Thanet,(England/Wales) Urban city and town,E10000016,639141.0,166318.0,Thanet 010,Thanet 010E,,,,,Outstanding,South-East England and South London,,200003079311.0,,Not applicable,Not applicable,,,E02005141,E01024708,26.0,
118754,886,Kent,3373,St Mary's Church of England Voluntary Aided Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,247.0,128.0,119.0,41.3,Not applicable,,Not applicable,,Not under a federation,,10072082.0,,Not applicable,07-12-2022,12-09-2023,St Mary's Road,,,Swanley,Kent,BR8 7BU,http://www.st-marys-swanley.kent.sch.uk,1322665212.0,Mrs,Amanda,McGarrigle,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Swanley St Mary's,Sevenoaks,(England/Wales) Urban major conurbation,E10000016,550895.0,168371.0,Sevenoaks 002,Sevenoaks 002A,,,,,Good,South-East England and South London,,200002881970.0,,Not applicable,Not applicable,,,E02005088,E01024476,102.0,
118764,886,Kent,3722,St Ethelbert's Catholic Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,209.0,88.0,121.0,33.5,Not applicable,,Not applicable,,Not under a federation,,10072744.0,,Not applicable,13-06-2019,03-06-2024,"St Ethelbert's Catholic Primary School, Dane Park Road",,,Ramsgate,Kent,CT11 7LS,www.stethelbertsschool.co.uk,1843585555.0,Mr,Simon,Marshall,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Eastcliff,South Thanet,(England/Wales) Urban city and town,E10000016,638595.0,165666.0,Thanet 012,Thanet 012A,,,,,Good,South-East England and South London,,100062282199.0,,Not applicable,Not applicable,,,E02005143,E01024669,70.0,
118765,886,Kent,3728,St Anselm's Catholic Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,209.0,91.0,118.0,9.6,Not applicable,,Not applicable,,Not under a federation,,10072743.0,,Not applicable,19-06-2019,21-05-2024,Littlebrook Manor Way,Temple Hill,,Dartford,Kent,DA1 5EA,http://www.st-anselms.kent.sch.uk/,1322225173.0,Mrs,Laura,White,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Temple Hill,Dartford,(England/Wales) Urban major conurbation,E10000016,555174.0,174821.0,Dartford 001,Dartford 001C,,,,,Good,South-East England and South London,,200000531818.0,,Not applicable,Not applicable,,,E02005028,E01024154,20.0,
118768,886,Kent,3733,"Our Lady's Catholic Primary School, Dartford",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,218.0,No Special Classes,19-01-2023,217.0,106.0,111.0,6.5,Not applicable,,Not applicable,,Not under a federation,,10072740.0,,Not applicable,12-02-2020,16-04-2024,King Edward Avenue,,,Dartford,Kent,DA1 2HX,http://www.our-ladys.kent.sch.uk,1322222759.0,Miss,Isabel,Quinn,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,West Hill,Dartford,(England/Wales) Urban major conurbation,E10000016,553550.0,174313.0,Dartford 003,Dartford 003E,,,,,Good,South-East England and South London,,10009429007.0,,Not applicable,Not applicable,,,E02005030,E01024184,14.0,
118777,886,Kent,3749,"St Thomas' Catholic Primary School, Canterbury",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,209.0,108.0,101.0,18.7,Not applicable,,Not applicable,,Not under a federation,,10072737.0,,Not applicable,20-04-2023,12-09-2023,99 Military Road,,,Canterbury,Kent,CT1 1NE,www.st-thomas-canterbury.kent.sch.uk,1227462539.0,Miss,Lisa,D'Agostini,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Barton,Canterbury,(England/Wales) Urban city and town,E10000016,615358.0,158108.0,Canterbury 014,Canterbury 014E,,,,,Good,South-East England and South London,,200000678008.0,,Not applicable,Not applicable,,,E02005023,E01024093,39.0,
118785,886,Kent,4026,Dartford Science & Technology College,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Girls,Does not apply,Does not apply,Not applicable,Non-selective,950.0,No Special Classes,19-01-2023,876.0,11.0,865.0,20.8,Not supported by a trust,,Not applicable,,Not under a federation,,10001855.0,,Not applicable,16-03-2022,07-05-2024,Heath Lane,,,Dartford,Kent,DA1 2LY,http://www.dstc.kent.sch.uk,1322224309.0,Miss,Joanne,Sangster,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Princes,Dartford,(England/Wales) Urban major conurbation,E10000016,553232.0,173727.0,Dartford 003,Dartford 003F,,,,,Good,South-East England and South London,,100062308838.0,,Not applicable,Not applicable,,,E02005030,E01024185,155.0,
118788,886,Kent,4040,Northfleet School for Girls,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Girls,Does not apply,Does not apply,Not applicable,Non-selective,1145.0,No Special Classes,19-01-2023,1251.0,30.0,1221.0,33.0,Supported by a trust,Northfleet Schools Co-Operative Trust,Not applicable,,Not under a federation,,10004754.0,,Not applicable,02-03-2022,27-03-2024,Hall Road,Northfleet,,Gravesend,Kent,DA11 8AQ,http://www.nsfg.org.uk,1474831020.0,Mr,C,Norwood,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Painters Ash,Gravesham,(England/Wales) Urban major conurbation,E10000016,562828.0,172592.0,Gravesham 006,Gravesham 006E,,,,,Good,South-East England and South London,,100062310786.0,,Not applicable,Not applicable,,,E02005060,E01024288,334.0,
118789,886,Kent,4043,Tunbridge Wells Girls' Grammar School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1039.0,No Special Classes,19-01-2023,984.0,0.0,984.0,2.5,Not supported by a trust,,Not applicable,,Not under a federation,,10007075.0,,Not applicable,20-09-2023,17-04-2024,Southfield Road,,,Tunbridge Wells,Kent,TN4 9UJ,http://www.twggs.kent.sch.uk/,1892520902.0,Mrs,Linda,Wybar,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,St John's,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558061.0,140816.0,Tunbridge Wells 007,Tunbridge Wells 007D,,,,,Outstanding,South-East England and South London,,100062585962.0,,Not applicable,Not applicable,,,E02005168,E01024838,18.0,
118790,886,Kent,4045,Tunbridge Wells Grammar School for Boys,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,Does not apply,Does not apply,Not applicable,Selective,1308.0,No Special Classes,19-01-2023,1636.0,1586.0,50.0,5.5,Not applicable,,Not applicable,,Not under a federation,,10007076.0,,Not applicable,25-11-2021,21-05-2024,St John's Road,,,Tunbridge Wells,Kent,TN4 9XB,http://www.twgsb.org.uk/,1892529551.0,Ms,Amanda,Simpson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,St John's,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558237.0,141498.0,Tunbridge Wells 002,Tunbridge Wells 002A,,,,,Good,South-East England and South London,,10008662060.0,,Not applicable,Not applicable,,,E02005163,E01024837,71.0,
118806,886,Kent,4109,Dover Grammar School for Girls,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Girls,Does not apply,Does not apply,Not applicable,Selective,885.0,No Special Classes,19-01-2023,882.0,24.0,858.0,15.2,Not applicable,,Not applicable,,Not under a federation,,10002018.0,,Not applicable,15-11-2013,08-04-2024,Frith Road,,,Dover,Kent,CT16 2PZ,http://dggs.kent.sch.uk/,1304206625.0,Mr,Robert,Benson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,St Radigunds,Dover,(England/Wales) Urban city and town,E10000016,631484.0,142361.0,Dover 012,Dover 012D,,,,,Outstanding,South-East England and South London,,100062289176.0,,Not applicable,Not applicable,,,E02005052,E01024247,103.0,
118835,886,Kent,4522,Maidstone Grammar School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,1416.0,No Special Classes,19-01-2023,1425.0,1341.0,84.0,5.4,Not supported by a trust,,Not applicable,,Not under a federation,,10004156.0,,Not applicable,16-01-2019,15-04-2024,Barton Road,,,Maidstone,Kent,ME15 7BT,www.mgs.kent.sch.uk,1622752101.0,Mr,Mark,Tomkins,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Maidstone,High Street,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,576678.0,154844.0,Maidstone 010,Maidstone 010A,,,,,Good,South-East England and South London,,200003683439.0,,Not applicable,Not applicable,,,E02005077,E01024371,57.0,
118836,886,Kent,4523,Maidstone Grammar School for Girls,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1240.0,No Special Classes,19-01-2023,1197.0,64.0,1133.0,7.4,Not supported by a trust,,Not applicable,,Not under a federation,,10004157.0,,Not applicable,08-03-2023,29-05-2024,Buckland Road,,,Maidstone,Kent,ME16 0SF,http://www.mggs.org/,1622752103.0,Miss,Deborah,Stanley,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Bridge,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,575292.0,156397.0,Maidstone 006,Maidstone 006B,,,,,Outstanding,South-East England and South London,,200003670344.0,,Not applicable,Not applicable,,,E02005073,E01024340,65.0,
118840,886,Kent,4534,Simon Langton Girls' Grammar School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1082.0,No Special Classes,19-01-2023,1244.0,33.0,1211.0,6.0,Not applicable,,Not applicable,,Not under a federation,,10005848.0,,Not applicable,27-09-2023,23-04-2024,Old Dover Road,,,Canterbury,Kent,CT1 3EW,http://www.langton.kent.sch.uk/,1227463711.0,Mr,Paul,Pollard,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Barton,Canterbury,(England/Wales) Urban city and town,E10000016,616129.0,156292.0,Canterbury 016,Canterbury 016C,,,,,Good,South-East England and South London,,200000682990.0,,Not applicable,Not applicable,,,E02005025,E01024046,53.0,
118843,886,Kent,4622,The Judd School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,1261.0,No Special Classes,19-01-2023,1472.0,1283.0,189.0,2.7,Not applicable,,Not applicable,,Not under a federation,,10006720.0,,Not applicable,07-05-2015,23-05-2024,Brook Street,,,Tonbridge,Kent,TN9 2PN,http://judd.online,1732770880.0,Mr,Jonathan,Wood,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,21.0,22.0,,,South East,Tonbridge and Malling,Judd,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,558333.0,145666.0,Tonbridge and Malling 013,Tonbridge and Malling 013A,,,,,Outstanding,South-East England and South London,,100062594180.0,,Not applicable,Not applicable,,,E02005161,E01024757,26.0,
118846,886,Kent,5200,Snodland CofE Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,420.0,No Special Classes,19-01-2023,407.0,220.0,187.0,30.2,Not applicable,,Not applicable,,Not under a federation,,10069067.0,,Not applicable,19-10-2022,21-05-2024,Roberts Road,,,Snodland,Kent,ME6 5HL,www.snodland.kent.sch.uk,1634241251.0,Mrs,Holley,Hunt,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Snodland West & Holborough Lakes,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,569746.0,161866.0,Tonbridge and Malling 002,Tonbridge and Malling 002E,,,,,Good,South-East England and South London,,200000958756.0,,Not applicable,Not applicable,,,E02005150,E01024773,123.0,
118847,886,Kent,5201,Borough Green Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,315.0,No Special Classes,19-01-2023,265.0,131.0,134.0,22.3,Not supported by a trust,,Not applicable,,Not under a federation,,10069648.0,,Not applicable,07-03-2024,22-05-2024,School Approach,Borough Green,,Sevenoaks,Kent,TN15 8JZ,http://www.bgpschool.kent.sch.uk,1732883459.0,Mrs,Karen,Jackson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Borough Green & Platt,Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,561085.0,157405.0,Tonbridge and Malling 006,Tonbridge and Malling 006C,,,,,Good,South-East England and South London,,200000965163.0,,Not applicable,Not applicable,,,E02005154,E01024725,59.0,
118849,886,Kent,5203,Roseacre Junior School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,396.0,No Special Classes,19-01-2023,423.0,217.0,206.0,3.3,Not supported by a trust,,Not applicable,,Not under a federation,,10069647.0,,Not applicable,03-11-2022,05-06-2024,The Landway,Bearsted,,Maidstone,Kent,ME14 4BL,http://www.roseacre.kent.sch.uk,1622737843.0,Mr,Duncan,Garrett,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Bearsted,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,579372.0,155693.0,Maidstone 005,Maidstone 005A,,,,,Outstanding,South-East England and South London,,200003691727.0,,Not applicable,Not applicable,,,E02005072,E01024330,14.0,
118852,886,Kent,5206,Herne Bay Junior School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,500.0,No Special Classes,19-01-2023,426.0,210.0,216.0,42.0,Not supported by a trust,,Not applicable,,Not under a federation,,10069646.0,,Not applicable,29-01-2020,09-05-2024,Kings Road,,,Herne Bay,Kent,CT6 5DA,http://www.hernebay-jun.kent.sch.uk/,1227374608.0,Mrs,Melody,Kingman,Acting Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Heron,North Thanet,(England/Wales) Urban city and town,E10000016,617911.0,167922.0,Canterbury 001,Canterbury 001A,,,,,Good,South-East England and South London,,200000697542.0,,Not applicable,Not applicable,,,E02005010,E01024078,179.0,
118853,886,Kent,5207,"St Francis' Catholic Primary School, Maidstone",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,420.0,No Special Classes,19-01-2023,418.0,194.0,224.0,15.3,Not applicable,,Not applicable,,Not under a federation,,10072733.0,,Not applicable,18-09-2018,05-06-2024,Queen's Road,,,Maidstone,Kent,ME16 0LB,www.st-francis.kent.sch.uk,1622771540.0,Mrs,Elisabeth,Blanden,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Bridge,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,574157.0,155660.0,Maidstone 003,Maidstone 003F,,,,,Good,South-East England and South London,,200003717931.0,,Not applicable,Not applicable,,,E02005070,E01024341,64.0,
118858,886,Kent,5212,Ditton Infant School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,180.0,No Special Classes,19-01-2023,174.0,85.0,89.0,24.1,Not supported by a trust,,Not applicable,,Not under a federation,,10078307.0,,Not applicable,05-10-2022,24-01-2024,Pear Tree Avenue,Ditton,,Aylesford,Kent,ME20 6EB,www.ditton-inf.kent.sch.uk/,1732844107.0,,Claire,Lewer,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Aylesford South & Ditton,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,571309.0,158026.0,Tonbridge and Malling 005,Tonbridge and Malling 005C,,,,,Good,South-East England and South London,,200000961077.0,,Not applicable,Not applicable,,,E02005153,E01024735,42.0,
118859,886,Kent,5213,"Holy Trinity Church of England Primary School, Dartford",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,420.0,No Special Classes,19-01-2023,423.0,214.0,209.0,15.6,Not applicable,,Not applicable,,Not under a federation,,10069066.0,,Not applicable,03-02-2023,29-05-2024,Chatsworth Road,,,Dartford,Kent,DA1 5AF,http://www.holytrinitydartford.co.uk,1322224474.0,Mrs,Vikki,Wall,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Burnham,Dartford,(England/Wales) Urban major conurbation,E10000016,553399.0,174917.0,Dartford 003,Dartford 003A,,,,,Good,South-East England and South London,,200000530383.0,,Not applicable,Not applicable,,,E02005030,E01024180,66.0,
118860,886,Kent,5214,"St Bartholomew's Catholic Primary School, Swanley",Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,350.0,No Special Classes,19-01-2023,324.0,158.0,166.0,19.4,Not applicable,,Not applicable,,Not under a federation,,10072732.0,,Not applicable,05-05-2022,07-05-2024,Sycamore Drive,,,Swanley,Kent,BR8 7AY,http://www.st-bartholomewsrc-pri.kent.sch.uk/,1322663119.0,Mrs,Giovanna,McRae,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Swanley White Oak,Sevenoaks,(England/Wales) Urban major conurbation,E10000016,551351.0,168878.0,Sevenoaks 002,Sevenoaks 002D,,,,,Good,South-East England and South London,,100062276753.0,,Not applicable,Not applicable,,,E02005088,E01024480,63.0,
118864,886,Kent,5218,Greatstone Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,364.0,No Special Classes,19-01-2023,300.0,141.0,159.0,24.6,Not supported by a trust,,Not applicable,,Supported by a federation,The Lightyear Federation,10069645.0,,Not applicable,25-05-2022,15-05-2024,Baldwin Road,Greatstone,,New Romney,Kent,TN28 8SY,www.greatstoneschool.co.uk,1797363916.0,Mr,Matt,Rawling,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Walland & Denge Marsh,Folkestone and Hythe,(England/Wales) Rural town and fringe,E10000016,607768.0,122481.0,Folkestone and Hythe 013,Folkestone and Hythe 013A,,,,,Good,South-East England and South London,,50003937.0,,Not applicable,Not applicable,,,E02005114,E01024532,67.0,
118867,886,Kent,5221,Wincheap Foundation Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,445.0,Not applicable,19-01-2023,432.0,219.0,213.0,31.5,Not supported by a trust,,Not applicable,,Not under a federation,,10073718.0,,Not applicable,09-12-2021,24-04-2024,Hollow Lane,,,Canterbury,Kent,CT1 3SD,www.wincheap.kent.sch.uk,1227464134.0,Mrs,Nicola,Dawson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,17.0,20.0,,,South East,Canterbury,Wincheap,Canterbury,(England/Wales) Urban city and town,E10000016,614237.0,156789.0,Canterbury 019,Canterbury 019D,,,,,Good,South-East England and South London,,10033162353.0,,Not applicable,Not applicable,,,E02006855,E01035310,136.0,
118869,886,Kent,5223,Brookfield Junior School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,256.0,No Special Classes,19-01-2023,246.0,128.0,118.0,31.3,Not applicable,,Not applicable,,Supported by a federation,Flourish,10079029.0,,Not applicable,29-03-2023,23-04-2024,Brookfield Junior School,Swallow Road,Larkfield,Aylesford,Kent,ME20 6PY,www.flourishfederation.co.uk,1732843667.0,Mr,Nathaniel,South,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Larkfield,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,570167.0,158770.0,Tonbridge and Malling 003,Tonbridge and Malling 003F,,,,,Good,South-East England and South London,,100062628494.0,,Not applicable,Not applicable,,,E02005151,E01024765,77.0,
118871,886,Kent,5225,Harcourt Primary School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,178.0,87.0,91.0,34.3,Not supported by a trust,,Not applicable,,Not under a federation,,10069644.0,,Not applicable,06-10-2021,13-04-2024,Biggins Wood Road,,,Folkestone,Kent,CT19 4NE,www.harcourt.kent.sch.uk/,1303275294.0,Mr,Anthony,Silk,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Cheriton,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,620022.0,137406.0,Folkestone and Hythe 002,Folkestone and Hythe 002A,,,,,Good,South-East England and South London,,50030583.0,,Not applicable,Not applicable,,,E02005103,E01024492,61.0,
118879,886,Kent,5407,Thamesview School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,910.0,Has Special Classes,19-01-2023,955.0,498.0,457.0,40.0,Not supported by a trust,,Not applicable,,Not under a federation,,10006569.0,,Not applicable,20-06-2018,03-06-2024,Thong Lane,,,Gravesend,Kent,DA12 4LF,http://www.thamesviewsch.co.uk/,1474566552.0,Mr,George,Rorke,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,PD - Physical Disability,,,,,,,,,,,,,Resourced provision,,,,,South East,Gravesham,Riverview Park,Gravesham,(England/Wales) Urban major conurbation,E10000016,566808.0,172052.0,Gravesham 008,Gravesham 008B,,,,,Good,South-East England and South London,,100062312649.0,,Not applicable,Not applicable,,,E02005062,E01024298,354.0,
118884,886,Kent,5412,Simon Langton Grammar School for Boys,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,1280.0,No Special Classes,19-01-2023,1247.0,1117.0,130.0,5.0,Not supported by a trust,,Not applicable,,Not under a federation,,10005849.0,,Not applicable,14-11-2013,28-05-2024,Langton Lane,Nackington Road,,Canterbury,Kent,CT4 7AS,http://www.thelangton.org.uk/,1227463567.0,Dr,Ken,Moffat,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,41.0,35.0,,,South East,Canterbury,Wincheap,Canterbury,(England/Wales) Urban city and town,E10000016,615323.0,155825.0,Canterbury 019,Canterbury 019E,,,,,Outstanding,South-East England and South London,,,,Not applicable,Not applicable,,,E02006855,E01035311,39.0,
118897,886,Kent,5425,The Malling School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1003.0,No Special Classes,19-01-2023,1010.0,547.0,463.0,23.0,Supported by a trust,The Malling Holmesdale Federation,Not applicable,,Not under a federation,,10006748.0,,Not applicable,29-03-2023,04-06-2024,Beech Road,East Malling,,West Malling,Kent,ME19 6DH,www.themallingschool.kent.sch.uk,1732840995.0,Mr,John,Vennart,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",ASD - Autistic Spectrum Disorder,,,,,,,,,,,,Resourced provision,124.0,121.0,,,South East,Tonbridge and Malling,"East Malling, West Malling & Offham",Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,569778.0,157407.0,Tonbridge and Malling 014,Tonbridge and Malling 014A,,,,,Good,South-East England and South London,,200000960428.0,,Not applicable,Not applicable,,,E02006833,E01024740,208.0,
118898,886,Kent,5426,The Archbishop's School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Non-selective,900.0,No Special Classes,19-01-2023,722.0,382.0,340.0,45.6,Not supported by a trust,,Not applicable,,Not under a federation,,10006581.0,,Not applicable,23-11-2023,23-04-2024,St Stephens Hill,,,Canterbury,Kent,CT2 7AP,http://www.archbishops-school.co.uk/,1227765805.0,Mr,David,Elliott,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,SpLD - Specific Learning Difficulty,VI - Visual Impairment,OTH - Other Difficulty/Disability,HI - Hearing Impairment,"SLCN - Speech, language and Communication",ASD - Autistic Spectrum Disorder,"SEMH - Social, Emotional and Mental Health",PD - Physical Disability,MLD - Moderate Learning Difficulty,,,,,Resourced provision,7.0,7.0,,,South East,Canterbury,St Stephen's,Canterbury,(England/Wales) Urban city and town,E10000016,614417.0,159483.0,Canterbury 013,Canterbury 013B,,,,,Good,South-East England and South London,,100062619198.0,,Not applicable,Not applicable,,,E02005022,E01024100,284.0,
118919,886,Kent,5447,St George's Church of England Foundation School,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,All-through,4.0,19,No boarders,No Nursery Classes,Has a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Non-selective,1375.0,No Special Classes,19-01-2023,1633.0,788.0,845.0,26.9,Not supported by a trust,,Not applicable,,Not under a federation,,10006163.0,,Not applicable,13-06-2019,21-05-2024,Westwood Road,,,Broadstairs,Kent,CT10 2LH,http://www.stgeorges-school.org.uk/,1843861696.0,Mr,Adam,Mirams,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,St Peters,South Thanet,(England/Wales) Urban city and town,E10000016,637425.0,167972.0,Thanet 011,Thanet 011E,,,,,Good,South-East England and South London,,200003079311.0,,Not applicable,Not applicable,,,E02005142,E01024691,404.0,
118928,886,Kent,5456,Northfleet Technology College,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,None,Does not apply,Not applicable,Non-selective,989.0,No Special Classes,19-01-2023,903.0,900.0,3.0,29.2,Supported by a trust,Northfleet Schools Co-Operative Trust,Not applicable,,Not under a federation,,10004755.0,,Not applicable,22-09-2022,21-05-2024,Colyer Road,Northfleet,,Gravesend,Kent,DA11 8BG,http://www.ntc.kent.sch.uk/,1474533802.0,Mr,Steven,Gallears,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Northfleet & Springhead,Gravesham,(England/Wales) Urban major conurbation,E10000016,563003.0,173050.0,Gravesham 006,Gravesham 006B,,,,,Good,South-East England and South London,,10012024936.0,,Not applicable,Not applicable,,,E02005060,E01024281,219.0,
118931,886,Kent,5459,Dover Grammar School for Boys,Foundation school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,880.0,No Special Classes,19-01-2023,835.0,822.0,13.0,15.3,Not supported by a trust,,Not applicable,,Not under a federation,,10002017.0,,Not applicable,16-10-2019,21-05-2024,Astor Avenue,,,Dover,Kent,CT17 0DQ,http://www.dgsb.co.uk,1304206117.0,Mr,Philip,Horstrup,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Tower Hamlets,Dover,(England/Wales) Urban city and town,E10000016,630305.0,141711.0,Dover 011,Dover 011H,,,,,Good,South-East England and South London,,10034874352.0,,Not applicable,Not applicable,,,E02005051,E01024248,103.0,
118933,886,Kent,5461,St John's Catholic Comprehensive,Voluntary aided school,Local authority maintained schools,"Open, but proposed to close",Not applicable,,Academy Converter,31-08-2024,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Non-selective,1184.0,No Special Classes,19-01-2023,1294.0,663.0,631.0,22.5,Not applicable,,Not applicable,,Not under a federation,,10006200.0,,Not applicable,15-05-2018,06-06-2024,Rochester Road,,,Gravesend,Kent,DA12 2JW,http://www.stjohnscs.com,1474534718.0,Mr,Matthew,Barron,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Denton,Gravesham,(England/Wales) Urban major conurbation,E10000016,565876.0,173278.0,Gravesham 003,Gravesham 003C,,,,,Good,South-East England and South London,,100062311894.0,,Not applicable,Not applicable,,,E02005057,E01024293,218.0,
118937,886,Kent,6000,Ashford School,Other independent school,Independent schools,Open,Not applicable,01-01-1918,Not applicable,,Not applicable,,18,Boarding school,Has Nursery Classes,Has a sixth form,Mixed,Christian,Christian,Not applicable,Not applicable,1084.0,No Special Classes,20-01-2022,1050.0,550.0,500.0,0.0,Not applicable,,Not applicable,,Not applicable,,10008077.0,,Not applicable,,28-03-2024,East Hill,,,Ashford,Kent,TN24 8PB,https://www.ashfordschool.co.uk,1233625171.0,Mr,Michael,Hall,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Ashford,Victoria,Ashford,(England/Wales) Urban city and town,E10000016,601413.0,142875.0,Ashford 005,Ashford 005G,ISI,281.0,40.0,,,South-East England and South London,,100062560535.0,,Not applicable,Not applicable,,,E02005000,E01034986,0.0,
118938,886,Kent,6001,Wellesley Haddon Dene School,Other independent school,Independent schools,Open,Not applicable,01-01-1929,Not applicable,,Not applicable,2.0,13,Boarding school,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England,Not applicable,Not applicable,320.0,No Special Classes,20-01-2022,210.0,126.0,84.0,0.0,Not applicable,,Not applicable,,Not applicable,,10015812.0,,Not applicable,,22-04-2024,114 Ramsgate Road,Broadstairs,Kent,,,CT10 2DG,www.wellesleyhouse.org,1843862991.0,Mrs,Joanne,Parpworth,Headmaster,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Thanet,Viking,South Thanet,(England/Wales) Urban city and town,E10000016,638726.0,167390.0,Thanet 010,Thanet 010C,ISI,3.0,20.0,Alpha Schools,,South-East England and South London,,200003079311.0,,Not applicable,Not applicable,,,E02005141,E01024706,0.0,
118939,886,Kent,6002,Benenden School,Other independent school,Independent schools,Open,Not applicable,01-01-1926,Not applicable,,Not applicable,10.0,19,Boarding school,No Nursery Classes,Has a sixth form,Girls,None,None,Not applicable,Not applicable,620.0,No Special Classes,20-01-2022,546.0,0.0,546.0,0.0,Not applicable,,Not applicable,,Not applicable,,10014830.0,,Not applicable,,07-05-2024,Cranbrook Road,Benenden,,Cranbrook,Kent,TN17 4AA,http://www.benenden.school,1580240592.0,Mrs,S,Price,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Benenden and Cranbrook,Maidstone and The Weald,(England/Wales) Rural village,E10000016,580246.0,133803.0,Tunbridge Wells 014,Tunbridge Wells 014A,ISI,,127.0,Benenden School (Kent) Ltd,,South-East England and South London,,100062552564.0,,Not applicable,Not applicable,,,E02005175,E01024789,0.0,
118940,886,Kent,6003,Dover College,Other independent school,Independent schools,Open,Not applicable,01-01-1909,Not applicable,,Not applicable,3.0,18,Boarding school,Has Nursery Classes,Has a sixth form,Mixed,Church of England,Church of England,Not applicable,Non-selective,478.0,No Special Classes,20-01-2022,313.0,172.0,141.0,0.0,Not applicable,,Not applicable,,Not applicable,,10008199.0,,Not applicable,,03-05-2024,Effingham Crescent,,,Dover,Kent,CT17 9RH,www.dovercollege.org.uk,1304205969.0,Mr,Simon,Fisher,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Dover,Town & Castle,Dover,(England/Wales) Urban city and town,E10000016,631537.0,141684.0,Dover 013,Dover 013B,ISI,,110.0,Corporation of Dover College,,South-East England and South London,,100062290526.0,,Not applicable,Not applicable,,,E02005053,E01024215,0.0,
118941,886,Kent,6004,Northbourne Park School,Other independent school,Independent schools,Open,Not applicable,01-01-1942,Not applicable,,Not applicable,2.0,13,Boarding school,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Church of England,Not applicable,Non-selective,205.0,No Special Classes,20-01-2022,193.0,99.0,94.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018503.0,,Not applicable,,30-01-2024,Betteshanger,,,DEAL,Kent,CT14 0NW,http://www.northbournepark.com,1304611215.0,Mr,Mark,Hammond,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Dover,Eastry Rural,Dover,(England/Wales) Rural village,E10000016,631045.0,152538.0,Dover 005,Dover 005A,ISI,,38.0,,,South-East England and South London,,10034873947.0,,Not applicable,Not applicable,,,E02005045,E01024201,0.0,
118942,886,Kent,6005,Marlborough House School,Other independent school,Independent schools,Open,Not applicable,01-01-1932,Not applicable,,Not applicable,2.0,13,Boarding school,Has Nursery Classes,Does not have a sixth form,Mixed,None,Christian,Not applicable,Non-selective,350.0,No Special Classes,20-01-2022,248.0,119.0,129.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018722.0,,Not applicable,,04-06-2024,Hawkhurst,,,Cranbrook,Kent,TN18 4PY,www.marlboroughhouseschool.co.uk,1580753555.0,Mr,Eddy,Newton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Hawkhurst and Sandhurst,Tunbridge Wells,(England/Wales) Rural hamlet and isolated dwellings,E10000016,575350.0,130678.0,Tunbridge Wells 014,Tunbridge Wells 014E,ISI,,63.0,Marlborough House Sch Trust Ltd,,South-East England and South London,,100062106196.0,,Not applicable,Not applicable,,,E02005175,E01024810,0.0,
118943,886,Kent,6006,St Ronan's School,Other independent school,Independent schools,Open,Not applicable,01-01-1917,Not applicable,,Not applicable,2.0,13,Boarding school,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England,Not applicable,Non-selective,468.0,No Special Classes,20-01-2022,455.0,241.0,214.0,0.0,Not applicable,,Not applicable,,Not applicable,,10017665.0,,Not applicable,,04-06-2024,Water Lane,Hawkhurst,,Cranbrook,Kent,TN18 5DJ,www.saintronans.co.uk,1580752271.0,Mr,William,Trelawney-Vernon,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Hawkhurst and Sandhurst,Tunbridge Wells,(England/Wales) Rural hamlet and isolated dwellings,E10000016,577801.0,130807.0,Tunbridge Wells 014,Tunbridge Wells 014E,ISI,,85.0,St Ronan's (Hawkhurst),,South-East England and South London,,10024135777.0,,Not applicable,Not applicable,,,E02005175,E01024810,0.0,
118944,886,Kent,6007,Gad's Hill School,Other independent school,Independent schools,Open,Not applicable,01-01-1948,Not applicable,,Not applicable,3.0,16,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Non-selective,755.0,No Special Classes,20-01-2022,384.0,194.0,190.0,0.0,Not applicable,,Not applicable,,Not applicable,,10015390.0,,Not applicable,,15-05-2024,Higham,,,Rochester,Kent,ME3 7PA,www.gadshill.org,1474822366.0,Mr,Paul,Savage,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Gravesham,Higham & Shorne,Gravesham,(England/Wales) Rural town and fringe,E10000016,570991.0,170882.0,Gravesham 010,Gravesham 010B,ISI,6.0,30.0,Gad's Hill School,,South-East England and South London,,10012012444.0,,Not applicable,Not applicable,,,E02005064,E01024266,0.0,
118946,886,Kent,6009,Kent College Pembury,Other independent school,Independent schools,Open,Not applicable,01-01-1933,Not applicable,,Not applicable,3.0,20,Boarding school,Has Nursery Classes,Has a sixth form,Girls,Methodist,Methodist,Not applicable,Selective,678.0,No Special Classes,20-01-2022,512.0,19.0,493.0,0.0,Not applicable,,Not applicable,,Not applicable,,10008307.0,,Not applicable,,08-05-2024,Old Church Road,Pembury,,Tunbridge Wells,Kent,TN2 4AX,http://www.kent-college.co.uk/,1892822006.0,Miss,Katrina,Handford,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Pembury,Tunbridge Wells,(England/Wales) Rural hamlet and isolated dwellings,E10000016,562692.0,143044.0,Tunbridge Wells 004,Tunbridge Wells 004B,ISI,7.0,155.0,Methodist Independent Schools Trust,,South-East England and South London,,10008667752.0,,Not applicable,Not applicable,,,E02005165,E01024825,0.0,
118947,886,Kent,6010,St Lawrence College,Other independent school,Independent schools,Open,Not applicable,01-01-1912,Not applicable,,Not applicable,10.0,18,Boarding school,No Nursery Classes,Has a sixth form,Mixed,Christian/Evangelical,Church of England,Not applicable,Not applicable,500.0,No Special Classes,20-01-2022,409.0,218.0,191.0,0.0,Not applicable,,Not applicable,,Not applicable,,10017219.0,,Not applicable,,18-04-2024,College Road,,,Ramsgate,Kent,CT11 7AE,www.slcuk.com,1843572900.0,Mr,Barney,Durrant,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Thanet,Eastcliff,South Thanet,(England/Wales) Urban city and town,E10000016,637926.0,165987.0,Thanet 015,Thanet 015C,ISI,1.0,,Corporation of St Lawrence College,,South-East England and South London,,100062281951.0,,Not applicable,Not applicable,,,E02005146,E01024668,0.0,
118949,886,Kent,6011,Beechwood School,Other independent school,Independent schools,Open,Not applicable,01-01-1943,Not applicable,,Not applicable,3.0,19,Boarding school,Has Nursery Classes,Has a sixth form,Mixed,None,Christian,Not applicable,Non-selective,420.0,No Special Classes,20-01-2022,309.0,161.0,148.0,0.0,Not applicable,,Not applicable,,Not applicable,,10014837.0,,Not applicable,,07-06-2024,12 Pembury Road,,,Tunbridge Wells,Kent,TN2 3QD,http://www.beechwood.org.uk,1892532747.0,Mr,Justin,Foster-Gandey,Headmaster,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Park,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,560091.0,139893.0,Tunbridge Wells 009,Tunbridge Wells 009B,ISI,,64.0,Alpha Schools,,South-East England and South London,,100062554131.0,,Not applicable,Not applicable,,,E02005170,E01024822,0.0,
118950,886,Kent,6012,Holmewood House School,Other independent school,Independent schools,Open,Not applicable,01-01-1951,Not applicable,,Not applicable,2.0,13,Boarding school,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Non-selective,540.0,No Special Classes,20-01-2022,449.0,242.0,207.0,0.0,Not applicable,,Not applicable,,Not applicable,,10015872.0,,Not applicable,,07-06-2024,Barrow Lane,Langton Green,,Tunbridge Wells,Kent,TN3 0EB,www.holmewoodhouse.co.uk,1892860000.0,Mrs,Ruth,O'Sullivan,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Speldhurst and Bidborough,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,555212.0,138621.0,Tunbridge Wells 006,Tunbridge Wells 006C,ISI,4.0,139.0,,,South-East England and South London,,100062108061.0,,Not applicable,Not applicable,,,E02005167,E01024852,0.0,
118951,886,Kent,6013,Rose Hill School,Other independent school,Independent schools,Open,Not applicable,01-01-1949,Not applicable,,Not applicable,3.0,13,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Not applicable,320.0,No Special Classes,20-01-2022,265.0,154.0,111.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018845.0,,Not applicable,,15-05-2024,Coniston Avenue,,,Tunbridge Wells,Kent,TN4 9SY,,1892525591.0,Ms,Emma,Neville,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Culverden,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,557231.0,140251.0,Tunbridge Wells 007,Tunbridge Wells 007B,ISI,6.0,82.0,Grange Rose Hill School Ltd,,South-East England and South London,,100062585961.0,,Not applicable,Not applicable,,,E02005168,E01024800,0.0,
118952,886,Kent,6014,Sevenoaks School,Other independent school,Independent schools,Open,Not applicable,01-01-1918,Not applicable,,Not applicable,11.0,18,Boarding school,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Not applicable,1250.0,No Special Classes,20-01-2022,1181.0,624.0,557.0,0.0,Not applicable,,Not applicable,,Not applicable,,10005765.0,,Not applicable,,08-05-2024,High Street,Sevenoaks,Kent,Sevenoaks,Kent,TN13 1HU,www.sevenoaksschool.org,1732455133.0,Mr,Jesse,Elzinga,Head,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Sevenoaks Town and St John's,Sevenoaks,(England/Wales) Urban city and town,E10000016,553207.0,154098.0,Sevenoaks 012,Sevenoaks 012F,ISI,,169.0,,,South-East England and South London,,100062546708.0,,Not applicable,Not applicable,,,E02005098,E01024471,0.0,
118953,886,Kent,6015,Sevenoaks Preparatory School,Other independent school,Independent schools,Open,Not applicable,26-03-1958,Not applicable,,Not applicable,3.0,14,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England,Not applicable,Non-selective,444.0,No Special Classes,20-01-2022,381.0,181.0,200.0,0.0,Not applicable,,Not applicable,,Not applicable,,10017399.0,,Not applicable,,09-04-2024,Fawke Cottage,Godden Green,,Sevenoaks,Kent,TN15 0JU,http://www.theprep.org.uk,1732762336.0,Mr,Luke,Harrison,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Seal and Weald,Sevenoaks,(England/Wales) Rural hamlet and isolated dwellings,E10000016,555440.0,154482.0,Sevenoaks 012,Sevenoaks 012A,ISI,,63.0,,,South-East England and South London,,10035182256.0,,Not applicable,Not applicable,,,E02005098,E01024458,0.0,
118954,886,Kent,6016,St Michael's Prep School,Other independent school,Independent schools,Open,Not applicable,01-01-1945,Not applicable,,Not applicable,2.0,13,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England,Not applicable,Non-selective,488.0,No Special Classes,20-01-2022,476.0,244.0,232.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018594.0,,Not applicable,,02-05-2024,St Michael's Preparatory School,Otford Court,Row Dow,Otford,,TN14 5RY,www.stmichaels.kent.sch.uk,1959522137.0,Mr,Nik,Pears,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Otford and Shoreham,Sevenoaks,(England/Wales) Rural town and fringe,E10000016,554260.0,159647.0,Sevenoaks 009,Sevenoaks 009D,ISI,2.0,71.0,,,South-East England and South London,United Kingdom,10035184625.0,,Not applicable,Not applicable,,,E02005095,E01024453,0.0,
118955,886,Kent,6017,The New Beacon School,Other independent school,Independent schools,Open,Not applicable,01-01-1917,Not applicable,,Not applicable,2.0,14,Boarding school,Has Nursery Classes,Does not have a sixth form,Boys,None,None,Not applicable,Non-selective,397.0,No Special Classes,20-01-2022,348.0,347.0,1.0,0.0,Not applicable,,Not applicable,,Not applicable,,10017253.0,,Not applicable,,29-04-2024,Brittains Lane,,,Sevenoaks,Kent,TN13 2PB,www.newbeacon.org.uk,1732452131.0,Mrs,Sarah,Brownsdon,Headmaster,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Sevenoaks Kippington,Sevenoaks,(England/Wales) Urban city and town,E10000016,552009.0,153717.0,Sevenoaks 011,Sevenoaks 011E,ISI,1.0,77.0,Tonbridge School of High Street,,South-East England and South London,,100062074386.0,,Not applicable,Not applicable,,,E02005097,E01024464,0.0,
118957,886,Kent,6018,Radnor House Sevenoaks,Other independent school,Independent schools,Open,New Provision,26-02-1997,Not applicable,,Not applicable,2.0,18,No boarders,Has Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Selective,750.0,No Special Classes,20-01-2022,533.0,308.0,225.0,0.0,Not applicable,,Not applicable,,Not applicable,,10008175.0,,Not applicable,,25-04-2024,Combe Bank Drive,Sevenoaks,,,Kent,TN14 6AE,www.radnor-sevenoaks.org,1959563720.0,Mr,David,Paton,Head,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Brasted, Chevening and Sundridge",Sevenoaks,(England/Wales) Rural village,E10000016,548115.0,155824.0,Sevenoaks 013,Sevenoaks 013A,ISI,,37.0,Radnor House Sevenoaks (Holdings) Ltd,,South-East England and South London,United Kingdom,10035181671.0,,Not applicable,Not applicable,,,E02005099,E01024417,0.0,
118958,886,Kent,6019,Sutton Valence School,Other independent school,Independent schools,Open,Not applicable,01-01-1908,Not applicable,,Not applicable,2.0,19,Boarding school,Has Nursery Classes,Has a sixth form,Mixed,Christian,Christian,Not applicable,Not applicable,880.0,No Special Classes,20-01-2022,868.0,516.0,352.0,0.0,Not applicable,,Not applicable,,Not applicable,,10017608.0,,Not applicable,,15-05-2024,North Street,Sutton Valence,,Maidstone,Kent,ME17 3HL,http://www.svs.org.uk/index.html,1622845203.0,Mr,James,Thomas,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Maidstone,Sutton Valence and Langley,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,581234.0,149347.0,Maidstone 017,Maidstone 017D,ISI,2.0,29.0,United Westminster Grey Coat Foundation,,South-East England and South London,,200003719418.0,,Not applicable,Not applicable,,,E02005084,E01024411,0.0,
118959,886,Kent,6020,Tonbridge School,Other independent school,Independent schools,Open,Not applicable,01-01-1918,Not applicable,,Not applicable,13.0,18,Boarding school,No Nursery Classes,Has a sixth form,Boys,None,Church of England,Not applicable,Not applicable,820.0,No Special Classes,20-01-2022,794.0,794.0,0.0,0.0,Not applicable,,Not applicable,,Not applicable,,10006936.0,,Not applicable,,10-05-2024,,,,Tonbridge,Kent,TN9 1JP,www.tonbridge-school.co.uk,1732365555.0,Mr,James,Priory,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Judd,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,559065.0,147021.0,Tonbridge and Malling 012,Tonbridge and Malling 012A,ISI,,150.0,,,South-East England and South London,,200000969928.0,,Not applicable,Not applicable,,,E02005160,E01024732,0.0,
118960,886,Kent,6021,Somerhill,Other independent school,Independent schools,Open,Not applicable,01-01-1935,Not applicable,,Not applicable,2.0,13,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Christian,Not applicable,Non-selective,654.0,No Special Classes,20-01-2022,608.0,383.0,225.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018591.0,,Not applicable,,21-05-2024,Tudeley Road,Tonbridge,Kent,,,TN11 0NJ,www.somerhill.org,1732352124.0,Mr,Duncan,Sinclair,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Capel,Tunbridge Wells,(England/Wales) Rural hamlet and isolated dwellings,E10000016,560772.0,145340.0,Tunbridge Wells 001,Tunbridge Wells 001A,ISI,,41.0,Somerhill Charitable Trust Limited,,South-East England and South London,,10008663663.0,,Not applicable,Not applicable,,,E02005162,E01024798,0.0,
118965,886,Kent,6024,Steephill School,Other independent school,Independent schools,Open,Not applicable,09-10-1957,Not applicable,,Not applicable,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England,Not applicable,Non-selective,125.0,No Special Classes,20-01-2022,132.0,59.0,73.0,0.0,Not applicable,,Not applicable,,Not applicable,,10070236.0,,Not applicable,,03-04-2024,Off Castle Hill,Fawkham,,Longfield,Kent,DA3 7BG,www.steephill.co.uk,1474702107.0,Mr,John,Abbott,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Fawkham and West Kingsdown,Sevenoaks,(England/Wales) Urban city and town,E10000016,559847.0,168076.0,Sevenoaks 007,Sevenoaks 007C,ISI,1.0,38.0,,,South-East England and South London,,10035182828.0,,Not applicable,Not applicable,,,E02005093,E01024437,0.0,
118967,886,Kent,6026,Bronte School,Other independent school,Independent schools,Open,Not applicable,17-10-1957,Not applicable,,Not applicable,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England,Not applicable,Not applicable,160.0,No Special Classes,20-01-2022,148.0,72.0,76.0,0.0,Not applicable,,Not applicable,,Not applicable,,10070235.0,,Not applicable,,04-06-2024,7 Pelham Road,,,Gravesend,Kent,DA11 0HN,,1474533805.0,Mrs,Emma,Wood,Headmistress,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Gravesham,Pelham,Gravesham,(England/Wales) Urban major conurbation,E10000016,564341.0,173911.0,Gravesham 002,Gravesham 002C,ISI,1.0,18.0,Nicholas Clements,,South-East England and South London,,200001873251.0,,Not applicable,Not applicable,,,E02005056,E01024290,0.0,
118971,886,Kent,6029,The Granville School,Other independent school,Independent schools,Open,Not applicable,31-03-1958,Not applicable,,Not applicable,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Inter- / non- denominational,Not applicable,Non-selective,215.0,No Special Classes,20-01-2022,162.0,7.0,155.0,0.0,Not applicable,,Not applicable,,Not applicable,,10080538.0,,Not applicable,,29-05-2024,2 Bradbourne Park Road,,,Sevenoaks,Kent,TN13 3LJ,www.granvilleschool.org,1732453039.0,Mrs,Louise,Lawrance,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Sevenoaks Town and St John's,Sevenoaks,(England/Wales) Urban city and town,E10000016,552345.0,155661.0,Sevenoaks 012,Sevenoaks 012E,ISI,,13.0,,,South-East England and South London,,100062546713.0,,Not applicable,Not applicable,,,E02005098,E01024470,0.0,
118973,886,Kent,6031,Hilden Grange School,Other independent school,Independent schools,Open,Not applicable,01-01-1957,Not applicable,,Not applicable,2.0,13,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England,Not applicable,Selective,370.0,No Special Classes,20-01-2022,298.0,193.0,105.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018656.0,,Not applicable,,11-04-2024,Dry Hill Park Road,,,Tonbridge,Kent,TN10 3BX,www.hildengrange.co.uk,1732352706.0,Mr,Malcolm,Gough,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Cage Green & Angel,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,558953.0,147481.0,Tonbridge and Malling 012,Tonbridge and Malling 012A,ISI,1.0,84.0,Inspired Education Group,,South-East England and South London,,100062543570.0,,Not applicable,Not applicable,,,E02005160,E01024732,0.0,
118974,886,Kent,6032,Hilden Oaks Preparatory School and Nursery,Other independent school,Independent schools,Open,Not applicable,17-10-1957,Not applicable,,Not applicable,,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Non-selective,222.0,No Special Classes,20-01-2022,166.0,70.0,96.0,0.0,Not applicable,,Not applicable,,Not applicable,,10080536.0,,Not applicable,,22-05-2024,38 Dry Hill Park Road,,,Tonbridge,Kent,TN10 3BU,www.hildenoaks.co.uk,1732353941.0,Mrs,Katy,Joiner,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Cage Green & Angel,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,558953.0,147481.0,Tonbridge and Malling 012,Tonbridge and Malling 012B,ISI,,27.0,Derick Walker,,South-East England and South London,,100062543569.0,,Not applicable,Not applicable,,,E02005160,E01024733,0.0,
118975,886,Kent,6033,The Mead School,Other independent school,Independent schools,Open,Not applicable,16-10-1957,Not applicable,,Not applicable,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Christian,Christian,Not applicable,Non-selective,250.0,No Special Classes,20-01-2022,238.0,111.0,127.0,0.0,Not applicable,,Not applicable,,Not applicable,,10080535.0,,Not applicable,,10-04-2024,16 Frant Road,,,Tunbridge Wells,Kent,TN2 5SN,www.themeadschool.co.uk,1892525837.0,Mrs,Catherine,Openshaw,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Pantiles and St Mark's,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558193.0,138430.0,Tunbridge Wells 012,Tunbridge Wells 012B,ISI,2.0,19.0,The Mead School Ltd,,South-East England and South London,,10000066049.0,,Not applicable,Not applicable,,,E02005173,E01024817,0.0,
118977,886,Kent,6035,Chartfield School,Other independent school,Independent schools,Open,Not applicable,08-10-1957,Not applicable,,Not applicable,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Christian,Not applicable,Non-selective,84.0,No Special Classes,20-01-2022,42.0,22.0,20.0,0.0,Not applicable,,Not applicable,,Not applicable,,10080534.0,,Not applicable,21-09-2023,20-02-2024,45 Minster Road,,,Westgate-on-Sea,Kent,CT8 8DA,www.chartfieldschool.org.uk,1843831716.0,Miss,Sarah,Neale,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Thanet,Westgate-on-Sea,North Thanet,(England/Wales) Urban city and town,E10000016,632551.0,169556.0,Thanet 007,Thanet 007E,Ofsted,,5.0,Chartfield School Ltd,Requires improvement,South-East England and South London,,,,Not applicable,Not applicable,,,E02005138,E01024716,0.0,
118978,886,Kent,6036,Bethany School,Other independent school,Independent schools,Open,Not applicable,06-11-1951,Not applicable,,Not applicable,11.0,18,Boarding school,No Nursery Classes,Has a sixth form,Mixed,Christian,Christian,Not applicable,Non-selective,450.0,No Special Classes,20-01-2022,348.0,234.0,114.0,0.0,Not applicable,,Not applicable,,Not applicable,,10013351.0,,Not applicable,,24-04-2024,Goudhurst,,,Cranbrook,Kent,TN17 1LB,http://www.bethanyschool.org.uk,1580211273.0,Mr,Francie,Healy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Goudhurst and Lamberhurst,Tunbridge Wells,(England/Wales) Rural hamlet and isolated dwellings,E10000016,573928.0,140377.0,Tunbridge Wells 011,Tunbridge Wells 011E,ISI,,240.0,Bethany School Limited,,South-East England and South London,,10008665682.0,,Not applicable,Not applicable,,,E02005172,E01024806,0.0,
118981,886,Kent,6038,Solefield School,Other independent school,Independent schools,Open,Not applicable,07-10-1957,Not applicable,,Not applicable,3.0,13,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England,Not applicable,Non-selective,190.0,No Special Classes,20-01-2022,151.0,151.0,0.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018776.0,,Not applicable,,08-05-2024,Solefields Road,,,Sevenoaks,Kent,TN13 1PH,http://www.solefieldschool.org,1732452142.0,Mrs,Helen,McClure,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Sevenoaks Kippington,Sevenoaks,(England/Wales) Urban city and town,E10000016,553072.0,153650.0,Sevenoaks 012,Sevenoaks 012C,ISI,4.0,55.0,,,South-East England and South London,,,,Not applicable,Not applicable,,,E02005098,E01024462,0.0,
118984,886,Kent,6039,Russell House School,Other independent school,Independent schools,Open,Not applicable,01-01-1952,Not applicable,,Not applicable,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Non-selective,218.0,No Special Classes,20-01-2022,183.0,88.0,95.0,0.0,Not applicable,,Not applicable,,Not applicable,,10071116.0,,Not applicable,,23-05-2024,Station Road,Otford,,Sevenoaks,Kent,TN14 5QU,www.russellhouseschool.co.uk,1959522352.0,Mr,Craig,McCarthy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Otford and Shoreham,Sevenoaks,(England/Wales) Rural hamlet and isolated dwellings,E10000016,552991.0,159400.0,Sevenoaks 009,Sevenoaks 009D,ISI,1.0,12.0,Dr Yvonne Lindsay RHS Ltd,,South-East England and South London,,100062621727.0,,Not applicable,Not applicable,,,E02005095,E01024453,0.0,
118986,886,Kent,6040,St Lawrence College Junior School,Other independent school,Independent schools,Open,Not applicable,01-01-1954,Not applicable,,Not applicable,2.0,11,Boarding school,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England/Christian,Not applicable,Not applicable,220.0,No Special Classes,20-01-2022,160.0,98.0,62.0,0.0,Not applicable,,Not applicable,,Not applicable,,10080532.0,,Not applicable,,07-05-2024,College Road,,,Ramsgate,Kent,CT11 7AF,https://www.slcuk.com/,1843572912.0,Mrs,Ellen,Rowe,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Thanet,Eastcliff,South Thanet,(England/Wales) Urban city and town,E10000016,637926.0,165987.0,Thanet 015,Thanet 015C,ISI,,36.0,Corporation of St Lawrence College,,South-East England and South London,,100062099015.0,,Not applicable,Not applicable,,,E02005146,E01024668,0.0,
118990,886,Kent,6043,The Dulwich School Cranbrook,Other independent school,Independent schools,Open,Not applicable,01-01-1920,Not applicable,,Not applicable,2.0,16,Boarding school,Has Nursery Classes,Does not have a sixth form,Mixed,None,Christian,Not applicable,Non-selective,592.0,No Special Classes,20-01-2022,343.0,175.0,168.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018413.0,,Not applicable,,08-05-2024,Coursehorn,,,CRANBROOK,Kent,TN17 3NP,www.dulwichcranbrook.org,1580712179.0,Mrs,Sophie,Bradshaw,Headmaster,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Benenden and Cranbrook,Maidstone and The Weald,(England/Wales) Rural hamlet and isolated dwellings,E10000016,579266.0,135858.0,Tunbridge Wells 013,Tunbridge Wells 013A,ISI,1.0,119.0,Dulwich Prep Cranbrook,,South-East England and South London,,10000064585.0,,Not applicable,Not applicable,,,E02005174,E01024787,0.0,
118991,886,Kent,6044,Cobham Hall,Other independent school,Independent schools,Open,Not applicable,18-10-1962,Not applicable,,Not applicable,11.0,19,Boarding school,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,250.0,No Special Classes,20-01-2022,137.0,1.0,136.0,0.0,Not applicable,,Not applicable,,Not applicable,,10001524.0,,Not applicable,,23-04-2024,Cobham Hall,Brewers Road,Gravesend,,Kent,DA12 3BL,www.cobhamhall.com,1474823371.0,Headteacher,Wendy,Barrett,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Gravesham,"Istead Rise, Cobham & Luddesdown",Gravesham,(England/Wales) Rural hamlet and isolated dwellings,E10000016,568367.0,168915.0,Gravesham 010,Gravesham 010E,ISI,3.0,27.0,The Mill Hill School Foundation,,South-East England and South London,United Kingdom,10012014498.0,,Not applicable,Not applicable,,,E02005064,E01024301,0.0,
118992,886,Kent,6045,Spring Grove School 2003 Ltd,Other independent school,Independent schools,Open,Not applicable,03-11-1967,Not applicable,,Not applicable,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Non-selective,245.0,No Special Classes,20-01-2022,225.0,107.0,118.0,0.0,Not applicable,,Not applicable,,Not applicable,,10080530.0,,Not applicable,,08-05-2024,Harville Road,Wye,,Ashford,Kent,TN25 5EZ,www.springgroveschool.co.uk,1233812337.0,Mrs,Therésa,Jaggard,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Ashford,Wye with Hinxhill,Ashford,(England/Wales) Rural hamlet and isolated dwellings,E10000016,604242.0,146688.0,Ashford 001,Ashford 001E,ISI,1.0,19.0,,,South-East England and South London,,200004393352.0,,Not applicable,Not applicable,,,E02004996,E01024041,0.0,
118996,886,Kent,6048,The King's School Canterbury,Other independent school,Independent schools,Open,Not applicable,01-01-1908,Not applicable,,Not applicable,13.0,18,Boarding school,No Nursery Classes,Has a sixth form,Mixed,Church of England,Church of England,Not applicable,Selective,960.0,No Special Classes,20-01-2022,943.0,485.0,458.0,0.0,Not applicable,,Not applicable,,Not applicable,,10008320.0,,Not applicable,,08-05-2024,25 The Precincts,,,Canterbury,Kent,CT1 2ES,www.kings-school.co.uk,1227595501.0,Ms,Jude,Lowson,Headmaster,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Canterbury,Westgate,Canterbury,(England/Wales) Urban city and town,E10000016,615194.0,158056.0,Canterbury 020,Canterbury 020D,ISI,,220.0,The Kings School Governors,,South-East England and South London,,100062279503.0,,Not applicable,Not applicable,,,E02006856,E01024124,0.0,
118998,886,Kent,6050,St Edmund's School Canterbury,Other independent school,Independent schools,Open,Not applicable,01-01-1918,Not applicable,,Not applicable,2.0,19,Boarding school,Has Nursery Classes,Has a sixth form,Mixed,Church of England,Christian,Not applicable,Not applicable,670.0,No Special Classes,20-01-2022,631.0,335.0,296.0,0.0,Not applicable,,Not applicable,,Not applicable,,10013984.0,,Not applicable,,26-04-2024,St Thomas Hill,,,Canterbury,Kent,CT2 8HU,http://www.stedmunds.org.uk/,1227475600.0,Mr,Edward,O'Connor,Head,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,Not applicable,,,,,South East,Canterbury,Blean Forest,Canterbury,(England/Wales) Urban city and town,E10000016,613410.0,159177.0,Canterbury 012,Canterbury 012E,ISI,11.0,80.0,,,South-East England and South London,,100062619208.0,,Not applicable,Not applicable,,,E02005021,E01024123,0.0,
119001,886,Kent,6053,Kent College (Canterbury),Other independent school,Independent schools,Open,Not applicable,30-09-1980,Not applicable,,Not applicable,11.0,19,Boarding school,Not applicable,Has a sixth form,Mixed,Methodist,Methodist,Not applicable,Not applicable,600.0,Has Special Classes,20-01-2022,574.0,311.0,263.0,0.0,Not applicable,,Not applicable,,Not applicable,,10016349.0,,Not applicable,,23-04-2024,Whitstable Road,,,Canterbury,Kent,CT2 9DT,,1227763231.0,Mr,Mark,Turnbull,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Canterbury,Blean Forest,Canterbury,(England/Wales) Urban city and town,E10000016,613117.0,159367.0,Canterbury 012,Canterbury 012D,ISI,3.0,36.0,Methodist Independent Schools Trust,,South-East England and South London,,100062293085.0,,Not applicable,Not applicable,,,E02005021,E01024068,0.0,
119002,886,Kent,6054,Walthamstow Hall,Other independent school,Independent schools,Open,Not applicable,30-09-1980,Not applicable,,Not applicable,2.0,19,No boarders,Has Nursery Classes,Has a sixth form,Mixed,None,Christian,Not applicable,Not applicable,700.0,No Special Classes,20-01-2022,549.0,0.0,549.0,0.0,Not applicable,,Not applicable,,Not applicable,,10007324.0,,Not applicable,,30-04-2024,Holly Bush Lane,,,Sevenoaks,Kent,TN13 3UL,www.walthamstow-hall.co.uk,1732451334.0,Ms,Louise,Chamberlain,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Sevenoaks Eastern,Sevenoaks,(England/Wales) Urban city and town,E10000016,553388.0,155609.0,Sevenoaks 010,Sevenoaks 010C,ISI,84.0,,,,South-East England and South London,,100062547957.0,,Not applicable,Not applicable,,,E02005096,E01024461,0.0,
119007,886,Kent,6058,Sackville School,Other independent school,Independent schools,Open,Not applicable,17-09-1987,Not applicable,,Not applicable,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Not applicable,242.0,No Special Classes,20-01-2022,206.0,158.0,48.0,0.0,Not applicable,,Not applicable,,Not applicable,,10017557.0,,Not applicable,,10-04-2024,Tonbridge Road,Hildenborough,,Tonbridge,Kent,TN11 9HN,www.sackvilleschool.co.uk,1732838888.0,Mrs,Leoni,Ellis,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Hildenborough,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,556338.0,148693.0,Tonbridge and Malling 010,Tonbridge and Malling 010D,ISI,51.0,23.0,,,South-East England and South London,,200000963023.0,,Not applicable,Not applicable,,,E02005158,E01024754,0.0,
119008,886,Kent,6059,St Faith's At Ash School Limited,Other independent school,Independent schools,Open,Not applicable,28-10-1987,Not applicable,,Not applicable,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Non-selective,260.0,No Special Classes,20-01-2022,228.0,116.0,112.0,0.0,Not applicable,,Not applicable,,Not applicable,,10075226.0,,Not applicable,,22-04-2024,5 The Street,Ash,,Canterbury,Kent,CT3 2HH,www.stfaithsprep.com,1304813409.0,Mrs,Helen,Coombs,Headmaster,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,SpLD - Specific Learning Difficulty,"SLCN - Speech, language and Communication",ASD - Autistic Spectrum Disorder,MSI - Multi-Sensory Impairment,,,,,,,,,,Resourced provision,28.0,30.0,,,South East,Dover,Little Stour & Ashstone,South Thanet,(England/Wales) Rural town and fringe,E10000016,628411.0,158389.0,Dover 001,Dover 001B,ISI,4.0,19.0,St Faith's At Ash School Ltd,,South-East England and South London,,100060886066.0,,Not applicable,Not applicable,,,E02005041,E01024207,0.0,
119010,886,Kent,6061,Junior King's School,Other independent school,Independent schools,Open,Not applicable,16-10-1989,Not applicable,,Not applicable,2.0,14,Boarding school,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Church of England,Not applicable,Not applicable,386.0,No Special Classes,20-01-2022,381.0,209.0,172.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018042.0,,Not applicable,,08-05-2024,Milner Court,Sturry,,Canterbury,Kent,CT2 0AY,www.junior-kings.co.uk,1227714000.0,Mrs,Emma,Karolyi,Head,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Canterbury,Sturry,Canterbury,(England/Wales) Rural town and fringe,E10000016,617596.0,160193.0,Canterbury 011,Canterbury 011E,ISI,1.0,16.0,,,South-East England and South London,,200000682998.0,,Not applicable,Not applicable,,,E02005020,E01024113,0.0,
119014,886,Kent,6064,Lorenden Preparatory School,Other independent school,Independent schools,Open,Not applicable,12-10-1993,Not applicable,,Not applicable,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Christian,Not applicable,Non-selective,140.0,No Special Classes,20-01-2022,120.0,60.0,60.0,0.0,Not applicable,,Not applicable,,Not applicable,,10080527.0,,Not applicable,,12-04-2024,Painters Forstal Road,Painters Forstal,,,,ME13 0EN,www.lorenden.org,1795590030.0,Mr,Richard,McIntosh,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Swale,East Downs,Faversham and Mid Kent,(England/Wales) Rural hamlet and isolated dwellings,E10000016,599351.0,159200.0,Swale 016,Swale 016A,ISI,1.0,19.0,Methodist Independent Schools Trust,,South-East England and South London,,200002534108.0,,Not applicable,Not applicable,,,E02005130,E01024565,0.0,
119020,886,Kent,6069,"Kent College Nursery, Infant and Junior School",Other independent school,Independent schools,Open,Not applicable,23-09-1980,Not applicable,,Not applicable,3.0,11,Boarding school,Has Nursery Classes,Does not have a sixth form,Mixed,None,Church of England/Methodist,Not applicable,Non-selective,240.0,Has Special Classes,20-01-2022,222.0,122.0,100.0,0.0,Not applicable,,Not applicable,,Not applicable,,10080525.0,,Not applicable,,23-04-2024,Harbledown,Canterbury,,Canterbury,Kent,CT2 9AQ,,1227762436.0,Mr,Simon,James,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Canterbury,Chartham & Stone Street,Canterbury,(England/Wales) Rural village,E10000016,612417.0,158066.0,Canterbury 012,Canterbury 012C,ISI,,22.0,,,South-East England and South London,,200000690375.0,,Not applicable,Not applicable,,,E02005021,E01024067,0.0,
130938,886,Kent,2682,New Ash Green Primary School,Community school,Local authority maintained schools,Open,Not applicable,01-09-1997,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,413.0,212.0,201.0,13.3,Not applicable,,Not applicable,,Not under a federation,,10075572.0,,Not applicable,25-02-2022,01-02-2024,North Square,New Ash Green,,Longfield,Kent,DA3 8JT,http://www.new-ash.kent.sch.uk,1474873858.0,Mrs,Caroline,Cain,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Ash and New Ash Green,Sevenoaks,(England/Wales) Urban city and town,E10000016,560624.0,165724.0,Sevenoaks 016,Sevenoaks 016A,,,,,Good,South-East England and South London,,100062314601.0,,Not applicable,Not applicable,,,E02006832,E01024413,55.0,
130948,886,Kent,3298,St. Edmund's Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,01-09-1996,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,Not applicable,19-01-2023,169.0,88.0,81.0,30.2,Not applicable,,Not applicable,,Supported by a federation,The Compass Federation,10075571.0,,Not applicable,14-11-2018,09-04-2024,Fawkham Road,West Kingsdown,,Sevenoaks,Kent,TN15 6JP,www.st-edmunds.kent.sch.uk,1474853484.0,Mr,Benjamin,Hulme,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Fawkham and West Kingsdown,Sevenoaks,(England/Wales) Rural town and fringe,E10000016,558036.0,162680.0,Sevenoaks 007,Sevenoaks 007A,,,,,Good,South-East England and South London,,100062550147.0,,Not applicable,Not applicable,,,E02005093,E01024435,51.0,
130952,886,Kent,2680,Kings Hill School Primary and Nursery,Community school,Local authority maintained schools,Open,Not applicable,01-09-1997,Not applicable,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,485.0,229.0,256.0,7.4,Not applicable,,Not applicable,,Not under a federation,,10075570.0,,Not applicable,21-02-2024,20-05-2024,Crispin Way,Kings Hill,,West Malling,Kent,ME19 4LS,www.kingshillschool.org.uk/,1732842739.0,Miss,Lottie,Barnden,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Kings Hill,Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,567411.0,155232.0,Tonbridge and Malling 007,Tonbridge and Malling 007F,,,,,Outstanding,South-East England and South London,,10002912179.0,,Not applicable,Not applicable,,,E02005155,E01032826,36.0,
131020,886,Kent,3902,Hythe Bay CofE Primary School,Voluntary controlled school,Local authority maintained schools,Open,Result of Amalgamation,01-09-2006,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,Has Special Classes,19-01-2023,297.0,170.0,127.0,38.7,Not applicable,,Not applicable,,Not under a federation,,10075218.0,,Not applicable,25-01-2023,09-04-2024,Cinque Ports Avenue,,,Hythe,Kent,CT21 6HS,www.hythebay.kent.sch.uk,1303267802.0,Mrs,Carolyn,Chivers,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,21.0,22.0,,,South East,Folkestone and Hythe,Hythe,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,615731.0,134394.0,Folkestone and Hythe 010,Folkestone and Hythe 010B,,,,,Good,South-East England and South London,,50113532.0,,Not applicable,Not applicable,,,E02005111,E01024524,115.0,
131181,886,Kent,6073,Beech Grove School,Other independent school,Independent schools,Open,Not applicable,21-02-1997,Not applicable,,Not applicable,4.0,19,Boarding school,No Nursery Classes,Has a sixth form,Mixed,Christian,Christian,Not applicable,Selective,120.0,Not applicable,20-01-2022,83.0,48.0,35.0,0.0,Not applicable,,Not applicable,,Not applicable,,10043893.0,,Not applicable,06-12-2019,03-06-2024,Forest Drive,,Nonington,Dover,Kent,CT15 4FB,beechgroveschool.co.uk,1304842980.0,Mr,Jeffrey,Maendel,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Dover,"Aylesham, Eythorne & Shepherdswell",Dover,(England/Wales) Rural village,E10000016,626361.0,152647.0,Dover 006,Dover 006A,Ofsted,,5.0,Church Communities UK,Good,South-East England and South London,,100060912465.0,,Not applicable,Not applicable,,,E02005046,E01024190,0.0,
131411,886,Kent,6075,The Worthgate School,Other independent school,Independent schools,Open,Not applicable,06-11-1997,Not applicable,,Not applicable,13.0,22,Boarding school,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Selective,500.0,Not applicable,20-01-2022,304.0,136.0,168.0,0.0,Not applicable,,Not applicable,,Not applicable,,10008526.0,,Not applicable,,13-05-2024,68 New Dover Road,,,Canterbury,Kent,CT1 3LQ,www.worthgateschool.com,1227866540.0,Dr,Ian,Gross,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Canterbury,Barton,Canterbury,(England/Wales) Urban city and town,E10000016,615887.0,156832.0,Canterbury 016,Canterbury 016C,ISI,,14.0,CEG Colleges Limited,,South-East England and South London,,100062280087.0,,Not applicable,Not applicable,,,E02005025,E01024046,0.0,
131567,886,Kent,6113,St Helens Montessori School,Other independent school,Independent schools,Open,New Provision,13-04-2006,Not applicable,,Not applicable,2.0,12,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Christian,Not applicable,Not applicable,130.0,Not applicable,20-01-2022,45.0,19.0,26.0,0.0,Not applicable,,Not applicable,,Not applicable,,10071874.0,,Not applicable,08-07-2021,15-04-2024,Lower Road,East Farleigh,,Maidstone,Kent,ME15 0JT,www.sthelensmontessori.co.uk,1622721731.0,Miss,Jeannelle,Dening Smitherman,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Maidstone,Coxheath and Hunton,Maidstone and The Weald,(England/Wales) Rural village,E10000016,572488.0,153442.0,Maidstone 014,Maidstone 014B,Ofsted,,1.0,Marie-Elise Jeannelle Dening-Smitherman,Good,South-East England and South London,,200003673434.0,,Not applicable,Not applicable,,,E02005081,E01024346,0.0,
132764,886,Kent,2689,The Craylands School,Community school,Local authority maintained schools,Open,New Provision,01-09-2003,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,417.0,224.0,193.0,23.7,Not applicable,,Not applicable,,Not under a federation,,10074200.0,,Not applicable,25-09-2019,01-05-2024,Craylands Lane,,,Swanscombe,Kent,DA10 0LP,http://www.craylands.kent.sch.uk,1322388230.0,Mr,Kris,Hiscock,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Swanscombe,Dartford,(England/Wales) Urban major conurbation,E10000016,560051.0,174464.0,Dartford 004,Dartford 004D,,,,,Good,South-East England and South London,,10002021725.0,,Not applicable,Not applicable,,,E02005031,E01024178,99.0,
133177,886,Kent,3904,Castle Hill Community Primary School,Community school,Local authority maintained schools,Open,Fresh Start,01-01-2007,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,406.0,Has Special Classes,19-01-2023,406.0,220.0,186.0,54.8,Not applicable,,Not applicable,,Not under a federation,,10076676.0,,Not applicable,13-10-2021,21-05-2024,Sidney Street,,,Folkestone,Kent,CT19 6HG,www.castlehill.kent.sch.uk/,1303251583.0,Mr,Peter,Talbot,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,HI - Hearing Impairment,,,,,,,,,,,,,Resourced provision,15.0,12.0,,,South East,Folkestone and Hythe,East Folkestone,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,623192.0,137077.0,Folkestone and Hythe 004,Folkestone and Hythe 004A,,,,,Requires improvement,South-East England and South London,,50049270.0,,Not applicable,Not applicable,,,E02005105,E01024499,194.0,
133627,886,Kent,3299,The John Wesley Church of England Methodist Voluntary Aided Primary School,Voluntary aided school,Local authority maintained schools,Open,New Provision,01-09-2007,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England/Methodist,Does not apply,Diocese of Canterbury,Not applicable,420.0,Not applicable,19-01-2023,462.0,231.0,231.0,20.1,Not applicable,,Not applicable,,Not under a federation,,10069422.0,,Not applicable,11-11-2021,18-03-2024,Wesley School Road,Cuckoo Lane,Singleton,Ashford,Kent,TN23 5LW,www.john-wesley.org.uk,1233614660.0,Miss,Rachael,Harrington,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,10.0,14.0,,,South East,Ashford,Washford,Ashford,(England/Wales) Urban city and town,E10000016,598815.0,141017.0,Ashford 007,Ashford 007E,,,,,Good,South-East England and South London,,10012841657.0,,Not applicable,Not applicable,,,E02005002,E01024017,93.0,
133961,886,Kent,3893,Phoenix Community Primary School,Foundation school,Local authority maintained schools,Open,Result of Amalgamation,01-04-2003,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,213.0,95.0,118.0,43.7,Supported by a trust,CARE Foundation Trust,Not applicable,,Not under a federation,,10074158.0,,Not applicable,29-06-2022,12-03-2024,Belmont Road,Kennington,,Ashford,Kent,TN24 9LS,www.phoenix-primary.kent.sch.uk/,1233622510.0,Mr,Leon,Robichaud,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Bybrook,Ashford,(England/Wales) Urban city and town,E10000016,601583.0,144521.0,Ashford 015,Ashford 015C,,,,,Good,South-East England and South London,,100062561305.0,,Not applicable,Not applicable,,,E02007046,E01023984,93.0,
134057,886,Kent,2065,The Discovery School,Community school,Local authority maintained schools,Open,New Provision,01-09-2003,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,Not applicable,19-01-2023,625.0,317.0,308.0,7.5,Not applicable,,Not applicable,,Not under a federation,,10074152.0,,Not applicable,22-02-2023,22-05-2024,Discovery Drive,Kings Hill,,West Malling,Kent,ME19 4GJ,www.discovery.kent.sch.uk,1732847000.0,Miss,Tina,Gobell,Interim Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Kings Hill,Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,568757.0,155312.0,Tonbridge and Malling 007,Tonbridge and Malling 007G,,,,,Outstanding,South-East England and South London,,10002911481.0,,Not applicable,Not applicable,,,E02005155,E01032827,47.0,
134452,886,Kent,6104,OneSchool Global UK - Maidstone Campus,Other independent school,Independent schools,Open,New Provision,29-08-2003,Not applicable,,Not applicable,7.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Plymouth Brethren Christian Church,Christian,Not applicable,Not applicable,225.0,Not applicable,20-01-2022,163.0,81.0,82.0,0.0,Not applicable,,Not applicable,,Not applicable,,10018081.0,,Not applicable,,06-06-2024,Heath Road,Linton,,Maidstone,Kent,ME17 4HT,https://www.oneschoolglobal.com/campus/united-kingdom/maidstone/,3000700507.0,Mrs,Keryn,Van Der Westhuizen,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Maidstone,Coxheath and Hunton,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,575491.0,154914.0,Maidstone 018,Maidstone 018A,ISI,2.0,10.0,OneSchool Global UK,,South-East England and South London,,10014308592.0,,Not applicable,Not applicable,,,E02005085,E01024345,0.0,
134515,886,Kent,3896,Downsview Community Primary School,Community school,Local authority maintained schools,Open,Result of Amalgamation,01-01-2004,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,174.0,97.0,77.0,39.7,Not applicable,,Not applicable,,Not under a federation,,10074133.0,,Not applicable,26-04-2023,13-09-2023,Beech Avenue,,,Swanley,Kent,BR8 8AU,www.downsview-primary.kent.sch.uk/,1322662594.0,Mr,Richard,Moore,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Swanley Christchurch and Swanley Village,Sevenoaks,(England/Wales) Urban major conurbation,E10000016,552107.0,168558.0,Sevenoaks 003,Sevenoaks 003B,,,,,Requires improvement,South-East England and South London,,100062276972.0,,Not applicable,Not applicable,,,E02005089,E01024473,69.0,
134582,886,Kent,6097,Kent College International Study Centre,Other independent school,Independent schools,Open,New Provision,20-08-2003,Not applicable,,Not applicable,11.0,18,Boarding school,No Nursery Classes,Has a sixth form,Mixed,None,Methodist,Not applicable,Not applicable,100.0,Not applicable,20-01-2022,18.0,14.0,4.0,0.0,Not applicable,,Not applicable,,Not applicable,,10016222.0,,Not applicable,,23-04-2024,Whitstable Road,,,Canterbury,Kent,CT2 9DT,,1227763231.0,Mr,Mark,Turnbull,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Canterbury,Blean Forest,Canterbury,(England/Wales) Urban city and town,E10000016,613117.0,159367.0,Canterbury 012,Canterbury 012D,ISI,,,Methodist Secondary Trustees,,South-East England and South London,,100062293085.0,,Not applicable,Not applicable,,,E02005021,E01024068,0.0,
134857,886,Kent,3898,Greenfields Community Primary School,Community school,Local authority maintained schools,Open,Result of Amalgamation,11-04-2005,Not applicable,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,367.0,Not applicable,19-01-2023,420.0,241.0,179.0,40.3,Not applicable,,Not applicable,,Not under a federation,,10071741.0,,Not applicable,15-05-2019,11-04-2024,Oxford Road,Shepway,,Maidstone,Kent,ME15 8DF,http://www.greenfieldscps.kent.sch.uk,1622758538.0,Mr,Daniel,Andrews,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Shepway North,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,578070.0,153905.0,Maidstone 010,Maidstone 010D,,,,,Good,South-East England and South London,,200003717312.0,,Not applicable,Not applicable,,,E02005077,E01024395,143.0,
135106,886,Kent,3906,Palace Wood Primary School,Community school,Local authority maintained schools,Open,Result of Amalgamation,01-01-2007,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,417.0,225.0,192.0,16.5,Not applicable,,Not applicable,,Not under a federation,,10072360.0,,Not applicable,15-09-2022,13-09-2023,Ash Grove,Allington,,Maidstone,Kent,ME16 0AB,www.palacewoodprimary.org.uk/,1622750084.0,Mrs,Clare,Cairns,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Maidstone,Allington,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,574102.0,156747.0,Maidstone 003,Maidstone 003D,,,,,Good,South-East England and South London,,200003659713.0,,Not applicable,Not applicable,,,E02005070,E01024323,69.0,
135118,886,Kent,3907,Hextable Primary School,Community school,Local authority maintained schools,Open,Result of Amalgamation,01-09-2007,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,Not applicable,19-01-2023,609.0,320.0,289.0,17.9,Not applicable,,Not applicable,,Not under a federation,,10072357.0,,Not applicable,27-09-2023,04-06-2024,Rowhill Road,Hextable,,Swanley,Kent,BR8 7RL,www.hextable-primary.kent.sch.uk/,1322663792.0,Mrs,Suzie,Hall,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Hextable,Sevenoaks,(England/Wales) Urban major conurbation,E10000016,551783.0,170689.0,Sevenoaks 001,Sevenoaks 001A,,,,,Good,South-East England and South London,,10013768802.0,,Not applicable,Not applicable,,,E02005087,E01024445,109.0,
135125,886,Kent,3909,Ashford Oaks Community Primary School,Community school,Local authority maintained schools,Open,Result of Amalgamation,01-09-2008,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,460.0,238.0,222.0,51.0,Not applicable,,Not applicable,,Not under a federation,,10071720.0,,Not applicable,29-03-2023,15-04-2024,Oak Tree Road,,,Ashford,Kent,TN23 4QR,http://www.ashfordoaks.kent.sch.uk/,1223631259.0,Mr,Phil,Chantler,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",ASD - Autistic Spectrum Disorder,"SEMH - Social, Emotional and Mental Health",MLD - Moderate Learning Difficulty,,,,,,,,,,Resourced provision,13.0,8.0,,,South East,Ashford,Beaver,Ashford,(England/Wales) Urban city and town,E10000016,599912.0,141837.0,Ashford 007,Ashford 007B,,,,,Good,South-East England and South London,,100062559273.0,,Not applicable,Not applicable,,,E02005002,E01023975,221.0,
135130,886,Kent,3910,Joy Lane Primary Foundation School,Foundation school,Local authority maintained schools,Open,Result of Amalgamation,01-09-2007,Not applicable,,Primary,1.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,Has Special Classes,19-01-2023,619.0,327.0,292.0,24.7,Supported by a trust,The Coastal Alliance Co-operative Trust,Not applicable,,Not under a federation,,10076634.0,,Not applicable,19-10-2018,02-04-2024,Joy Lane,,,Whitstable,Kent,CT5 4LT,www.joylane.kent.sch.uk/,1227261430.0,Ms,Debra,Hines,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,34.0,30.0,,,South East,Canterbury,Seasalter,Canterbury,(England/Wales) Urban city and town,E10000016,610128.0,165477.0,Canterbury 008,Canterbury 008E,,,,,Good,South-East England and South London,,200002882935.0,,Not applicable,Not applicable,,,E02005017,E01024106,153.0,
135164,886,Kent,3913,Rusthall St Paul's CofE VA Primary School,Voluntary aided school,Local authority maintained schools,"Open, but proposed to close",Result of Amalgamation,01-09-2007,Academy Converter,31-08-2024,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,150.0,No Special Classes,19-01-2023,138.0,79.0,59.0,31.9,Not applicable,,Not applicable,,Not under a federation,,10072353.0,,Not applicable,20-04-2023,13-05-2024,High Street,Rusthall,,Tunbridge Wells,Kent,TN4 8RZ,www.rusthall-cep.kent.sch.uk,1892520582.0,Mrs,Lyndsay,Smurthwaite,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Rusthall,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,555920.0,139686.0,Tunbridge Wells 010,Tunbridge Wells 010C,,,,,Requires improvement,South-East England and South London,,10008659425.0,,Not applicable,Not applicable,,,E02005171,E01024830,44.0,
135197,886,Kent,3916,Green Park Community Primary School,Community school,Local authority maintained schools,Open,Result of Amalgamation,01-08-2007,Not applicable,,Primary,4.0,11,Not applicable,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,390.0,206.0,184.0,45.6,Not applicable,,Not applicable,,Not under a federation,,10076633.0,,Not applicable,25-05-2023,17-04-2024,The Linces,Buckland,Green Park Community Primary School,Dover,Kent,CT16 2BN,www.greenparkcps.co.uk/,1304822663.0,Mr,Richard,Hawkins,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,PD - Physical Disability,,,,,,,,,,,,,Resourced provision,,,,,South East,Dover,Buckland,Dover,(England/Wales) Urban city and town,E10000016,630734.0,143609.0,Dover 011,Dover 011D,,,,,Outstanding,South-East England and South London,,100062289415.0,,Not applicable,Not applicable,,,E02005051,E01024196,178.0,
135212,886,Kent,3917,Garlinge Primary School and Nursery,Foundation school,Local authority maintained schools,Open,Result of Amalgamation,01-09-2007,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,840.0,No Special Classes,19-01-2023,769.0,406.0,363.0,41.6,Supported by a trust,Thanet Endeavour Learning Trust,Not applicable,,Not under a federation,,10076631.0,,Not applicable,29-11-2023,08-05-2024,Westfield Road,,,Margate,Kent,CT9 5PA,www.garlingeprimary.co.uk,1843221877.0,Mr,James,Williams,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,PD - Physical Disability,,,,,,,,,,,,Resourced provision,22.0,23.0,,,South East,Thanet,Garlinge,North Thanet,(England/Wales) Urban city and town,E10000016,633980.0,169704.0,Thanet 005,Thanet 005C,,,,,Good,South-East England and South London,,100062307988.0,,Not applicable,Not applicable,,,E02005136,E01024674,310.0,
135214,886,Kent,3918,Newington Community Primary School,Community school,Local authority maintained schools,"Open, but proposed to close",Result of Amalgamation,01-09-2007,Academy Converter,30-06-2024,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,694.0,No Special Classes,19-01-2023,703.0,370.0,333.0,43.3,Not applicable,,Not applicable,,Not under a federation,,10071712.0,,Not applicable,16-03-2017,16-05-2024,Princess Margaret Avenue,,,Ramsgate,Kent,CT12 6HX,www.newington-ramsgate.org.uk/,1843593412.0,Headteacher,Hannah,Tudor,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Newington,South Thanet,(England/Wales) Urban city and town,E10000016,636335.0,165855.0,Thanet 013,Thanet 013A,,,,,Outstanding,South-East England and South London,United Kingdom,100062284319.0,,Not applicable,Not applicable,,,E02005144,E01024682,290.0,
135290,886,Kent,6909,The Marsh Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2007,Not applicable,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1110.0,No Special Classes,19-01-2023,1064.0,533.0,531.0,30.0,Supported by a multi-academy trust,SKINNERS' ACADEMIES TRUST,Linked to a sponsor,The Skinners' Company,Not applicable,,10021032.0,,Not applicable,16-11-2022,30-05-2024,Station Road,,,New Romney,Kent,TN28 8BB,www.marshacademy.org.uk,1797364593.0,Mr,Shaun,Simmons,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,20.0,24.0,,,South East,Folkestone and Hythe,New Romney,Folkestone and Hythe,(England/Wales) Rural town and fringe,E10000016,607023.0,124940.0,Folkestone and Hythe 012,Folkestone and Hythe 012C,,,,,Good,South-East England and South London,,50002925.0,,Not applicable,Not applicable,,,E02005113,E01024539,270.0,
135297,886,Kent,6910,The Leigh Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2007,Not applicable,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1500.0,No Special Classes,19-01-2023,1359.0,768.0,591.0,23.6,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10021033.0,,Not applicable,26-04-2023,30-04-2024,Green Street Green Road,,,Dartford,Kent,DA1 1QE,http://www.leighacademy.org.uk/,1322620400.0,Mrs,Julia,Collins,Academy Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,HI - Hearing Impairment,"SLCN - Speech, language and Communication",,,,,,,,,,,,Resourced provision,16.0,16.0,,,South East,Dartford,Brent,Dartford,(England/Wales) Urban major conurbation,E10000016,555487.0,173173.0,Dartford 008,Dartford 008B,,,,,Good,South-East England and South London,,100062308614.0,,Not applicable,Not applicable,,,E02005035,E01024136,272.0,
135305,886,Kent,6911,Spires Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2007,Not applicable,,Secondary,11.0,16,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,750.0,No Special Classes,19-01-2023,690.0,324.0,366.0,37.4,Supported by a multi-academy trust,EDUCATION FOR THE 21ST CENTURY,Linked to a sponsor,Education for the 21st Century,Not applicable,,10021093.0,,Not applicable,11-01-2023,26-09-2023,Bredlands Lane,Sturry,,Canterbury,Kent,CT2 0HD,http://www.spiresacademy.com/,1227710392.0,Mrs,Anna,Burden,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Sturry,Canterbury,(England/Wales) Rural hamlet and isolated dwellings,E10000016,619494.0,161797.0,Canterbury 011,Canterbury 011B,,,,,Good,South-East England and South London,,10090317463.0,,Not applicable,Not applicable,,,E02005020,E01024110,258.0,
135371,886,Kent,6913,Cornwallis Academy,Academy sponsor led,Academies,Open,New Provision,03-09-2007,Not applicable,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1825.0,No Special Classes,19-01-2023,1337.0,761.0,576.0,27.8,Supported by a multi-academy trust,FUTURE SCHOOLS TRUST,Linked to a sponsor,Future Schools Trust,Not applicable,,10021031.0,,Not applicable,12-01-2023,22-04-2024,Hubbards Lane,Linton,,Maidstone,Kent,ME17 4HX,http://www.futureschoolstrust.com/,1622743152.0,Mrs,Samantha,McMahon,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Loose,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,575978.0,150975.0,Maidstone 016,Maidstone 016D,,,,,Good,South-East England and South London,,200003720219.0,,Not applicable,Not applicable,,,E02005083,E01024376,277.0,
135372,886,Kent,6912,New Line Learning Academy,Academy sponsor led,Academies,Open,New Provision,03-09-2007,Not applicable,,Secondary,11.0,16,No boarders,Not applicable,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1050.0,No Special Classes,19-01-2023,719.0,372.0,347.0,43.7,Supported by a multi-academy trust,FUTURE SCHOOLS TRUST,Linked to a sponsor,Future Schools Trust,Not applicable,,10021098.0,,Not applicable,13-11-2019,21-05-2024,Boughton Lane,,,Maidstone,Kent,ME15 9QL,https://www.newlinelearning.com/,1622743286.0,Ms,Sharry,Mackie,Interim Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,VI - Visual Impairment,PD - Physical Disability,,,,,,,,,,,,Resourced provision,6.0,12.0,,,South East,Maidstone,South,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,576813.0,153053.0,Maidstone 012,Maidstone 012D,,,,,Good,South-East England and South London,,200003677498.0,,Not applicable,Not applicable,,,E02005079,E01024404,313.0,
135432,886,Kent,1123,The Rosewood School,Pupil referral unit,Local authority maintained schools,Open,New Provision,01-11-2007,Not applicable,,Not applicable,11.0,18,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,120.0,Has Special Classes,19-01-2023,0.0,0.0,0.0,0.0,Not applicable,,Not applicable,,Not applicable,,10025535.0,,Not applicable,23-06-2022,17-11-2023,40 Teddington Drive,Leybourne,,West Malling,Kent,ME19 5FF,http://www.trs.kent.sch.uk/,1732875694.0,Mrs,Tina,Hamer,Executive Headteacher,Not applicable,,,,Provides places for Teen Mothers,,Does not have child care facilities,PRU Does have Provision for SEN,PRU Does not have EBD provision,120.0,PRU offers full time provision,Does not offer tuition by another provider,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,"Birling, Leybourne & Ryarsh",Tonbridge and Malling,(England/Wales) Rural hamlet and isolated dwellings,E10000016,567730.0,159105.0,Tonbridge and Malling 014,Tonbridge and Malling 014G,,,,,Good,South-East England and South London,,100062387483.0,,Not applicable,Not applicable,,,E02006833,E01035010,0.0,
135462,886,Kent,1124,Birchwood,Pupil referral unit,Local authority maintained schools,Open,,01-01-2008,Not applicable,,Not applicable,14.0,16,Not applicable,Not applicable,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,44.0,Has Special Classes,19-01-2023,0.0,0.0,0.0,0.0,Not applicable,,Not applicable,,Not applicable,,10025590.0,,Not applicable,06-02-2019,07-05-2024,Bowen Road,,,Folkestone,Kent,CT19 4FP,www.birchwoodpru.kent.sch.uk,3000658450.0,Ms,Jane,Waters,Headteacher,Not applicable,,,,Does not provide places for Teen Mothers,,Does not have child care facilities,PRU Does have Provision for SEN,PRU Does have EBD provision,92.0,PRU offers full time provision,Does not offer tuition by another provider,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Cheriton,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,620521.0,137026.0,Folkestone and Hythe 006,Folkestone and Hythe 006B,,,,,Good,South-East England and South London,United Kingdom,50125207.0,,Not applicable,Not applicable,,,E02005107,E01024512,0.0,
135465,886,Kent,1127,Maidstone and Malling Alternative Provision,Pupil referral unit,Local authority maintained schools,Open,,01-01-2008,Not applicable,,Not applicable,12.0,17,Not applicable,Not applicable,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,52.0,Not applicable,19-01-2023,0.0,0.0,0.0,0.0,Not applicable,,Not applicable,,Not applicable,,10025522.0,,Not applicable,06-11-2019,05-06-2024,8 Bower Mount Road,,,Maidstone,Kent,ME16 8AU,www.m-map.co.uk,1622753772.0,Mrs,Stacie,Smith,Headteacher,Not applicable,,,,Does not provide places for Teen Mothers,,Does not have child care facilities,PRU Does have Provision for SEN,PRU Does have EBD provision,52.0,PRU offers full time provision,PRU does offer tuition by another provider,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Bridge,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,574902.0,155729.0,Maidstone 006,Maidstone 006B,,,,,Good,South-East England and South London,,200003728228.0,,Not applicable,Not applicable,,,E02005073,E01024340,0.0,
135466,886,Kent,1128,Enterprise Learning Alliance,Pupil referral unit,Local authority maintained schools,Open,,01-01-2008,Not applicable,,Not applicable,11.0,16,Not applicable,Not applicable,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,140.0,Not applicable,19-01-2023,0.0,0.0,0.0,0.0,Not applicable,,Not applicable,,Not applicable,,10025536.0,,Not applicable,06-06-2019,10-05-2024,Westwood Centre,Westwood Industrial Estate,Enterprise Road,Margate,Kent,CT9 4JA,www.ela.kent.sch.uk,1843606666.0,Mrs,Micheala,Clay,Executive Head Teacher,Not applicable,,,,Does not provide places for Teen Mothers,,Does not have child care facilities,PRU Does have Provision for SEN,PRU Does have EBD provision,168.0,PRU offers full time provision,Does not offer tuition by another provider,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Salmestone,North Thanet,(England/Wales) Urban city and town,E10000016,636075.0,168581.0,Thanet 004,Thanet 004E,,,,,Good,South-East England and South London,,10013309226.0,,Not applicable,Not applicable,,,E02005135,E01024696,0.0,
135467,886,Kent,1129,Two Bridges School,Pupil referral unit,Local authority maintained schools,Open,,01-01-2008,Not applicable,,Not applicable,11.0,18,Not applicable,Not applicable,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,,Not applicable,19-01-2023,0.0,0.0,0.0,0.0,Not applicable,,Not applicable,,Not applicable,,10025613.0,,Not applicable,28-02-2024,22-05-2024,Charles Street,Southborough,Two Bridges School,Tunbridge Wells,Kent,TN4 0DS,www.twobridgesschool.com,1892518461.0,Mrs,Kate,Middleton,Head Teacher,Not applicable,,,,Does not provide places for Teen Mothers,,Does not have child care facilities,PRU Does have Provision for SEN,PRU Does have EBD provision,94.0,PRU offers full time provision,PRU does offer tuition by another provider,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Southborough and High Brooms,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558073.0,141848.0,Tunbridge Wells 002,Tunbridge Wells 002C,,,,,Special Measures,South-East England and South London,,100062585348.0,,Not applicable,Not applicable,,,E02005163,E01024846,0.0,
135630,886,Kent,6914,Longfield Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2008,Not applicable,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1150.0,No Special Classes,19-01-2023,1035.0,533.0,502.0,25.1,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10024300.0,,Not applicable,27-09-2023,08-05-2024,Main Road,,,Longfield,Kent,DA3 7PH,http://www.longfieldacademy.org,1474700700.0,Dr,Felix,Donkor,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,37.0,40.0,,,South East,Dartford,"Longfield, New Barn & Southfleet",Dartford,(England/Wales) Urban city and town,E10000016,560573.0,168906.0,Dartford 013,Dartford 013B,,,,,Good,South-East England and South London,,200000538016.0,,Not applicable,Not applicable,,,E02005040,E01024158,224.0,
135721,886,Kent,6915,Oasis Academy Isle of Sheppey,Academy sponsor led,Academies,"Open, but proposed to close",New Provision,01-09-2009,Result of Amalgamation/Merger,31-08-2024,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,2450.0,Not applicable,19-01-2023,1486.0,763.0,723.0,49.2,Supported by a multi-academy trust,OASIS COMMUNITY LEARNING,Linked to a sponsor,Oasis Community Learning,Not applicable,,10027535.0,,Not applicable,08-06-2022,28-03-2024,Minster Road,,,Minster-on-Sea,Kent,ME12 3JQ,www.oasisacademyisleofsheppey.org,1795873591.0,Mr,Andrew,Booth,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Queenborough and Halfway,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,593655.0,172623.0,Swale 004,Swale 004A,,,,,Special Measures,South-East England and South London,,200002529794.0,,Not applicable,Not applicable,,,E02005118,E01024595,665.0,
135888,886,Kent,6916,Skinners' Kent Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2009,Not applicable,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1150.0,Not applicable,19-01-2023,1084.0,580.0,504.0,22.8,Supported by a multi-academy trust,SKINNERS' ACADEMIES TRUST,Linked to a sponsor,The Skinners' Company,Not applicable,,10027550.0,,Not applicable,11-05-2023,21-05-2024,Sandown Park,,,Tunbridge Wells,Kent,TN2 4PY,https://www.skinnerskentacademy.org.uk/,1892534377.0,Miss,Hannah,Knowles,Executive Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Sherwood,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,560482.0,140402.0,Tunbridge Wells 005,Tunbridge Wells 005C,,,,,Good,South-East England and South London,,10008671585.0,,Not applicable,Not applicable,,,E02005166,E01024842,215.0,
136128,886,Kent,6905,Knole Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2010,Not applicable,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1550.0,No Special Classes,19-01-2023,1373.0,671.0,702.0,17.9,Supported by a single-academy trust,KNOLE ACADEMY TRUST,Linked to a sponsor,Gordon Phillips (Knole academy),Not applicable,,10030458.0,,Not applicable,23-11-2022,10-05-2024,Knole Academy,Bradbourne Vale Road,,Sevenoaks,Kent,TN13 3LE,www.knoleacademy.org,1732454608.0,Mr,David,Collins,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Sevenoaks Northern,Sevenoaks,(England/Wales) Urban city and town,E10000016,552379.0,156485.0,Sevenoaks 011,Sevenoaks 011F,,,,,Good,South-East England and South London,,100062548177.0,,Not applicable,Not applicable,,,E02005097,E01024467,217.0,
136177,886,Kent,6918,Duke of York's Royal Military School,Academy sponsor led,Academies,Open,New Provision,01-09-2010,Not applicable,,Secondary,11.0,18,Boarding school,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,722.0,No Special Classes,19-01-2023,501.0,299.0,202.0,1.3,Supported by a single-academy trust,DYRMS - AN ACADEMY WITH MILITARY TRADITIONS,Linked to a sponsor,Ministry of Defence,Not applicable,,10030792.0,,Not applicable,09-02-2023,30-05-2024,Duke of York's Royal Military School,,,Dover,Kent,CT15 5EQ,www.doyrms.com,1304245023.0,Mr,Alex,Foreman,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,"Guston, Kingsdown & St Margaret's-at-Cliffe",Dover,(England/Wales) Rural village,E10000016,632730.0,143466.0,Dover 012,Dover 012B,,,,,Good,South-East England and South London,,10034881145.0,,Not applicable,Not applicable,,,E02005052,E01024238,5.0,
136197,886,Kent,6919,The John Wallis Church of England Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2010,Not applicable,,All-through,3.0,19,No boarders,Has Nursery Classes,Has a sixth form,Mixed,Church of England,None,Diocese of Canterbury,Non-selective,1790.0,No Special Classes,19-01-2023,1763.0,889.0,874.0,37.8,Supported by a single-academy trust,"THE JOHN WALLIS CHURCH OF ENGLAND ACADEMY, ASHFORD",Linked to a sponsor,The Diocese of Canterbury Academies Company Limited,Not applicable,,10030997.0,,Not applicable,01-02-2024,20-05-2024,Millbank Road,Kingsnorth,,Ashford,Kent,TN23 3HG,http://www.thejohnwallisacademy.org,1233623465.0,Mr,Damian,McBeath,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Stanhope,Ashford,(England/Wales) Urban city and town,E10000016,599919.0,140348.0,Ashford 008,Ashford 008B,,,,,Good,South-East England and South London,,100062558283.0,,Not applicable,Not applicable,,,E02005003,E01024019,619.0,
136205,886,Kent,6920,Wilmington Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2010,Not applicable,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1400.0,No Special Classes,19-01-2023,1388.0,867.0,521.0,17.8,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10031094.0,,Not applicable,05-05-2023,22-04-2024,Common Lane,,,Wilmington,Kent,DA2 7DR,www.wilmingtonacademy.org.uk,1322272111.0,Mr,Michael,Gore,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,17.0,17.0,,,South East,Dartford,Maypole & Leyton Cross,Dartford,(England/Wales) Urban major conurbation,E10000016,552526.0,172176.0,Dartford 011,Dartford 011D,,,,,Outstanding,South-East England and South London,,200000534711.0,,Not applicable,Not applicable,,,E02005038,E01024189,213.0,
136251,886,Kent,3920,Goat Lees Primary School,Foundation school,Local authority maintained schools,Open,New Provision,01-09-2013,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,,Not applicable,210.0,No Special Classes,19-01-2023,212.0,112.0,100.0,41.5,Not supported by a trust,,Not applicable,,Not under a federation,,10072306.0,,Not applicable,22-01-2020,05-06-2024,Hurst Road,Kennington,,Ashford,Kent,TN24 9RR,www.goatlees.kent.sch.uk/,1233630201.0,Ms,Teresa,Adams,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Goat Lees,Ashford,(England/Wales) Urban city and town,E10000016,600985.0,145239.0,Ashford 001,Ashford 001F,,,,,Good,South-East England and South London,,200004392081.0,,Not applicable,Not applicable,,,E02004996,E01032810,88.0,
136270,886,Kent,3912,Westlands Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2010,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,540.0,No Special Classes,19-01-2023,578.0,303.0,275.0,32.4,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10031923.0,,Not applicable,26-06-2019,16-05-2024,Homewood Avenue,,,Sittingbourne,Kent,ME10 1XN,www.westlandsprimary.org.uk/,1795470862.0,Mrs,Victoria,Pettett,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Homewood,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,589625.0,163383.0,Swale 012,Swale 012E,,,,,Good,South-East England and South London,,200002527704.0,,Not applicable,Not applicable,,,E02005126,E01024632,187.0,
136286,886,Kent,5434,Westlands School,Academy converter,Academies,Open,Academy Converter,01-09-2010,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1604.0,Has Special Classes,19-01-2023,1784.0,935.0,849.0,22.3,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10031371.0,,Not applicable,27-02-2019,13-05-2024,Westlands Avenue,,,Sittingbourne,Kent,ME10 1PF,http://www.westlands.org.uk/,1795477475.0,Miss,Christina,Honess,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,SpLD - Specific Learning Difficulty,PD - Physical Disability,,,,,,,,,,,,Resourced provision and SEN unit,10.0,10.0,28.0,32.0,South East,Swale,Borden and Grove Park,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,588904.0,163864.0,Swale 012,Swale 012C,,,,,Good,South-East England and South London,,100062375039.0,,Not applicable,Not applicable,,,E02005126,E01024569,356.0,
136302,886,Kent,5421,The Canterbury Academy,Academy converter,Academies,Open,Academy Converter,07-10-2010,,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1300.0,Has Special Classes,19-01-2023,1844.0,949.0,895.0,27.6,Supported by a multi-academy trust,THE CANTERBURY ACADEMY TRUST,-,,Not applicable,,10031579.0,,Not applicable,22-02-2023,18-04-2024,Knight Avenue,,,Canterbury,Kent,CT2 8QA,http://www.canterbury.kent.sch.uk/,1227463971.0,Mr,Jon,Watson,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,HI - Hearing Impairment,"SLCN - Speech, language and Communication",ASD - Autistic Spectrum Disorder,,,,,,,,,,,Resourced provision,47.0,47.0,,,South East,Canterbury,Westgate,Canterbury,(England/Wales) Urban city and town,E10000016,613730.0,157724.0,Canterbury 020,Canterbury 020C,,,,,Requires improvement,South-East England and South London,,100062292855.0,,Not applicable,Not applicable,,,E02006856,E01024122,311.0,
136304,886,Kent,4031,Orchards Academy,Academy converter,Academies,Open,Academy Converter,01-11-2010,,,Secondary,11.0,18,No boarders,Not applicable,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,828.0,No Special Classes,19-01-2023,585.0,280.0,305.0,39.8,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10032208.0,,Not applicable,02-07-2021,30-04-2024,St Mary's Road,,,Swanley,Kent,BR8 7TE,http://www.orchards-tkat.org,1322665231.0,Mr,Andy,Lazenby,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,6.0,12.0,,,South East,Sevenoaks,Swanley St Mary's,Sevenoaks,(England/Wales) Urban major conurbation,E10000016,551053.0,168589.0,Sevenoaks 002,Sevenoaks 002A,,,,,Good,South-East England and South London,,200002881968.0,,Not applicable,Not applicable,,,E02005088,E01024476,233.0,
136305,886,Kent,4080,Highsted Grammar School,Academy converter,Academies,Open,Academy Converter,01-10-2010,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,830.0,No Special Classes,19-01-2023,889.0,7.0,882.0,8.1,Supported by a single-academy trust,HIGHSTED ACADEMY TRUST,-,,Not applicable,,10031571.0,,Not applicable,18-01-2023,07-06-2024,Highsted Road,,,Sittingbourne,Kent,ME10 4PT,http://www.highsted.kent.sch.uk,1795424223.0,Ms,Anne,Kelly,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Woodstock,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,590779.0,162957.0,Swale 013,Swale 013A,,,,,Good,South-East England and South London,,100062376278.0,,Not applicable,Not applicable,,,E02005127,E01024606,58.0,
136317,886,Kent,5463,Sandwich Technology School,Academy converter,Academies,Open,Academy Converter,01-11-2010,,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1368.0,No Special Classes,19-01-2023,1353.0,684.0,669.0,29.2,Supported by a single-academy trust,SANDWICH TECHNOLOGY SCHOOL,-,,Not applicable,,10032210.0,,Not applicable,02-05-2019,16-04-2024,Deal Road,,,Sandwich,Kent,CT13 0FA,http://www.sandwich-tech.kent.sch.uk,1304610000.0,Mrs,Tracey,Savage,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Sandwich,South Thanet,(England/Wales) Rural town and fringe,E10000016,632791.0,157060.0,Dover 002,Dover 002B,,,,,Good,South-East England and South London,,10034879953.0,,Not applicable,Not applicable,,,E02005042,E01024242,354.0,
136324,886,Kent,5414,Fulston Manor School,Academy converter,Academies,Open,Academy Converter,01-10-2010,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1104.0,No Special Classes,19-01-2023,1340.0,661.0,679.0,20.9,Supported by a multi-academy trust,FULSTON MANOR ACADEMIES TRUST,Linked to a sponsor,Fulston Manor Academies Trust,Not applicable,,10031570.0,,Not applicable,15-11-2023,05-06-2024,Brenchley Road,,,Sittingbourne,Kent,ME10 4EG,http://www.fulstonmanor.kent.sch.uk,1795475228.0,Mrs,Susie,Burden,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Woodstock,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,590750.0,162857.0,Swale 013,Swale 013G,,,,,Requires improvement,South-East England and South London,,100062376597.0,,Not applicable,Not applicable,,,E02005127,E01032737,222.0,
136344,886,Kent,2654,The Canterbury Primary School,Academy converter,Academies,Open,Academy Converter,07-10-2010,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,None,Does not apply,Not applicable,Not applicable,435.0,Has Special Classes,19-01-2023,408.0,209.0,199.0,41.9,Supported by a multi-academy trust,THE CANTERBURY ACADEMY TRUST,-,,Not applicable,,10031917.0,,Not applicable,08-12-2022,09-04-2024,City View,Franklyn Road,,Canterbury,Kent,CT2 8PT,www.canterbury.kent.sch.uk/,1227462883.0,Mrs,Bev,Farrell,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,17.0,15.0,,,South East,Canterbury,Westgate,Canterbury,(England/Wales) Urban city and town,E10000016,613518.0,157596.0,Canterbury 020,Canterbury 020E,,,,,Good,South-East England and South London,,100062293053.0,,Not applicable,Not applicable,,,E02006856,E01024126,171.0,
136349,886,Kent,5455,Leigh Academy Tonbridge,Academy converter,Academies,Open,Academy Converter,01-12-2010,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Boys,None,Does not apply,Not applicable,Non-selective,1020.0,No Special Classes,19-01-2023,477.0,476.0,1.0,25.7,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10031580.0,,Not applicable,07-12-2022,29-04-2024,Brook Street,,,Tonbridge,Kent,TN9 2PH,http://leighacademytonbridge.org.uk,1732500600.0,Mr,Michael,Crow,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Judd,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,558063.0,145659.0,Tonbridge and Malling 013,Tonbridge and Malling 013A,,,,,Good,South-East England and South London,,200000962881.0,,Not applicable,Not applicable,,,E02005161,E01024757,109.0,
136351,886,Kent,2656,Meopham Community Academy,Academy converter,Academies,Open,Academy Converter,01-12-2010,,,Primary,2.0,11,No boarders,Has Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,467.0,240.0,227.0,6.9,Supported by a multi-academy trust,THE GOLDEN THREAD ALLIANCE,-,,Not applicable,,10032229.0,,Not applicable,16-10-2018,18-04-2024,Longfield Road,Meopham,,Gravesend,Kent,DA13 0JW,http://www.meophamca.com,1474812259.0,Mr,Thomas,Waterman,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Gravesham,Meopham North,Gravesham,(England/Wales) Rural town and fringe,E10000016,564320.0,166643.0,Gravesham 012,Gravesham 012D,,,,,Good,South-East England and South London,,100062313197.0,,Not applicable,Not applicable,,,E02005066,E01024271,30.0,
136359,886,Kent,5406,Dartford Grammar School,Academy converter,Academies,Open,Academy Converter,01-12-2010,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,1550.0,No Special Classes,19-01-2023,1516.0,1291.0,225.0,5.9,Supported by a single-academy trust,DARTFORD GRAMMAR SCHOOL,-,,Not applicable,,10032228.0,,Not applicable,07-12-2022,07-05-2024,West Hill,,,Dartford,Kent,DA1 2HW,http://www.dartfordgrammarschool.org.uk,1322223039.0,Mr,Julian,Metcalf,Headmaster,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Dartford,West Hill,Dartford,(England/Wales) Urban major conurbation,E10000016,553364.0,174104.0,Dartford 003,Dartford 003F,,,,,Outstanding,South-East England and South London,,200000540995.0,,Not applicable,Not applicable,,,E02005030,E01024185,54.0,
136379,886,Kent,4092,Highworth Grammar School,Academy converter,Academies,Open,Academy Converter,01-01-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,Does not apply,Does not apply,Not applicable,Selective,1227.0,No Special Classes,19-01-2023,1542.0,100.0,1442.0,6.7,Supported by a single-academy trust,HIGHWORTH GRAMMAR SCHOOL TRUST,-,,Not applicable,,10032347.0,,Not applicable,14-06-2013,21-05-2024,Maidstone Road,,,Ashford,Kent,TN24 8UD,http://www.highworth.kent.sch.uk/,1233624910.0,Mr,Duncan,Beer,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Furley,Ashford,(England/Wales) Urban city and town,E10000016,600386.0,143340.0,Ashford 015,Ashford 015B,,,,,Outstanding,South-East England and South London,,100062560536.0,,Not applicable,Not applicable,,,E02007046,E01023981,73.0,
136382,886,Kent,5462,Chatham & Clarendon Grammar School,Academy converter,Academies,Open,Academy Converter,01-01-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Selective,1600.0,No Special Classes,19-01-2023,1503.0,766.0,737.0,13.4,Supported by a multi-academy trust,CHATHAM & CLARENDON GRAMMAR SCHOOL,-,,Not applicable,,10032384.0,,Not applicable,16-05-2018,14-05-2024,Chatham Street,,,Ramsgate,Kent,CT11 7PS,http://www.ccgrammarschool.co.uk,1843591075.0,Mrs,Debra,Liddicoat,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Eastcliff,South Thanet,(England/Wales) Urban city and town,E10000016,638046.0,165251.0,Thanet 015,Thanet 015D,,,,,Good,South-East England and South London,,100062281955.0,,Not applicable,Not applicable,,,E02005146,E01024670,135.0,
136393,886,Kent,2608,St Stephen's Junior School,Academy converter,Academies,Open,Academy Converter,01-01-2011,,,Primary,7.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,360.0,No Special Classes,19-01-2023,404.0,218.0,186.0,30.0,Supported by a single-academy trust,ST STEPHEN'S ACADEMY CANTERBURY,-,,Not applicable,,10032362.0,,Not applicable,01-03-2023,21-05-2024,Hales Drive,St Stephens,,Canterbury,Kent,CT2 7AD,www.ststephensjuniorschool.co.uk/,1227464119.0,Co Headteacher,Laura Cutts,Sarah Heaney,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,St Stephen's,Canterbury,(England/Wales) Urban city and town,E10000016,614829.0,159308.0,Canterbury 013,Canterbury 013B,,,,,Good,South-East England and South London,,200000677176.0,,Not applicable,Not applicable,,,E02005022,E01024100,121.0,
136417,886,Kent,5443,Tonbridge Grammar School,Academy converter,Academies,Open,Academy Converter,01-01-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1260.0,No Special Classes,19-01-2023,1131.0,29.0,1102.0,1.9,Supported by a single-academy trust,TONBRIDGE GRAMMAR SCHOOL,-,,Not applicable,,10032608.0,,Not applicable,17-10-2019,22-05-2024,Deakin Leas,,,Tonbridge,Kent,TN9 2JR,http://www.tgs.kent.sch.uk,1732365125.0,Mrs,Rebecca,Crean,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Vauxhall,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,559055.0,145279.0,Tonbridge and Malling 013,Tonbridge and Malling 013C,,,,,Outstanding,South-East England and South London,,100062594177.0,,Not applicable,Not applicable,,,E02005161,E01024778,17.0,
136455,886,Kent,4046,Weald of Kent Grammar School,Academy converter,Academies,Open,Academy Converter,01-02-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,2475.0,No Special Classes,19-01-2023,1966.0,81.0,1885.0,3.3,Supported by a single-academy trust,WEALD OF KENT GRAMMAR SCHOOL ACADEMY TRUST,-,,Not applicable,,10032960.0,,Not applicable,27-04-2022,21-05-2024,Tudeley Lane,,,Tonbridge,Kent,TN9 2JP,http://www.wealdgs.org,1732373500.0,Mr,Richard,Booth,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Vauxhall,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,559489.0,145217.0,Tonbridge and Malling 012,Tonbridge and Malling 012E,,,,,Requires improvement,South-East England and South London,,200000962006.0,,Not applicable,Not applicable,,,E02005160,E01024767,50.0,
136465,886,Kent,5448,Herne Bay High School,Academy converter,Academies,Open,Academy Converter,01-03-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1494.0,No Special Classes,19-01-2023,1586.0,826.0,760.0,25.2,Supported by a single-academy trust,HERNE BAY HIGH SCHOOL,-,,Not applicable,,10032981.0,,Not applicable,15-06-2022,08-04-2024,Bullockstone Road,,,Herne Bay,Kent,CT6 7NS,http://www.hernebayhigh.org,1227361221.0,Mr,Jon,Boyes,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Greenhill,North Thanet,(England/Wales) Urban city and town,E10000016,616784.0,167105.0,Canterbury 003,Canterbury 003A,,,,,Good,South-East England and South London,,10033162926.0,,Not applicable,Not applicable,,,E02005012,E01024064,333.0,
136499,886,Kent,2141,Amherst School,Academy converter,Academies,Open,Academy Converter,01-03-2011,,,Primary,7.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,384.0,No Special Classes,19-01-2023,379.0,205.0,174.0,5.0,Supported by a multi-academy trust,AMHERST SCHOOL (ACADEMY) TRUST,-,,Not applicable,,10033038.0,,Not applicable,11-05-2022,23-05-2024,Witches Lane,Riverhead,,Sevenoaks,Kent,TN13 2AX,http://www.amherst.kent.sch.uk,1732452577.0,Mr,Andrew,Reid,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Brasted, Chevening and Sundridge",Sevenoaks,(England/Wales) Urban city and town,E10000016,550933.0,155835.0,Sevenoaks 011,Sevenoaks 011B,,,,,Good,South-East England and South London,,50002017544.0,,Not applicable,Not applicable,,,E02005097,E01024418,19.0,
136501,886,Kent,5428,Sir Roger Manwood's School,Academy converter,Academies,Open,Academy Converter,01-03-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Selective,1070.0,No Special Classes,19-01-2023,979.0,474.0,505.0,9.4,Supported by a single-academy trust,SIR ROGER MANWOOD'S SCHOOL,-,,Not applicable,,10033035.0,,Not applicable,28-09-2022,25-03-2024,Manwood Road,,,Sandwich,Kent,CT13 9JX,http://www.manwoods.co.uk,1304610200.0,Mr,Lee,Hunter,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Sandwich,South Thanet,(England/Wales) Rural town and fringe,E10000016,633436.0,157821.0,Dover 002,Dover 002B,,,,,Good,South-East England and South London,,100062284711.0,,Not applicable,Not applicable,,,E02005042,E01024242,71.0,
136570,886,Kent,5449,Queen Elizabeth's Grammar School,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Selective,1000.0,No Special Classes,19-01-2023,1020.0,503.0,517.0,7.3,Supported by a multi-academy trust,QUEEN ELIZABETH'S GRAMMAR SCHOOL TRUST FAVERSHAM,-,,Not applicable,,10033266.0,,Not applicable,01-03-2023,21-05-2024,Abbey Place,,,Faversham,Kent,ME13 7BQ,http://www.queenelizabeths.kent.sch.uk,1795533132.0,Mr,David,Anderson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Abbey,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,601923.0,161598.0,Swale 015,Swale 015C,,,,,Good,South-East England and South London,,10034900923.0,,Not applicable,Not applicable,,,E02005129,E01024553,56.0,
136571,886,Kent,4172,Hartsdown Academy,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Non-selective,1175.0,Not applicable,19-01-2023,773.0,408.0,365.0,59.9,Supported by a multi-academy trust,COASTAL ACADEMIES TRUST,Linked to a sponsor,Coastal Academies Trust,Not applicable,,10033264.0,,Not applicable,08-12-2021,07-05-2024,George V Avenue,,,Margate,Kent,CT9 5RE,http://hartsdown.org/,1843227957.0,Mr,Matthew,Tate,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Thanet,Garlinge,North Thanet,(England/Wales) Urban city and town,E10000016,634567.0,169921.0,Thanet 005,Thanet 005A,,,,,Good,South-East England and South London,,100062627471.0,,Not applicable,Not applicable,,,E02005136,E01024672,438.0,
136581,886,Kent,4249,Valley Park School,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1157.0,Not applicable,19-01-2023,1655.0,779.0,876.0,15.5,Supported by a multi-academy trust,VALLEY INVICTA ACADEMIES TRUST,Linked to a sponsor,Valley Invicta Academies Trust,Not applicable,,10033421.0,,Not applicable,05-03-2020,12-04-2024,Huntsman Lane,,,Maidstone,Kent,ME14 5DT,http://www.valleypark.viat.org.uk/,1622679421.0,Mr,D,Jones,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Boxley,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,577242.0,155795.0,Maidstone 005,Maidstone 005B,,,,,Good,South-East England and South London,,200003716140.0,,Not applicable,Not applicable,,,E02005072,E01024336,206.0,
136582,886,Kent,4058,Invicta Grammar School,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1319.0,No Special Classes,19-01-2023,1647.0,43.0,1604.0,5.4,Supported by a multi-academy trust,VALLEY INVICTA ACADEMIES TRUST,Linked to a sponsor,Valley Invicta Academies Trust,Not applicable,,10033423.0,,Not applicable,21-09-2012,06-06-2024,Huntsman Lane,,,Maidstone,Kent,ME14 5DS,http://www.invicta.viat.org.uk,1622755856.0,Mrs,Van,Beales (Executive Headteacher),Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,High Street,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,577046.0,155881.0,Maidstone 004,Maidstone 004G,,,,,Outstanding,South-East England and South London,,200003717570.0,,Not applicable,Not applicable,,,E02005071,E01033092,68.0,
136583,886,Kent,4196,Towers School and Sixth Form Centre,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Non-selective,1625.0,No Special Classes,19-01-2023,1460.0,676.0,784.0,24.5,Supported by a single-academy trust,TOWERS SCHOOL ACADEMY TRUST,-,,Not applicable,,10033255.0,,Not applicable,23-01-2019,03-06-2024,Faversham Road,Kennington,,Ashford,Kent,TN24 9AL,www.towers.kent.sch.uk,1233634171.0,Mr,Richard,Billings,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Kennington,Ashford,(England/Wales) Urban city and town,E10000016,601709.0,145611.0,Ashford 003,Ashford 003B,,,,,Good,South-East England and South London,,200004392081.0,,Not applicable,Not applicable,,,E02004998,E01023999,312.0,
136584,886,Kent,4120,King Ethelbert School,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,16,No boarders,Not applicable,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,750.0,No Special Classes,19-01-2023,757.0,379.0,378.0,25.2,Supported by a multi-academy trust,COASTAL ACADEMIES TRUST,Linked to a sponsor,Coastal Academies Trust,Not applicable,,10033425.0,,Not applicable,03-10-2018,28-05-2024,Canterbury Road,,,Birchington,Kent,CT7 9BL,http://www.kingethelbert.com/,1843831999.0,,Tom,Sellen,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Birchington South,North Thanet,(England/Wales) Urban city and town,E10000016,631297.0,169465.0,Thanet 008,Thanet 008C,,,,,Good,South-East England and South London,,100062303868.0,,Not applicable,Not applicable,,,E02005139,E01024638,191.0,
136585,886,Kent,5460,Dane Court Grammar School,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Selective,1154.0,No Special Classes,19-01-2023,1236.0,589.0,647.0,16.2,Supported by a multi-academy trust,COASTAL ACADEMIES TRUST,Linked to a sponsor,Coastal Academies Trust,Not applicable,,10033426.0,,Not applicable,11-05-2022,08-05-2024,Broadstairs Road,,,Broadstairs,Kent,CT10 2RT,http://danecourt.kent.sch.uk/,1843864941.0,Mr,Martin,Jones,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,St Peters,South Thanet,(England/Wales) Urban city and town,E10000016,638084.0,167977.0,Thanet 011,Thanet 011C,,,,,Good,South-East England and South London,,200003079311.0,,Not applicable,Not applicable,,,E02005142,E01024689,142.0,
136603,886,Kent,5464,Bennett Memorial Diocesan School,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Non-selective,1452.0,No Special Classes,19-01-2023,1865.0,954.0,911.0,6.7,Supported by a multi-academy trust,THE TENAX SCHOOLS TRUST,Linked to a sponsor,The Tenax Schools Trust,Not applicable,,10033233.0,,Not applicable,14-12-2023,14-05-2024,Culverden Down,,,Tunbridge Wells,Kent,TN4 9SH,https://www.bennettmemorial.co.uk/,1892521595.0,Dr,Karen,Brookes,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,St John's,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,557344.0,140560.0,Tunbridge Wells 007,Tunbridge Wells 007D,,,,,Outstanding,South-East England and South London,,100062585960.0,,Not applicable,Not applicable,,,E02005168,E01024838,98.0,
136727,886,Kent,5422,Oakwood Park Grammar School,Academy converter,Academies,Open,Academy Converter,01-05-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,1035.0,No Special Classes,19-01-2023,1096.0,1047.0,49.0,5.6,Supported by a multi-academy trust,OAKWOOD PARK GRAMMAR SCHOOL,-,,Not applicable,,10033587.0,,Not applicable,07-02-2019,05-06-2024,Oakwood Park,,,Maidstone,Kent,ME16 8AH,http://www.opgs.org,1622726683.0,Mr,Kevin,Moody,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Heath,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,574384.0,155244.0,Maidstone 008,Maidstone 008C,,,,,Good,South-East England and South London,,200003717871.0,,Not applicable,Not applicable,,,E02005075,E01024367,44.0,
136794,886,Kent,2249,Regis Manor Primary School,Academy converter,Academies,Open,Academy Converter,01-06-2011,,,Primary,3.0,11,No boarders,Has Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,570.0,No Special Classes,19-01-2023,580.0,293.0,287.0,24.1,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10033808.0,,Not applicable,04-07-2023,30-04-2024,North Street,,,Sittingbourne,Kent,ME10 2HW,www.regismanor.org.uk,1795472971.0,Mr,Matthew,Perry,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Milton Regis,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,590298.0,165171.0,Swale 007,Swale 007F,,,,,Good,South-East England and South London,United Kingdom,100062375806.0,,Not applicable,Not applicable,,,E02005121,E01024583,130.0,
136847,886,Kent,5439,Mascalls Academy,Academy converter,Academies,Open,Academy Converter,01-07-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1450.0,Has Special Classes,19-01-2023,1356.0,731.0,625.0,20.1,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10034109.0,,Not applicable,17-11-2021,13-03-2024,Maidstone Road,Paddock Wood,,Tonbridge,Kent,TN12 6LT,http://www.mascallsacademy.org.uk,1892835366.0,Mrs,Jo,Brooks,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Paddock Wood West,Tunbridge Wells,(England/Wales) Rural town and fringe,E10000016,567107.0,143847.0,Tunbridge Wells 001,Tunbridge Wells 001G,,,,,Good,South-East England and South London,,100062545662.0,,Not applicable,Not applicable,,,E02005162,E01024816,231.0,
136923,886,Kent,4000,St Augustine Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2011,Not applicable,,Secondary,11.0,16,No boarders,Not applicable,Does not have a sixth form,Mixed,Church of England,None,Diocese of Canterbury,Non-selective,750.0,Not applicable,19-01-2023,765.0,400.0,365.0,29.9,Supported by a multi-academy trust,WOODARD ACADEMIES TRUST,Linked to a sponsor,Woodard Academies Trust,Not applicable,,10034935.0,,Not applicable,13-07-2023,07-06-2024,Oakwood Road,,,Maidstone,Kent,ME16 8AE,http://www.saa.woodard.co.uk/,1622752490.0,Mr,Steffan,Ball,Principal,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,12.0,12.0,,,South East,Maidstone,Heath,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,574440.0,155313.0,Maidstone 008,Maidstone 008C,,,,,Requires improvement,South-East England and South London,,10014313780.0,,Not applicable,Not applicable,,,E02005075,E01024367,229.0,
137071,886,Kent,2000,St Johns Church of England Primary School,Voluntary controlled school,Local authority maintained schools,Open,Result of Amalgamation,01-09-2012,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,419.0,218.0,201.0,50.7,Not applicable,,Not applicable,,Not under a federation,,10079922.0,,Not applicable,24-01-2024,21-05-2024,St John's Place,Northgate,,Canterbury,Kent,CT1 1BD,www.stjohns-canterbury.kent.sch.uk/,1227462360.0,Mrs,Jo,Williamson,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Northgate,Canterbury,(England/Wales) Urban city and town,E10000016,615068.0,158363.0,Canterbury 014,Canterbury 014E,,,,,Good,South-East England and South London,,200000678007.0,,Not applicable,Not applicable,,,E02005023,E01024093,212.0,
137099,886,Kent,5465,Gravesend Grammar School,Academy converter,Academies,Open,Academy Converter,01-08-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,1032.0,No Special Classes,19-01-2023,1424.0,1340.0,84.0,7.4,Supported by a multi-academy trust,THE DECUS EDUCATIONAL TRUST,Linked to a sponsor,Gravesend Grammar School,Not applicable,,10034589.0,,Not applicable,26-06-2015,06-06-2024,Church Walk,,,Gravesend,Kent,DA12 2PR,http://gravesendgrammar.com/,1474331893.0,Mr,Malcolm,Moaby,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Denton,Gravesham,(England/Wales) Urban major conurbation,E10000016,565789.0,173594.0,Gravesham 005,Gravesham 005A,,,,,Outstanding,South-East England and South London,,10012012057.0,,Not applicable,Not applicable,,,E02005059,E01024259,76.0,
137104,886,Kent,5450,Hillview School for Girls,Academy converter,Academies,Open,Academy Converter,01-08-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Non-selective,1340.0,No Special Classes,19-01-2023,1496.0,58.0,1438.0,12.6,Supported by a single-academy trust,HILLVIEW SCHOOL FOR GIRLS ACADEMY TRUST,-,,Not applicable,,10034679.0,,Not applicable,20-09-2023,23-05-2024,Brionne Gardens,,,Tonbridge,Kent,TN9 2HE,http://www.hillview.kent.sch.uk,1732352793.0,Mrs,Hilary,Burkett,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Vauxhall,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,559690.0,145686.0,Tonbridge and Malling 012,Tonbridge and Malling 012E,,,,,Good,South-East England and South London,,200000962877.0,,Not applicable,Not applicable,,,E02005160,E01024767,144.0,
137136,886,Kent,2001,Horizon Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2011,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,None,None,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,202.0,109.0,93.0,41.6,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10034965.0,,Not applicable,15-11-2018,21-05-2024,Hilda May Avenue,,,Swanley,Kent,BR8 7BT,www.horizon-tkat.org/,1322665235.0,Mr,David,Moss,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Swanley White Oak,Sevenoaks,(England/Wales) Urban major conurbation,E10000016,551164.0,169131.0,Sevenoaks 002,Sevenoaks 002D,,,,,Good,South-East England and South London,,100062622098.0,,Not applicable,Not applicable,,,E02005088,E01024480,84.0,
137227,886,Kent,5403,Wilmington Grammar School for Boys,Academy converter,Academies,Open,Academy Converter,01-08-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,848.0,No Special Classes,19-01-2023,1079.0,993.0,86.0,8.1,Supported by a multi-academy trust,ENDEAVOUR MAT,-,,Not applicable,,10034780.0,,Not applicable,14-03-2023,07-05-2024,Common Lane,Wilmington,,Dartford,Kent,DA2 7DA,http://www.wgsb.co.uk,1322223090.0,Mr,Stuart,Harrington,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Maypole & Leyton Cross,Dartford,(England/Wales) Urban major conurbation,E10000016,552660.0,172195.0,Dartford 011,Dartford 011D,,,,,Good,South-East England and South London,,200000534710.0,,Not applicable,Not applicable,,,E02005038,E01024189,68.0,
137250,886,Kent,5400,Wilmington Grammar School for Girls,Academy converter,Academies,Open,Academy Converter,01-08-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1070.0,No Special Classes,19-01-2023,1068.0,92.0,976.0,4.6,Supported by a multi-academy trust,ENDEAVOUR MAT,-,,Not applicable,,10034848.0,,Not applicable,17-11-2022,05-06-2024,Wilmington Grange,Parsons Lane,Wilmington,Dartford,Kent,DA2 7BB,http://www.gsgw.org.uk/,1322226351.0,Mrs,Michelle,Lawson,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Maypole & Leyton Cross,Dartford,(England/Wales) Urban major conurbation,E10000016,552565.0,172488.0,Dartford 011,Dartford 011C,,,,,Good,South-East England and South London,,200000534735.0,,Not applicable,Not applicable,,,E02005038,E01024188,38.0,
137397,886,Kent,2246,Sheldwich Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2011,,,Primary,2.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,267.0,124.0,143.0,6.0,Supported by a single-academy trust,SHELDWICH PRIMARY SCHOOL,-,,Not applicable,,10035075.0,,Not applicable,09-11-2012,22-05-2024,Lees Court Road,Sheldwich,,Faversham,Kent,ME13 0LU,http://www.sheldwich.kent.sch.uk,1795532779.0,Mrs,Sarah,Garrett,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Boughton and Courtenay,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,601215.0,156561.0,Swale 017,Swale 017A,,,,,Outstanding,South-East England and South London,,200002532965.0,,Not applicable,Not applicable,,,E02005131,E01024555,16.0,
137458,886,Kent,5466,Brockhill Park Performing Arts College,Academy converter,Academies,Open,Academy Converter,01-09-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1384.0,No Special Classes,19-01-2023,1351.0,680.0,671.0,25.7,Supported by a single-academy trust,BROCKHILL PARK PERFORMING ARTS COLLEGE,-,,Not applicable,,10035076.0,,Not applicable,13-10-2021,05-04-2024,Sandling Road,Saltwood,,Hythe,Kent,CT21 4HL,http://www.brockhill.kent.sch.uk/,1303265521.0,Mr,Charles,Joseph,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Hythe,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,614826.0,135838.0,Folkestone and Hythe 008,Folkestone and Hythe 008D,,,,,Good,South-East England and South London,,50016401.0,,Not applicable,Not applicable,,,E02005109,E01024550,301.0,
137467,886,Kent,2233,Lynsted and Norton Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2011,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,105.0,No Special Classes,19-01-2023,73.0,41.0,32.0,45.2,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10035094.0,,Not applicable,08-03-2023,23-04-2024,Lynsted Lane,Lynsted,,Sittingbourne,Kent,ME9 0RL,www.lynsted-norton.kent.sch.uk,1795521362.0,Mrs,Catherine,McLaughlin,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Teynham and Lynsted,Sittingbourne and Sheppey,(England/Wales) Rural hamlet and isolated dwellings,E10000016,594445.0,161097.0,Swale 016,Swale 016E,,,,,Requires improvement,South-East England and South London,,200002528949.0,,Not applicable,Not applicable,,,E02005130,E01024624,33.0,
137474,886,Kent,5444,Barton Court Grammar School,Academy converter,Academies,Open,Academy Converter,01-09-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Selective,810.0,No Special Classes,19-01-2023,985.0,577.0,408.0,9.2,Supported by a multi-academy trust,BARTON COURT ACADEMY TRUST,Linked to a sponsor,Barton Court Academy Trust,Not applicable,,10035093.0,,Not applicable,12-02-2020,23-04-2024,Longport,,,Canterbury,Kent,CT1 1PH,http://www.bartoncourt.org,1227464600.0,Mr,Jonathan,Hopkins,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Barton,Canterbury,(England/Wales) Urban city and town,E10000016,615693.0,157611.0,Canterbury 016,Canterbury 016A,,,,,Good,South-East England and South London,,100062279040.0,,Not applicable,Not applicable,,,E02005025,E01024044,67.0,
137481,886,Kent,3112,Selling Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2011,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,128.0,75.0,53.0,21.1,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10035102.0,,Not applicable,11-11-2021,06-05-2024,The Street,Selling,,Faversham,Kent,ME13 9RQ,http://www.selling-faversham.kent.sch.uk/,1227752202.0,Mr,Richard,Paez,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Boughton and Courtenay,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,603872.0,156507.0,Swale 017,Swale 017A,,,,,Good,South-East England and South London,,10023196074.0,,Not applicable,Not applicable,,,E02005131,E01024555,27.0,
137483,886,Kent,3110,Milstead and Frinsted Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2011,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,70.0,No Special Classes,19-01-2023,85.0,48.0,37.0,23.5,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10035126.0,,Not applicable,03-11-2022,31-05-2024,School Lane,Milstead,,Sittingbourne,Kent,ME9 0SJ,http://www.milstead.kent.sch.uk,1795830241.0,Mr,Scott,Guy,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,West Downs,Sittingbourne and Sheppey,(England/Wales) Rural hamlet and isolated dwellings,E10000016,590320.0,158072.0,Swale 013,Swale 013C,,,,,Requires improvement,South-East England and South London,,100062626973.0,,Not applicable,Not applicable,,,E02005127,E01024628,20.0,
137484,886,Kent,5408,Homewood School and Sixth Form Centre,Academy converter,Academies,Open,Academy Converter,01-09-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,2156.0,No Special Classes,19-01-2023,2103.0,960.0,1143.0,26.5,Supported by a multi-academy trust,TENTERDEN SCHOOLS TRUST,-,,Not applicable,,10035054.0,,Not applicable,26-04-2023,14-05-2024,Ashford Road,,,Tenterden,Kent,TN30 6LT,http://www.homewood-school.co.uk/,1580764222.0,Mr,Jeremy,Single,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Tenterden North,Ashford,(England/Wales) Rural town and fringe,E10000016,588805.0,134276.0,Ashford 013,Ashford 013E,,,,,Good,South-East England and South London,,100062566868.0,,Not applicable,Not applicable,,,E02005008,E01024024,464.0,
137529,886,Kent,2288,Smarden Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2011,,,Primary,2.0,11,No boarders,Has Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,105.0,No Special Classes,19-01-2023,174.0,97.0,77.0,8.6,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10035486.0,,Not applicable,11-05-2023,27-03-2024,Pluckley Road,Smarden,,Ashford,Kent,TN27 8ND,www.smardenprimaryschool.co.uk/,1233770316.0,Mrs,Claudia,Miller,Executive Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Weald North,Ashford,(England/Wales) Rural village,E10000016,588338.0,142472.0,Ashford 011,Ashford 011D,,,,,Good,South-East England and South London,,100062563757.0,,Not applicable,Not applicable,,,E02005006,E01024036,15.0,
137581,886,Kent,4001,Ebbsfleet Academy,Academy sponsor led,Academies,Open,New Provision,01-11-2013,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Non-selective,750.0,No Special Classes,19-01-2023,766.0,421.0,345.0,34.1,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10038343.0,,Not applicable,02-10-2019,14-03-2024,Southfleet Road,,,Swanscombe,Kent,DA10 0BZ,http://www.ebbsfleetacademy.org.uk,1322242252.0,Mrs,Gurjit Kaur,Shergill,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Swanscombe,Dartford,(England/Wales) Urban major conurbation,E10000016,560829.0,173926.0,Dartford 004,Dartford 004B,,,,,Good,South-East England and South London,,200000535991.0,,Not applicable,Not applicable,,,E02005031,E01024176,237.0,
137609,886,Kent,5404,Saint George's Church of England School,Academy converter,Academies,Open,Academy Converter,01-11-2011,,,All-through,4.0,18,No boarders,Not applicable,Has a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Non-selective,1410.0,No Special Classes,19-01-2023,1381.0,722.0,659.0,17.4,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10035681.0,,Not applicable,18-10-2023,25-04-2024,Meadow Road,,,Gravesend,Kent,DA11 7LS,http://www.saintgeorgescofe.kent.sch.uk,1474533082.0,Mr,Simon,Murphy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Woodlands,Gravesham,(England/Wales) Urban major conurbation,E10000016,564257.0,172583.0,Gravesham 005,Gravesham 005E,,,,,Good,South-East England and South London,,100062310647.0,,Not applicable,Not applicable,,,E02005059,E01024317,202.0,
137615,886,Kent,3372,"Maidstone, St John's Church of England Primary School",Academy converter,Academies,Open,Academy Converter,01-11-2011,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,441.0,211.0,230.0,8.4,Supported by a single-academy trust,ST JOHN'S CHURCH OF ENGLAND PRIMARY SCHOOL MAIDSTONE,-,,Not applicable,,10035701.0,,Not applicable,16-07-2015,16-04-2024,Provender Way,Grove Green,,Maidstone,Kent,ME14 5TZ,www.st-johns-maidstone.kent.sch.uk/,1622735916.0,Mr,D J,Smith,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Boxley,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,578084.0,155874.0,Maidstone 005,Maidstone 005C,,,,,Outstanding,South-East England and South London,,200003688398.0,,Not applicable,Not applicable,,,E02005072,E01024337,37.0,
137660,886,Kent,2500,Joydens Wood Infant School,Academy converter,Academies,Open,Academy Converter,01-11-2011,,,Primary,4.0,7,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,238.0,122.0,116.0,5.5,Supported by a multi-academy trust,NEXUS EDUCATION SCHOOLS TRUST,Linked to a sponsor,Nexus Education Schools Trust,Not applicable,,10035690.0,,Not applicable,05-10-2023,29-04-2024,Park Way,,,Bexley,Kent,DA5 2JD,www.joydens-wood-infant.kent.sch.uk/,1322523188.0,Headteacher,Allison Morris/,Gerard Strong,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Joyden's Wood,Dartford,(England/Wales) Urban major conurbation,E10000016,551436.0,172012.0,Dartford 010,Dartford 010D,,,,,Good,South-East England and South London,,200000534792.0,,Not applicable,Not applicable,,,E02005037,E01024153,13.0,
137661,886,Kent,2438,Joydens Wood Junior School,Academy converter,Academies,Open,Academy Converter,01-11-2011,,,Primary,7.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Non-selective,280.0,No Special Classes,19-01-2023,294.0,147.0,147.0,9.5,Supported by a multi-academy trust,NEXUS EDUCATION SCHOOLS TRUST,Linked to a sponsor,Nexus Education Schools Trust,Not applicable,,10035673.0,,Not applicable,08-06-2022,04-04-2024,Birchwood Drive,Wilmington,,Dartford,Kent,DA2 7NE,http://www.joydens-wood-junior.kent.sch.uk,1322522151.0,Mr,Paul,Redford,Acting Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Joyden's Wood,Dartford,(England/Wales) Urban major conurbation,E10000016,551348.0,171986.0,Dartford 010,Dartford 010A,,,,,Requires improvement,South-East England and South London,,100060870222.0,,Not applicable,Not applicable,,,E02005037,E01024150,28.0,
137663,886,Kent,5219,Wilmington Primary School,Academy converter,Academies,Open,Academy Converter,01-11-2011,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,None,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,210.0,112.0,98.0,7.1,Supported by a multi-academy trust,ENDEAVOUR MAT,-,,Not applicable,,10035695.0,,Not applicable,20-06-2019,22-04-2024,Common Lane,Wilmington,,Dartford,Kent,DA2 7DF,www.wilmingtonprimaryschool.co.uk,1322274080.0,Mrs,Charlotte,Scott,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,"Wilmington, Sutton-at-Hone & Hawley",Dartford,(England/Wales) Urban major conurbation,E10000016,552812.0,172220.0,Dartford 011,Dartford 011C,,,,,Good,South-East England and South London,,200000534694.0,,Not applicable,Not applicable,,,E02005038,E01024188,15.0,
137687,886,Kent,4002,The Sittingbourne School,Academy sponsor led,Academies,Open,New Provision,01-01-2012,Not applicable,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,1350.0,No Special Classes,19-01-2023,1589.0,777.0,812.0,36.4,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10036067.0,,Not applicable,22-03-2023,21-05-2024,Swanstree Avenue,,,Sittingbourne,Kent,ME10 4NL,http://www.thesittingbourneschool.org.uk,1795472449.0,Mr,Nick,Smith,Trust Principal,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,HI - Hearing Impairment,"SLCN - Speech, language and Communication",,,,,,,,,,,,Resourced provision,82.0,60.0,,,South East,Swale,Roman,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,592123.0,162907.0,Swale 011,Swale 011D,,,,,Good,South-East England and South London,,100062627032.0,,Not applicable,Not applicable,,,E02005125,E01024600,509.0,
137728,886,Kent,3025,Chiddingstone Church of England School,Academy converter,Academies,Open,Academy Converter,01-12-2011,,,Primary,5.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,209.0,96.0,113.0,4.3,Supported by a single-academy trust,CHIDDINGSTONE CHURCH OF ENGLAND SCHOOL,-,,Not applicable,,10035696.0,,Not applicable,27-03-2015,15-04-2024,Chiddingstone,,,Edenbridge,Kent,TN8 7AH,www.chiddingstoneschool.co.uk/,1892870339.0,,Kate,Haysom,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Penshurst, Fordcombe and Chiddingstone",Tonbridge and Malling,(England/Wales) Rural village,E10000016,550144.0,145154.0,Sevenoaks 015,Sevenoaks 015C,,,,,Outstanding,South-East England and South London,,10035181506.0,,Not applicable,Not applicable,,,E02005101,E01024455,9.0,
137739,886,Kent,5416,Cranbrook School,Academy converter,Academies,Open,Academy Converter,01-12-2011,,,Secondary,11.0,18,Boarding school,Not applicable,Has a sixth form,Mixed,Christian,Does not apply,Not applicable,Selective,910.0,No Special Classes,19-01-2023,884.0,515.0,369.0,2.7,Supported by a single-academy trust,CRANBROOK SCHOOL ACADEMY TRUST,-,,Not applicable,,10035657.0,,Not applicable,23-03-2022,30-04-2024,Waterloo Road,,,Cranbrook,Kent,TN17 3JD,http://www.cranbrookschool.co.uk/,1580711800.0,Mr,David,Clark,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Benenden and Cranbrook,Maidstone and The Weald,(England/Wales) Rural town and fringe,E10000016,577829.0,136133.0,Tunbridge Wells 013,Tunbridge Wells 013C,,,,,Good,South-East England and South London,,100062552225.0,,Not applicable,Not applicable,,,E02005174,E01024790,15.0,
137800,886,Kent,4527,Borden Grammar School,Academy converter,Academies,Open,Academy Converter,01-01-2012,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,802.0,No Special Classes,19-01-2023,889.0,861.0,28.0,9.8,Supported by a single-academy trust,BORDEN GRAMMAR SCHOOL TRUST,-,,Not applicable,,10035796.0,,Not applicable,24-11-2021,15-05-2024,Avenue of Remembrance,,,Sittingbourne,Kent,ME10 4DB,http://website.bordengrammar.kent.sch.uk/,1795424192.0,Mr,Ashley,Tomlin,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Homewood,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,590580.0,163359.0,Swale 013,Swale 013A,,,,,Good,South-East England and South London,,100062376270.0,,Not applicable,Not applicable,,,E02005127,E01024606,65.0,
137806,886,Kent,2002,Repton Manor Primary School,Foundation school,Local authority maintained schools,Open,New Provision,01-09-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,471.0,244.0,227.0,19.5,Not supported by a trust,,Not applicable,,Supported by a federation,The Lightyear Federation,10072299.0,,Not applicable,29-11-2023,06-03-2024,Repton Avenue,,,Ashford,Kent,TN23 3RX,http://www.reptonmanorprimary.co.uk/,1233666307.0,Mr,Matthew,Rawling,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Repton,Ashford,(England/Wales) Urban city and town,E10000016,599566.0,143671.0,Ashford 016,Ashford 016B,,,,,Good,South-East England and South London,,10012859115.0,,Not applicable,Not applicable,,,E02007047,E01032820,92.0,
137833,886,Kent,5401,The Maplesden Noakes School,Academy converter,Academies,Open,Academy Converter,01-02-2012,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1500.0,No Special Classes,19-01-2023,1359.0,675.0,684.0,18.1,Supported by a single-academy trust,THE MAPLESDEN NOAKES SCHOOL,Linked to a sponsor,The Maplesden Noakes School,Not applicable,,10036261.0,,Not applicable,14-11-2018,30-04-2024,Buckland Road,,,Maidstone,Kent,ME16 0TJ,http://www.maplesden.kent.sch.uk/,1622759036.0,Mr,Richard,Owen,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Maidstone,Bridge,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,575149.0,156457.0,Maidstone 006,Maidstone 006B,,,,,Good,South-East England and South London,,200003670026.0,,Not applicable,Not applicable,,,E02005073,E01024340,197.0,
137834,886,Kent,5467,"Mayfield Grammar School, Gravesend",Academy converter,Academies,Open,Academy Converter,01-02-2012,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1207.0,No Special Classes,19-01-2023,1349.0,40.0,1309.0,10.5,Supported by a single-academy trust,"MAYFIELD GRAMMAR SCHOOL, GRAVESEND",-,,Not applicable,,10036417.0,,Not applicable,12-06-2013,09-05-2024,Pelham Road,,,Gravesend,Kent,DA11 0JE,http://www.mgsg.kent.sch.uk/,1474352896.0,Headteacher,Elaine,Wilson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Pelham,Gravesham,(England/Wales) Urban major conurbation,E10000016,564094.0,173489.0,Gravesham 002,Gravesham 002C,,,,,Outstanding,South-East England and South London,,100062310034.0,,Not applicable,Not applicable,,,E02005056,E01024290,107.0,
137836,886,Kent,2684,Wentworth Primary School,Academy converter,Academies,Open,Academy Converter,01-02-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,Not applicable,19-01-2023,651.0,321.0,330.0,14.9,Supported by a single-academy trust,WENTWORTH PRIMARY SCHOOL,-,,Not applicable,,10036263.0,,Not applicable,08-06-2023,21-05-2024,Wentworth Drive,,,Dartford,Kent,DA1 3NG,www.wentworthonline.co.uk/,1322225694.0,Mr,Lewis,Pollock,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Heath,Dartford,(England/Wales) Urban major conurbation,E10000016,552144.0,173935.0,Dartford 007,Dartford 007A,,,,,Good,South-East England and South London,,,,Not applicable,Not applicable,,,E02005034,E01024144,97.0,
137837,886,Kent,5437,The Folkestone School for Girls,Academy converter,Academies,Open,Academy Converter,01-02-2012,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1053.0,No Special Classes,19-01-2023,1217.0,0.0,1217.0,12.1,Supported by a multi-academy trust,THE FOLKESTONE SCHOOL FOR GIRLS ACADEMY TRUST,-,,Not applicable,,10036180.0,,Not applicable,12-10-2012,17-04-2024,Coolinge Lane,,,Folkestone,Kent,CT20 3RB,http://www.folkestonegirls.kent.sch.uk/,1303251125.0,Mr,Mark,Lester,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Sandgate & West Folkestone,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,620830.0,135551.0,Folkestone and Hythe 006,Folkestone and Hythe 006H,,,,,Outstanding,South-East England and South London,,50026109.0,,Not applicable,Not applicable,,,E02005107,E01024521,112.0,
137871,886,Kent,2229,Graveney Primary School,Academy converter,Academies,Open,Academy Converter,01-02-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,105.0,No Special Classes,19-01-2023,100.0,50.0,50.0,18.0,Supported by a multi-academy trust,GRAVENEY PRIMARY SCHOOL,-,,Not applicable,,10035872.0,,Not applicable,04-10-2023,17-04-2024,Seasalter Road,Graveney,,Faversham,Kent,ME13 9DU,www.graveneyprimary.com,1795532005.0,Mrs,Alison,Blackwell,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Boughton and Courtenay,Faversham and Mid Kent,(England/Wales) Rural village,E10000016,605092.0,162256.0,Swale 017,Swale 017B,,,,,Good,South-East England and South London,,200002531105.0,,Not applicable,Not applicable,,,E02005131,E01024556,18.0,
137881,886,Kent,2003,Oaks Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-04-2012,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Not applicable,213.0,No Special Classes,19-01-2023,216.0,103.0,113.0,40.4,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10037058.0,,Not applicable,22-09-2021,28-05-2024,Oak Tree Avenue,,,Maidstone,Kent,ME15 9AX,http://www.oaksprimaryacademy.org.uk,1622755960.0,Principal,Tom,Moore,Principal,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Shepway North,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,577321.0,153197.0,Maidstone 013,Maidstone 013C,,,,,Outstanding,South-East England and South London,,200003718069.0,,Not applicable,Not applicable,,,E02005080,E01024391,78.0,
137882,886,Kent,2004,Tree Tops Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-04-2012,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Not applicable,315.0,No Special Classes,19-01-2023,314.0,148.0,166.0,48.8,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10037063.0,,Not applicable,12-06-2019,13-09-2023,Brishing Lane,Park Wood,,Maidstone,Kent,ME15 9EZ,http://www.treetopsprimaryacademy.org/,1622754888.0,Miss,Denise,White,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Park Wood,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,578482.0,152246.0,Maidstone 013,Maidstone 013I,,,,,Good,South-East England and South London,,10014314389.0,,Not applicable,Not applicable,,,E02005080,E01034996,148.0,
137961,886,Kent,2264,Hampton Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2012,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,710.0,No Special Classes,19-01-2023,675.0,348.0,327.0,28.1,Supported by a single-academy trust,HAMPTON PRIMARY SCHOOL ACADEMY,-,,Not applicable,,10036924.0,,Not applicable,11-03-2020,07-05-2024,Fitzgerald Avenue,,,Herne Bay,Kent,CT6 8NB,www.hampton.kent.sch.uk,1227372159.0,Ms,Yvonne,Nunn,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,PD - Physical Disability,,,,,,,,,,,,,Resourced provision,,,,,South East,Canterbury,West Bay,North Thanet,(England/Wales) Urban city and town,E10000016,616209.0,167469.0,Canterbury 004,Canterbury 004D,,,,,Good,South-East England and South London,,200000682720.0,,Not applicable,Not applicable,,,E02005013,E01024119,188.0,
138001,886,Kent,3142,Pluckley Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,96.0,51.0,45.0,15.6,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10036989.0,,Not applicable,06-06-2019,15-04-2024,The Street,Pluckley,,Ashford,Kent,TN27 0QS,www.pluckleyprimaryschool.co.uk,1233840422.0,Mrs,Lorraine,Smith,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Upper Weald,Ashford,(England/Wales) Rural village,E10000016,592582.0,145357.0,Ashford 002,Ashford 002E,,,,,Good,South-East England and South London,,100062563578.0,,Not applicable,Not applicable,,,E02004997,E01024033,15.0,
138019,886,Kent,4528,The Norton Knatchbull School,Academy converter,Academies,Open,Academy Converter,01-04-2012,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,1316.0,No Special Classes,19-01-2023,1252.0,1226.0,26.0,7.9,Supported by a single-academy trust,THE NORTON KNATCHBULL SCHOOL,-,,Not applicable,,10036999.0,,Not applicable,14-12-2023,07-06-2024,Hythe Road,,,Ashford,Kent,TN24 0QJ,http://www.nks.kent.sch.uk,1233620045.0,Mr,Ben,Greene,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Furley,Ashford,(England/Wales) Urban city and town,E10000016,602275.0,142571.0,Ashford 005,Ashford 005C,,,,,Good,South-East England and South London,,100062559840.0,,Not applicable,Not applicable,,,E02005000,E01024023,79.0,
138034,886,Kent,2232,Luddenham School,Academy converter,Academies,Open,Academy Converter,01-04-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,201.0,92.0,109.0,25.4,Supported by a single-academy trust,LUDDENHAM SCHOOL,-,,Not applicable,,10037009.0,,Not applicable,27-02-2019,04-06-2024,Luddenham,,,Faversham,Kent,ME13 0TE,www.luddenham.kent.sch.uk,1795532061.0,Mrs,Claire,Vincett,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Teynham and Lynsted,Sittingbourne and Sheppey,(England/Wales) Rural hamlet and isolated dwellings,E10000016,599374.0,162425.0,Swale 016,Swale 016C,,,,,Good,South-East England and South London,,200002532858.0,,Not applicable,Not applicable,,,E02005130,E01024622,51.0,
138074,886,Kent,2006,St James the Great Academy,Academy sponsor led,Academies,Open,New Provision,01-04-2012,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,197.0,101.0,96.0,42.6,Supported by a multi-academy trust,ACADEMIES ENTERPRISE TRUST,Linked to a sponsor,Academies Enterprise Trust (AET),Not applicable,,10037082.0,,Not applicable,13-09-2023,23-05-2024,Chapman Way,,,East Malling,Kent,ME19 6SD,http://www.stjamesthegreatacademy.org/,1732841912.0,Miss,Tamasin,Springett,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,"East Malling, West Malling & Offham",Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,569675.0,157748.0,Tonbridge and Malling 014,Tonbridge and Malling 014B,,,,,Good,South-East England and South London,,100062388024.0,,Not applicable,Not applicable,,,E02006833,E01024742,81.0,
138151,886,Kent,2595,Grove Park Primary School,Academy converter,Academies,Open,Academy Converter,01-06-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,412.0,214.0,198.0,21.1,Supported by a multi-academy trust,BOURNE ALLIANCE MULTI ACADEMY TRUST,Linked to a sponsor,TIMU Academy Trust,Not applicable,,10037293.0,,Not applicable,24-05-2023,16-04-2024,Hilton Drive,,,Sittingbourne,Kent,ME10 1PT,www.grovepark-ba-mat.org.uk,1795477417.0,Mrs,Lauren,Flain,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Borden and Grove Park,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,588827.0,164604.0,Swale 009,Swale 009H,,,,,Requires improvement,South-East England and South London,,200002527488.0,,Not applicable,Not applicable,,,E02005123,E01035306,87.0,
138167,886,Kent,4113,Astor Secondary School,Academy converter,Academies,Open,Academy Converter,02-06-2012,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Non-selective,1230.0,No Special Classes,19-01-2023,803.0,348.0,455.0,49.3,Supported by a multi-academy trust,SAMPHIRE STAR EDUCATION TRUST,-,,Not applicable,,10037500.0,,Not applicable,01-11-2023,15-04-2024,Astor Avenue,,,Dover,Kent,CT17 0AS,http://www.astorschool.com,1304201151.0,Mr,Lee,Kane,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Dover,Tower Hamlets,Dover,(England/Wales) Urban city and town,E10000016,630219.0,141531.0,Dover 011,Dover 011H,,,,,Requires improvement,South-East England and South London,,10034874352.0,,Not applicable,Not applicable,,,E02005051,E01024248,350.0,
138168,886,Kent,2315,White Cliffs Primary and Nursery School,Academy converter,Academies,Open,Academy Converter,01-06-2012,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,360.0,No Special Classes,19-01-2023,315.0,179.0,136.0,59.0,Supported by a multi-academy trust,SAMPHIRE STAR EDUCATION TRUST,-,,Not applicable,,10037463.0,,Not applicable,09-01-2019,22-05-2024,St Radigund's Road,,,Dover,Kent,CT17 0LB,http://www.whitecliffsprimary.com,1304206174.0,Mrs,Helen,Castle,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,St Radigunds,Dover,(England/Wales) Urban city and town,E10000016,630188.0,142202.0,Dover 011,Dover 011F,,,,,Good,South-East England and South London,,200002882635.0,,Not applicable,Not applicable,,,E02005051,E01024240,186.0,
138169,886,Kent,2310,Barton Junior School,Academy converter,Academies,Open,Academy Converter,01-06-2012,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,240.0,No Special Classes,19-01-2023,215.0,121.0,94.0,53.5,Supported by a multi-academy trust,SAMPHIRE STAR EDUCATION TRUST,-,,Not applicable,,10037462.0,,Not applicable,05-12-2018,22-05-2024,Barton Road,,,Dover,Kent,CT16 2ND,www.bartonjuniorschool.org/,1304201643.0,Miss,Melanie,O'Dell,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,St Radigunds,Dover,(England/Wales) Urban city and town,E10000016,631229.0,142506.0,Dover 012,Dover 012C,,,,,Good,South-East England and South London,,100062289419.0,,Not applicable,Not applicable,,,E02005052,E01024239,115.0,
138170,886,Kent,2316,Shatterlocks Infant and Nursery School,Academy converter,Academies,Open,Academy Converter,01-06-2012,,,Primary,3.0,7,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,232.0,No Special Classes,19-01-2023,202.0,90.0,112.0,40.5,Supported by a multi-academy trust,SAMPHIRE STAR EDUCATION TRUST,-,,Not applicable,,10037459.0,,Not applicable,16-05-2019,27-02-2024,Heathfield Avenue,,,Dover,Kent,CT16 2PB,http://www.shatterlocks.com,1304204264.0,Miss,Melanie,O'Dell,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Buckland,Dover,(England/Wales) Urban city and town,E10000016,630755.0,142875.0,Dover 011,Dover 011A,,,,,Outstanding,South-East England and South London,,100062289420.0,,Not applicable,Not applicable,,,E02005051,E01024193,77.0,
138195,886,Kent,2007,Molehill Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-06-2012,,,Primary,3.0,11,,Has Nursery Classes,Not applicable,Mixed,None,None,Not applicable,Not applicable,315.0,Not applicable,19-01-2023,303.0,159.0,144.0,43.2,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10037485.0,,Not applicable,14-06-2023,03-06-2024,Hereford Road,,,Maidstone,Kent,ME15 7ND,http://www.molehillprimaryacademy.org.uk,1622751729.0,Principal,Laura,Smith,Head of Academy,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,HI - Hearing Impairment,"SLCN - Speech, language and Communication",,,,,,,,,,,,Resourced provision,5.0,10.0,,,South East,Maidstone,Shepway South,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,577701.0,153158.0,Maidstone 013,Maidstone 013E,,,,,Good,South-East England and South London,,200003717486.0,,Not applicable,Not applicable,,,E02005080,E01024398,128.0,
138232,886,Kent,2008,Tiger Primary School,Free schools,Free Schools,Open,New Provision,03-09-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,427.0,217.0,210.0,33.7,Supported by a multi-academy trust,FUTURE SCHOOLS TRUST,Linked to a sponsor,Future Schools Trust,Not applicable,,10038742.0,,Not applicable,20-09-2023,22-11-2023,Boughton Lane,,,Maidstone,Kent,ME15 9QL,www.futureschoolstrust.com,1622745166.0,Mr,Daniel,Siggs,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,South,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,576813.0,153053.0,Maidstone 012,Maidstone 012D,Ofsted,,,,Good,South-East England and South London,,200003677498.0,,Not applicable,Not applicable,,,E02005079,E01024404,144.0,
138405,886,Kent,6138,Earlscliffe (Sussex Summer Schools Ltd),Other independent school,Independent schools,Open,New Provision,17-07-2012,,,Not applicable,14.0,19,Boarding school,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Not applicable,160.0,Not applicable,20-01-2022,129.0,83.0,46.0,0.0,Not applicable,,Not applicable,,Not applicable,,10037987.0,,Not applicable,28-11-2019,08-04-2024,29 Shorncliffe Road,,,Folkestone,Kent,CT20 2NB,www.earlscliffe.co.uk,1303253951.0,Mr,Niall,Johnson,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not approved,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Folkestone Central,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,621725.0,136091.0,Folkestone and Hythe 006,Folkestone and Hythe 006A,ISI,,12.0,,,South-East England and South London,,50033584.0,,Not applicable,Not applicable,,,E02005107,E01024511,0.0,
138434,886,Kent,2009,Northdown Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2012,,,Primary,3.0,11,No boarders,Has Nursery Classes,Not applicable,Mixed,None,None,Not applicable,Not applicable,427.0,Not applicable,19-01-2023,325.0,157.0,168.0,73.5,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10038398.0,,Not applicable,24-11-2021,09-05-2024,Tenterden Way,,,Margate,Kent,CT9 3RE,www.northdown-tkat.org,1843226077.0,Mr,Matthew,Harris,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Dane Valley,North Thanet,(England/Wales) Urban city and town,E10000016,637269.0,170097.0,Thanet 006,Thanet 006C,,,,,Good,South-East England and South London,,100062307407.0,,Not applicable,Not applicable,,,E02005137,E01024662,228.0,
138436,886,Kent,2010,Newlands Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2012,,,Primary,4.0,11,Not applicable,Not applicable,Not applicable,Mixed,None,None,Not applicable,Not applicable,315.0,Not applicable,19-01-2023,291.0,159.0,132.0,60.8,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10038052.0,,Not applicable,02-11-2022,26-04-2024,Dumpton Lane,,,Ramsgate,Kent,CT11 7AJ,www.newlands-tkat.org,1843593086.0,Mr,David,Bailey,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Sir Moses Montefiore,South Thanet,(England/Wales) Urban city and town,E10000016,638271.0,166231.0,Thanet 012,Thanet 012C,,,,,Good,South-East England and South London,,100062282198.0,,Not applicable,Not applicable,,,E02005143,E01024699,177.0,
138438,886,Kent,2011,Salmestone Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2012,,,Primary,3.0,11,,Has Nursery Classes,Not applicable,Mixed,None,None,Not applicable,Non-selective,210.0,Not applicable,19-01-2023,215.0,114.0,101.0,41.4,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10038040.0,,Not applicable,23-01-2019,22-02-2024,College Road,,,Margate,Kent,CT9 4DB,www.salmestone-tkat.org/,1843220949.0,Mr,Thomas,Platten,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Salmestone,North Thanet,(England/Wales) Urban city and town,E10000016,635418.0,169813.0,Thanet 003,Thanet 003C,,,,,Good,South-East England and South London,,100062307602.0,,Not applicable,Not applicable,,,E02005134,E01024695,84.0,
138480,886,Kent,4101,The Harvey Grammar School,Academy converter,Academies,Open,Academy Converter,01-08-2012,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,Does not apply,Does not apply,Not applicable,Selective,980.0,No Special Classes,19-01-2023,1026.0,1026.0,0.0,10.8,Supported by a multi-academy trust,THE HARVEY ACADEMY,-,,Not applicable,,10038103.0,,Not applicable,14-12-2022,21-05-2024,Cheriton Road,,,Folkestone,Kent,CT19 5JY,http://www.harveygs.kent.sch.uk/,1303252131.0,Mr,S,Norman,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Broadmead,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,621203.0,136613.0,Folkestone and Hythe 015,Folkestone and Hythe 015D,,,,,Outstanding,South-East England and South London,,50032937.0,,Not applicable,Not applicable,,,E02006880,E01024517,81.0,
138579,886,Kent,2013,Water Meadows Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2012,,,Primary,4.0,11,,Not applicable,Not applicable,Mixed,None,None,Not applicable,Not applicable,150.0,Not applicable,19-01-2023,148.0,72.0,76.0,43.5,Supported by a multi-academy trust,THE STOUR ACADEMY TRUST,Linked to a sponsor,The Stour Academy Trust,Not applicable,,10038477.0,,Not applicable,20-03-2019,28-05-2024,Shaftesbury Road,Hersden,,Canterbury,Kent,CT3 4HS,www.watermeadows.kent.sch.uk,1227710414.0,Mr,Ben,Martin,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Sturry,North Thanet,(England/Wales) Rural town and fringe,E10000016,620217.0,162160.0,Canterbury 010,Canterbury 010C,,,,,Good,South-East England and South London,,200000683090.0,,Not applicable,Not applicable,,,E02005019,E01024086,64.0,
138592,886,Kent,2014,St Laurence In Thanet Church of England Junior Academy,Academy sponsor led,Academies,Open,New Provision,01-12-2012,,,Primary,7.0,11,,Not applicable,Not applicable,Mixed,Church of England,None,Diocese of Canterbury,Not applicable,256.0,Not applicable,19-01-2023,177.0,95.0,82.0,60.5,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10038488.0,,Not applicable,04-07-2018,07-05-2024,Newington Road,,,Ramsgate,Kent,CT11 0QX,www.stlaurencejuniors.co.uk/,1843592257.0,Ms,Sarah,Graham,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Newington,South Thanet,(England/Wales) Urban city and town,E10000016,636976.0,165548.0,Thanet 013,Thanet 013C,,,,,Good,South-East England and South London,,200002234791.0,,Not applicable,Not applicable,,,E02005144,E01024684,107.0,
138737,886,Kent,3086,West Malling Church of England Primary School and McGinty Speech and Language Srp,Academy converter,Academies,Open,Academy Converter,01-09-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,Has Special Classes,19-01-2023,207.0,109.0,98.0,24.6,Supported by a multi-academy trust,THE TENAX SCHOOLS TRUST,Linked to a sponsor,The Tenax Schools Trust,Not applicable,,10037972.0,,Not applicable,25-01-2023,06-06-2024,Old Cricket Ground,Norman Road,,West Malling,Kent,ME19 6RL,http://www.west-malling.kent.sch.uk,1732842061.0,Mr,David,Rye,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,14.0,21.0,,,South East,Tonbridge and Malling,"East Malling, West Malling & Offham",Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,567936.0,157853.0,Tonbridge and Malling 014,Tonbridge and Malling 014C,,,,,Good,South-East England and South London,,100062388025.0,,Not applicable,Not applicable,,,E02006833,E01024783,51.0,
138738,886,Kent,3128,Sturry Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,406.0,195.0,211.0,26.8,Supported by a multi-academy trust,THE STOUR ACADEMY TRUST,Linked to a sponsor,The Stour Academy Trust,Not applicable,,10038650.0,,Not applicable,28-01-2015,08-04-2024,Park View,Sturry,,Canterbury,Kent,CT2 0NR,http://www.sturry.kent.sch.uk,1227710477.0,Mrs,M,Mannings,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Sturry,Canterbury,(England/Wales) Rural town and fringe,E10000016,617998.0,161082.0,Canterbury 011,Canterbury 011C,,,,,Outstanding,South-East England and South London,,200000679701.0,,Not applicable,Not applicable,,,E02005020,E01024111,109.0,
138972,886,Kent,2015,Dame Janet Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-12-2012,,,Primary,4.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,360.0,Not applicable,19-01-2023,371.0,193.0,178.0,58.1,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10039504.0,,Not applicable,03-10-2018,22-02-2024,Newington Road,,,Ramsgate,Kent,CT12 6QY,www.damejanet-tkat.org/,1843591807.0,Mr,Sam,Atkinson,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Northwood,South Thanet,(England/Wales) Urban city and town,E10000016,636796.0,166666.0,Thanet 011,Thanet 011B,,,,,Good,South-East England and South London,,100062284279.0,,Not applicable,Not applicable,,,E02005142,E01024688,215.0,
139021,886,Kent,2017,Drapers Mills Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-12-2012,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,330.0,169.0,161.0,66.1,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10039726.0,,Not applicable,01-11-2023,18-03-2024,St Peter's Footpath,,,Margate,Kent,CT9 2SP,http://www.drapersmillsprimary.co.uk/,1843223989.0,Mrs,Kathleen,Davis,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Dane Valley,North Thanet,(England/Wales) Urban city and town,E10000016,636260.0,169934.0,Thanet 004,Thanet 004B,,,,,Good,South-East England and South London,,200003079364.0,,Not applicable,Not applicable,,,E02005135,E01024664,218.0,
139052,886,Kent,2018,Temple Grove Academy,Academy sponsor led,Academies,Open,New Provision,01-01-2013,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,210.0,Not applicable,19-01-2023,208.0,96.0,112.0,47.0,Supported by a single-academy trust,TEMPLE GROVE ACADEMY TRUST,Linked to a sponsor,Temple Grove Schools Trust,Not applicable,,10039910.0,,Not applicable,18-09-2019,10-04-2024,Friars Way,,,Tunbridge Wells,Kent,TN2 3UA,http://www.templegroveacademy.com/,1892520562.0,Mrs,Rebekah,Leeves,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Sherwood,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,559898.0,140821.0,Tunbridge Wells 005,Tunbridge Wells 005B,,,,,Good,South-East England and South London,,10000066049.0,,Not applicable,Not applicable,,,E02005166,E01024841,93.0,
139075,886,Kent,4004,Meopham School,Academy sponsor led,Academies,Open,New Provision,01-02-2013,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,832.0,Not applicable,19-01-2023,989.0,505.0,484.0,16.0,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10039851.0,,Not applicable,20-04-2023,16-04-2024,Wrotham Road,Meopham,,Gravesend,Kent,DA13 0AH,meophamschool.org.uk,1474814646.0,Mr,Glenn,Prebble,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision and SEN unit,20.0,20.0,20.0,20.0,South East,Gravesham,Meopham North,Gravesham,(England/Wales) Rural village,E10000016,564231.0,165820.0,Gravesham 012,Gravesham 012D,,,,,Good,South-East England and South London,,100062313194.0,,Not applicable,Not applicable,,,E02005066,E01024271,144.0,
139096,886,Kent,5209,Allington Primary School,Academy converter,Academies,Open,Academy Converter,01-12-2012,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,465.0,223.0,242.0,4.9,Supported by a multi-academy trust,ORCHARD ACADEMY TRUST,Linked to a sponsor,Allington Primary School Academy Trust (Orchard Academy Trust),Not applicable,,10039700.0,,Not applicable,13-07-2022,16-04-2024,Hildenborough Crescent,London Road,,Maidstone,Kent,ME16 0PG,www.allington.kent.sch.uk/,1622757350.0,Mrs,C,Howson,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Allington,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,574093.0,157190.0,Maidstone 003,Maidstone 003D,,,,,Outstanding,South-East England and South London,,200003717229.0,,Not applicable,Not applicable,,,E02005070,E01024323,23.0,
139186,886,Kent,2307,Warden House Primary School,Academy converter,Academies,Open,Academy Converter,01-01-2013,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,437.0,228.0,209.0,36.2,Supported by a multi-academy trust,VERITAS MULTI ACADEMY TRUST,Linked to a sponsor,Veritas Multi Academy Trust,Not applicable,,10040005.0,,Not applicable,03-12-2014,21-05-2024,Birdwood Avenue,,,Deal,Kent,CT14 9SF,http://www.warden-house.kent.sch.uk,1304375040.0,Mr,Robert,Hackett,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Middle Deal,Dover,(England/Wales) Urban city and town,E10000016,636229.0,152116.0,Dover 003,Dover 003A,,,,,Outstanding,South-East England and South London,,100062287038.0,,Not applicable,Not applicable,,,E02005043,E01024219,158.0,
139254,886,Kent,2019,Chantry Community Primary School,Academy sponsor led,Academies,Open,New Provision,01-06-2013,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,454.0,229.0,225.0,43.7,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10040148.0,,Not applicable,27-01-2022,18-04-2024,Ordnance Road,,,Gravesend,Kent,DA12 2RL,www.chantryprimary.co.uk,1474350011.0,Mrs,Kathryn,Duncan,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Town,Gravesham,(England/Wales) Urban major conurbation,E10000016,565390.0,174044.0,Gravesham 002,Gravesham 002E,,,,,Good,South-East England and South London,,100062311901.0,,Not applicable,Not applicable,,,E02005056,E01024295,176.0,
139255,886,Kent,2020,"Christ Church Church of England Junior School, Ramsgate",Academy sponsor led,Academies,Open,New Provision,01-12-2013,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,None,Diocese of Canterbury,Not applicable,240.0,Not applicable,19-01-2023,200.0,104.0,96.0,43.5,Supported by a single-academy trust,"CHRIST CHURCH CHURCH OF ENGLAND JUNIOR SCHOOL, RAMSGATE",Linked to a sponsor,The Diocese of Canterbury Academies Company Limited,Not applicable,,10040135.0,,Not applicable,10-11-2021,14-05-2024,London Road,,,Ramsgate,Kent,CT11 0ZZ,www.christchurchjuniors.com/,1843593350.0,Mr,Neil,Tucker,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Cliffsend and Pegwell,South Thanet,(England/Wales) Urban city and town,E10000016,637368.0,164573.0,Thanet 017,Thanet 017B,,,,,Good,South-East England and South London,,100062628044.0,,Not applicable,Not applicable,,,E02005148,E01024651,87.0,
139309,886,Kent,3148,"Christ Church Cep Academy, Folkestone",Academy converter,Academies,Open,Academy Converter,01-03-2013,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,422.0,193.0,229.0,46.7,Supported by a single-academy trust,"CHRIST CHURCH CHURCH OF ENGLAND PRIMARY ACADEMY, FOLKESTONE",-,,Not applicable,,10040025.0,,Not applicable,01-12-2022,21-05-2024,Brockman Road,,,Folkestone,Kent,CT20 1DJ,www.christchurchfolkestone.com/,1303253645.0,Mr,Robin,Flack,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Folkestone Central,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,622492.0,136267.0,Folkestone and Hythe 014,Folkestone and Hythe 014B,,,,,Good,South-East England and South London,,50041734.0,,Not applicable,Not applicable,,,E02006879,E01024507,197.0,
139310,886,Kent,3349,Folkestone St. Mary's Church of England Primary Academy,Academy converter,Academies,Open,Academy Converter,01-02-2013,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,449.0,228.0,221.0,36.3,Supported by a single-academy trust,FOLKESTONE ST MARY'S CHURCH OF ENGLAND PRIMARY ACADEMY,-,,Not applicable,,10040279.0,,Not applicable,20-10-2021,08-05-2024,Warren Road,,,Folkestone,Kent,CT19 6QH,www.stmarysfolkestone.com,1303251390.0,Mrs,Amanda,Wolfram,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Folkestone and Hythe,Folkestone Harbour,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,623841.0,136685.0,Folkestone and Hythe 003,Folkestone and Hythe 003D,,,,,Good,South-East England and South London,,50046311.0,,Not applicable,Not applicable,,,E02005104,E01024503,144.0,
139315,886,Kent,3348,St Eanswythe's Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-02-2013,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,212.0,94.0,118.0,25.0,Supported by a single-academy trust,ST EANSWYTHE'S CHURCH OF ENGLAND PRIMARY SCHOOL,-,,Not applicable,,10040285.0,,Not applicable,13-03-2019,31-05-2024,Church Street,,,Folkestone,Kent,CT20 1SE,http://www.st-eanswythes.kent.sch.uk/,1303255516.0,Headteacher,Claire,Jacobs,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Folkestone Central,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,622986.0,135909.0,Folkestone and Hythe 014,Folkestone and Hythe 014D,,,,,Outstanding,South-East England and South London,,50036799.0,,Not applicable,Not applicable,,,E02006879,E01033215,53.0,
139396,886,Kent,2021,Kemsley Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-04-2013,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,232.0,112.0,120.0,31.4,Supported by a multi-academy trust,REACH2 ACADEMY TRUST,Linked to a sponsor,REAch2 Academy Trust,Not applicable,,10040770.0,,Not applicable,14-02-2019,16-01-2024,Coldharbour Lane,Kemsley,,Sittingbourne,Kent,ME10 2RP,www.kemsley.kent.sch.uk,1795428689.0,,Iris,Homer,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Kemsley,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,590740.0,166282.0,Swale 007,Swale 007J,,,,,Good,South-East England and South London,,10035063593.0,,Not applicable,Not applicable,,,E02005121,E01035303,69.0,
139397,886,Kent,2022,Milton Court Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-04-2013,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,238.0,Not applicable,19-01-2023,245.0,121.0,124.0,52.7,Supported by a multi-academy trust,REACH2 ACADEMY TRUST,Linked to a sponsor,REAch2 Academy Trust,Not applicable,,10040771.0,,Not applicable,18-09-2019,13-05-2024,Brewery Road,Milton Regis,,Sittingbourne,Kent,ME10 2EE,www.milton-court.kent.sch.uk,1795472972.0,Miss,Sarah,Gadsdon,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Milton Regis,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,590434.0,164874.0,Swale 010,Swale 010B,,,,,Good,South-East England and South London,,100062375804.0,,Not applicable,Not applicable,,,E02005124,E01024584,125.0,
139436,886,Kent,2023,Temple Ewell Church of England Primary School,Academy sponsor led,Academies,Open,New Provision,01-02-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,None,Diocese of Canterbury,Not applicable,140.0,Not applicable,19-01-2023,145.0,74.0,71.0,18.6,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10041585.0,,Not applicable,04-07-2023,26-03-2024,3-4 Brookside,Temple Ewell,,Dover,Kent,CT16 3DT,www.temple-ewell.kent.sch.uk/,1304822665.0,Mrs,Angela,Matthews,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Dover Downs & River,Dover,(England/Wales) Urban city and town,E10000016,628536.0,144298.0,Dover 010,Dover 010G,,,,,Good,South-East England and South London,,100062289542.0,,Not applicable,Not applicable,,,E02005050,E01033210,27.0,
139542,886,Kent,5409,Wrotham School,Academy converter,Academies,Open,Academy Converter,01-04-2013,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,716.0,No Special Classes,19-01-2023,1029.0,553.0,476.0,16.3,Supported by a multi-academy trust,CHARACTER EDUCATION TRUST,Linked to a sponsor,Wrotham School,Not applicable,,10035479.0,,Not applicable,22-05-2019,06-06-2024,Borough Green Road,Wrotham,,Sevenoaks,Kent,TN15 7RD,http://www.wrothamschool.com/,1732905860.0,Mr,Michael,Cater,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Pilgrims with Ightham,Tonbridge and Malling,(England/Wales) Rural village,E10000016,561109.0,158269.0,Tonbridge and Malling 006,Tonbridge and Malling 006F,,,,,Good,South-East England and South London,,100062550537.0,,Not applicable,Not applicable,,,E02005154,E01024786,139.0,
139554,886,Kent,4006,Trinity School,Free schools,Free Schools,Open,New Provision,01-09-2013,,,Secondary,11.0,19,Not applicable,No Nursery Classes,Has a sixth form,Mixed,Christian,Christian,,Non-selective,1140.0,Not applicable,19-01-2023,1130.0,619.0,511.0,14.8,Supported by a single-academy trust,TRINITY SCHOOL SEVENOAKS LTD,-,,Not applicable,,10041643.0,,Not applicable,02-10-2018,02-05-2024,Seal Hollow Rd,,,Sevenoaks,Kent,TN13 3SL,http://www.trinitysevenoaks.org.uk/,1732469111.0,Dr,Matthew,Pawson,Headmaster,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Seal and Weald,Sevenoaks,(England/Wales) Urban city and town,E10000016,554061.0,156627.0,Sevenoaks 012,Sevenoaks 012A,Ofsted,,,,Good,South-East England and South London,,10013774563.0,,Not applicable,Not applicable,,,E02005098,E01024458,136.0,
139615,886,Kent,2511,Hartley Primary Academy,Academy converter,Academies,Open,Academy Converter,01-05-2013,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,443.0,230.0,213.0,9.3,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10041353.0,,Not applicable,11-10-2023,16-04-2024,Round Ash Way,Hartley,,Longfield,Kent,DA3 8BT,www.hartleyprimaryacademy.org.uk/,1474702742.0,Mr,Stuart,Mitchell,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Sevenoaks,Hartley and Hodsoll Street,Dartford,(England/Wales) Urban city and town,E10000016,560221.0,167409.0,Sevenoaks 004,Sevenoaks 004C,,,,,Outstanding,South-East England and South London,,100062688333.0,,Not applicable,Not applicable,,,E02005090,E01024443,40.0,
139664,886,Kent,4007,Wye School,Free schools,Free Schools,Open,New Provision,03-09-2013,,,Secondary,11.0,18,Not applicable,No Nursery Classes,Has a sixth form,Mixed,None,None,,Non-selective,600.0,Not applicable,19-01-2023,573.0,295.0,278.0,17.5,Supported by a multi-academy trust,UNITED LEARNING TRUST,Linked to a sponsor,United Learning Trust,Not applicable,,10041669.0,,Not applicable,11-12-2018,15-04-2024,Olantigh Road,,,Wye,Kent,TN25 5EJ,http://www.wyeschool.org.uk/,1233811110.0,Mr,Luke,Magee,Principal,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Ashford,Wye with Hinxhill,Ashford,(England/Wales) Rural town and fringe,E10000016,605615.0,146915.0,Ashford 001,Ashford 001E,Ofsted,,,,Good,South-East England and South London,,10012843405.0,,Not applicable,Not applicable,,,E02004996,E01024041,88.0,
139685,886,Kent,2024,Copperfield Academy,Academy sponsor led,Academies,Open,New Provision,01-11-2013,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,480.0,Not applicable,19-01-2023,443.0,231.0,212.0,34.1,Supported by a multi-academy trust,REACH2 ACADEMY TRUST,Linked to a sponsor,REAch2 Academy Trust,Not applicable,,10041614.0,,Not applicable,06-05-2021,13-09-2023,Dover Road East,Northfleet,,Gravesend,Kent,DA11 0RB,www.copperfieldacademy.org,1474352488.0,,Ben,Clark,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Coldharbour & Perry Street,Gravesham,(England/Wales) Urban major conurbation,E10000016,563486.0,173483.0,Gravesham 004,Gravesham 004D,,,,,Good,South-East England and South London,,100062310549.0,,Not applicable,Not applicable,,,E02005058,E01024283,145.0,
139696,886,Kent,2025,The Wells Free School,Free schools,Free Schools,Open,New Provision,01-09-2013,,,Primary,4.0,11,Not applicable,No Nursery Classes,Does not have a sixth form,Mixed,None,None,,Not applicable,210.0,Not applicable,19-01-2023,208.0,115.0,93.0,13.0,Supported by a single-academy trust,THE WELLS FREE SCHOOL,-,,Not applicable,,10041721.0,,Not applicable,18-06-2019,07-05-2024,King Charles Square,,,Tunbridge Wells,Kent,TN4 8FA,www.thewellsfreeschool.co.uk/,1892739075.0,Mrs,Katharine,Le Page,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Culverden,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558235.0,139866.0,Tunbridge Wells 008,Tunbridge Wells 008E,Ofsted,,,,Good,South-East England and South London,,10024139359.0,,Not applicable,Not applicable,,,E02005169,E01035012,27.0,
139697,886,Kent,4009,Hadlow Rural Community School,Free schools,Free Schools,Open,New Provision,01-09-2013,,,Secondary,11.0,16,Not applicable,No Nursery Classes,Does not have a sixth form,Mixed,None,None,,Non-selective,375.0,Not applicable,19-01-2023,371.0,224.0,147.0,24.0,Supported by a single-academy trust,HADLOW RURAL COMMUNITY SCHOOL LIMITED,-,,Not applicable,,10041646.0,,Not applicable,26-02-2019,20-05-2024,Tonbridge Road,,,Hadlow,Kent,TN11 0AU,www.hrcschool.org,1732498120.0,Mr,Paul,Boxall,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Bourne,Tonbridge and Malling,(England/Wales) Rural hamlet and isolated dwellings,E10000016,562706.0,149711.0,Tonbridge and Malling 008,Tonbridge and Malling 008C,Ofsted,,,,Good,South-East England and South London,,10092971671.0,,Not applicable,Not applicable,,,E02005156,E01024745,89.0,
139810,886,Kent,2026,Petham Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2013,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,115.0,Not applicable,19-01-2023,103.0,50.0,53.0,16.5,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10042015.0,,Not applicable,05-07-2019,31-05-2024,Petham,,,Canterbury,Kent,CT4 5RD,http://www.petham.kent.sch.uk/,1227700260.0,Mr,Scott,Guy,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Chartham & Stone Street,Canterbury,(England/Wales) Rural village,E10000016,613071.0,151303.0,Canterbury 017,Canterbury 017C,,,,,Good,South-East England and South London,,200000675436.0,,Not applicable,Not applicable,,,E02005026,E01024054,17.0,
139822,886,Kent,2027,Archbishop Courtenay Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Church of England,Diocese of Canterbury,Not applicable,315.0,Not applicable,19-01-2023,307.0,162.0,145.0,36.2,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10042411.0,,Not applicable,07-06-2023,15-04-2024,Eccleston Road,Tovil,,Maidstone,Kent,ME15 6QN,www.archbishopcourtenay.org.uk/,1622754666.0,Mrs,Sue,Heather,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Maidstone,South,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,575645.0,154791.0,Maidstone 009,Maidstone 009D,,,,,Good,South-East England and South London,,10014313238.0,,Not applicable,Not applicable,,,E02005076,E01024401,111.0,
140012,886,Kent,2028,Cliftonville Primary School,Academy sponsor led,Academies,Open,New Provision,01-12-2013,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,862.0,Not applicable,19-01-2023,828.0,407.0,421.0,49.1,Supported by a multi-academy trust,COASTAL ACADEMIES TRUST,Linked to a sponsor,Coastal Academies Trust,Not applicable,,10042921.0,,Not applicable,18-01-2023,22-05-2024,Northumberland Avenue,Cliftonville,,Margate,Kent,CT9 3LY,www.cliftonvilleprimary.co.uk/,1843227575.0,Ms,Claire,Whichcord,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Cliftonville East,South Thanet,(England/Wales) Urban city and town,E10000016,637095.0,170622.0,Thanet 002,Thanet 002C,,,,,Outstanding,South-East England and South London,,100062307559.0,,Not applicable,Not applicable,,,E02005133,E01024655,390.0,
140167,886,Kent,2029,Tymberwood Academy,Academy sponsor led,Academies,Open,New Provision,01-02-2014,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,384.0,186.0,198.0,48.7,Supported by a multi-academy trust,REACH2 ACADEMY TRUST,Linked to a sponsor,REAch2 Academy Trust,Not applicable,,10043284.0,,Not applicable,03-03-2022,03-04-2024,Cerne Road,,,Gravesend,Kent,DA12 4BN,www.tymberwoodacademy.org/,1474361193.0,Mr,Frazer,Westmorland,Head Teacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,PD - Physical Disability,,,,,,,,,,,,,Resourced provision,10.0,8.0,,,South East,Gravesham,Riverview Park,Gravesham,(England/Wales) Urban major conurbation,E10000016,566437.0,172049.0,Gravesham 007,Gravesham 007B,,,,,Good,South-East England and South London,,100062312652.0,,Not applicable,Not applicable,,,E02005061,E01024310,175.0,
140168,886,Kent,2030,Valley Invicta Primary School At Aylesford,Academy sponsor led,Academies,Open,New Provision,01-12-2013,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,315.0,Not applicable,19-01-2023,381.0,189.0,192.0,18.4,Supported by a multi-academy trust,VALLEY INVICTA ACADEMIES TRUST,Linked to a sponsor,Valley Invicta Academies Trust,Not applicable,,10043311.0,,Not applicable,11-05-2023,25-04-2024,Teapot Lane,,,Aylesford,Kent,ME20 7JU,www.aylesford.viat.org.uk/,1622718192.0,Mr,Billy,Harrington,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Aylesford South & Ditton,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,571993.0,158332.0,Tonbridge and Malling 005,Tonbridge and Malling 005B,,,,,Outstanding,South-East England and South London,,100062389712.0,,Not applicable,Not applicable,,,E02005153,E01024718,70.0,
140322,886,Kent,2686,Furley Park Primary Academy,Academy converter,Academies,Open,Academy Converter,01-11-2013,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,Not applicable,19-01-2023,575.0,294.0,281.0,16.7,Supported by a multi-academy trust,ACE LEARNING,-,,Not applicable,,10043951.0,,Not applicable,06-07-2022,18-04-2024,Reed Crescent,Park Farm,Kingsnorth,Ashford,Kent,TN23 3PA,www.furleypark.org.uk/,1233501732.0,Mrs,Emma,Collip,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Park Farm South,Ashford,(England/Wales) Urban city and town,E10000016,601223.0,138948.0,Ashford 009,Ashford 009I,,,,,Requires improvement,South-East England and South London,,200002407842.0,,Not applicable,Not applicable,,,E02005004,E01032819,96.0,
140323,886,Kent,2286,Hamstreet Primary Academy,Academy converter,Academies,Open,Academy Converter,01-11-2013,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,315.0,No Special Classes,19-01-2023,269.0,132.0,137.0,15.2,Supported by a multi-academy trust,ACE LEARNING,-,,Not applicable,,10043950.0,,Not applicable,18-05-2023,29-05-2024,Hamstreet,,,Ashford,Kent,TN26 2EA,www.ham-street.org.uk/,1233732577.0,Mrs,Helen,Glancy,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Weald South,Ashford,(England/Wales) Rural town and fringe,E10000016,599958.0,133831.0,Ashford 014,Ashford 014D,,,,,Good,South-East England and South London,,10012848068.0,,Not applicable,Not applicable,,,E02005009,E01024037,41.0,
140393,886,Kent,2034,Thistle Hill Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,359.0,183.0,176.0,41.2,Supported by a multi-academy trust,THE STOUR ACADEMY TRUST,Linked to a sponsor,The Stour Academy Trust,Not applicable,,10053864.0,,Not applicable,27-04-2022,16-04-2024,Aspen Drive,Minster-on-Sea,,Sheerness,Kent,ME12 3UD,http://www.thistlehill.kent.sch.uk,1795899119.0,Ms,Rebecca,Handebeaux,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,10.0,10.0,,,South East,Swale,Sheppey Central,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,594815.0,172145.0,Swale 004,Swale 004H,,,,,Requires improvement,South-East England and South London,,10023203143.0,,Not applicable,Not applicable,,,E02005118,E01035298,148.0,
140430,886,Kent,2036,Valley Invicta Primary School At Leybourne Chase,Academy sponsor led,Academies,Open,New Provision,01-09-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,None,,Not applicable,220.0,Not applicable,19-01-2023,227.0,119.0,108.0,11.0,Supported by a multi-academy trust,VALLEY INVICTA ACADEMIES TRUST,Linked to a sponsor,Valley Invicta Academies Trust,Not applicable,,10053401.0,,Not applicable,22-02-2024,20-05-2024,Derby Drive,Leybourne Chase,,West Malling,Kent,ME19 5FF,www.leybournechase.viat.org.uk,1732840908.0,Mrs,Gemma,Robinson (Head of School),Executive Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,16.0,15.0,,,South East,Tonbridge and Malling,"Birling, Leybourne & Ryarsh",Tonbridge and Malling,(England/Wales) Rural hamlet and isolated dwellings,E10000016,567807.0,159097.0,Tonbridge and Malling 014,Tonbridge and Malling 014G,,,,,Good,South-East England and South London,,100062387483.0,,Not applicable,Not applicable,,,E02006833,E01035010,25.0,
140431,886,Kent,2037,Valley Invicta Primary School at Holborough Lakes,Academy sponsor led,Academies,Open,New Provision,01-09-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,227.0,Has Special Classes,19-01-2023,228.0,105.0,123.0,13.2,Supported by a multi-academy trust,VALLEY INVICTA ACADEMIES TRUST,Linked to a sponsor,Valley Invicta Academies Trust,Not applicable,,10052657.0,,Not applicable,31-01-2024,20-05-2024,Holborough Lakes,Pollyfield Close,,Snodland,Kent,ME6 5GR,www.holboroughlakes.viat.org.uk,1634242839.0,Mrs,Lisa,Vickers,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,17.0,15.0,,,South East,Tonbridge and Malling,Snodland West & Holborough Lakes,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,570281.0,162312.0,Tonbridge and Malling 002,Tonbridge and Malling 002I,,,,,Good,South-East England and South London,,10013924379.0,,Not applicable,Not applicable,,,E02005150,E01035006,30.0,
140432,886,Kent,2038,Valley Invicta Primary School At Kings Hill,Academy sponsor led,Academies,Open,New Provision,01-09-2015,,,Primary,4.0,11,Not applicable,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,222.0,122.0,100.0,13.1,Supported by a multi-academy trust,VALLEY INVICTA ACADEMIES TRUST,Linked to a sponsor,Valley Invicta Academies Trust,Not applicable,,10053404.0,,Not applicable,14-03-2024,22-05-2024,Warwick Way (Off Tower View),Kings Hill,,West Malling,Kent,ME19 4AL,www.kingshill.viat.org.uk,1732841695.0,Mrs,Steph,Guthrie,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,15.0,15.0,,,South East,Tonbridge and Malling,Kings Hill,Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,567363.0,155590.0,Tonbridge and Malling 007,Tonbridge and Malling 007E,,,,,Good,South-East England and South London,,10092970953.0,,Not applicable,Not applicable,,,E02005155,E01032825,29.0,
140433,886,Kent,2039,Martello Primary,Academy sponsor led,Academies,Open,New Provision,01-09-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,172.0,97.0,75.0,64.0,Supported by a multi-academy trust,TURNER SCHOOLS,Linked to a sponsor,Turner Schools,Not applicable,,10053863.0,,Not applicable,09-03-2022,24-05-2024,Warren Way,,,Folkestone,Kent,CT19 6DT,www.turnermartello.org,1303847540.0,Miss,Natalie,Barrow,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,17.0,15.0,,,South East,Folkestone and Hythe,Folkestone Harbour,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,623927.0,137063.0,Folkestone and Hythe 003,Folkestone and Hythe 003D,,,,,Good,South-East England and South London,,50114714.0,,Not applicable,Not applicable,,,E02005104,E01024503,110.0,
140520,886,Kent,3719,"St Joseph's Catholic Primary School, Aylesham",Academy converter,Academies,Open,Academy Converter,01-01-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,133.0,No Special Classes,19-01-2023,131.0,72.0,59.0,36.6,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10044505.0,,Not applicable,02-11-2021,25-01-2024,Ackholt Road,Aylesham,,Canterbury,Kent,CT3 3AS,www.stjosephs-aylesham.co.uk,1304840370.0,Mrs,Hester,Seager-Fleming,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,"Aylesham, Eythorne & Shepherdswell",Dover,(England/Wales) Rural town and fringe,E10000016,624091.0,152415.0,Dover 006,Dover 006F,,,,,Good,South-East England and South London,,10034883661.0,,Not applicable,Not applicable,,,E02005046,E01035315,48.0,
140521,886,Kent,2435,South Avenue Primary School,Academy converter,Academies,Open,Academy Converter,01-01-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,407.0,205.0,202.0,32.2,Supported by a multi-academy trust,FULSTON MANOR ACADEMIES TRUST,Linked to a sponsor,Fulston Manor Academies Trust,Not applicable,,10044503.0,,Not applicable,12-10-2022,30-05-2024,South Avenue,,,Sittingbourne,Kent,ME10 4SU,www.southavenue.kent.sch.uk,1795477750.0,Miss,Tracy,Cadwallader,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Roman,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,591229.0,163193.0,Swale 010,Swale 010D,,,,,Good,South-East England and South London,,200002532192.0,,Not applicable,Not applicable,,,E02005124,E01024599,131.0,
140537,886,Kent,5432,St Simon Stock Catholic School,Academy converter,Academies,Open,Academy Converter,01-01-2014,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Non-selective,1018.0,No Special Classes,19-01-2023,1106.0,584.0,522.0,14.9,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10044507.0,,Not applicable,13-10-2021,23-04-2024,Oakwood Park,,,Maidstone,Kent,ME16 0JP,http://www.ssscs.co.uk/,1622754551.0,Mrs,Andrea,Denny,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Heath,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,574251.0,155595.0,Maidstone 008,Maidstone 008C,,,,,Good,South-East England and South London,,200003717928.0,,Not applicable,Not applicable,,,E02005075,E01024367,134.0,
140592,886,Kent,2679,The Brent Primary School,Academy converter,Academies,Open,Academy Converter,01-02-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Non-selective,630.0,No Special Classes,19-01-2023,652.0,322.0,330.0,25.0,Supported by a multi-academy trust,CYGNUS ACADEMIES TRUST,Linked to a sponsor,Cygnus Academies Trust,Not applicable,,10044811.0,,Not applicable,22-02-2023,15-04-2024,London Road,Stone,,Dartford,Kent,DA2 6BA,www.brent.kent.sch.uk,1322223943.0,Mrs,Sarah,Rye,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Stone House,Dartford,(England/Wales) Urban major conurbation,E10000016,556186.0,173935.0,Dartford 006,Dartford 006A,,,,,Outstanding,South-East England and South London,,200000534113.0,,Not applicable,Not applicable,,,E02005033,E01024169,162.0,
140593,886,Kent,2685,The Gateway Primary Academy,Academy converter,Academies,Open,Academy Converter,01-02-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,210.0,110.0,100.0,12.4,Supported by a single-academy trust,THE GATEWAY PRIMARY ACADEMY,-,,Not applicable,,10044810.0,,Not applicable,29-06-2022,14-04-2024,Milestone Road,,,Dartford,Kent,DA2 6DW,www.gateway-pri.kent.sch.uk/,1322220090.0,Mr,Jamiel,Cassem,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Stone House,Dartford,(England/Wales) Urban major conurbation,E10000016,555850.0,174010.0,Dartford 005,Dartford 005D,,,,,Good,South-East England and South London,,200000544345.0,,Not applicable,Not applicable,,,E02005032,E01024163,26.0,
140595,886,Kent,5418,The Skinners' School,Academy converter,Academies,Open,Academy Converter,01-02-2014,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,945.0,No Special Classes,19-01-2023,1118.0,1118.0,0.0,4.2,Supported by a multi-academy trust,SKINNERS' ACADEMIES TRUST,Linked to a sponsor,The Skinners' Company,Not applicable,,10044808.0,,Not applicable,17-11-2021,25-04-2024,St John's Road,,,Tunbridge Wells,Kent,TN4 9PG,http://www.skinners-school.co.uk,1892520732.0,Mr,Edward,Wesson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,VI - Visual Impairment,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,Resourced provision,2.0,2.0,,,South East,Tunbridge Wells,St John's,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558264.0,140612.0,Tunbridge Wells 007,Tunbridge Wells 007D,,,,,Good,South-East England and South London,,10008661460.0,,Not applicable,Not applicable,,,E02005168,E01024838,34.0,
140640,886,Kent,5435,St Gregory's Catholic School,Academy converter,Academies,Open,Academy Converter,01-03-2014,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Non-selective,1082.0,No Special Classes,19-01-2023,1339.0,796.0,543.0,18.3,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10045187.0,,Not applicable,,07-05-2024,Reynolds Lane,,,Tunbridge Wells,Kent,TN4 9XL,http://www.sgschool.org.uk,1892527444.0,Mr,Michael,Wilson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,HI - Hearing Impairment,,,,,,,,,,,,,Resourced provision,,,,,South East,Tunbridge Wells,St John's,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558104.0,141564.0,Tunbridge Wells 002,Tunbridge Wells 002A,,,,,,South-East England and South London,,100062586238.0,,Not applicable,Not applicable,,,E02005163,E01024837,201.0,
140641,886,Kent,3890,"St Joseph's Catholic Primary School, Broadstairs",Academy converter,Academies,Open,Academy Converter,01-03-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,Not applicable,19-01-2023,199.0,100.0,99.0,30.7,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10045193.0,,Not applicable,09-06-2022,21-05-2024,"St Joseph's Catholic Primary School, Broadstairs",,St Peter's Park Road,Broadstairs,Kent,CT10 2BA,www.st-josephs-broadstairs.kent.sch.uk,1843861738.0,Mrs,Vicki,O'Halloran,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,Not Applicable,,,,,,,,,,,,,Resourced provision,186.0,210.0,,,South East,Thanet,St Peters,South Thanet,(England/Wales) Urban city and town,E10000016,638835.0,168425.0,Thanet 009,Thanet 009E,,,,,Requires improvement,South-East England and South London,,200003079311.0,,Not applicable,Not applicable,,,E02005140,E01024693,61.0,
140800,886,Kent,3900,Whitehill Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2014,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,19-01-2023,659.0,347.0,312.0,29.7,Supported by a multi-academy trust,THE DECUS EDUCATIONAL TRUST,Linked to a sponsor,Gravesend Grammar School,Not applicable,,10045602.0,,Not applicable,28-02-2024,22-05-2024,Sun Lane,,,Gravesend,Kent,DA12 5HN,www.whitehillprimary.com,1474352973.0,Mrs,Angela,Carpenter,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Gravesham,Whitehill & Windmill Hill,Gravesham,(England/Wales) Urban major conurbation,E10000016,565183.0,172378.0,Gravesham 005,Gravesham 005D,,,,,Requires improvement,South-East England and South London,,10012028072.0,,Not applicable,Not applicable,,,E02005059,E01024313,185.0,
140873,886,Kent,3889,"St Gregory's Catholic Primary School, Margate",Academy converter,Academies,Open,Academy Converter,01-05-2014,,,Primary,3.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,315.0,No Special Classes,19-01-2023,291.0,145.0,146.0,35.1,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10045950.0,,Not applicable,19-09-2019,14-05-2024,Nash Road,,,Margate,Kent,CT9 4BU,www.st-gregorys.kent.sch.uk,1843221896.0,Mr,David,Walker,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Salmestone,North Thanet,(England/Wales) Rural town and fringe,E10000016,635277.0,169530.0,Thanet 004,Thanet 004E,,,,,Good,South-East England and South London,,100062307601.0,,Not applicable,Not applicable,,,E02005135,E01024696,102.0,
140874,886,Kent,5446,"St Anselm's Catholic School, Canterbury",Academy converter,Academies,Open,Academy Converter,01-05-2014,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Non-selective,1071.0,No Special Classes,19-01-2023,1099.0,555.0,544.0,18.0,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10045938.0,,Not applicable,13-09-2023,05-06-2024,Old Dover Road,,,Canterbury,Kent,CT1 3EN,http://www.stanselmscanterbury.org.uk/,1227826200.0,Mr,J,Rowarth,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,PD - Physical Disability,,,,,,,,,,,,Resourced provision,16.0,15.0,,,South East,Canterbury,Barton,Canterbury,(England/Wales) Urban city and town,E10000016,616376.0,156068.0,Canterbury 016,Canterbury 016C,,,,,Good,South-East England and South London,,200000678848.0,,Not applicable,Not applicable,,,E02005025,E01024046,163.0,
140899,886,Kent,2223,Bobbing Village School,Academy converter,Academies,Open,Academy Converter,01-06-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,208.0,114.0,94.0,8.2,Supported by a multi-academy trust,BOURNE ALLIANCE MULTI ACADEMY TRUST,Linked to a sponsor,TIMU Academy Trust,Not applicable,,10046193.0,,Not applicable,22-02-2023,19-03-2024,Sheppey Way,Bobbing,,Sittingbourne,Kent,ME9 8PL,www.bourne-alliance-mat.org.uk,1795423939.0,Mr,Tim,Harwood,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,"Bobbing, Iwade and Lower Halstow",Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,588784.0,165079.0,Swale 009,Swale 009F,,,,,Outstanding,South-East England and South London,,200002532781.0,,Not applicable,Not applicable,,,E02005123,E01035304,17.0,
140900,886,Kent,2230,Iwade School,Academy converter,Academies,Open,Academy Converter,01-06-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,19-01-2023,621.0,326.0,295.0,12.6,Supported by a multi-academy trust,BOURNE ALLIANCE MULTI ACADEMY TRUST,Linked to a sponsor,TIMU Academy Trust,Not applicable,,10046192.0,,Not applicable,22-09-2022,19-10-2023,School Lane,Iwade,,Sittingbourne,Kent,ME9 8RS,www.iwade-ba-mat.org.uk,1795472578.0,Mrs,Katrine,Stewart,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,"Bobbing, Iwade and Lower Halstow",Sittingbourne and Sheppey,(England/Wales) Rural town and fringe,E10000016,589970.0,167845.0,Swale 007,Swale 007G,,,,,Good,South-East England and South London,,100062397902.0,,Not applicable,Not applicable,,,E02005121,E01032655,78.0,
140980,886,Kent,2041,The Holy Family Catholic Primary School,Academy sponsor led,Academies,Open,New Provision,01-06-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Roman Catholic,Archdiocese of Southwark,Not applicable,210.0,Not applicable,19-01-2023,209.0,112.0,97.0,51.7,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10046167.0,,Not applicable,12-10-2023,23-04-2024,Bicknor Road,Park Wood,,Maidstone,Kent,ME15 9PS,www.holyfamily.kent.sch.uk,1622756778.0,Mrs,Megan,Underhill,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Park Wood,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,578525.0,151872.0,Maidstone 013,Maidstone 013B,,,,,Good,South-East England and South London,,200003680167.0,,Not applicable,Not applicable,,,E02005080,E01024390,108.0,
140987,886,Kent,4012,The Leigh UTC,University technical college,Free Schools,Open,New Provision,01-09-2014,,,Secondary,11.0,18,Not applicable,No Nursery Classes,Has a sixth form,Mixed,None,Does not apply,,,960.0,Not applicable,19-01-2023,730.0,558.0,172.0,28.8,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10047247.0,,Not applicable,26-05-2022,15-04-2024,Brunel Way,,,Dartford,Kent,DA1 5TF,http://theleighutc.org.uk/,1322626600.0,Mr,Kevin,Watson,Principal,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Bridge,Dartford,(England/Wales) Rural town and fringe,E10000016,554583.0,175781.0,Dartford 001,Dartford 001F,,,,,Good,South-East England and South London,,10023439451.0,,Not applicable,Not applicable,,,E02005028,E01035271,178.0,
141025,886,Kent,2043,Jubilee Primary School,Free schools,Free Schools,Open,New Provision,01-09-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Christian,,,420.0,Not applicable,19-01-2023,301.0,160.0,141.0,25.2,Supported by a single-academy trust,JUBILEE PRIMARY SCHOOL,-,,Not applicable,,10047086.0,,Not applicable,18-10-2023,23-04-2024,Gatland Lane,,,Maidstone,Kent,ME16 8PF,www.jubileeprimaryschool.org.uk,1622808873.0,Dr,Marilyn,Nadesan,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Fant,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,573703.0,154618.0,Maidstone 009,Maidstone 009A,,,,,Outstanding,South-East England and South London,,200003717426.0,,Not applicable,Not applicable,,,E02005076,E01024360,76.0,
141065,886,Kent,3720,St Mary's Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-07-2014,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,185.0,94.0,91.0,25.9,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10046463.0,,Not applicable,17-11-2022,26-04-2024,St Richard's Road,,,Deal,Kent,CT14 9LF,www.stmarysdeal.co.uk/,1304375046.0,Mrs,Maria,Pullen,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Mill Hill,Dover,(England/Wales) Urban city and town,E10000016,635925.0,151281.0,Dover 005,Dover 005C,,,,,Good,South-East England and South London,,200001851337.0,,Not applicable,Not applicable,,,E02005045,E01024223,48.0,
141067,886,Kent,3743,"St Simon of England Roman Catholic Primary School, Ashford",Academy converter,Academies,Open,Academy Converter,01-07-2014,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,209.0,112.0,97.0,18.7,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10046324.0,,Not applicable,01-12-2022,21-05-2024,Noakes Meadow,,,Ashford,Kent,TN23 4RB,www.st-simon.kent.sch.uk,1233623199.0,Mr,Peter,McCabe,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Beaver,Ashford,(England/Wales) Urban city and town,E10000016,600090.0,141538.0,Ashford 007,Ashford 007B,,,,,Requires improvement,South-East England and South London,,100062559274.0,,Not applicable,Not applicable,,,E02005002,E01023975,39.0,
141085,886,Kent,2045,Skinners' Kent Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2015,,,Primary,4.0,11,Not applicable,No Nursery Classes,Does not have a sixth form,Mixed,None,None,,,210.0,Not applicable,19-01-2023,210.0,117.0,93.0,17.1,Supported by a multi-academy trust,SKINNERS' ACADEMIES TRUST,Linked to a sponsor,The Skinners' Company,Not applicable,,10053936.0,,Not applicable,07-02-2024,21-05-2024,The Avenue,Knights Wood,,Tunbridge Wells,Kent,TN2 3GS,www.skps.org.uk,1892553060.0,,Gemma,Wyatt,Executive Principal,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Sherwood,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,560430.0,141932.0,Tunbridge Wells 003,Tunbridge Wells 003B,,,,,Good,South-East England and South London,,10008671585.0,,Not applicable,Not applicable,,,E02005164,E01024839,36.0,
141156,886,Kent,3744,St Margaret Clitherow Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-08-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,420.0,No Special Classes,19-01-2023,397.0,191.0,206.0,7.3,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10046759.0,,Not applicable,02-11-2022,16-04-2024,Trench Road,,,Tonbridge,Kent,TN11 9NG,www.stmargaretclitherowschool.org.uk,1732358000.0,Mrs,Fiona,Oubridge,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tonbridge and Malling,Hildenborough,Tonbridge and Malling,(England/Wales) Rural village,E10000016,558678.0,148870.0,Tonbridge and Malling 010,Tonbridge and Malling 010D,,,,,Good,South-East England and South London,,10002908678.0,,Not applicable,Not applicable,,,E02005158,E01024754,29.0,
141157,886,Kent,3751,"St Thomas' Catholic Primary School, Sevenoaks",Academy converter,Academies,Open,Academy Converter,01-08-2014,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Non-selective,240.0,No Special Classes,19-01-2023,218.0,108.0,110.0,8.4,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10046758.0,,Not applicable,,17-05-2024,South Park,,,Sevenoaks,Kent,TN13 1EH,www.saintthomas.co.uk,1732453921.0,Mrs,Geraldine,Leahy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Sevenoaks,Sevenoaks Town and St John's,Sevenoaks,(England/Wales) Urban city and town,E10000016,552746.0,154671.0,Sevenoaks 012,Sevenoaks 012F,,,,,,South-East England and South London,,10035182527.0,,Not applicable,Not applicable,,,E02005098,E01024471,17.0,
141216,886,Kent,2048,Reculver Church of England Primary School,Academy sponsor led,Academies,Open,New Provision,01-07-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Church of England,Diocese of Canterbury,Not applicable,525.0,Not applicable,19-01-2023,493.0,247.0,246.0,20.7,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10047006.0,,Not applicable,04-07-2018,02-05-2024,Hillborough,,,Herne Bay,Kent,CT6 6TA,www.reculver.kent.sch.uk,1227375907.0,Mrs,Stella,Collins,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,VI - Visual Impairment,SLD - Severe Learning Difficulty,,,,,,,,,,,,Resourced provision,17.0,15.0,,,South East,Canterbury,Reculver,North Thanet,(England/Wales) Urban city and town,E10000016,621137.0,167984.0,Canterbury 002,Canterbury 002A,,,,,Outstanding,South-East England and South London,,10033163216.0,,Not applicable,Not applicable,,,E02005011,E01024094,102.0,
141217,886,Kent,4013,St Edmund's Catholic School,Academy sponsor led,Academies,Open,,01-07-2016,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Roman Catholic,None,Archdiocese of Southwark,Non-selective,600.0,Not applicable,19-01-2023,567.0,296.0,271.0,36.5,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10047005.0,,Not applicable,13-07-2022,21-05-2024,Old Charlton Road,,,Dover,Kent,CT16 2QB,www.st-edmunds.com,1304201551.0,Mrs,Grainne,Parsons,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Buckland,Dover,(England/Wales) Urban city and town,E10000016,631515.0,142620.0,Dover 011,Dover 011C,,,,,Good,South-East England and South London,,100062289422.0,,Not applicable,Not applicable,,,E02005051,E01024195,207.0,
141220,886,Kent,2051,St Mary of Charity CofE (Aided) Primary School,Academy sponsor led,Academies,Open,New Provision,01-08-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,None,Diocese of Canterbury,Not applicable,210.0,Not applicable,19-01-2023,208.0,105.0,103.0,36.5,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10047011.0,,Not applicable,11-07-2018,28-03-2024,Orchard Place,,,Faversham,Kent,ME13 8AP,,1795532496.0,Mrs,Louise,Rowley-Jones,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Abbey,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,601949.0,161379.0,Swale 015,Swale 015A,,,,,Outstanding,South-East England and South London,,200002530657.0,,Not applicable,Not applicable,,,E02005129,E01024551,76.0,
141308,886,Kent,3119,Adisham Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,97.0,49.0,48.0,19.6,Supported by a multi-academy trust,THE STOUR ACADEMY TRUST,Linked to a sponsor,The Stour Academy Trust,Not applicable,,10047192.0,,Not applicable,29-11-2023,17-05-2024,The Street,Adisham,,Canterbury,Kent,CT3 3JW,www.adisham.kent.sch.uk/,1304840246.0,Miss,Sophie,Metcalf,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Little Stour & Adisham,Canterbury,(England/Wales) Rural village,E10000016,622676.0,153952.0,Canterbury 018,Canterbury 018A,,,,,Outstanding,South-East England and South London,,100062619270.0,,Not applicable,Not applicable,,,E02005027,E01024042,19.0,
141329,886,Kent,2052,Kennington Church of England Academy,Academy sponsor led,Academies,Open,New Provision,01-11-2014,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,None,Diocese of Canterbury,Not applicable,360.0,Not applicable,19-01-2023,356.0,179.0,177.0,29.5,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10047449.0,,Not applicable,08-03-2023,29-01-2024,Upper Vicarage Road,Kennington,,Ashford,Kent,TN24 9AG,http://www.kenningtonacademy.co.uk,1233623744.0,Mrs,Karen,Godsell,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Kennington,Ashford,(England/Wales) Urban city and town,E10000016,602027.0,145151.0,Ashford 003,Ashford 003B,,,,,Good,South-East England and South London,,100062561303.0,,Not applicable,Not applicable,,,E02004998,E01023999,105.0,
141386,886,Kent,2054,St Edward's Catholic Primary School,Academy sponsor led,Academies,Open,,01-07-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,None,Archdiocese of Southwark,Not applicable,210.0,Not applicable,19-01-2023,197.0,97.0,100.0,50.3,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10047523.0,,Not applicable,22-05-2019,05-06-2024,New Road,,,Sheerness,Kent,ME12 1BW,www.st-edwards-sheerness.co.uk,1795662708.0,Mrs,Sara,Wakefield,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Sheerness,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,591704.0,174591.0,Swale 002,Swale 002B,,,,,Good,South-East England and South London,,200002533178.0,,Not applicable,Not applicable,,,E02005116,E01024614,99.0,
141471,886,Kent,3714,St Peter's Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,212.0,107.0,105.0,11.8,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10047621.0,,Not applicable,07-02-2024,20-05-2024,West Ridge,,,Sittingbourne,Kent,ME10 1UJ,www.st-peters-sittingbourne.co.uk,1795423479.0,Ms,Catherine,Vedamuttu,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Homewood,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,589880.0,162952.0,Swale 012,Swale 012D,,,,,Good,South-East England and South London,,200002527647.0,,Not applicable,Not applicable,,,E02005126,E01024630,25.0,
141472,886,Kent,3745,More Park Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,207.0,95.0,112.0,8.7,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10047622.0,,Not applicable,23-02-2023,16-04-2024,Lucks Hill,,,West Malling,Kent,ME19 6HN,www.moreparkprimary.co.uk/,1732843047.0,Mrs,Deborah,Seal,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,"East Malling, West Malling & Offham",Tonbridge and Malling,(England/Wales) Rural hamlet and isolated dwellings,E10000016,568701.0,157897.0,Tonbridge and Malling 014,Tonbridge and Malling 014C,,,,,Good,South-East England and South London,,200000960428.0,,Not applicable,Not applicable,,,E02006833,E01024783,18.0,
141497,886,Kent,3740,St Richard's Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,191.0,80.0,111.0,30.9,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10047638.0,,Not applicable,06-10-2022,29-05-2024,Castle Avenue,,,Dover,Kent,CT16 1EZ,http://www.st-richards.kent.sch.uk,1304201118.0,Mr,Colin,Taylor,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Town & Castle,Dover,(England/Wales) Urban city and town,E10000016,631763.0,142271.0,Dover 012,Dover 012E,,,,,Good,South-East England and South London,,100062288989.0,,Not applicable,Not applicable,,,E02005052,E01033209,59.0,
141532,886,Kent,5217,"Our Lady of Hartley Catholic Primary School, Hartley, Longfield",Academy converter,Academies,Open,Academy Converter,01-11-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,218.0,No Special Classes,19-01-2023,212.0,95.0,117.0,4.2,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10047893.0,,Not applicable,,14-11-2023,Stack Lane,Hartley,,Longfield,Kent,DA3 8BL,http://www.ourladyhartley.kent.sch.uk/,1474706385.0,Mr,James,Baker,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Hartley and Hodsoll Street,Dartford,(England/Wales) Urban city and town,E10000016,560720.0,167649.0,Sevenoaks 004,Sevenoaks 004A,,,,,,South-East England and South London,,10035182405.0,,Not applicable,Not applicable,,,E02005090,E01024441,9.0,
141534,886,Kent,2069,Dartford Primary Academy,Academy converter,Academies,Open,Academy Converter,01-11-2014,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,654.0,No Special Classes,19-01-2023,673.0,333.0,340.0,17.2,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10047892.0,,Not applicable,13-09-2023,09-04-2024,York Road,,,Dartford,Kent,DA1 1SQ,www.dartfordprimary.org.uk/,1322224453.0,Miss,Rebecca,Roberts,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Brent,Dartford,(England/Wales) Urban major conurbation,E10000016,554979.0,173734.0,Dartford 008,Dartford 008C,,,,,Good,South-East England and South London,,200000533723.0,,Not applicable,Not applicable,,,E02005035,E01024137,115.0,
141548,886,Kent,2055,Lansdowne Primary School,Academy sponsor led,Academies,Open,New Provision,01-11-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,397.0,201.0,196.0,33.5,Supported by a multi-academy trust,THE STOUR ACADEMY TRUST,Linked to a sponsor,The Stour Academy Trust,Not applicable,,10047877.0,,Not applicable,14-12-2022,29-05-2024,Gladstone Drive,,,Sittingbourne,Kent,ME10 3BH,www.lansdowne.kent.sch.uk/,1795423752.0,Mrs,Claire,Jobe,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Murston,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,592376.0,163394.0,Swale 011,Swale 011B,,,,,Good,South-East England and South London,,200002528849.0,,Not applicable,Not applicable,,,E02005125,E01024592,133.0,
141578,886,Kent,3019,Shorne Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-12-2014,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,209.0,114.0,95.0,4.8,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10048077.0,,Not applicable,08-03-2023,23-04-2024,Cob Drive,Shorne,,Gravesend,Kent,DA12 3DU,www.shorne.kent.sch.uk,1474822312.0,Miss,Tara,Hewett,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Higham & Shorne,Gravesham,(England/Wales) Rural village,E10000016,569273.0,171239.0,Gravesham 010,Gravesham 010E,,,,,Good,South-East England and South London,,100062312571.0,,Not applicable,Not applicable,,,E02005064,E01024301,10.0,
141579,886,Kent,5210,St Botolph's Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-12-2014,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,422.0,197.0,225.0,25.6,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10048078.0,,Not applicable,29-03-2023,10-05-2024,Dover Road,Northfleet,,Gravesend,Kent,DA11 9PL,www.st-botolphs.kent.sch.uk,1474365737.0,Mrs,Alice,Martin,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Rosherville,Gravesham,(England/Wales) Urban major conurbation,E10000016,562966.0,173733.0,Gravesham 001,Gravesham 001A,,,,,Good,South-East England and South London,,100062311179.0,,Not applicable,Not applicable,,,E02005055,E01024276,108.0,
141580,886,Kent,5222,"St Joseph's Catholic Primary School, Northfleet",Academy converter,Academies,Open,Academy Converter,01-12-2014,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,208.0,106.0,102.0,15.4,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10047684.0,,Not applicable,11-01-2023,13-09-2023,Springhead Road,Northfleet,,Gravesend,Kent,DA11 9QZ,www.st-josephs-northfleet.kent.sch.uk/,1474533515.0,Mr,Andrew,Baldock,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Northfleet & Springhead,Gravesham,(England/Wales) Urban major conurbation,E10000016,562589.0,173691.0,Gravesham 001,Gravesham 001B,,,,,Outstanding,South-East England and South London,,100062311131.0,,Not applicable,Not applicable,,,E02005055,E01024277,32.0,
141628,886,Kent,4633,Ursuline College,Academy converter,Academies,Open,Academy Converter,01-01-2015,,,Secondary,11.0,18,Not applicable,Not applicable,Has a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Non-selective,763.0,Not applicable,19-01-2023,978.0,473.0,505.0,26.4,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10048333.0,,Not applicable,09-11-2022,03-06-2024,225 Canterbury Road,,,Westgate-on-Sea,Kent,CT8 8LX,http://www.ursuline.kent.sch.uk/,1843834431.0,Miss,Danielle,Lancefield,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Westgate-on-Sea,North Thanet,(England/Wales) Urban city and town,E10000016,631675.0,169531.0,Thanet 007,Thanet 007B,,,,,Good,South-East England and South London,,200003078464.0,,Not applicable,Not applicable,,,E02005138,E01024713,218.0,
141629,886,Kent,5216,Stella Maris Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-01-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,211.0,106.0,105.0,19.0,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10048334.0,,Not applicable,21-06-2023,01-05-2024,Parkfield Road,,,Folkestone,Kent,CT19 5BY,www.stellamaris.kent.sch.uk/,1303252127.0,Mr,Andrew,Langley,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Broadmead,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,622234.0,136791.0,Folkestone and Hythe 006,Folkestone and Hythe 006E,,,,,Good,South-East England and South London,,50040637.0,,Not applicable,Not applicable,,,E02005107,E01024515,40.0,
141650,886,Kent,2180,South Borough Primary School,Academy converter,Academies,Open,Academy Converter,01-02-2015,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,480.0,No Special Classes,19-01-2023,509.0,240.0,269.0,23.2,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10048683.0,,Not applicable,26-04-2023,18-04-2024,Stagshaw Close,Postley Road,,Maidstone,Kent,ME15 6TL,http://www.southboroughprimary.org.uk,1622752161.0,Mr,Mathew,Currie,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,High Street,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,576421.0,154655.0,Maidstone 009,Maidstone 009C,,,,,Good,South-East England and South London,,200003683342.0,,Not applicable,Not applicable,,,E02005076,E01024374,116.0,
141659,886,Kent,2058,Charlton Church of England Primary School,Academy sponsor led,Academies,Open,New Provision,01-03-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,None,Diocese of Canterbury,Not applicable,210.0,Not applicable,19-01-2023,199.0,88.0,111.0,35.7,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10048211.0,,Not applicable,22-11-2023,23-04-2024,Barton Road,,,Dover,Kent,CT16 2LX,www.charlton.kent.sch.uk/,1304201275.0,Mrs,Sally-Anne,Pettersen,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Buckland,Dover,(England/Wales) Urban city and town,E10000016,631452.0,142470.0,Dover 011,Dover 011B,,,,,Good,South-East England and South London,,100062289316.0,,Not applicable,Not applicable,,,E02005051,E01024194,71.0,
141660,886,Kent,2059,Lydd Primary School,Academy sponsor led,Academies,Open,New Provision,01-03-2015,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,280.0,Not applicable,19-01-2023,274.0,150.0,124.0,50.6,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10048212.0,,Not applicable,13-09-2023,07-05-2024,20 Skinner Road,Lydd,,Romney Marsh,Kent,TN29 9HW,www.lyddprimary.org.uk,1797320362.0,Mrs,Nicki,Man,Head Teacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Walland & Denge Marsh,Folkestone and Hythe,(England/Wales) Rural town and fringe,E10000016,604171.0,120623.0,Folkestone and Hythe 013,Folkestone and Hythe 013C,,,,,Good,South-East England and South London,,50114553.0,,Not applicable,Not applicable,,,E02005114,E01024534,129.0,
141754,886,Kent,2625,Godinton Primary School,Academy converter,Academies,Open,Academy Converter,01-03-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,419.0,229.0,190.0,13.6,Supported by a single-academy trust,GODINTON ACADEMY TRUST,-,,Not applicable,,10048785.0,,Not applicable,07-02-2024,03-06-2024,Lockholt Close,,,Ashford,Kent,TN23 3JR,http://www.godinton.kent.sch.uk,1233621616.0,,Jillian,Talbot,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Godinton,Ashford,(England/Wales) Urban city and town,E10000016,599006.0,143191.0,Ashford 016,Ashford 016D,,,,,Good,South-East England and South London,,100062558565.0,,Not applicable,Not applicable,,,E02007047,E01023993,57.0,
141766,886,Kent,2596,Chilton Primary School,Academy converter,Academies,Open,Academy Converter,01-03-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,418.0,211.0,207.0,18.9,Supported by a multi-academy trust,VIKING ACADEMY TRUST,-,,Not applicable,,10048967.0,,Not applicable,10-01-2019,17-09-2023,Chilton Lane,,,Ramsgate,Kent,CT11 0LQ,http://www.chiltonprimary.co.uk/,1843597695.0,Mr,Alex,McAuley,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Cliffsend and Pegwell,South Thanet,(England/Wales) Urban city and town,E10000016,636338.0,164593.0,Thanet 017,Thanet 017A,,,,,Outstanding,South-East England and South London,,100062281920.0,,Not applicable,Not applicable,,,E02005148,E01024650,79.0,
141871,886,Kent,2060,Beaver Green Primary School,Academy sponsor led,Academies,Open,New Provision,01-04-2015,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,480.0,248.0,232.0,44.6,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10049033.0,,Not applicable,14-03-2023,15-05-2024,Cuckoo Lane,,,Ashford,Kent,TN23 5DA,www.beaver-green.kent.sch.uk,1233621989.0,Ms,Tina,Oakley,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Beaver,Ashford,(England/Wales) Urban city and town,E10000016,599449.0,141135.0,Ashford 007,Ashford 007C,,,,,Good,South-East England and South London,,200004396685.0,,Not applicable,Not applicable,,,E02005002,E01023977,193.0,
141881,886,Kent,2061,Finberry Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2015,,,Primary,2.0,11,,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,350.0,Has Special Classes,19-01-2023,334.0,175.0,159.0,22.3,Supported by a multi-academy trust,THE STOUR ACADEMY TRUST,Linked to a sponsor,The Stour Academy Trust,Not applicable,,10053381.0,,Not applicable,24-01-2024,20-05-2024,Avocet Way,Finberry,,Ashford,Kent,TN25 7GS,http://www.finberryprimaryschool.org.uk/,1233622686.0,Headteacher,Siobhan,Risley,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,"SEMH - Social, Emotional and Mental Health",,,,,,,,,,,,,Resourced provision,5.0,8.0,,,South East,Ashford,"Mersham, Sevington South with Finberry",Ashford,(England/Wales) Urban city and town,E10000016,602230.0,139442.0,Ashford 010,Ashford 010E,,,,,Good,South-East England and South London,United Kingdom,10012868578.0,,Not applicable,Not applicable,,,E02005005,E01034987,71.0,
142052,886,Kent,2063,Istead Rise Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,243.0,125.0,118.0,16.5,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10049666.0,,Not applicable,28-02-2024,22-05-2024,Downs Road,Northfleet,,Gravesend,Kent,DA13 9HG,,1474833177.0,Mr,Steven,Payne,Executive Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,"Istead Rise, Cobham & Luddesdown",Gravesham,(England/Wales) Rural town and fringe,E10000016,563354.0,169714.0,Gravesham 012,Gravesham 012A,,,,,Good,South-East England and South London,,10012011594.0,,Not applicable,Not applicable,,,E02005066,E01024268,40.0,
142117,886,Kent,2064,Ramsgate Arts Primary School,Free schools,Free Schools,Open,New Provision,01-09-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,None,,,420.0,Not applicable,19-01-2023,355.0,161.0,194.0,29.9,Supported by a multi-academy trust,VIKING ACADEMY TRUST,-,,Not applicable,,10053814.0,,Not applicable,28-09-2023,13-12-2023,140-144 Newington Road,,,Ramsgate,Kent,CT12 6PP,http://www.ramsgateartsprimaryschool.co.uk/,1843582847.0,Mr,Nicholas,Budge,Executive Head Teacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Northwood,South Thanet,(England/Wales) Urban city and town,E10000016,636761.0,166126.0,Thanet 013,Thanet 013D,,,,,Good,South-East England and South London,,100061133646.0,,Not applicable,Not applicable,,,E02005144,E01024685,106.0,
142156,886,Kent,3708,"St John's Catholic Primary School, Gravesend",Academy converter,Academies,Open,Academy Converter,01-07-2015,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,840.0,No Special Classes,19-01-2023,886.0,441.0,445.0,16.5,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10053098.0,,Not applicable,18-10-2023,23-04-2024,Rochester Road,,,Gravesend,Kent,DA12 2SY,http://www.stjohnsprimary.kent.sch.uk,1474534546.0,Co Headteacher,Caroline Barron,Paula Cooneyhan,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Gravesham,Denton,Gravesham,(England/Wales) Urban major conurbation,E10000016,565990.0,173541.0,Gravesham 003,Gravesham 003C,,,,,Good,South-East England and South London,,100062311904.0,,Not applicable,Not applicable,,,E02005057,E01024293,142.0,
142162,886,Kent,3715,"St Mary's Catholic Primary School, Whitstable",Academy converter,Academies,Open,Academy Converter,01-07-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,420.0,No Special Classes,19-01-2023,374.0,186.0,188.0,12.3,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10053095.0,,Not applicable,08-11-2023,21-05-2024,Northwood Road,,,Whitstable,Kent,CT5 2EY,http://www.st-marys-whitstable.kent.sch.uk,1227272692.0,Mrs,Michele,Blunt,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Canterbury,Tankerton,Canterbury,(England/Wales) Urban city and town,E10000016,611618.0,166842.0,Canterbury 007,Canterbury 007E,,,,,Good,South-East England and South London,,100062300983.0,,Not applicable,Not applicable,,,E02005016,E01024116,46.0,
142188,886,Kent,2073,Langley Park Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2016,,,Primary,3.0,11,,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,451.0,232.0,219.0,15.5,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10053393.0,,Not applicable,19-06-2019,15-04-2024,Edmett Way,,,Maidstone,Kent,ME17 3FX,www.langleyparkprimaryacademy.org.uk,1622250880.0,Miss,Sally,Brading,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,10.0,10.0,,,South East,Maidstone,Park Wood,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,579116.0,151664.0,Maidstone 015,Maidstone 015H,,,,,Good,South-East England and South London,,10093304704.0,,Not applicable,Not applicable,,,E02005082,E01034999,70.0,
142346,886,Kent,2110,Culverstone Green Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,212.0,121.0,91.0,10.8,Supported by a multi-academy trust,THE GOLDEN THREAD ALLIANCE,-,,Not applicable,,10054199.0,,Not applicable,18-10-2018,18-04-2024,Wrotham Road,Meopham,,Gravesend,Kent,DA13 0RF,http://www.cgps.kent.sch.uk,1732822568.0,,James,Bernard,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Meopham South & Vigo,Gravesham,(England/Wales) Rural hamlet and isolated dwellings,E10000016,563542.0,163114.0,Gravesham 013,Gravesham 013A,,,,,Good,South-East England and South London,,100062312941.0,,Not applicable,Not applicable,,,E02005067,E01024273,23.0,
142347,886,Kent,2650,Dymchurch Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,311.0,No Special Classes,19-01-2023,159.0,73.0,86.0,36.5,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10054200.0,,Not applicable,27-04-2022,15-05-2024,New Hall Close,Dymchurch,,Romney Marsh,Kent,TN29 0LE,http://www.dymchurch.kent.sch.uk,1303872377.0,Mr,Iain,Rudgyard,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Romney Marsh,Folkestone and Hythe,(England/Wales) Rural town and fringe,E10000016,610150.0,129670.0,Folkestone and Hythe 011,Folkestone and Hythe 011A,,,,,Requires improvement,South-East England and South London,,50009728.0,,Not applicable,Not applicable,,,E02005112,E01024486,58.0,
142363,886,Kent,2462,Riverview Infant School,Academy converter,Academies,Open,Academy Converter,01-10-2015,,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,360.0,No Special Classes,19-01-2023,330.0,167.0,163.0,19.1,Supported by a multi-academy trust,THE GOLDEN THREAD ALLIANCE,-,,Not applicable,,10054175.0,,Not applicable,08-12-2021,09-04-2024,Cimba Wood,,,Gravesend,Kent,DA12 4SD,www.riverview-infant.com,1474566484.0,Mrs,Kerrie,Ward,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Riverview Park,Gravesham,(England/Wales) Urban major conurbation,E10000016,566337.0,171561.0,Gravesham 008,Gravesham 008B,,,,,Good,South-East England and South London,,10012012176.0,,Not applicable,Not applicable,,,E02005062,E01024298,63.0,
142372,886,Kent,5228,St Georges CofE (Aided) Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,393.0,189.0,204.0,20.6,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10054170.0,,Not applicable,07-02-2024,20-05-2024,Chequers Road,,,Sheerness,Kent,ME12 3QU,http://www.st-georges-sheppey.kent.sch.uk/,1795877667.0,Mr,Howard,Fisher,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Sheppey Central,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,596107.0,172691.0,Swale 005,Swale 005D,,,,,Good,South-East England and South London,,200002530151.0,,Not applicable,Not applicable,,,E02005119,E01024620,81.0,
142429,886,Kent,3140,Kingsnorth Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-11-2015,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,420.0,202.0,218.0,11.2,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10054668.0,,Not applicable,09-10-2018,22-04-2024,Church Hill,Kingsnorth,,Ashford,Kent,TN23 3EF,www.kingsnorth.kent.sch.uk,1233622673.0,Mr,Iain,Witts,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Kingsnorth Village & Bridgefield,Ashford,(England/Wales) Urban city and town,E10000016,600571.0,139333.0,Ashford 010,Ashford 010G,,,,,Good,South-East England and South London,,100062558563.0,,Not applicable,Not applicable,,,E02005005,E01034989,47.0,
142517,886,Kent,2076,Cherry Orchard Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2017,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,,,,Not applicable,450.0,Not applicable,19-01-2023,446.0,223.0,223.0,13.6,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10064709.0,,,10-11-2021,11-01-2024,Cherry Orchard,Cherry Orchard Road,Ebbsfleet Valley,Ebbsfleet,Kent,DA10 1AD,www.cherryorchardprimaryacademy.org.uk,1322242011.0,Mrs,Julie,Forsythe,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,14.0,15.0,,,South East,Dartford,Ebbsfleet,Dartford,(England/Wales) Urban major conurbation,E10000016,560297.0,173251.0,Dartford 002,Dartford 002H,,,,,Outstanding,South-East England and South London,United Kingdom,10023446223.0,,Not applicable,Not applicable,,,E02005029,E01035280,60.0,
142591,886,Kent,3915,Manor Community Primary School,Academy converter,Academies,Open,Academy Converter,01-02-2016,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,674.0,No Special Classes,19-01-2023,670.0,334.0,336.0,31.2,Supported by a multi-academy trust,CYGNUS ACADEMIES TRUST,Linked to a sponsor,Cygnus Academies Trust,Not applicable,,10055399.0,,Not applicable,31-10-2018,29-05-2024,Keary Road,,,Swanscombe,Kent,DA10 0BU,www.manor.kent.sch.uk/,1322383314.0,Mrs,Natalie,Hill,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Swanscombe,Dartford,(England/Wales) Urban major conurbation,E10000016,560606.0,173953.0,Dartford 004,Dartford 004B,,,,,Good,South-East England and South London,,10023438316.0,,Not applicable,Not applicable,,,E02005031,E01024176,199.0,
142613,886,Kent,2077,Westgate Primary School,Academy sponsor led,Academies,Open,New Provision,01-04-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,210.0,101.0,109.0,21.0,Supported by a multi-academy trust,CYGNUS ACADEMIES TRUST,Linked to a sponsor,Cygnus Academies Trust,Not applicable,,10055488.0,,,06-03-2019,02-06-2024,Summerhill Road,,,Dartford,Kent,DA1 2LP,https://www.westgateprimary.org/,1322223382.0,Mrs,Laura,Crosley,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Town,Dartford,(England/Wales) Urban major conurbation,E10000016,553773.0,173889.0,Dartford 003,Dartford 003C,,,,,Good,South-East England and South London,,100062616136.0,,Not applicable,Not applicable,,,E02005030,E01024182,44.0,
142689,886,Kent,3306,Brenchley and Matfield Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-05-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,196.0,93.0,103.0,9.7,Supported by a multi-academy trust,THE TENAX SCHOOLS TRUST,Linked to a sponsor,The Tenax Schools Trust,Not applicable,,10056161.0,,Not applicable,15-11-2018,13-09-2023,Market Heath,Brenchley,,Tonbridge,Kent,TN12 7NY,www.bmprimary.org.uk,1892722929.0,Miss,Jane,Mallon,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Brenchley and Horsmonden,Tunbridge Wells,(England/Wales) Rural village,E10000016,567404.0,141906.0,Tunbridge Wells 004,Tunbridge Wells 004A,,,,,Good,South-East England and South London,,100062546036.0,,Not applicable,Not applicable,,,E02005165,E01024793,19.0,
142814,886,Kent,2078,St Nicholas Church of England Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-06-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,,Diocese of Canterbury,Not applicable,378.0,Not applicable,19-01-2023,396.0,212.0,184.0,34.8,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10056538.0,,,23-05-2019,08-05-2024,Fairfield Road,,,New Romney,Kent,TN28 8BP,www.st-nicholas-newromney.kent.sch.uk,1797361906.0,Mr,Christopher,Dale,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,2.0,14.0,,,South East,Folkestone and Hythe,New Romney,Folkestone and Hythe,(England/Wales) Rural town and fringe,E10000016,606585.0,125146.0,Folkestone and Hythe 012,Folkestone and Hythe 012C,,,,,Good,South-East England and South London,,50002925.0,,Not applicable,Not applicable,,,E02005113,E01024539,138.0,
142834,886,Kent,2079,Woodlands Primary School,Community school,Local authority maintained schools,Open,Result of Amalgamation,01-09-2016,,,Primary,4.0,11,Not applicable,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,,Not applicable,630.0,Not applicable,19-01-2023,643.0,355.0,288.0,20.7,Not applicable,,Not applicable,,Not under a federation,,10058897.0,,,12-06-2019,11-04-2024,Higham School Lane,Hunt Road,,Tonbridge,Kent,TN10 4BB,www.woodlands.kent.sch.uk,1732355577.0,Mrs,Vicki,Lonie,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tonbridge and Malling,Higham,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,560317.0,148629.0,Tonbridge and Malling 011,Tonbridge and Malling 011C,,,,,Good,South-East England and South London,,10013922163.0,,Not applicable,Not applicable,,,E02005159,E01024749,133.0,
142924,886,Kent,2080,Barming Primary School,Academy sponsor led,Academies,Open,New Provision,01-07-2016,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,467.0,244.0,223.0,25.1,Supported by a multi-academy trust,ORCHARD ACADEMY TRUST,Linked to a sponsor,Allington Primary School Academy Trust (Orchard Academy Trust),Not applicable,,10056809.0,,,09-05-2019,30-04-2024,Belmont Close,Barming,,Maidstone,Kent,ME16 9DY,https://www.barming.kent.sch.uk/,1622726472.0,Mr,Christopher,Laker,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Barming and Teston,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,572627.0,154790.0,Maidstone 014,Maidstone 014A,,,,,Good,South-East England and South London,,200003720125.0,,Not applicable,Not applicable,,,E02005081,E01024325,107.0,
143073,886,Kent,2309,Priory Fields School,Academy converter,Academies,Open,Academy Converter,01-08-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,365.0,178.0,187.0,57.3,Supported by a multi-academy trust,WHINLESS DOWN ACADEMY TRUST,-,,Not applicable,,10057450.0,,Not applicable,20-11-2018,08-05-2024,Astor Avenue,,,Dover,Kent,CT17 0FS,http://www.prioryfields.kent.sch.uk,1304211543.0,Miss,Casey,Hall,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Tower Hamlets,Dover,(England/Wales) Urban city and town,E10000016,630848.0,141634.0,Dover 011,Dover 011H,,,,,Good,South-East England and South London,,10034874352.0,,Not applicable,Not applicable,,,E02005051,E01024248,209.0,
143075,886,Kent,2313,St Martin's School,Academy converter,Academies,Open,Academy Converter,01-08-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,194.0,102.0,92.0,17.0,Supported by a multi-academy trust,WHINLESS DOWN ACADEMY TRUST,-,,Not applicable,,10057448.0,,Not applicable,08-02-2024,20-05-2024,Markland Road,,,Dover,Kent,CT17 9LY,www.stmartins.kent.sch.uk/,1304206620.0,Mrs,Helen,Thompson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Maxton & Elms Vale,Dover,(England/Wales) Urban city and town,E10000016,630181.0,141199.0,Dover 014,Dover 014C,,,,,Good,South-East England and South London,,100062290538.0,,Not applicable,Not applicable,,,E02005054,E01024213,33.0,
143218,886,Kent,3914,Oakfield Primary Academy,Academy converter,Academies,Open,Academy Converter,01-09-2016,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,Has Special Classes,19-01-2023,719.0,383.0,336.0,27.5,Supported by a multi-academy trust,THE GOLDEN THREAD ALLIANCE,-,,Not applicable,,10057852.0,,Not applicable,06-10-2021,03-06-2024,Oakfield Lane,,,Dartford,Kent,DA1 2SW,http://www.oakfield-dartford.co.uk,1322220831.0,Mrs,Rajinder,Kaur-Gill,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,14.0,12.0,,,South East,Dartford,"Wilmington, Sutton-at-Hone & Hawley",Dartford,(England/Wales) Urban major conurbation,E10000016,553836.0,172851.0,Dartford 009,Dartford 009D,,,,,Good,South-East England and South London,,200000534405.0,,Not applicable,Not applicable,,,E02005036,E01024168,192.0,
143219,886,Kent,2657,Temple Hill Primary Academy,Academy converter,Academies,Open,Academy Converter,01-09-2016,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,914.0,Has Special Classes,19-01-2023,891.0,458.0,433.0,38.5,Supported by a multi-academy trust,THE GOLDEN THREAD ALLIANCE,-,,Not applicable,,10057853.0,,Not applicable,26-06-2019,03-06-2024,St Edmund's Road,Temple Hill,,Dartford,Kent,DA1 5ND,http://www.temple-hill.kent.sch.uk,1322224600.0,Mr,Leon,Dawson,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,5.0,8.0,3.0,12.0,South East,Dartford,Temple Hill,Dartford,(England/Wales) Urban major conurbation,E10000016,555040.0,175006.0,Dartford 001,Dartford 001I,,,,,Good,South-East England and South London,,200000530828.0,,Not applicable,Not applicable,,,E02005028,E01035274,329.0,
143220,886,Kent,2523,Upton Junior School,Academy converter,Academies,Open,Academy Converter,01-09-2016,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,512.0,No Special Classes,19-01-2023,513.0,263.0,250.0,22.2,Supported by a multi-academy trust,VIKING ACADEMY TRUST,-,,Not applicable,,10057856.0,,Not applicable,,05-06-2024,"Upton Junior School, Edge End Road",,,Broadstairs,Kent,CT10 2AH,http://www.uptonjunior.com/,1843861393.0,Miss,Darci,Arthur,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Viking,South Thanet,(England/Wales) Urban city and town,E10000016,638779.0,167831.0,Thanet 010,Thanet 010C,,,,,,South-East England and South London,,100062627193.0,,Not applicable,Not applicable,,,E02005141,E01024706,114.0,
143517,886,Kent,2081,Brenzett Church of England Primary School,Academy sponsor led,Academies,Open,New Provision,01-10-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,,Diocese of Canterbury,Not applicable,140.0,Not applicable,19-01-2023,83.0,40.0,43.0,38.6,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10061368.0,,,03-07-2019,18-04-2024,Straight Lane,,Brenzett,Romney Marsh,Kent,TN29 9UA,www.brenzett.kent.sch.uk,1797344335.0,Mrs,Rowan,Wright,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Walland & Denge Marsh,Folkestone and Hythe,(England/Wales) Rural hamlet and isolated dwellings,E10000016,600427.0,127014.0,Folkestone and Hythe 011,Folkestone and Hythe 011D,,,,,Good,South-East England and South London,,50100964.0,,Not applicable,Not applicable,,,E02005112,E01024548,32.0,
143605,886,Kent,5220,Halfway Houses Primary School,Academy converter,Academies,Open,Academy Converter,01-11-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,19-01-2023,591.0,302.0,289.0,28.4,Supported by a multi-academy trust,THE ISLAND LEARNING TRUST,Linked to a sponsor,The Island Learning Trust,Not applicable,,10061768.0,,Not applicable,13-11-2018,18-04-2024,Danley Road,Minster-on-Sea,,Sheerness,Kent,ME12 3AP,www.halfwayhouses.kent.sch.uk,1795662875.0,Mrs,Lindsay,Fordyce,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Queenborough and Halfway,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,593286.0,173082.0,Swale 004,Swale 004B,,,,,Good,South-East England and South London,,10093084941.0,,Not applicable,Not applicable,,,E02005118,E01024598,168.0,
143606,886,Kent,2235,Minster in Sheppey Primary School,Academy converter,Academies,Open,Academy Converter,01-11-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,600.0,No Special Classes,19-01-2023,579.0,285.0,294.0,25.9,Supported by a multi-academy trust,THE ISLAND LEARNING TRUST,Linked to a sponsor,The Island Learning Trust,Not applicable,,10061767.0,,Not applicable,10-03-2022,25-04-2024,Brecon Chase,Minster,,Sheerness,Kent,ME12 2HX,http://www.minster-sheppey.kent.sch.uk,1795872138.0,Mrs,Michelle Jeffery co-head,Lynne Lewis co-head,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Minster Cliffs,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,595361.0,173030.0,Swale 003,Swale 003D,,,,,Good,South-East England and South London,,200002530145.0,,Not applicable,Not applicable,,,E02005117,E01024589,150.0,
143787,886,Kent,2290,Tenterden Infant School,Academy converter,Academies,Open,Academy Converter,01-12-2016,,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,211.0,No Special Classes,19-01-2023,151.0,78.0,73.0,21.2,Supported by a multi-academy trust,TENTERDEN SCHOOLS TRUST,-,,Not applicable,,10061964.0,,Not applicable,05-02-2019,13-05-2024,Recreation Ground Road,,,Tenterden,Kent,TN30 6RA,www.tenterdenprimaryfederation.kent.sch.uk/,1580762086.0,Mrs,Tina,McIntosh,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Tenterden South,Ashford,(England/Wales) Rural town and fringe,E10000016,588615.0,133196.0,Ashford 013,Ashford 013F,,,,,Good,South-East England and South London,,100062567470.0,,Not applicable,Not applicable,,,E02005008,E01024025,32.0,
143788,886,Kent,3143,St Michael's Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-12-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,160.0,93.0,67.0,25.6,Supported by a multi-academy trust,TENTERDEN SCHOOLS TRUST,-,,Not applicable,,10061960.0,,Not applicable,12-12-2018,13-05-2024,Ashford Road,St Michael's,,Tenterden,Kent,TN30 6PU,www.stmcep.school,1580763210.0,Mrs,"Sara Williamson,",Mrs Jo Paskhin,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Tenterden St Michael's,Ashford,(England/Wales) Rural town and fringe,E10000016,588469.0,135486.0,Ashford 013,Ashford 013C,,,,,Good,South-East England and South London,,100062567391.0,,Not applicable,Not applicable,,,E02005008,E01024011,41.0,
143789,886,Kent,3144,Tenterden Church of England Junior School,Academy converter,Academies,Open,Academy Converter,01-12-2016,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Diocese of Canterbury,Not applicable,240.0,No Special Classes,19-01-2023,194.0,91.0,103.0,28.9,Supported by a multi-academy trust,TENTERDEN SCHOOLS TRUST,-,,Not applicable,,10061969.0,,Not applicable,11-12-2018,13-05-2024,Recreation Ground Road,,,Tenterden,Kent,TN30 6RA,www.tenterdenprimaryfederation.kent.sch.uk/,1580763717.0,Mrs,Tina,McIntosh,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Tenterden South,Ashford,(England/Wales) Rural town and fringe,E10000016,588577.0,133233.0,Ashford 013,Ashford 013F,,,,,Good,South-East England and South London,,200004397348.0,,Not applicable,Not applicable,,,E02005008,E01024025,56.0,
143954,886,Kent,4015,The Lenham School,Academy sponsor led,Academies,Open,New Provision,01-03-2017,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Does not apply,,Not applicable,Non-selective,1012.0,Not applicable,19-01-2023,779.0,392.0,387.0,23.0,Supported by a multi-academy trust,VALLEY INVICTA ACADEMIES TRUST,Linked to a sponsor,Valley Invicta Academies Trust,Not applicable,,10062504.0,,,06-11-2019,07-05-2024,Ham Lane,Lenham,,Maidstone,Kent,ME17 2LL,www.thelenham.viat.org.uk,1622858267.0,Mr,Robbie,Ferguson,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Harrietsham and Lenham,Faversham and Mid Kent,(England/Wales) Rural town and fringe,E10000016,589367.0,152380.0,Maidstone 011,Maidstone 011B,,,,,Good,South-East England and South London,,200003719333.0,,Not applicable,Not applicable,,,E02005078,E01024362,172.0,
143987,886,Kent,3324,"Leybourne, St Peter and St Paul Church of England Primary Academy",Academy converter,Academies,Open,Academy Converter,01-03-2017,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,216.0,No Special Classes,19-01-2023,216.0,103.0,113.0,6.5,Supported by a multi-academy trust,THE TENAX SCHOOLS TRUST,Linked to a sponsor,The Tenax Schools Trust,Not applicable,,10062539.0,,Not applicable,03-11-2021,09-05-2024,Rectory Lane North,Leybourne,,West Malling,Kent,ME19 5HD,http://www.leybourne.school,1732842008.0,,Tina,Holditch,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tonbridge and Malling,"Birling, Leybourne & Ryarsh",Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,569081.0,158746.0,Tonbridge and Malling 003,Tonbridge and Malling 003G,,,,,Good,South-East England and South London,,10002908134.0,,Not applicable,Not applicable,,,E02005151,E01024782,14.0,
144005,886,Kent,2658,Westcourt Primary School,Academy converter,Academies,Open,Academy Converter,01-02-2017,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,240.0,No Special Classes,19-01-2023,358.0,177.0,181.0,43.2,Supported by a multi-academy trust,THE PRIMARY FIRST TRUST,Linked to a sponsor,The Primary First Trust,Not applicable,,10062555.0,,Not applicable,27-11-2019,07-03-2024,Silver Road,,,Gravesend,Kent,DA12 4JG,www.westcourt.kent.sch.uk/,1474566411.0,Miss,Mags,Sexton,Acting Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Westcourt,Gravesham,(England/Wales) Urban major conurbation,E10000016,566426.0,172839.0,Gravesham 007,Gravesham 007C,,,,,Good,South-East England and South London,,100062312611.0,,Not applicable,Not applicable,,,E02005061,E01024311,145.0,
144015,886,Kent,4016,The Charles Dickens School,Academy sponsor led,Academies,Open,New Provision,01-03-2017,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,,Not applicable,Not applicable,1104.0,Not applicable,19-01-2023,1111.0,540.0,571.0,36.0,Supported by a multi-academy trust,BARTON COURT ACADEMY TRUST,Linked to a sponsor,Barton Court Academy Trust,Not applicable,,10062895.0,,,29-03-2023,23-04-2024,Broadstairs Road,,,Broadstairs,Kent,CT10 2RL,www.cds.kent.sch.uk,1843862988.0,Mr,Warren,Smith,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,VI - Visual Impairment,,,,,,,,,,,,,Resourced provision,3.0,5.0,,,South East,Thanet,St Peters,South Thanet,(England/Wales) Urban city and town,E10000016,638334.0,167981.0,Thanet 011,Thanet 011D,,,,,Good,South-East England and South London,,200003079311.0,,Not applicable,Not applicable,,,E02005142,E01024690,400.0,
144098,886,Kent,3021,Stone St Mary's CofE Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2017,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,630.0,No Special Classes,19-01-2023,645.0,327.0,318.0,18.8,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10063054.0,,Not applicable,05-02-2020,14-09-2023,Hayes Road,Horns Cross,,Greenhithe,Kent,DA9 9EF,http://www.stone.kent.sch.uk,1322382292.0,Mrs,Jane,Rolfe,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Stone Castle,Dartford,(England/Wales) Urban major conurbation,E10000016,557252.0,173910.0,Dartford 006,Dartford 006C,,,,,Good,South-East England and South London,,200000536262.0,,Not applicable,Not applicable,,,E02005033,E01024171,121.0,
144099,886,Kent,5215,Horton Kirby Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2017,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,240.0,No Special Classes,19-01-2023,236.0,114.0,122.0,20.8,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10063053.0,,Not applicable,17-05-2023,23-04-2024,Horton Road,Horton Kirby,,Dartford,Kent,DA4 9BN,www.hortonkirby.kent.sch.uk,1322863278.0,Mr,Glenn,Pollard,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Farningham, Horton Kirby and South Darenth",Sevenoaks,(England/Wales) Rural town and fringe,E10000016,556340.0,168608.0,Sevenoaks 005,Sevenoaks 005B,,,,,Good,South-East England and South London,,100062317327.0,,Not applicable,Not applicable,,,E02005091,E01024432,49.0,
144100,886,Kent,5411,Dartford Grammar School for Girls,Academy converter,Academies,Open,Academy Converter,01-06-2017,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1119.0,No Special Classes,19-01-2023,1248.0,41.0,1207.0,18.0,Supported by a multi-academy trust,THE ARETÉ TRUST,-,,Not applicable,,10063935.0,,Not applicable,20-10-2021,04-06-2024,Shepherds Lane,,,Dartford,Kent,DA1 2NT,http://www.dartfordgrammargirls.org.uk,1322223123.0,Mrs,Sharon,Pritchard,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,West Hill,Dartford,(England/Wales) Urban major conurbation,E10000016,553265.0,173905.0,Dartford 003,Dartford 003F,,,,,Outstanding,South-East England and South London,,200000532843.0,,Not applicable,Not applicable,,,E02005030,E01024185,160.0,
144354,886,Kent,4091,The Whitstable School,Academy converter,Academies,Open,Academy Converter,01-09-2018,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Does not apply,,Not applicable,Non-selective,1220.0,Not applicable,19-01-2023,1080.0,514.0,566.0,19.9,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10068468.0,,,13-03-2024,22-05-2024,Bellevue Road,,,Whitstable,Kent,CT5 1PX,www.thewhitstableschool.org.uk,1227931300.0,Mr,Alex,Holmes,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Gorrell,Canterbury,(England/Wales) Urban city and town,E10000016,611643.0,165739.0,Canterbury 009,Canterbury 009A,,,,,Good,South-East England and South London,,100062300161.0,,Not applicable,Not applicable,,,E02005018,E01024062,197.0,
144420,886,Kent,3716,St Teresa's Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-05-2017,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,218.0,No Special Classes,19-01-2023,213.0,100.0,113.0,14.6,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10063828.0,,Not applicable,16-01-2020,20-05-2024,Quantock Drive,,,Ashford,Kent,TN24 8QN,www.st-teresas.kent.sch.uk/,1233622797.0,Mrs,H,Bennett,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Furley,Ashford,(England/Wales) Urban city and town,E10000016,600520.0,143538.0,Ashford 015,Ashford 015D,,,,,Good,South-East England and South London,,100062560866.0,,Not applicable,Not applicable,,,E02007046,E01024022,31.0,
144531,886,Kent,2172,Valley Invicta Primary School At East Borough,Academy converter,Academies,Open,Academy Converter,01-11-2017,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,455.0,No Special Classes,19-01-2023,471.0,250.0,221.0,20.4,Supported by a multi-academy trust,VALLEY INVICTA ACADEMIES TRUST,Linked to a sponsor,Valley Invicta Academies Trust,Not applicable,,10065310.0,,Not applicable,14-10-2021,04-06-2024,Vinters Road,,,Maidstone,Kent,ME14 5DX,www.eastborough.viat.org.uk,1622754633.0,Mrs,C,Bacon,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,9.0,10.0,,,South East,Maidstone,East,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,576832.0,155960.0,Maidstone 005,Maidstone 005E,,,,,Good,South-East England and South London,,200003689415.0,,Not applicable,Not applicable,,,E02005072,E01024351,96.0,
144615,886,Kent,2085,Royal Rise Primary School,Academy sponsor led,Academies,Open,New Provision,01-07-2017,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,203.0,94.0,109.0,34.5,Supported by a multi-academy trust,CYGNUS ACADEMIES TRUST,Linked to a sponsor,Cygnus Academies Trust,Not applicable,,10064021.0,,,15-09-2021,29-04-2024,Royal Rise,,,Tonbridge,Kent,TN9 2DQ,,1732354143.0,Mrs,Sarah,Griggs,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Vauxhall,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,559446.0,145748.0,Tonbridge and Malling 012,Tonbridge and Malling 012H,,,,,Good,South-East England and South London,,200000966929.0,,Not applicable,Not applicable,,,E02005160,E01035009,70.0,
144634,886,Kent,2086,Bishop Chavasse Primary School,Free schools,Free Schools,Open,,01-09-2017,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Church of England,,Non-selective,420.0,Not applicable,19-01-2023,311.0,162.0,149.0,22.8,Supported by a multi-academy trust,THE TENAX SCHOOLS TRUST,Linked to a sponsor,The Tenax Schools Trust,Not applicable,,10064781.0,,,06-07-2022,03-04-2024,2a Baker Lane,,,Tonbridge,Kent,TN11 0FB,www.bishopchavasseschool.org.uk,1732676040.0,Mrs,Becks,Hood,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Tonbridge and Malling,Vauxhall,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,560184.0,145430.0,Tonbridge and Malling 012,Tonbridge and Malling 012E,,,,,Good,South-East England and South London,United Kingdom,10092972630.0,,Not applicable,Not applicable,,,E02005160,E01024767,71.0,
144668,886,Kent,2676,West Hill Primary Academy,Academy converter,Academies,Open,Academy Converter,01-09-2017,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,507.0,No Special Classes,19-01-2023,534.0,271.0,263.0,12.5,Supported by a multi-academy trust,THE GOLDEN THREAD ALLIANCE,-,,Not applicable,,10064807.0,,Not applicable,01-10-2021,03-06-2024,Dartford Road,,,Dartford,Kent,DA1 3DZ,www.west-hill.kent.sch.uk/,1322226019.0,Ms,Katy,Ward,Executive Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,West Hill,Dartford,(England/Wales) Urban major conurbation,E10000016,553136.0,174316.0,Dartford 003,Dartford 003D,,,,,Good,South-East England and South London,,100062309268.0,,Not applicable,Not applicable,,,E02005030,E01024183,67.0,
144716,886,Kent,4019,School of Science and Technology Maidstone,Free schools,Free Schools,Open,New Provision,01-09-2020,,,Secondary,11.0,19,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,,,1200.0,Not applicable,19-01-2023,576.0,385.0,191.0,9.9,Supported by a multi-academy trust,VALLEY INVICTA ACADEMIES TRUST,Linked to a sponsor,Valley Invicta Academies Trust,Not applicable,,10086463.0,,,25-01-2023,20-12-2023,New Cut Road,,,Maidstone,Kent,ME14 5GQ,,1622938444.0,Mr,Ryan,Royston (Head of School),,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Boxley,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,577636.0,155754.0,Maidstone 005,Maidstone 005B,,,,,Outstanding,South-East England and South London,United Kingdom,10094441687.0,,Not applicable,Not applicable,,,E02005072,E01024336,57.0,
144835,886,Kent,3343,Charing Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-07-2017,,,Primary,2.0,11,Not applicable,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,140.0,No Special Classes,19-01-2023,165.0,87.0,78.0,35.1,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10064466.0,,Not applicable,20-10-2021,19-02-2024,School Road,Charing,,Ashford,Kent,TN27 0JN,www.charingschool.org.uk/,1233712277.0,Mr,Thomas,Bird,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Charing,Ashford,(England/Wales) Rural town and fringe,E10000016,595188.0,149495.0,Ashford 002,Ashford 002B,,,,,Good,South-East England and South London,,100062563576.0,,Not applicable,Not applicable,,,E02004997,E01023986,52.0,
144836,886,Kent,3754,St Augustine's Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-07-2017,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,285.0,No Special Classes,19-01-2023,287.0,154.0,133.0,17.1,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10064464.0,,Not applicable,15-09-2021,03-06-2024,Wilman Road,,,Tunbridge Wells,Kent,TN4 9AL,https://www.st-augustines.kent.sch.uk/,1892529796.0,Mr,Jon,Crozier,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,St John's,Tunbridge Wells,(England/Wales) Urban city and town,E10000016,558501.0,141283.0,Tunbridge Wells 002,Tunbridge Wells 002A,,,,,Good,South-East England and South London,,100062586226.0,,Not applicable,Not applicable,,,E02005163,E01024837,49.0,
144867,886,Kent,3329,Borden Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-08-2017,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,126.0,No Special Classes,19-01-2023,123.0,64.0,59.0,14.6,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10064657.0,,Not applicable,29-06-2022,28-05-2024,School Lane,Borden,,Sittingbourne,Kent,ME9 8JS,www.borden.kent.sch.uk,1795472593.0,Miss,Georgina,Ingram,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Borden and Grove Park,Sittingbourne and Sheppey,(England/Wales) Rural village,E10000016,587791.0,163390.0,Swale 009,Swale 009A,,,,,Requires improvement,South-East England and South London,,100062626970.0,,Not applicable,Not applicable,,,E02005123,E01024554,18.0,
144868,886,Kent,3330,Bredgar Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-08-2017,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,106.0,No Special Classes,19-01-2023,108.0,52.0,56.0,10.2,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10064679.0,,Not applicable,12-01-2022,28-05-2024,Bexon Lane,Bredgar,,Sittingbourne,Kent,ME9 8HB,www.bredgar.kent.sch.uk/,1622884359.0,Miss,Joanna,Heath,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,West Downs,Sittingbourne and Sheppey,(England/Wales) Rural village,E10000016,588053.0,160269.0,Swale 013,Swale 013C,,,,,Good,South-East England and South London,,100062626605.0,,Not applicable,Not applicable,,,E02005127,E01024628,11.0,
144869,886,Kent,2463,Minterne Junior School,Academy converter,Academies,Open,Academy Converter,01-08-2017,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,360.0,Has Special Classes,19-01-2023,374.0,182.0,192.0,16.0,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10064678.0,,Not applicable,06-10-2021,23-04-2024,Minterne Avenue,,,Sittingbourne,Kent,ME10 1SB,http://www.minterne.org,1795472323.0,Ms,Kirsty,Warner,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,,,,,South East,Swale,Homewood,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,589818.0,162822.0,Swale 012,Swale 012D,,,,,Good,South-East England and South London,,200002527646.0,,Not applicable,Not applicable,,,E02005126,E01024630,60.0,
144870,886,Kent,2513,The Oaks Infant School,Academy converter,Academies,Open,Academy Converter,01-08-2017,,,Primary,3.0,7,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,Has Special Classes,19-01-2023,324.0,165.0,159.0,16.8,Supported by a multi-academy trust,OUR COMMUNITY MULTI ACADEMY TRUST,-,,Not applicable,,10064677.0,,Not applicable,24-11-2021,23-04-2024,Gore Court Road,,,Sittingbourne,Kent,ME10 1GL,http://www.theoaksinfantschool.co.uk,1795423619.0,Mrs,Jenny,Wynn,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,4.0,12.0,,,South East,Swale,Woodstock,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,589925.0,162789.0,Swale 012,Swale 012D,,,,,Good,South-East England and South London,,200002532277.0,,Not applicable,Not applicable,,,E02005126,E01024630,47.0,
144910,886,Kent,5204,Sutton-At-Hone Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2017,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,420.0,No Special Classes,19-01-2023,400.0,198.0,202.0,18.0,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10065030.0,,Not applicable,04-03-2020,26-03-2024,Church Road,Sutton-At-Hone,,Dartford,Kent,DA4 9EX,www.sutton-at-hone.kent.sch.uk/,1322862147.0,Mrs,Karen,Trowell,Acting Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,"Wilmington, Sutton-at-Hone & Hawley",Dartford,(England/Wales) Rural town and fringe,E10000016,555501.0,170379.0,Dartford 012,Dartford 012D,,,,,Good,South-East England and South London,,200000535148.0,,Not applicable,Not applicable,,,E02005039,E01024174,72.0,
145012,886,Kent,2087,Morehall Primary School and Nursery,Academy sponsor led,Academies,Open,Fresh Start,01-01-2017,,,Primary,2.0,11,,Has Nursery Classes,Not applicable,Mixed,None,None,,,210.0,Not applicable,19-01-2023,228.0,113.0,115.0,26.0,Supported by a multi-academy trust,TURNER SCHOOLS,Linked to a sponsor,Turner Schools,Not applicable,,10064517.0,,,02-10-2019,15-04-2024,Morehall Primary School and Nursery,Chart Road,,Folkestone,Kent,CT19 4PN,www.turnermorehall.org,1303275128.0,Mrs,Am'e,Moris,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,VI - Visual Impairment,,,,,,,,,,,,,Resourced provision,2.0,3.0,,,South East,Folkestone and Hythe,Cheriton,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,620753.0,136837.0,Folkestone and Hythe 006,Folkestone and Hythe 006C,,,,,Good,South-East England and South London,,50027301.0,,Not applicable,Not applicable,,,E02005107,E01024513,57.0,
145013,886,Kent,2090,Richmond Primary School,Academy sponsor led,Academies,Open,Fresh Start,01-01-2017,,,Primary,2.0,11,,Has Nursery Classes,Not applicable,Mixed,None,None,,,420.0,Not applicable,19-01-2023,325.0,156.0,169.0,64.2,Supported by a multi-academy trust,THE STOUR ACADEMY TRUST,Linked to a sponsor,The Stour Academy Trust,Not applicable,,10064518.0,,,09-11-2022,07-06-2024,Unity Street,,,Sheerness,Kent,ME12 2ET,,1795662891.0,,Lesley,Conway,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Sheerness,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,592928.0,174502.0,Swale 001,Swale 001D,,,,,Good,South-East England and South London,,100062378139.0,,Not applicable,Not applicable,,,E02005115,E01024612,188.0,
145014,886,Kent,2092,Knockhall Primary School,Academy sponsor led,Academies,Open,Fresh Start,01-01-2017,,,Primary,3.0,11,Not applicable,Has Nursery Classes,Not applicable,Mixed,None,None,,Not applicable,682.0,Not applicable,19-01-2023,385.0,215.0,170.0,33.7,Supported by a multi-academy trust,THE WOODLAND ACADEMY TRUST,Linked to a sponsor,The Woodland Academy Trust,Not applicable,,10064519.0,,,21-06-2023,10-05-2024,Eynsford Road,,,Greenhithe,Kent,DA9 9RF,www.knockhallprimaryschool.co.uk,1322382053.0,Miss,Kathryn,Yiannadji,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Greenhithe & Knockhall,Dartford,(England/Wales) Urban major conurbation,E10000016,559140.0,174692.0,Dartford 004,Dartford 004F,,,,,Requires improvement,South-East England and South London,,200000537409.0,,Not applicable,Not applicable,,,E02005031,E01035283,126.0,
145081,886,Kent,3059,"St Mark's Church of England Primary School, Eccles",Academy converter,Academies,Open,Academy Converter,01-11-2017,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,140.0,No Special Classes,19-01-2023,128.0,61.0,67.0,15.6,Supported by a multi-academy trust,THE PILGRIM MULTI ACADEMY TRUST,-,,Not applicable,,10065389.0,,Not applicable,22-03-2022,17-04-2024,Eccles Row,Eccles,,Aylesford,Kent,ME20 7HS,www.st-marks-aylesford.kent.sch.uk,1622717337.0,Mr,Jonathan,Bassett,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Aylesford North & North Downs,Chatham and Aylesford,(England/Wales) Rural town and fringe,E10000016,572898.0,160831.0,Tonbridge and Malling 001,Tonbridge and Malling 001F,,,,,Good,South-East England and South London,,200000961684.0,,Not applicable,Not applicable,,,E02005149,E01024728,20.0,
145115,886,Kent,2093,Chilmington Green Primary School,Free schools,Free Schools,Open,,03-09-2018,,,Primary,2.0,11,,Has Nursery Classes,Not applicable,Mixed,None,None,,,460.0,Not applicable,19-01-2023,205.0,110.0,95.0,21.5,Supported by a multi-academy trust,THE STOUR ACADEMY TRUST,Linked to a sponsor,The Stour Academy Trust,Not applicable,,10068096.0,,,07-12-2022,29-05-2024,Mock Lane,,,Ashford,Kent,TN23 3DS,www.chilmingtongreen.kent.sch.uk,1233228241.0,Miss,Tamsin,Mobbs,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,Not Applicable,,,,,,,,,,,,,Resourced provision,,15.0,,,South East,Ashford,Weald Central,Ashford,(England/Wales) Rural hamlet and isolated dwellings,E10000016,600157.0,141878.0,Ashford 012,Ashford 012F,,,,,Good,South-East England and South London,United Kingdom,10012877144.0,,Not applicable,Not applicable,,,E02005007,E01032814,42.0,
145117,886,Kent,2096,Riverview Junior School,Academy sponsor led,Academies,Open,New Provision,01-10-2017,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,,Not applicable,Not applicable,480.0,Not applicable,19-01-2023,504.0,257.0,247.0,24.6,Supported by a multi-academy trust,THE GOLDEN THREAD ALLIANCE,-,,Not applicable,,10065188.0,,,09-02-2022,22-05-2024,Cimba Wood,,,Gravesend,Kent,DA12 4SD,https://www.riverview-junior.co.uk/,1474352620.0,Mr,Aaron,Jones,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,SpLD - Specific Learning Difficulty,"SLCN - Speech, language and Communication",ASD - Autistic Spectrum Disorder,"SEMH - Social, Emotional and Mental Health",MLD - Moderate Learning Difficulty,,,,,,,,,Resourced provision,,,,,South East,Gravesham,Riverview Park,Gravesham,(England/Wales) Urban major conurbation,E10000016,566276.0,171553.0,Gravesham 008,Gravesham 008B,,,,,Good,South-East England and South London,,10012012179.0,,Not applicable,Not applicable,,,E02005062,E01024298,124.0,
145355,886,Kent,2531,Vale View Community School,Academy converter,Academies,Open,Academy Converter,01-01-2018,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,229.0,112.0,117.0,50.7,Supported by a multi-academy trust,WHINLESS DOWN ACADEMY TRUST,-,,Not applicable,,10066413.0,,Not applicable,27-04-2022,27-03-2024,Vale View Road,Elms Vale,,Dover,Kent,CT17 9NP,www.vale-view.kent.sch.uk,1304202821.0,Mrs,Lisa,Sprigmore,Acting Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Town & Castle,Dover,(England/Wales) Urban city and town,E10000016,630652.0,141278.0,Dover 013,Dover 013C,,,,,Good,South-East England and South London,,100062290539.0,,Not applicable,Not applicable,,,E02005053,E01024216,116.0,
145420,886,Kent,4020,Folkestone Academy,Academy sponsor led,Academies,Open,Fresh Start,01-12-2017,,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,None,None,,Non-selective,2170.0,Not applicable,19-01-2023,1080.0,538.0,542.0,45.8,Supported by a multi-academy trust,TURNER SCHOOLS,Linked to a sponsor,Turner Schools,Not applicable,,10066337.0,,,21-04-2022,14-05-2024,Academy Lane,,,Folkestone,Kent,CT19 5FP,www.folkestoneacademy.com,1303842400.0,Mr,Steven,Shaw,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Broadmead,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,621910.0,137354.0,Folkestone and Hythe 006,Folkestone and Hythe 006F,,,,,Good,South-East England and South London,United Kingdom,50120541.0,,Not applicable,Not applicable,,,E02005107,E01024516,426.0,
145815,886,Kent,2666,Wrotham Road Primary School,Academy converter,Academies,Open,Academy Converter,01-06-2018,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,446.0,235.0,211.0,29.5,Supported by a multi-academy trust,THE GOLDEN THREAD ALLIANCE,-,,Not applicable,,10067738.0,,Not applicable,06-10-2022,18-04-2024,Wrotham Road,,,Gravesend,Kent,DA11 0QF,http://www.wrotham-road.kent.sch.uk,1474534540.0,Ms,Nicole,Galinis,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Pelham,Gravesham,(England/Wales) Urban major conurbation,E10000016,564628.0,173560.0,Gravesham 002,Gravesham 002D,,,,,Good,South-East England and South London,,100062310321.0,,Not applicable,Not applicable,,,E02005056,E01024291,121.0,
145923,886,Kent,4021,Turner Free School,Free schools,Free Schools,Open,,01-09-2018,,,Secondary,11.0,18,,Not applicable,Has a sixth form,Mixed,None,None,,Non-selective,1260.0,No Special Classes,19-01-2023,826.0,430.0,396.0,35.6,Supported by a multi-academy trust,TURNER SCHOOLS,Linked to a sponsor,Turner Schools,Not applicable,,10068105.0,,,07-12-2022,21-05-2024,Tile Kiln Lane,Cheriton,,Folkestone,,CT19 4PB,www.turnerfreeschool.org,1303842400.0,Ms,Jennifer,van Deelen,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Folkestone and Hythe,Cheriton,Folkestone and Hythe,(England/Wales) Urban city and town,X999999,620593.0,137066.0,Folkestone and Hythe 006,Folkestone and Hythe 006C,,,,,Good,South-East England and South London,,50114755.0,,Not applicable,Not applicable,,,E02005107,E01024513,294.0,
145951,886,Kent,2098,Pilgrims' Way Primary School,Academy sponsor led,Academies,Open,Fresh Start,01-05-2018,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,,,420.0,Not applicable,19-01-2023,348.0,184.0,164.0,52.9,Supported by a multi-academy trust,VERITAS MULTI ACADEMY TRUST,Linked to a sponsor,Veritas Multi Academy Trust,Not applicable,,10067579.0,,,22-09-2022,14-05-2024,Pilgrims Way,,,Canterbury,,CT1 1XU,https://www.pilgrims-way.kent.sch.uk,1227760084.0,Mrs,Emma,Campbell,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Canterbury,Barton,Canterbury,(England/Wales) Urban city and town,E10000016,616215.0,157035.0,Canterbury 016,Canterbury 016B,,,,,Good,South-East England and South London,United Kingdom,200000683218.0,,Not applicable,Not applicable,,,E02005025,E01024045,171.0,
146081,886,Kent,2099,Edenbridge Primary School,Academy sponsor led,Academies,Open,New Provision,01-07-2018,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,450.0,No Special Classes,19-01-2023,407.0,206.0,201.0,38.2,Supported by a multi-academy trust,THE PIONEER ACADEMY,Linked to a sponsor,The Pioneer Academy,Not applicable,,10068058.0,,,12-10-2022,23-04-2024,High Street,,,Edenbridge,Kent,TN8 5AB,https://edenbridge.kent.sch.uk/kent/primary/edenbridge,1732863787.0,,Mary,Gates,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Edenbridge North and East,Tonbridge and Malling,(England/Wales) Rural town and fringe,E10000016,544347.0,146395.0,Sevenoaks 014,Sevenoaks 014A,,,,,Good,South-East England and South London,United Kingdom,100061001421.0,,Not applicable,Not applicable,,,E02005100,E01024425,153.0,
146114,886,Kent,2677,Coxheath Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2018,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,434.0,212.0,222.0,21.7,Supported by a multi-academy trust,COPPICE PRIMARY PARTNERSHIP,Linked to a sponsor,The Coppice Primary Partnership,Not applicable,,10068466.0,,Not applicable,08-02-2023,14-09-2023,Stockett Lane,Coxheath,,Maidstone,Kent,ME17 4PS,www.coxheath.kent.sch.uk/,1622745553.0,Mr,Giacomo,Mazza,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Coxheath and Hunton,Maidstone and The Weald,(England/Wales) Rural town and fringe,E10000016,574377.0,151268.0,Maidstone 016,Maidstone 016A,,,,,Good,South-East England and South London,,200003715377.0,,Not applicable,Not applicable,,,E02005083,E01024342,94.0,
146143,886,Kent,2044,Loose Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2018,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,,Not applicable,630.0,Not applicable,19-01-2023,656.0,343.0,313.0,8.1,Supported by a multi-academy trust,COPPICE PRIMARY PARTNERSHIP,Linked to a sponsor,The Coppice Primary Partnership,Not applicable,,10068467.0,,Not applicable,28-06-2023,07-05-2024,Loose Road,,,Maidstone,Kent,ME15 9UW,www.loose-primary.kent.sch.uk/,1622743549.0,Mr,Trevor,North,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Loose,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,576115.0,152490.0,Maidstone 016,Maidstone 016D,,,,,Good,South-East England and South London,,200003676025.0,,Not applicable,Not applicable,,,E02005083,E01024376,53.0,
146376,886,Kent,2107,Rosherville Church of England Academy,Academy sponsor led,Academies,Open,Fresh Start,01-09-2018,,,Primary,4.0,11,,No Nursery Classes,Not applicable,Mixed,Church of England,None,,,140.0,Not applicable,19-01-2023,141.0,76.0,65.0,41.8,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10081064.0,,,28-09-2022,26-04-2024,London Road,,,Northfleet,Kent,DA11 9JQ,www.rosherville.co.uk,1474365266.0,Mr,Marc,Dockrell,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Northfleet & Springhead,Gravesham,(England/Wales) Urban major conurbation,E10000016,562934.0,174025.0,Gravesham 001,Gravesham 001B,,,,,Good,South-East England and South London,United Kingdom,100062064703.0,,Not applicable,Not applicable,,,E02005055,E01024277,59.0,
146400,886,Kent,3313,Fordcombe Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2018,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,105.0,No Special Classes,19-01-2023,70.0,38.0,32.0,27.1,Supported by a multi-academy trust,THE TENAX SCHOOLS TRUST,Linked to a sponsor,The Tenax Schools Trust,Not applicable,,10081146.0,,Not applicable,18-10-2022,21-05-2024,The Green,Fordcombe,,Tunbridge Wells,Kent,TN3 0RY,http://www.fordcombe.kent.sch.uk,1892740224.0,Mr,Chris,Blackburn,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Penshurst, Fordcombe and Chiddingstone",Tonbridge and Malling,(England/Wales) Rural village,E10000016,552622.0,140271.0,Sevenoaks 015,Sevenoaks 015D,,,,,Good,South-East England and South London,,10035185120.0,,Not applicable,Not applicable,,,E02005101,E01024456,19.0,
146574,886,Kent,2062,Greenlands Primary School,Academy converter,Academies,Open,Academy Converter,01-02-2019,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,187.0,94.0,93.0,42.8,Supported by a multi-academy trust,CYGNUS ACADEMIES TRUST,Linked to a sponsor,Cygnus Academies Trust,Not applicable,,10082225.0,,Not applicable,18-05-2023,06-06-2024,Green Street Green Road,Darenth,,Dartford,Kent,DA2 8DH,www.greenlandsprimary.org.uk,1474703178.0,Mrs,Alison,Cook,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Darenth,Dartford,(England/Wales) Rural village,E10000016,557498.0,170938.0,Dartford 012,Dartford 012C,,,,,Requires improvement,South-East England and South London,,200000533883.0,,Not applicable,Not applicable,,,E02005039,E01024135,80.0,
146624,886,Kent,4023,Goodwin Academy,Academy sponsor led,Academies,Open,Fresh Start,01-09-2018,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,None,,Non-selective,1150.0,Not applicable,19-01-2023,900.0,435.0,465.0,32.5,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10081522.0,,,19-10-2022,03-06-2024,Hamilton Road,,,Deal,,CT14 9BD,https://www.goodwinacademy.org.uk/,3333602210.0,Mr,Phil,Jones,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,Resourced provision,14.0,13.0,,,South East,Dover,Middle Deal,Dover,(England/Wales) Urban city and town,E10000016,637076.0,151679.0,Dover 007,Dover 007A,,,,,Requires improvement,South-East England and South London,United Kingdom,100062286680.0,,Not applicable,Not applicable,,,E02005047,E01024218,276.0,
146950,886,Kent,5224,All Soul's Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2019,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,315.0,No Special Classes,19-01-2023,250.0,124.0,126.0,40.0,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10083010.0,,Not applicable,13-09-2023,23-04-2024,Stanley Road,,,Folkestone,Kent,CT19 4LG,www.allsouls.kent.sch.uk/,1303275967.0,Mrs,Lisa,Ransley,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Cheriton,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,620109.0,136784.0,Folkestone and Hythe 005,Folkestone and Hythe 005A,,,,,Good,South-East England and South London,,50028932.0,,Not applicable,Not applicable,,,E02005106,E01024491,100.0,
147053,886,Kent,3353,Deal Parochial Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2019,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,199.0,95.0,104.0,36.7,Supported by a multi-academy trust,DEAL EDUCATION ALLIANCE FOR LEARNING TRUST,-,,Not applicable,,10083015.0,,Not applicable,28-06-2023,28-03-2024,Gladstone Road,Walmer,,Deal,Kent,CT14 7ER,http://www.deal-parochial.kent.sch.uk,1304374464.0,Ms,Justine,Brown,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Walmer,Dover,(England/Wales) Urban city and town,E10000016,637295.0,151463.0,Dover 004,Dover 004D,,,,,Good,South-East England and South London,,200002882433.0,,Not applicable,Not applicable,,,E02005044,E01024252,73.0,
147054,886,Kent,3911,Hornbeam Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2019,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,240.0,Not applicable,19-01-2023,238.0,118.0,120.0,29.8,Supported by a multi-academy trust,DEAL EDUCATION ALLIANCE FOR LEARNING TRUST,-,,Not applicable,,10083013.0,,Not applicable,11-10-2023,01-05-2024,Mongeham Road,,,Deal,Kent,CT14 9PQ,www.hornbeam.kent.sch.uk,1304374033.0,Mrs,Rose,Cope,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Mill Hill,Dover,(England/Wales) Urban city and town,E10000016,635697.0,152063.0,Dover 005,Dover 005E,,,,,Good,South-East England and South London,,100062287063.0,,Not applicable,Not applicable,,,E02005045,E01024226,71.0,
147055,886,Kent,3172,Northbourne Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2019,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,140.0,No Special Classes,19-01-2023,132.0,69.0,63.0,6.8,Supported by a multi-academy trust,DEAL EDUCATION ALLIANCE FOR LEARNING TRUST,-,,Not applicable,,10083011.0,,Not applicable,18-07-2023,07-05-2024,Coldharbour Lane,Northbourne,,Deal,Kent,CT14 0LP,www.northbourne-cep.kent.sch.uk,1304611376.0,Mr,Matthew,Reynolds,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Eastry Rural,Dover,(England/Wales) Rural village,E10000016,632267.0,151903.0,Dover 005,Dover 005A,,,,,Good,South-East England and South London,,10034875643.0,,Not applicable,Not applicable,,,E02005045,E01024201,9.0,
147056,886,Kent,2659,Sandown School,Academy converter,Academies,Open,Academy Converter,01-04-2019,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,380.0,191.0,189.0,32.1,Supported by a multi-academy trust,DEAL EDUCATION ALLIANCE FOR LEARNING TRUST,-,,Not applicable,,10083016.0,,Not applicable,20-09-2023,20-05-2024,Golf Road,,,Deal,Kent,CT14 6PY,http://www.sandown.kent.sch.uk/,1304374951.0,Ms,Kate,Luxford,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,North Deal,Dover,(England/Wales) Urban city and town,E10000016,637419.0,153252.0,Dover 004,Dover 004B,,,,,Good,South-East England and South London,,100062285576.0,,Not applicable,Not applicable,,,E02005044,E01024230,122.0,
147057,886,Kent,3358,Sholden Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2019,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,105.0,No Special Classes,19-01-2023,97.0,46.0,51.0,21.6,Supported by a multi-academy trust,DEAL EDUCATION ALLIANCE FOR LEARNING TRUST,-,,Not applicable,,10083012.0,,Not applicable,14-06-2023,20-05-2024,London Road,Sholden,,Deal,Kent,CT14 0AB,www.sholdenprimary.org.uk,1304374852.0,Mrs,Dawn,Theaker,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Eastry Rural,Dover,(England/Wales) Urban city and town,E10000016,635694.0,152316.0,Dover 003,Dover 003A,,,,,Good,South-East England and South London,,100062285027.0,,Not applicable,Not applicable,,,E02005043,E01024219,21.0,
147058,886,Kent,3163,The Downs Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2019,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,420.0,No Special Classes,19-01-2023,317.0,156.0,161.0,36.9,Supported by a multi-academy trust,DEAL EDUCATION ALLIANCE FOR LEARNING TRUST,-,,Not applicable,,10083014.0,,Not applicable,13-09-2023,07-05-2024,Owen Square,Walmer,,Deal,Kent,CT14 7TL,http://www.downs.kent.sch.uk/,1304372486.0,Ms,Natalie,Luxford,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Walmer,Dover,(England/Wales) Urban city and town,E10000016,636946.0,150846.0,Dover 007,Dover 007D,,,,,Good,South-East England and South London,,100062286224.0,,Not applicable,Not applicable,,,E02005047,E01024250,117.0,
147059,886,Kent,4024,Stone Lodge School,Free schools,Free Schools,Open,New Provision,02-09-2019,,,Secondary,11.0,19,,No Nursery Classes,Has a sixth form,Mixed,None,None,,Non-selective,930.0,Not applicable,19-01-2023,677.0,392.0,285.0,26.9,Supported by a multi-academy trust,ENDEAVOUR MAT,-,,Not applicable,,10083768.0,,,18-10-2023,23-04-2024,Stone Lodge Road,,,Dartford,Kent,DA2 6FY,https://www.stonelodgeschool.co.uk/,1322250340.0,Mr,Gavin,Barnett,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Dartford,Stone Castle,Dartford,(England/Wales) Urban major conurbation,E10000016,556289.0,174355.0,Dartford 006,Dartford 006B,,,,,Good,South-East England and South London,United Kingdom,10094155641.0,,Not applicable,Not applicable,,,E02005033,E01024170,177.0,
147083,886,Kent,2112,River Mill Primary School,Free schools,Free Schools,Open,New Provision,02-09-2019,,,Primary,3.0,11,,Has Nursery Classes,Does not have a sixth form,Mixed,,,,Non-selective,420.0,Not applicable,19-01-2023,240.0,128.0,112.0,9.2,Supported by a multi-academy trust,CONNECT SCHOOLS ACADEMY TRUST,Linked to a sponsor,Connect Schools Academy Trust,Not applicable,,10083765.0,,,06-12-2023,20-05-2024,Central Road,,,Dartford,,DA1 5XR,www.rivermillprimaryschool.co.uk,1322466975.0,Ms,Suzanne,Leader,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Town,Dartford,(England/Wales) Urban major conurbation,E10000016,554517.0,175013.0,Dartford 001,Dartford 001J,,,,,Good,South-East England and South London,United Kingdom,10023444394.0,,Not applicable,Not applicable,,,E02005028,E01035275,22.0,
147104,886,Kent,2114,Cage Green Primary School,Academy sponsor led,Academies,Open,New Provision,01-07-2019,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,,421.0,Has Special Classes,19-01-2023,225.0,126.0,99.0,44.9,Supported by a multi-academy trust,CONNECT SCHOOLS ACADEMY TRUST,Linked to a sponsor,Connect Schools Academy Trust,Not applicable,,10083593.0,,Not applicable,09-11-2023,08-05-2024,Cage Green Road,,,Tonbridge,Kent,TN10 4PT,www.cage-green.kent.sch.uk,1732354325.0,,Joanna,Styles,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,19.0,22.0,,,South East,Tonbridge and Malling,Trench,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,559644.0,148493.0,Tonbridge and Malling 011,Tonbridge and Malling 011A,,,,,Good,South-East England and South London,,100062543771.0,,Not applicable,Not applicable,,,E02005159,E01024729,101.0,
147205,886,Kent,6156,VTC Independent School,Other independent school,Independent schools,Open,New Provision,04-05-2020,,,Not applicable,13.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Selective,32.0,Has Special Classes,20-01-2022,19.0,18.0,1.0,0.0,Not applicable,,Not applicable,,Not applicable,,,,,30-11-2023,04-06-2024,"Unit 2,",Centre 2000,St Michaels Road,Sittingbourne,Kent,ME10 3DZ,https://vtcindependentschool.co.uk/,1795899240.0,Mrs,Anna,Daly,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not approved,,,,,,,,,,,,,,,,,,,South East,Swale,Roman,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,591338.0,163638.0,Swale 010,Swale 010D,Ofsted,18.0,1.0,Vocational Training Centre Ltd,Good,South-East England and South London,United Kingdom,200002540944.0,,Not applicable,Not applicable,,,E02005124,E01024599,0.0,
147280,886,Kent,2135,Horsmonden Primary Academy,Academy converter,Academies,Open,Academy Converter,01-09-2019,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,180.0,94.0,86.0,10.0,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10084109.0,,Not applicable,19-10-2023,09-05-2024,Back Lane,Horsmonden,,Tonbridge,Kent,TN12 8NJ,https://horsmondenprimaryacademy.org.uk/,1892722529.0,Mrs,Hayley,Sharp,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Brenchley and Horsmonden,Tunbridge Wells,(England/Wales) Rural town and fringe,E10000016,570239.0,140737.0,Tunbridge Wells 011,Tunbridge Wells 011A,,,,,Good,South-East England and South London,,10008667663.0,,Not applicable,Not applicable,,,E02005172,E01024792,18.0,
147409,886,Kent,2127,Paddock Wood Primary Academy,Academy converter,Academies,Open,Academy Converter,01-09-2019,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,19-01-2023,611.0,325.0,286.0,18.0,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10084108.0,,Not applicable,09-11-2023,30-04-2024,Old Kent Road,Paddock Wood,,Tonbridge,Kent,TN12 6JE,www.paddockwoodprimaryacademy.org.uk,1892833654.0,Mr,Simon,Page (Interim),Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tunbridge Wells,Paddock Wood East,Tunbridge Wells,(England/Wales) Rural town and fringe,E10000016,566923.0,144859.0,Tunbridge Wells 001,Tunbridge Wells 001D,,,,,Good,South-East England and South London,,100062545661.0,,Not applicable,Not applicable,,,E02005162,E01024813,110.0,
147454,886,Kent,2117,Dartford Bridge Community Primary School,Academy sponsor led,Academies,Open,New Provision,01-10-2019,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,,446.0,No Special Classes,19-01-2023,471.0,242.0,229.0,8.6,Supported by a multi-academy trust,CYGNUS ACADEMIES TRUST,Linked to a sponsor,Cygnus Academies Trust,Not applicable,,10084107.0,,,28-02-2024,22-05-2024,Community Campus,Birdwood Avenue,,Dartford,Kent,DA1 5GB,dartfordbridgecps.com,1322470678.0,Mrs,Sarah,Smith,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Bridge,Dartford,(England/Wales) Rural town and fringe,E10000016,554858.0,176047.0,Dartford 001,Dartford 001F,,,,,Good,South-East England and South London,United Kingdom,10023437975.0,,Not applicable,Not applicable,,,E02005028,E01035271,36.0,
147563,886,Kent,2287,Rolvenden Primary School,Academy converter,Academies,Open,Academy Converter,01-11-2019,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,98.0,No Special Classes,19-01-2023,83.0,44.0,39.0,20.5,Supported by a multi-academy trust,TENTERDEN SCHOOLS TRUST,-,,Not applicable,,10084732.0,,Not applicable,,22-05-2024,Hastings Road,Rolvenden,,Cranbrook,Kent,TN17 4LS,http://www.rolvenden.kent.sch.uk,1580241444.0,,Ben,Vincer,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Ashford,Rolvenden & Tenterden West,Ashford,(England/Wales) Rural village,E10000016,584417.0,131221.0,Ashford 013,Ashford 013B,,,,,,South-East England and South London,,100062552639.0,,Not applicable,Not applicable,,,E02005008,E01024010,17.0,
147591,886,Kent,2118,St Katherine's School & Nursery,Academy sponsor led,Academies,Open,New Provision,01-11-2019,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,19-01-2023,511.0,257.0,254.0,28.0,Supported by a multi-academy trust,COPPICE PRIMARY PARTNERSHIP,Linked to a sponsor,The Coppice Primary Partnership,Not applicable,,10084731.0,,,31-01-2024,20-05-2024,St. Katherines Lane,,,Snodland,Kent,ME6 5EJ,www.stkatherineskent.co.uk,1634240061.0,Mr,Ray,Lang,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Snodland East & Ham Hill,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,569847.0,161292.0,Tonbridge and Malling 002,Tonbridge and Malling 002D,,,,,Good,South-East England and South London,United Kingdom,100062628713.0,,Not applicable,Not applicable,,,E02005150,E01024772,143.0,
147729,886,Kent,2126,Sunny Bank Primary School,Academy sponsor led,Academies,Open,New Provision,01-02-2020,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,315.0,Not applicable,19-01-2023,194.0,104.0,90.0,56.0,Supported by a multi-academy trust,THE ISLAND LEARNING TRUST,Linked to a sponsor,The Island Learning Trust,Not applicable,,10085416.0,,,,16-05-2024,Sunny Bank,Murston,,Sittingbourne,Kent,ME10 3QN,www.sunnybank.kent.sch.uk,1795473891.0,Mr,Jack,Allen,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Murston,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,591932.0,164074.0,Swale 011,Swale 011C,,,,,,South-East England and South London,United Kingdom,200002528712.0,,Not applicable,Not applicable,,,E02005125,E01024593,94.0,
147749,886,Kent,2237,Queenborough School and Nursery,Academy converter,Academies,Open,Academy Converter,01-03-2020,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,470.0,233.0,237.0,37.2,Supported by a multi-academy trust,EKC SCHOOLS TRUST LIMITED,-,,Not applicable,,10085584.0,,Not applicable,04-07-2023,03-05-2024,Edward Road,,,Queenborough,Kent,ME11 5DF,http://www.queenborough.kent.sch.uk,1795662574.0,Mr,Jason,Howard,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Queenborough and Halfway,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,591694.0,172082.0,Swale 005,Swale 005A,,,,,Outstanding,South-East England and South London,,100062626308.0,,Not applicable,Not applicable,,,E02005119,E01024594,162.0,
147750,886,Kent,2534,Bysing Wood Primary School,Academy converter,Academies,Open,Academy Converter,01-03-2020,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,236.0,128.0,108.0,46.5,Supported by a multi-academy trust,EKC SCHOOLS TRUST LIMITED,-,,Not applicable,,10085585.0,,Not applicable,,19-03-2024,Lower Road,,,Faversham,Kent,ME13 7NU,http://www.bysing-wood.kent.sch.uk,1795534644.0,Mr,Andrew,Harrison,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,St Ann's,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,600233.0,161634.0,Swale 014,Swale 014C,,,,,,South-East England and South London,,200002530516.0,,Not applicable,Not applicable,,,E02005128,E01024604,100.0,
147751,886,Kent,2569,Briary Primary School,Academy converter,Academies,Open,Academy Converter,01-03-2020,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,295.0,148.0,147.0,35.9,Supported by a multi-academy trust,EKC SCHOOLS TRUST LIMITED,-,,Not applicable,,10085586.0,,Not applicable,21-02-2024,20-05-2024,Greenhill Road,,,Herne Bay,Kent,CT6 7RS,www.briary.kent.sch.uk/,1227373095.0,Mrs,Kate,Espley,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Greenhill,North Thanet,(England/Wales) Urban city and town,E10000016,616083.0,166658.0,Canterbury 004,Canterbury 004B,,,,,Good,South-East England and South London,,200000682218.0,,Not applicable,Not applicable,,,E02005013,E01024065,106.0,
147752,886,Kent,2629,Holywell Primary School,Academy converter,Academies,Open,Academy Converter,01-03-2020,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,196.0,104.0,92.0,14.4,Supported by a multi-academy trust,EKC SCHOOLS TRUST LIMITED,-,,Not applicable,,10085587.0,,Not applicable,,03-06-2024,Forge Lane,Upchurch,,Sittingbourne,Kent,ME9 7AE,http://www.holywell.kent.sch.uk/,1634388416.0,Mrs,Nicky,Murrell,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,"Hartlip, Newington and Upchurch",Sittingbourne and Sheppey,(England/Wales) Rural village,E10000016,584508.0,167486.0,Swale 008,Swale 008D,,,,,,South-East England and South London,,200002533102.0,,Not applicable,Not applicable,,,E02005122,E01024573,25.0,
147850,886,Kent,2129,Springhead Park Primary School,Free schools,Free Schools,Open,New Provision,01-09-2020,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,,Non-selective,472.0,Not applicable,19-01-2023,368.0,176.0,192.0,20.1,Supported by a multi-academy trust,THE PRIMARY FIRST TRUST,Linked to a sponsor,The Primary First Trust,Not applicable,,10086458.0,,,25-05-2023,07-05-2024,Springhead Parkway,Springhead Park,,Northfleet,Kent,DA11 8BY,www.springheadparkprimary.com,1474555155.0,Mr,Wayne,Clayton,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Northfleet & Springhead,Gravesham,(England/Wales) Urban major conurbation,E10000016,562032.0,173001.0,Gravesham 006,Gravesham 006F,,,,,Good,South-East England and South London,United Kingdom,10012022831.0,,Not applicable,Not applicable,,,E02005060,E01035284,67.0,
147866,886,Kent,2131,Bearsted Primary Academy,Free schools,Free Schools,Open,New Provision,01-09-2020,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,,Non-selective,446.0,,19-01-2023,263.0,122.0,141.0,6.5,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10086483.0,,,25-01-2023,20-05-2024,Popesfield Way,Weavering,,Maidstone,Kent,ME14 5GA,https://bearstedprimaryacademy.org.uk/,1622250040.0,Mrs,Jane,Tipple,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Maidstone,Boxley,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,578618.0,156729.0,Maidstone 005,Maidstone 005B,,,,,Outstanding,South-East England and South London,United Kingdom,10095448157.0,,Not applicable,Not applicable,,,E02005072,E01024336,17.0,
147867,886,Kent,2140,Ebbsfleet Green Primary School,Free schools,Free Schools,Open,New Provision,01-09-2020,,,Primary,3.0,11,,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,,Non-selective,461.0,Not applicable,19-01-2023,262.0,148.0,114.0,8.4,Supported by a multi-academy trust,MARITIME ACADEMY TRUST,Linked to a sponsor,Maritime Academy Trust,Not applicable,,10086480.0,,,08-03-2023,14-09-2023,Ackers Drive Weldon,,Ebbsfleet Valley,Swanscombe,Kent,DA10 1AL,http://www.ebbsfleetgreenprimary.org.uk,1987591627.0,Mrs,Joanne,Wilkinson-Tabi,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,9.0,15.0,,,South East,Dartford,Ebbsfleet,Dartford,(England/Wales) Urban major conurbation,E10000016,560812.0,173242.0,Dartford 002,Dartford 002I,,,,,Good,South-East England and South London,United Kingdom,10094156607.0,,Not applicable,Not applicable,,,E02005029,E01035281,22.0,
147897,886,Kent,4027,The Holmesdale School,Academy sponsor led,Academies,Open,New Provision,01-09-2022,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,959.0,No Special Classes,19-01-2023,509.0,252.0,257.0,36.3,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10086757.0,,,,14-05-2024,Malling Road,,,Snodland,Kent,ME6 5HS,https://www.holmesdale.kent.sch.uk,1634240416.0,Mr,Lee,Downey,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,5.0,5.0,,,South East,Tonbridge and Malling,Snodland East & Ham Hill,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,569974.0,161137.0,Tonbridge and Malling 002,Tonbridge and Malling 002D,,,,,,South-East England and South London,United Kingdom,10002905073.0,,Not applicable,Not applicable,,,E02005150,E01024772,168.0,
148068,886,Kent,2143,Folkestone Primary,Academy sponsor led,Academies,Open,Split school,01-09-2020,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,,None,,,450.0,Not applicable,19-01-2023,424.0,211.0,213.0,24.1,Supported by a multi-academy trust,TURNER SCHOOLS,Linked to a sponsor,Turner Schools,Not applicable,,10086281.0,,,28-06-2023,14-05-2024,Academy Lane,,,Folkestone,,CT19 5FP,https://www.turnerfolkestoneprimary.com/home,1303842400.0,,Louise,Feaver,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Broadmead,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,621910.0,137354.0,Folkestone and Hythe 006,Folkestone and Hythe 006F,,,,,Good,South-East England and South London,United Kingdom,50120541.0,,Not applicable,Not applicable,,,E02005107,E01024516,102.0,
148116,886,Kent,2183,Marden Primary Academy,Academy converter,Academies,Open,Academy Converter,01-09-2020,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,275.0,No Special Classes,19-01-2023,281.0,154.0,127.0,29.9,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10086832.0,,,01-03-2023,14-04-2024,Goudhurst Road,Marden,,Tonbridge,Kent,TN12 9JX,www.mardenprimaryacademy.org.uk,1622831393.0,Mrs,Hannah,Penning,Acting Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Maidstone,Marden and Yalding,Maidstone and The Weald,(England/Wales) Rural town and fringe,E10000016,574009.0,144505.0,Maidstone 018,Maidstone 018C,Not applicable,,,,Good,South-East England and South London,,200003718702.0,,Not applicable,Not applicable,,,E02005085,E01024380,84.0,
148118,886,Kent,3106,Eastchurch Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2020,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,368.0,187.0,181.0,47.0,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10086841.0,,,12-07-2023,03-05-2024,Warden Road,Eastchurch,,Sheerness,Kent,ME12 4EJ,http://www.eastchurch.kent.sch.uk,1795880279.0,Mrs,Teresa,Oliver (Acting Head),Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Sheppey East,Sittingbourne and Sheppey,(England/Wales) Rural village,E10000016,598963.0,171467.0,Swale 006,Swale 006F,Not applicable,,,,Requires improvement,South-East England and South London,,100062626436.0,,Not applicable,Not applicable,,,E02005120,E01035301,162.0,
148144,886,Kent,1132,North West Kent Alternative Provision Service,Academy alternative provision sponsor led,Academies,Open,New Provision,01-09-2020,,,Not applicable,11.0,16,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,,Not applicable,19-01-2023,7.0,6.0,1.0,14.3,Supported by a multi-academy trust,ALTERNATIVE LEARNING TRUST,Linked to a sponsor,Alternative Learning Trust,Not applicable,,10086859.0,,,14-06-2023,05-06-2024,Richmond Drive,,,Gravesend,,DA12 4DJ,,1474332897.0,Ms,Abigail,Woodhouse,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Westcourt,Gravesham,(England/Wales) Urban major conurbation,E10000016,566417.0,172683.0,Gravesham 007,Gravesham 007C,,,,,Good,South-East England and South London,United Kingdom,10012024036.0,,Not applicable,Not applicable,,,E02005061,E01024311,1.0,
148217,886,Kent,5202,Holy Trinity Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-11-2020,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,470.0,No Special Classes,19-01-2023,457.0,239.0,218.0,27.3,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10087078.0,,,04-10-2023,30-04-2024,Trinity Road,,,Gravesend,Kent,DA12 1LU,www.holytrinity-gravesend.kent.sch.uk/,1474534746.0,Mrs,Pamela,Gough,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Town,Gravesham,(England/Wales) Urban major conurbation,E10000016,565155.0,173712.0,Gravesham 003,Gravesham 003A,Not applicable,,,,Good,South-East England and South London,,100062311696.0,,Not applicable,Not applicable,,,E02005057,E01024258,118.0,
148308,886,Kent,3173,Kingsdown and Ringwould Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-01-2021,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,210.0,No Special Classes,19-01-2023,213.0,114.0,99.0,14.1,Supported by a multi-academy trust,DEAL EDUCATION ALLIANCE FOR LEARNING TRUST,-,,Not applicable,,10087305.0,,,25-05-2023,20-02-2024,Glen Road,Kingsdown,,Deal,Kent,CT14 8DD,http://www.kingsdown-ringwould.kent.sch.uk,1304373734.0,Mrs,Joanne,Hygate,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Dover,"Guston, Kingsdown & St Margaret's-at-Cliffe",Dover,(England/Wales) Rural town and fringe,E10000016,637415.0,148426.0,Dover 009,Dover 009A,Not applicable,,,,Outstanding,South-East England and South London,,100062286573.0,,Not applicable,Not applicable,,,E02005049,E01024232,30.0,
148370,886,Kent,2327,Worth Primary School,Academy converter,Academies,Open,Academy Converter,01-03-2021,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,70.0,No Special Classes,19-01-2023,63.0,37.0,26.0,20.6,Supported by a multi-academy trust,DEAL EDUCATION ALLIANCE FOR LEARNING TRUST,-,,Not applicable,,10087569.0,,,07-02-2024,20-05-2024,The Street,,,Deal,Kent,CT14 0DF,http://www.worthprimary.co.uk,1304612148.0,Mrs,Katy,Chance,Executive Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Eastry Rural,South Thanet,(England/Wales) Rural village,E10000016,633761.0,156191.0,Dover 002,Dover 002B,Not applicable,,,,Good,South-East England and South London,,100062620829.0,,Not applicable,Not applicable,,,E02005042,E01024242,13.0,
148500,886,Kent,2259,Chartham Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2021,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,382.0,199.0,183.0,26.4,Supported by a multi-academy trust,INSPIRA ACADEMY TRUST,-,,Not applicable,,10088095.0,,,07-02-2024,20-05-2024,Shalmsford Street,Chartham,,Canterbury,Kent,CT4 7QN,http://www.charthamprimary.org.uk,1227738225.0,Mr,Jamie,Noble,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Chartham & Stone Street,Canterbury,(England/Wales) Rural hamlet and isolated dwellings,E10000016,610126.0,154535.0,Canterbury 017,Canterbury 017A,Not applicable,,,,Good,South-East England and South London,,200000682327.0,,Not applicable,Not applicable,,,E02005026,E01024052,101.0,
148501,886,Kent,2611,St Stephen's Infant School,Academy converter,Academies,Open,Academy Converter,01-04-2021,,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,269.0,146.0,123.0,28.3,Supported by a multi-academy trust,INSPIRA ACADEMY TRUST,-,,Not applicable,,10088094.0,,,24-01-2024,06-06-2024,Hales Drive,St Stephen's,,Canterbury,Kent,CT2 7AB,www.st-stephens-infant.kent.sch.uk,1227769204.0,Mrs,Alice,Edgington,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,St Stephen's,Canterbury,(England/Wales) Urban city and town,E10000016,614817.0,159227.0,Canterbury 013,Canterbury 013B,Not applicable,,,,Good,South-East England and South London,,200002882763.0,,Not applicable,Not applicable,,,E02005022,E01024100,76.0,
148502,886,Kent,2626,Sandwich Infant School,Academy converter,Academies,Open,Academy Converter,01-04-2021,,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,168.0,No Special Classes,19-01-2023,148.0,73.0,75.0,23.1,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10088093.0,,,30-01-2024,20-05-2024,School Road,,,Sandwich,Kent,CT13 9HT,www.sandwich-infant.kent.sch.uk/,1304612228.0,Miss,Leanne,Bennett,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dover,Sandwich,South Thanet,(England/Wales) Rural town and fringe,E10000016,632813.0,158407.0,Dover 002,Dover 002D,Not applicable,,,,Good,South-East England and South London,,100062284920.0,,Not applicable,Not applicable,,,E02005042,E01024244,34.0,
148519,886,Kent,5229,Fleetdown Primary Academy,Academy converter,Academies,Open,Academy Converter,01-04-2021,,,Primary,4.0,11,,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,654.0,No Special Classes,19-01-2023,648.0,345.0,303.0,13.3,Supported by a multi-academy trust,THE GOLDEN THREAD ALLIANCE,-,,Not applicable,,10088076.0,,,,03-06-2024,Lunedale Road,Darenth,,Dartford,Kent,DA2 6JX,http://www.fleetdown.kent.sch.uk,1322226891.0,Mrs,Alice,Harrington,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,HI - Hearing Impairment,,,,,,,,,,,,,Resourced provision,6.0,12.0,,,South East,Dartford,Brent,Dartford,(England/Wales) Urban major conurbation,E10000016,556256.0,173026.0,Dartford 008,Dartford 008E,Not applicable,,,,,South-East England and South London,,200000545083.0,,Not applicable,Not applicable,,,E02005035,E01024139,86.0,
148632,886,Kent,6164,MEPA ACADEMY,Other independent school,Independent schools,Open,New Provision,09-09-2021,,,Not applicable,11.0,16,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,,50.0,Not applicable,20-01-2022,17.0,3.0,14.0,0.0,Not applicable,,Not applicable,,Not applicable,,,,,29-09-2022,07-05-2024,27 & 29 EARL STREET,MAIDSTONE,KENT,,,ME14 1PF,https://www.mepaacademy.com/,1622756644.0,Mrs,Mandy,Ellen,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not approved,,,,,,,,,,,,,,,,,,,South East,Maidstone,High Street,Maidstone and The Weald,(England/Wales) Urban city and town,E10000016,575951.0,155842.0,Maidstone 004,Maidstone 004H,Ofsted,,6.0,Mandy Ellen Cook,Good,South-East England and South London,United Kingdom,10091815091.0,,Not applicable,Not applicable,,,E02005071,E01034991,0.0,
148711,886,Kent,2296,Mundella Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2021,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,173.0,87.0,86.0,56.1,Supported by a multi-academy trust,VERITAS MULTI ACADEMY TRUST,Linked to a sponsor,Veritas Multi Academy Trust,Not applicable,,10088877.0,,,,08-04-2024,Black Bull Road,,,Folkestone,Kent,CT19 5QX,http://www.mundella.kent.sch.uk,1303252265.0,Mrs,Lisa Paez and Lauren Wharmby,.,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,East Folkestone,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,622754.0,136911.0,Folkestone and Hythe 004,Folkestone and Hythe 004C,Not applicable,,,,,South-East England and South London,,50040639.0,,Not applicable,Not applicable,,,E02005105,E01024501,97.0,
148712,886,Kent,4246,The North School,Academy converter,Academies,Open,Academy Converter,01-01-2022,,,Secondary,11.0,19,No boarders,No Nursery Classes,Has a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Non-selective,1265.0,Not applicable,19-01-2023,1267.0,700.0,567.0,31.1,Supported by a multi-academy trust,SWALE ACADEMIES TRUST,Linked to a sponsor,Swale Academies Trust,Not applicable,,10088876.0,,,,28-05-2024,Essella Road,,,Ashford,Kent,TN24 8AL,https://www.thenorthschool.org.uk/,1233614600.0,Mrs,Clair,Ellerby,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision,25.0,25.0,,,South East,Ashford,Furley,Ashford,(England/Wales) Urban city and town,E10000016,601952.0,142258.0,Ashford 005,Ashford 005C,Not applicable,,,,,South-East England and South London,,100062560863.0,,Not applicable,Not applicable,,,E02005000,E01024023,350.0,
148876,886,Kent,2133,Halstead Community Primary School,Academy converter,Academies,Open,Academy Converter,01-03-2022,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,175.0,No Special Classes,19-01-2023,54.0,33.0,21.0,25.9,Supported by a multi-academy trust,THE PIONEER ACADEMY,Linked to a sponsor,The Pioneer Academy,Not applicable,,10089754.0,,,,03-06-2024,Otford Lane,Halstead,,Sevenoaks,Kent,TN14 7EA,www.halstead.kent.sch.uk,1959532224.0,Mrs,Sue,Saheed,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,"Halstead, Knockholt and Badgers Mount",Sevenoaks,(England/Wales) Rural village,E10000016,548908.0,161035.0,Sevenoaks 008,Sevenoaks 008D,Not applicable,,,,,South-East England and South London,,50002001021.0,,Not applicable,Not applicable,,,E02005094,E01024440,14.0,
148918,886,Kent,2119,Shears Green Infant School,Academy converter,Academies,Open,Academy Converter,01-07-2022,,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,360.0,No Special Classes,19-01-2023,342.0,163.0,179.0,21.3,Supported by a multi-academy trust,HORNCHURCH ACADEMY TRUST,-,,Not applicable,,10089902.0,,,,04-05-2024,Packham Road,Northfleet,,Gravesend,Kent,DA11 7JF,http://www.shearsgreeninfantschool.co.uk,1474566700.0,Ms,Hayley,Kotze,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Gravesham,Coldharbour & Perry Street,Gravesham,(England/Wales) Urban major conurbation,E10000016,563816.0,172261.0,Gravesham 009,Gravesham 009A,Not applicable,,,,,South-East England and South London,,100062310733.0,,Not applicable,Not applicable,,,E02005063,E01024264,73.0,
148991,886,Kent,2272,East Stour Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2022,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,472.0,No Special Classes,19-01-2023,438.0,233.0,205.0,36.2,Supported by a multi-academy trust,EKC SCHOOLS TRUST LIMITED,-,,Not applicable,,10090164.0,,,,07-06-2024,Earlsworth Road,South Willesborough,,Ashford,Kent,TN24 0DW,www.east-stour.kent.sch.uk/,1233630820.0,Mrs,E,Law,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Aylesford & East Stour,Ashford,(England/Wales) Urban city and town,E10000016,601863.0,140767.0,Ashford 009,Ashford 009G,Not applicable,,,,,South-East England and South London,,100062560510.0,,Not applicable,Not applicable,,,E02005004,E01032817,147.0,
148992,886,Kent,2672,Palm Bay Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2022,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,428.0,No Special Classes,19-01-2023,424.0,218.0,206.0,26.9,Supported by a multi-academy trust,EKC SCHOOLS TRUST LIMITED,-,,Not applicable,,10090163.0,,,,07-06-2024,Palm Bay Avenue,Cliftonville,,Margate,Kent,CT9 3PP,http://www.palmbay.uk,1843290050.0,Miss,Lizzie,Williams,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Cliftonville East,South Thanet,(England/Wales) Urban city and town,E10000016,637983.0,171167.0,Thanet 002,Thanet 002D,Not applicable,,,,,South-East England and South London,,100062307578.0,,Not applicable,Not applicable,,,E02005133,E01024656,114.0,
149039,886,Kent,4028,Barton Manor School,Free schools,Free Schools,Open,New Provision,01-09-2022,,,Secondary,11.0,19,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,1050.0,Not applicable,19-01-2023,149.0,71.0,78.0,36.9,Supported by a multi-academy trust,BARTON COURT ACADEMY TRUST,Linked to a sponsor,Barton Court Academy Trust,Not applicable,,10090861.0,,,,17-05-2024,Spring Lane,,,Canterbury,Kent,CT1 1SU,https://www.bartonmanor.org/,1227532140.0,Mr,Richard,Morgan,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Canterbury,Barton,Canterbury,(England/Wales) Urban city and town,E10000016,616290.0,157296.0,Canterbury 016,Canterbury 016B,,,,,,South-East England and South London,United Kingdom,10094587078.0,,Not applicable,Not applicable,,,E02005025,E01024045,55.0,
149123,886,Kent,3020,Sedley's Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-06-2022,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,105.0,No Special Classes,19-01-2023,99.0,57.0,42.0,9.1,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10090460.0,,,12-07-2023,07-06-2024,Church Street,Southfleet,,Gravesend,Kent,DA13 9NR,www.sedleys.kent.sch.uk/,1474833221.0,Mrs,T,Handley,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,"Longfield, New Barn & Southfleet",Dartford,(England/Wales) Rural village,E10000016,561345.0,171128.0,Dartford 013,Dartford 013A,Not applicable,,,,Good,South-East England and South London,,200000535394.0,,Not applicable,Not applicable,,,E02005040,E01024157,9.0,
149261,886,Kent,3718,St Augustine's Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2022,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,203.0,111.0,92.0,13.8,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10090965.0,,,,23-04-2024,St John's Road,,,Hythe,Kent,CT21 4BE,www.st-augustines-hythe.kent.sch.uk,1303266578.0,Mrs,Nicola,Clarke,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,Hythe,Folkestone and Hythe,(England/Wales) Urban city and town,E10000016,615271.0,135480.0,Folkestone and Hythe 008,Folkestone and Hythe 008A,Not applicable,,,,,South-East England and South London,,50017101.0,,Not applicable,Not applicable,,,E02005109,E01024523,28.0,
149319,886,Kent,4029,Aylesford School,Academy sponsor led,Academies,Open,New Provision,01-09-2022,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,1044.0,No Special Classes,19-01-2023,873.0,453.0,420.0,20.7,Supported by a multi-academy trust,CHARACTER EDUCATION TRUST,Linked to a sponsor,Wrotham School,Not applicable,,10091142.0,,,,06-06-2024,Teapot Lane,,,Aylesford,Kent,ME20 7JU,www.aylesford.kent.sch.uk,1622717341.0,Miss,Tanya,Kelvie,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Aylesford South & Ditton,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,571899.0,158410.0,Tonbridge and Malling 005,Tonbridge and Malling 005B,,,,,,South-East England and South London,United Kingdom,200000966311.0,,Not applicable,Not applicable,,,E02005153,E01024718,163.0,
149554,886,Kent,4030,The Royal Harbour Academy,Academy sponsor led,Academies,Open,New Provision,01-04-2023,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,916.0,No Special Classes,,,,,,Supported by a multi-academy trust,COASTAL ACADEMIES TRUST,Linked to a sponsor,Coastal Academies Trust,Not applicable,,10091882.0,,,,13-05-2024,Newlands Lane,,,Ramsgate,Kent,CT12 6RH,www.rha.kent.sch.uk,1843572500.0,Mr,Simon,Pullen,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Thanet,Northwood,South Thanet,(England/Wales) Urban city and town,E10000016,637611.0,166588.0,Thanet 011,Thanet 011A,,,,,,South-East England and South London,United Kingdom,10022962106.0,,Not applicable,Not applicable,,,E02005142,E01024686,,
149623,886,Kent,3134,John Mayne Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2023,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Not applicable,140.0,No Special Classes,,,,,,Supported by a multi-academy trust,TENTERDEN SCHOOLS TRUST,-,,Not applicable,,10092108.0,,,,18-04-2024,High Street,Biddenden,,Ashford,Kent,TN27 8AL,www.john-mayne.kent.sch.uk/,1580291424.0,Mrs,Helen,Tester,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Biddenden,Ashford,(England/Wales) Rural town and fringe,E10000016,584986.0,138375.0,Ashford 011,Ashford 011B,Not applicable,,,,,South-East England and South London,,100062563751.0,,Not applicable,Not applicable,,,E02005006,E01023979,,
149666,886,Kent,2144,St. Clement's CofE Primary School,Academy converter,Academies,Open,Split school,01-04-2023,,,Primary,4.0,11,Not applicable,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Canterbury,Non-selective,210.0,Not applicable,,,,,,Supported by a multi-academy trust,THE DIOCESE OF CANTERBURY ACADEMIES TRUST,Linked to a sponsor,"Aquila, The Diocese of Canterbury Academies Trust",Not applicable,,10092363.0,,,,30-04-2024,Leysdown Road,,,Sheerness,Kent,ME12 4AB,www.stclementscep.co.uk,1795506910.0,Mrs,Kelly,Lockwood,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Sheppey East,Sittingbourne and Sheppey,(England/Wales) Rural village,E10000016,,,Swale 006,Swale 006A,,,,,,South-East England and South London,United Kingdom,100061077964.0,,Not applicable,Not applicable,,,E02005120,E01024580,,
149840,886,Kent,4032,Chilmington Green School,Free schools,Free Schools,Open,Academy Free School,01-09-2023,,,Secondary,11.0,19,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Non-selective,1140.0,Not applicable,,,,,,Supported by a multi-academy trust,UNITED LEARNING TRUST,Linked to a sponsor,United Learning Trust,Not applicable,,10093045.0,,,,01-05-2024,Jemmett Road,,,Ashford,Kent,TN23 4QE,https://chilmingtongreenschool.org.uk/,1233438800.0,Mr,Jonathan,Rutland,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Ashford,Beaver,Ashford,(England/Wales) Urban city and town,E10000016,,,Ashford 007,Ashford 007B,,,,,,South-East England and South London,United Kingdom,10012841381.0,,Not applicable,Not applicable,,,E02005002,E01023975,,
149893,886,Kent,4033,The Abbey School,Academy converter,Academies,Open,Fresh Start,01-04-2023,,,Secondary,11.0,19,,No Nursery Classes,Has a sixth form,Mixed,None,None,,,1226.0,Not applicable,,,,,,Supported by a multi-academy trust,THE HOWARD ACADEMY TRUST,Linked to a sponsor,The Howard Academy Trust,Not applicable,,10092583.0,,,,22-05-2024,London Road,,,Faversham,Kent,ME13 8RZ,www.abbeyschoolfaversham.co.uk,1795532633.0,Dr,Rowland,Speller,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision and SEN unit,44.0,44.0,44.0,44.0,South East,Swale,Watling,Faversham and Mid Kent,(England/Wales) Urban city and town,E10000016,,,Swale 014,Swale 014E,,,,,,South-East England and South London,United Kingdom,100062379926.0,,Not applicable,Not applicable,,,E02005128,E01024626,,
149975,886,Kent,2066,Maypole Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2023,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,,,,,,Supported by a multi-academy trust,INSPIRE ACADEMY MOVEMENT TRUST,-,,Not applicable,,10092968.0,,,,08-05-2024,Franklin Road,,,Dartford,Kent,DA2 7UZ,www.maypole.kent.sch.uk/,1322523830.0,Miss,Katie,McCann,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Dartford,Maypole & Leyton Cross,Dartford,(England/Wales) Urban major conurbation,E10000016,551223.0,172486.0,Dartford 010,Dartford 010C,Not applicable,,,,,South-East England and South London,,10002021970.0,,Not applicable,Not applicable,,,E02005037,E01024152,,
149976,886,Kent,2134,Four Elms Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2023,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,108.0,No Special Classes,,,,,,Supported by a multi-academy trust,INSPIRE ACADEMY MOVEMENT TRUST,-,,Not applicable,,10092967.0,,,,15-05-2024,Bough Beech Road,Four Elms,,Edenbridge,Kent,TN8 6NE,www.four-elms.kent.sch.uk,1732700274.0,Mrs,Liz,Mitchell,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Cowden and Hever,Tonbridge and Malling,(England/Wales) Rural village,E10000016,546847.0,148273.0,Sevenoaks 015,Sevenoaks 015A,Not applicable,,,,,South-East England and South London,,10035181444.0,,Not applicable,Not applicable,,,E02005101,E01024420,,
149978,886,Kent,3035,Seal Church of England Voluntary Controlled Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2023,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,444.0,No Special Classes,,,,,,Supported by a multi-academy trust,INSPIRE ACADEMY MOVEMENT TRUST,-,,Not applicable,,10092966.0,,,,09-05-2024,Zambra Way,Seal,,Sevenoaks,Kent,TN15 0DJ,www.sealprimary.com,1732762388.0,Mrs,Tamsin,Jones,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Sevenoaks,Seal and Weald,Sevenoaks,(England/Wales) Urban city and town,E10000016,554704.0,157107.0,Sevenoaks 010,Sevenoaks 010A,Not applicable,,,,,South-East England and South London,,10035185574.0,,Not applicable,Not applicable,,,E02005096,E01024457,,
150156,886,Kent,5208,Ditton Church of England Junior School,Academy converter,Academies,Open,Academy Converter,01-11-2023,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,256.0,No Special Classes,,,,,,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10093280.0,,,,21-05-2024,New Road,Ditton,,Aylesford,Kent,ME20 6AE,http://www.ditton-jun.kent.sch.uk,1732843446.0,Mr,Graham,Ward,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Aylesford South & Ditton,Chatham and Aylesford,(England/Wales) Urban city and town,E10000016,571105.0,158080.0,Tonbridge and Malling 005,Tonbridge and Malling 005D,Not applicable,,,,,South-East England and South London,,10002907508.0,,Not applicable,Not applicable,,,E02005153,E01024736,,
150255,886,Kent,2692,The Churchill School,Academy converter,Academies,Open,Academy Converter,01-12-2023,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,Not applicable,,,,,,Supported by a multi-academy trust,EKC SCHOOLS TRUST LIMITED,-,,Not applicable,,10093663.0,,,,23-05-2024,Haven Drive,Hawkinge,,Folkestone,Kent,CT18 7RH,http://www.thechurchillschool.co.uk,1303893892.0,Mrs,Zoe,Stone,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Folkestone and Hythe,North Downs East,Folkestone and Hythe,(England/Wales) Rural town and fringe,E10000016,621237.0,139587.0,Folkestone and Hythe 002,Folkestone and Hythe 002F,Not applicable,,,,,South-East England and South London,,50102503.0,,Not applicable,Not applicable,,,E02005103,E01033214,,
150278,886,Kent,4034,Dover Christ Church Academy,Academy sponsor led,Academies,Open,Fresh Start,01-09-2023,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,None,,,990.0,Not applicable,,,,,,Supported by a multi-academy trust,TURNER SCHOOLS,Linked to a sponsor,Turner Schools,Not applicable,,10093628.0,,,,14-05-2024,Melbourne Avenue,,,Dover,,CT16 2EG,,,Mr,Jamie,MacLean,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,PMLD - Profound and Multiple Learning Difficulty,,,,,,,,,,,,,SEN unit,,,69.0,72.0,South East,Dover,Whitfield,Dover,(England/Wales) Urban city and town,E10000016,630895.0,144193.0,Dover 010,Dover 010E,,,,,,South-East England and South London,United Kingdom,100062289416.0,,Not applicable,Not applicable,,,E02005050,E01024254,,
150743,886,Kent,4036,Leigh Academy Hugh Christie,Academy sponsor led,Academies,Open,New Provision,01-04-2024,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,1226.0,Has Special Classes,,,,,,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10094758.0,,,,01-04-2024,White Cottage Road,,,Tonbridge,Kent,TN10 4PU,,1732353544.0,Mr,Palak,Shah,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Tonbridge and Malling,Trench,Tonbridge and Malling,(England/Wales) Urban city and town,E10000016,559444.0,148580.0,Tonbridge and Malling 009,Tonbridge and Malling 009A,,,,,,South-East England and South London,United Kingdom,10002906320.0,,Not applicable,Not applicable,,,E02005157,E01024730,,
150934,886,Kent,4037,EKC Sheppey Secondary,Academy sponsor led,Academies,Proposed to open,Split school,01-09-2024,,,Secondary,11.0,16,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,,None,,,750.0,Not applicable,,,,,,Not supported by a trust,,-,,Not applicable,,10095470.0,,,,27-04-2024,Marine Parade,,,Sheerness,,ME12 2BE,,,,January,Lorman,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Sheerness,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,593060.0,174642.0,Swale 001,Swale 001B,,,,,,South-East England and South London,United Kingdom,100062378138.0,,Not applicable,Not applicable,,,E02005115,E01024610,,
150935,886,Kent,4038,Leigh Academy Minster,Academy sponsor led,Academies,Proposed to open,Split school,01-09-2024,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,,None,,,1150.0,Not applicable,,,,,,Not supported by a trust,,-,,Not applicable,,10095469.0,,,,27-04-2024,Minster Road,,,Sheerness,,ME12 3JQ,,,,Mathieu,Stevens,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Swale,Queenborough and Halfway,Sittingbourne and Sheppey,(England/Wales) Urban city and town,E10000016,593740.0,172606.0,Swale 004,Swale 004A,,,,,,South-East England and South London,United Kingdom,200002529794.0,,Not applicable,Not applicable,,,E02005118,E01024595,,
Can't render this file because it is too large.

View File

@ -1,21 +0,0 @@
SyllabusSubject,SyllabusKeyStage,SyllabusStageID,SyllabusYearID,TopicStage,TopicSubjectCode,Topic,Lesson,TopicID,LessonID,LessonTitle,LessonTitleEnter,LessonType,NumberOfLearningOutcomes,SuggestedNumberOfPeriodsForLesson,LessonLearningObjectiveEnter,SuggestedActivities,WebLinks,SkillsLearned,TopicTitle,LessonTitleAuto,,,,,,,
Science,3,KS3.Science,Y7.Science,7,B,1,1,7B1,7B1.1,"Living, dead and never been alive","Living, dead and never been alive",Standard,3,1,Describe the features of living organisms,Class Prac: Have student carry out mini actions - use these to deduce MRS GRENDiscuss: What determines whether something is alive or not? Use objects/images to help with this.Worksheets: 7Aa1,,,Life Processes,,,,,,,,
Science,3,KS3.Science,Y7.Science,7,B,1,2,7B1,7B1.2,Plant and animal cells,Plant and animal cells,Standard,3,1,Identify the main parts of animal cells and describe their functions.,Class Prac: Use bio-viewers to look at simple animal and plants cells. Sketch cells. Label cells. Describe their functions. Venn diagram - Compare plant and animal cells. Highlight differences.Worksheet: 7Ad1,,,Life Processes,,,,,,,,
Science,3,KS3.Science,Y7.Science,7,B,1,R,7B1,7B1.R,Revision of topic 7B1 Life Processes,Null,Review,1,1,,,,,Life Processes,Revision of topic 7B1 Life Processes,,,,,,,
Science,3,KS3.Science,Y7.Science,7,B,1,T,7B1,7B1.T,Topic test: 7B1 Life Processes,Null,Assessment,1,1,,,,,Life Processes,Topic test: 7B1 Life Processes,,,,,,,
Science,3,KS3.Science,Y7.Science,7,B,2,1,7B2,7B2.1,Aerobic Respiration,Aerobic Respiration,Standard,3,1,Be able to describe what happens during respiration,Brain dump: Students write down prior knowledge opportunity to deal with misconceptions (see starter slide). Demo: Screaming jelly baby,,,Respiration And Circulation,,,,,,,,
Science,3,KS3.Science,Y7.Science,7,B,2,2,7B2,7B2.2,Anaerobic respiration,Anaerobic respiration,Standard,3,1,Describe what happens in anaerobic respiration in humans,Explain how and why anaerobic respiration happens in humans. Extend into fermentation. Class Prac: Investigate the rate of anaerobic respiration in yeast. Compare pros and cons of aerobic and anaerobic respiration Worksheets: 8Db-2,,,Respiration And Circulation,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,12-1,AP.PAG,AP.PAG.12-1,PAG 12 Research,PAG 12 Research,Focus,1,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,12-2,AP.PAG,AP.PAG.12-2,PAG 12 Research,PAG 12 Research,Focus,0,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,12-3,AP.PAG,AP.PAG.12-3,PAG 12 Research,PAG 12 Research,Focus,0,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,2-1,AP.PAG,AP.PAG.2-1,PAG 2 Investigating Properties of Materials,PAG 2 Investigating Properties of Materials,Focus,1,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,2-2,AP.PAG,AP.PAG.2-2,PAG 2 Investigating Properties of Materials,PAG 2 Investigating Properties of Materials,Focus,0,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,2-3,AP.PAG,AP.PAG.2-3,PAG 2 Investigating Properties of Materials,PAG 2 Investigating Properties of Materials,Focus,0,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,3-1,AP.PAG,AP.PAG.3-1,PAG 3 Investigating Electrical Properties: Resistivity of a metal,PAG 3 Investigating Electrical Properties: Resistivity of a metal,Focus,1,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,3-2,AP.PAG,AP.PAG.3-2,PAG 3 Investigating Electrical Properties: Investigating electrical characteristics,PAG 3 Investigating Electrical Properties: Investigating electrical characteristics,Focus,1,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,3-3,AP.PAG,AP.PAG.3-3,PAG 3 Investigating Electrical Properties: Determining the maximum power from a cell,PAG 3 Investigating Electrical Properties: Determining the maximum power from a cell,Focus,0,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,1-1,AP.PAG,AP.PAG.1-1,PAG 4 Investigating Electrical Circuits: Investigating electrical circuits,PAG 4 Investigating Electrical Circuits: Investigating electrical circuits,Focus,1,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,1-2,AP.PAG,AP.PAG.1-2,PAG 4 Investigating Electrical Circuits: Electrical circuits with more than one source of emf,PAG 4 Investigating Electrical Circuits: Electrical circuits with more than one source of emf,Focus,0,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,1-3,AP.PAG,AP.PAG.1-3,PAG 4 Investigating Electrical Circuits: Using non-ohmic devices as sensors,PAG 4 Investigating Electrical Circuits: Using non-ohmic devices as sensors,Focus,0,1,,,,,A-level Physics PAG,,,,,,,,
Physics,5,KS5.Physics,KS5.Physics.Special,A,P,PAG,1-1,AP.PAG,AP.PAG.1-1,PAG 5 Investigating Waves: Determining wavelength with diffraction grating,PAG 5 Investigating Waves: Determining wavelength with diffraction grating,Focus,1,1,,,,,A-level Physics PAG,,,,,,,,
1 SyllabusSubject SyllabusKeyStage SyllabusStageID SyllabusYearID TopicStage TopicSubjectCode Topic Lesson TopicID LessonID LessonTitle LessonTitleEnter LessonType NumberOfLearningOutcomes SuggestedNumberOfPeriodsForLesson LessonLearningObjectiveEnter SuggestedActivities WebLinks SkillsLearned TopicTitle LessonTitleAuto
2 Science 3 KS3.Science Y7.Science 7 B 1 1 7B1 7B1.1 Living, dead and never been alive Living, dead and never been alive Standard 3 1 Describe the features of living organisms Class Prac: Have student carry out mini actions - use these to deduce MRS GRENDiscuss: What determines whether something is alive or not? Use objects/images to help with this.Worksheets: 7Aa1 Life Processes
3 Science 3 KS3.Science Y7.Science 7 B 1 2 7B1 7B1.2 Plant and animal cells Plant and animal cells Standard 3 1 Identify the main parts of animal cells and describe their functions. Class Prac: Use bio-viewers to look at simple animal and plants cells. Sketch cells. Label cells. Describe their functions. Venn diagram - Compare plant and animal cells. Highlight differences.Worksheet: 7Ad1 Life Processes
4 Science 3 KS3.Science Y7.Science 7 B 1 R 7B1 7B1.R Revision of topic 7B1 Life Processes Null Review 1 1 Life Processes Revision of topic 7B1 Life Processes
5 Science 3 KS3.Science Y7.Science 7 B 1 T 7B1 7B1.T Topic test: 7B1 Life Processes Null Assessment 1 1 Life Processes Topic test: 7B1 Life Processes
6 Science 3 KS3.Science Y7.Science 7 B 2 1 7B2 7B2.1 Aerobic Respiration Aerobic Respiration Standard 3 1 Be able to describe what happens during respiration Brain dump: Students write down prior knowledge – opportunity to deal with misconceptions (see starter slide). Demo: Screaming jelly baby Respiration And Circulation
7 Science 3 KS3.Science Y7.Science 7 B 2 2 7B2 7B2.2 Anaerobic respiration Anaerobic respiration Standard 3 1 Describe what happens in anaerobic respiration in humans Explain how and why anaerobic respiration happens in humans. Extend into fermentation. Class Prac: Investigate the rate of anaerobic respiration in yeast. Compare pros and cons of aerobic and anaerobic respiration Worksheets: 8Db-2 Respiration And Circulation
8 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 12-1 AP.PAG AP.PAG.12-1 PAG 12 Research PAG 12 Research Focus 1 1 A-level Physics PAG
9 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 12-2 AP.PAG AP.PAG.12-2 PAG 12 Research PAG 12 Research Focus 0 1 A-level Physics PAG
10 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 12-3 AP.PAG AP.PAG.12-3 PAG 12 Research PAG 12 Research Focus 0 1 A-level Physics PAG
11 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 2-1 AP.PAG AP.PAG.2-1 PAG 2 Investigating Properties of Materials PAG 2 Investigating Properties of Materials Focus 1 1 A-level Physics PAG
12 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 2-2 AP.PAG AP.PAG.2-2 PAG 2 Investigating Properties of Materials PAG 2 Investigating Properties of Materials Focus 0 1 A-level Physics PAG
13 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 2-3 AP.PAG AP.PAG.2-3 PAG 2 Investigating Properties of Materials PAG 2 Investigating Properties of Materials Focus 0 1 A-level Physics PAG
14 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 3-1 AP.PAG AP.PAG.3-1 PAG 3 Investigating Electrical Properties: Resistivity of a metal PAG 3 Investigating Electrical Properties: Resistivity of a metal Focus 1 1 A-level Physics PAG
15 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 3-2 AP.PAG AP.PAG.3-2 PAG 3 Investigating Electrical Properties: Investigating electrical characteristics PAG 3 Investigating Electrical Properties: Investigating electrical characteristics Focus 1 1 A-level Physics PAG
16 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 3-3 AP.PAG AP.PAG.3-3 PAG 3 Investigating Electrical Properties: Determining the maximum power from a cell PAG 3 Investigating Electrical Properties: Determining the maximum power from a cell Focus 0 1 A-level Physics PAG
17 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 1-1 AP.PAG AP.PAG.1-1 PAG 4 Investigating Electrical Circuits: Investigating electrical circuits PAG 4 Investigating Electrical Circuits: Investigating electrical circuits Focus 1 1 A-level Physics PAG
18 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 1-2 AP.PAG AP.PAG.1-2 PAG 4 Investigating Electrical Circuits: Electrical circuits with more than one source of emf PAG 4 Investigating Electrical Circuits: Electrical circuits with more than one source of emf Focus 0 1 A-level Physics PAG
19 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 1-3 AP.PAG AP.PAG.1-3 PAG 4 Investigating Electrical Circuits: Using non-ohmic devices as sensors PAG 4 Investigating Electrical Circuits: Using non-ohmic devices as sensors Focus 0 1 A-level Physics PAG
20 Physics 5 KS5.Physics KS5.Physics.Special A P PAG 1-1 AP.PAG AP.PAG.1-1 PAG 5 Investigating Waves: Determining wavelength with diffraction grating PAG 5 Investigating Waves: Determining wavelength with diffraction grating Focus 1 1 A-level Physics PAG

View File

@ -1,8 +0,0 @@
SyllabusSubject,SyllabusKeyStage,SyllabusStageID,SyllabusYearID,TopicStage,TopicSubject,Topic,Lesson,Statement,TopicID,LessonID,StatementID,TopicTitle,LessonTitle,LearningStatement,LearningStatementEnter,StatementType,StatementLevel,LearningStatementAuto,,,,,,,,,,,
Science,3,KS3.Science,Y7.Science,7,B,1,1,1,7B1,7B1.1,7B1.1.1,Life Processes,"Living, dead and never been alive",Recall the different life processes,Recall the different life processes,Outcome,,Incomplete,,,,,,,,,,,
Physics,5,KS5.Physics,Y12.Physics,A,P,8,1,1,AP.8,AP.8.1,AP.8.1.1,Charge And Current,Current And Charge,Understand electric current as the rate of flow of charge using the equation I = ΔQ/Δt,Understand electric current as the rate of flow of charge using the equation I = ΔQ/Δt,Outcome,,Incomplete,,,,,,,,,,,
Physics,5,KS5.Physics,Y12.Physics,A,P,8,1,2,AP.8,AP.8.1,AP.8.1.2,Charge And Current,Current And Charge,Define the coulomb as the unit of electric charge,Define the coulomb as the unit of electric charge,Outcome,,Incomplete,,,,,,,,,,,
Physics,5,KS5.Physics,Y12.Physics,A,P,8,1,3,AP.8,AP.8.1,AP.8.1.3,Charge And Current,Current And Charge,State the elementary charge e as 1.6 x 10^-19 C,State the elementary charge e as 1.6 x 10^-19 C,Outcome,,Incomplete,,,,,,,,,,,
Physics,5,KS5.Physics,Y12.Physics,A,P,8,1,4,AP.8,AP.8.1,AP.8.1.4,Charge And Current,Current And Charge,Recognize that the net charge on a particle or object is quantized and is a multiple of e,Recognize that the net charge on a particle or object is quantized and is a multiple of e,Outcome,,Incomplete,,,,,,,,,,,
Physics,5,KS5.Physics,Y12.Physics,A,P,8,2,1,AP.8,AP.8.2,AP.8.2.1,Charge And Current,Moving Charges,Explain current as the movement of electrons in metals and the movement of ions in electrolytes,Explain current as the movement of electrons in metals and the movement of ions in electrolytes,Outcome,,Incomplete,,,,,,,,,,,
Physics,5,KS5.Physics,Y12.Physics,A,P,8,2,2,AP.8,AP.8.2,AP.8.2.2,Charge And Current,Moving Charges,Differentiate between conventional current and electron flow,Differentiate between conventional current and electron flow,Outcome,,Incomplete,,,,,,,,,,,
1 SyllabusSubject SyllabusKeyStage SyllabusStageID SyllabusYearID TopicStage TopicSubject Topic Lesson Statement TopicID LessonID StatementID TopicTitle LessonTitle LearningStatement LearningStatementEnter StatementType StatementLevel LearningStatementAuto
2 Science 3 KS3.Science Y7.Science 7 B 1 1 1 7B1 7B1.1 7B1.1.1 Life Processes Living, dead and never been alive Recall the different life processes Recall the different life processes Outcome Incomplete
3 Physics 5 KS5.Physics Y12.Physics A P 8 1 1 AP.8 AP.8.1 AP.8.1.1 Charge And Current Current And Charge Understand electric current as the rate of flow of charge using the equation I = ΔQ/Δt Understand electric current as the rate of flow of charge using the equation I = ΔQ/Δt Outcome Incomplete
4 Physics 5 KS5.Physics Y12.Physics A P 8 1 2 AP.8 AP.8.1 AP.8.1.2 Charge And Current Current And Charge Define the coulomb as the unit of electric charge Define the coulomb as the unit of electric charge Outcome Incomplete
5 Physics 5 KS5.Physics Y12.Physics A P 8 1 3 AP.8 AP.8.1 AP.8.1.3 Charge And Current Current And Charge State the elementary charge e as 1.6 x 10^-19 C State the elementary charge e as 1.6 x 10^-19 C Outcome Incomplete
6 Physics 5 KS5.Physics Y12.Physics A P 8 1 4 AP.8 AP.8.1 AP.8.1.4 Charge And Current Current And Charge Recognize that the net charge on a particle or object is quantized and is a multiple of e Recognize that the net charge on a particle or object is quantized and is a multiple of e Outcome Incomplete
7 Physics 5 KS5.Physics Y12.Physics A P 8 2 1 AP.8 AP.8.2 AP.8.2.1 Charge And Current Moving Charges Explain current as the movement of electrons in metals and the movement of ions in electrolytes Explain current as the movement of electrons in metals and the movement of ions in electrolytes Outcome Incomplete
8 Physics 5 KS5.Physics Y12.Physics A P 8 2 2 AP.8 AP.8.2 AP.8.2.2 Charge And Current Moving Charges Differentiate between conventional current and electron flow Differentiate between conventional current and electron flow Outcome Incomplete

View File

@ -1,15 +0,0 @@
SyllabusSubject,SyllabusKeyStage,SyllabusYear,SyllabusStageID,SyllabusYearID,TopicStage,TopicSubjectCode,Topic,TopicID,TopicTitle,TotalNumberOfLessonsForTopic,TopicType,TopicAssessmentType,,
Science,3,7,KS3.Science,Y7.Science,I,B,1,7B1,Life Processes,11,Standard,Test,,
Science,3,7,KS3.Science,Y7.Science,I,B,2,7B2,Respiration And Circulation,11,Standard,Test,,
Science,3,7,KS3.Science,Y7.Science,I,B,3,7B3,Variation,11,Standard,Test,,
Science,3,7,KS3.Science,Y7.Science,I,B,4,7B4,Food And Digestion,12,Standard,Test,,
Science,3,7,KS3.Science,Y7.Science,I,B,5,7B5,Reproduction,11,Standard,Test,,
Physics,Y13.Physics,A,P,15,AP.15,Ideal Gases,5,Standard,Test,,
Physics,5,13,KS5.Physics,Y13.Physics,A,P,16,AP.16,Circular Motion,5,Standard,Test,,
Physics,5,13,KS5.Physics,Y13.Physics,A,P,17,AP.17,Oscillations,5,Standard,Test,,
Physics,5,13,KS5.Physics,Y13.Physics,A,P,18,AP.18,Gravitational Fields,5,Standard,Test,,
Physics,5,13,KS5.Physics,Y13.Physics,A,P,19,AP.19,Stars,5,Standard,Test,,
Physics,5,13,KS5.Physics,Y13.Physics,A,P,20,AP.20,Cosmology,5,Standard,Test,,
Physics,5,13,KS5.Physics,Y13.Physics,A,P,21,AP.21,Capacitors,5,Standard,Test,,
Physics,5,13,KS5.Physics,Y13.Physics,A,P,22,AP.22,Electric Fields,5,Standard,Test,,
Physics,5,13,KS5.Physics,Y13.Physics,A,P,23,AP.23,Magnetic Fields,5,Standard,Test,,
1 SyllabusSubject,SyllabusKeyStage,SyllabusYear,SyllabusStageID,SyllabusYearID,TopicStage,TopicSubjectCode,Topic,TopicID,TopicTitle,TotalNumberOfLessonsForTopic,TopicType,TopicAssessmentType,,
2 Science,3,7,KS3.Science,Y7.Science,I,B,1,7B1,Life Processes,11,Standard,Test,,
3 Science,3,7,KS3.Science,Y7.Science,I,B,2,7B2,Respiration And Circulation,11,Standard,Test,,
4 Science,3,7,KS3.Science,Y7.Science,I,B,3,7B3,Variation,11,Standard,Test,,
5 Science,3,7,KS3.Science,Y7.Science,I,B,4,7B4,Food And Digestion,12,Standard,Test,,
6 Science,3,7,KS3.Science,Y7.Science,I,B,5,7B5,Reproduction,11,Standard,Test,,
7 Physics,Y13.Physics,A,P,15,AP.15,Ideal Gases,5,Standard,Test,,
8 Physics,5,13,KS5.Physics,Y13.Physics,A,P,16,AP.16,Circular Motion,5,Standard,Test,,
9 Physics,5,13,KS5.Physics,Y13.Physics,A,P,17,AP.17,Oscillations,5,Standard,Test,,
10 Physics,5,13,KS5.Physics,Y13.Physics,A,P,18,AP.18,Gravitational Fields,5,Standard,Test,,
11 Physics,5,13,KS5.Physics,Y13.Physics,A,P,19,AP.19,Stars,5,Standard,Test,,
12 Physics,5,13,KS5.Physics,Y13.Physics,A,P,20,AP.20,Cosmology,5,Standard,Test,,
13 Physics,5,13,KS5.Physics,Y13.Physics,A,P,21,AP.21,Capacitors,5,Standard,Test,,
14 Physics,5,13,KS5.Physics,Y13.Physics,A,P,22,AP.22,Electric Fields,5,Standard,Test,,
15 Physics,5,13,KS5.Physics,Y13.Physics,A,P,23,AP.23,Magnetic Fields,5,Standard,Test,,

View File

@ -1,105 +0,0 @@
URN,LA (code),LA (name),EstablishmentNumber,EstablishmentName,TypeOfEstablishment (name),EstablishmentTypeGroup (name),EstablishmentStatus (name),ReasonEstablishmentOpened (name),OpenDate,ReasonEstablishmentClosed (name),CloseDate,PhaseOfEducation (name),StatutoryLowAge,StatutoryHighAge,Boarders (name),NurseryProvision (name),OfficialSixthForm (name),Gender (name),ReligiousCharacter (name),ReligiousEthos (name),Diocese (name),AdmissionsPolicy (name),SchoolCapacity,SpecialClasses (name),CensusDate,NumberOfPupils,NumberOfBoys,NumberOfGirls,PercentageFSM,TrustSchoolFlag (name),Trusts (name),SchoolSponsorFlag (name),SchoolSponsors (name),FederationFlag (name),Federations (name),UKPRN,FEHEIdentifier,FurtherEducationType (name),OfstedLastInsp,LastChangedDate,Street,Locality,Address3,Town,County (name),Postcode,SchoolWebsite,TelephoneNum,HeadTitle (name),HeadFirstName,HeadLastName,HeadPreferredJobTitle,BSOInspectorateName (name),InspectorateReport,DateOfLastInspectionVisit,NextInspectionVisit,TeenMoth (name),TeenMothPlaces,CCF (name),SENPRU (name),EBD (name),PlacesPRU,FTProv (name),EdByOther (name),Section41Approved (name),SEN1 (name),SEN2 (name),SEN3 (name),SEN4 (name),SEN5 (name),SEN6 (name),SEN7 (name),SEN8 (name),SEN9 (name),SEN10 (name),SEN11 (name),SEN12 (name),SEN13 (name),TypeOfResourcedProvision (name),ResourcedProvisionOnRoll,ResourcedProvisionCapacity,SenUnitOnRoll,SenUnitCapacity,GOR (name),DistrictAdministrative (name),AdministrativeWard (name),ParliamentaryConstituency (name),UrbanRural (name),GSSLACode (name),Easting,Northing,MSOA (name),LSOA (name),InspectorateName (name),SENStat,SENNoStat,PropsName,OfstedRating (name),RSCRegion (name),Country (name),UPRN,SiteName,QABName (name),EstablishmentAccredited (name),QABReport,CHNumber,MSOA (code),LSOA (code),FSM,AccreditationExpiryDate
118317,887,Medway,2198,Greenvale Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,120.0,No Special Classes,19-01-2023,110.0,58.0,52.0,39.1,Not applicable,,Not applicable,,Not under a federation,,10074076.0,,Not applicable,22-11-2023,22-04-2024,Symons Avenue,,,Chatham,Kent,ME4 5UP,www.greenvale.medway.sch.uk,1634409521.0,Mrs,Amanda,Allnutt,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Chatham Central & Brompton,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576183.0,166676.0,Medway 022,Medway 022B,,,,,Good,South-East England and South London,,100062391942.0,,Not applicable,Not applicable,,,E02003335,E01016023,43.0,
118320,887,Medway,2202,New Road Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,360.0,No Special Classes,19-01-2023,360.0,187.0,173.0,38.6,Not applicable,,Not applicable,,Not under a federation,,10076230.0,,Not applicable,19-04-2023,04-06-2024,Bryant Street,,,Chatham,Kent,ME4 5QN,http://www.newroad.medway.sch.uk,1634843084.0,Mrs,Samantha,Cooper,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Chatham Central & Brompton,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576251.0,167414.0,Medway 015,Medway 015C,,,,,Good,South-East England and South London,,44054185.0,,Not applicable,Not applicable,,,E02003328,E01016019,139.0,
118329,887,Medway,2215,Balfour Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,266.0,140.0,126.0,23.8,Not applicable,,Not applicable,,Not under a federation,,10074074.0,,Not applicable,04-06-2019,12-04-2024,Pattens Lane,,,Rochester,Kent,ME1 2QT,http://www.balfourinf.medway.sch.uk,1634338280.0,Ms,Donna,Atkinson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Fort Pitt,Rochester and Strood,(England/Wales) Urban city and town,E06000035,575083.0,166460.0,Medway 026,Medway 026C,,,,,Good,South-East England and South London,,44035930.0,,Not applicable,Not applicable,,,E02003339,E01016124,63.0,
118330,887,Medway,2216,Crest Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,177.0,83.0,94.0,34.5,Not applicable,,Not applicable,,Not under a federation,,10074073.0,,Not applicable,12-02-2020,29-04-2024,Fleet Road,,,Rochester,Kent,ME1 2QA,www.crestinfants.co.uk,1634844127.0,Mrs,Kerry,Seales,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester East & Warren Wood,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574568.0,166523.0,Medway 024,Medway 024A,,,,,Good,South-East England and South London,,200000909496.0,,Not applicable,Not applicable,,,E02003337,E01016116,60.0,
118423,887,Medway,2403,Hempstead Junior School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,360.0,No Special Classes,19-01-2023,353.0,193.0,160.0,7.9,Not applicable,,Not applicable,,Not under a federation,,10079033.0,,Not applicable,20-06-2018,06-06-2024,Birch Grove,Hempstead,,Gillingham,Kent,ME7 3HJ,www.hempsteadjnr.medway.sch.uk/,1634336963.0,Mr,Paul,Cross,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Hempstead & Wigmore,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,579226.0,164022.0,Medway 035,Medway 035A,,,,,Good,South-East England and South London,,100062394567.0,,Not applicable,Not applicable,,,E02003348,E01016050,28.0,
118442,887,Medway,2439,Horsted Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,180.0,No Special Classes,19-01-2023,177.0,93.0,84.0,10.2,Not applicable,,Not applicable,,Supported by a federation,The Bluebell Federation,10074065.0,,Not applicable,11-10-2023,03-06-2024,Barberry Avenue,,,Chatham,Kent,ME5 9TF,www.horstedschool.co.uk/,1634335400.0,Mrs,Sarah,Steer,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Fort Horsted,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574928.0,164210.0,Medway 033,Medway 033C,,,,,Good,South-East England and South London,,200000909501.0,,Not applicable,Not applicable,,,E02003346,E01016123,18.0,
118472,887,Medway,2494,Parkwood Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,540.0,No Special Classes,19-01-2023,546.0,270.0,276.0,16.8,Not applicable,,Not applicable,,Not under a federation,,10074063.0,,Not applicable,08-06-2023,07-05-2024,Deanwood Drive,Rainham,,Gillingham,Kent,ME8 9LP,www.parkwoodprimary.org.uk,1634234699.0,Headteacher,Lee,McCormack,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham South East,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,581085.0,164262.0,Medway 036,Medway 036D,,,,,Requires improvement,South-East England and South London,,100062396933.0,,Not applicable,Not applicable,,,E02003349,E01016105,92.0,
118477,887,Medway,2506,Horsted Junior School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,248.0,No Special Classes,19-01-2023,249.0,130.0,119.0,16.5,Not applicable,,Not applicable,,Supported by a federation,The Bluebell Federation,10079031.0,,Not applicable,13-09-2023,03-06-2024,Barberry Avenue,,,Chatham,Kent,ME5 9TF,www.horstedschool.co.uk,1634335400.0,Mrs,Sarah,Steer,Executive Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Fort Horsted,Rochester and Strood,(England/Wales) Urban city and town,E06000035,575006.0,164184.0,Medway 033,Medway 033C,,,,,Good,South-East England and South London,,44018867.0,,Not applicable,Not applicable,,,E02003346,E01016123,41.0,
118509,887,Medway,2549,Swingate Primary School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,19-01-2023,659.0,335.0,324.0,12.0,Not applicable,,Not applicable,,Not under a federation,,10076224.0,,Not applicable,08-11-2018,21-05-2024,Sultan Road,Lordswood,,Chatham,Kent,ME5 8TJ,www.swingate.medway.sch.uk/,1634863778.0,Mr,Steven,Geary,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Lordswood & Walderslade,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,577377.0,162361.0,Medway 038,Medway 038B,,,,,Good,South-East England and South London,,44058696.0,,Not applicable,Not applicable,,,E02003351,E01016056,76.0,
118555,887,Medway,2638,Hempstead Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,270.0,149.0,121.0,5.2,Not applicable,,Not applicable,,Not under a federation,,10074059.0,,Not applicable,13-03-2024,22-05-2024,Hempstead Road,Hempstead,,Gillingham,Kent,ME7 3QG,www.hempsteadschoolsfederation.org.uk,1634336963.0,Mr,Paul,Cross,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Hempstead & Wigmore,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,579161.0,164155.0,Medway 035,Medway 035B,,,,,Good,South-East England and South London,,200000901137.0,,Not applicable,Not applicable,,,E02003348,E01016051,14.0,
118576,887,Medway,2665,St Peter's Infant School,Community school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,100.0,No Special Classes,19-01-2023,94.0,53.0,41.0,32.3,Not applicable,,Not applicable,,Not under a federation,,10074058.0,,Not applicable,13-12-2018,02-06-2024,Holcombe Road,,,Rochester,Kent,ME1 2HU,http://www.stpetersinfants.co.uk/,1634843590.0,Mrs,Joanna,Worrall (Interim),Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester East & Warren Wood,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574398.0,167163.0,Medway 017,Medway 017D,,,,,Good,South-East England and South London,,44025555.0,,Not applicable,Not applicable,,,E02003330,E01016118,30.0,
118641,887,Medway,3096,"St Helen's Church of England Primary School, Cliffe",Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,211.0,107.0,104.0,18.5,Not applicable,,Not applicable,,Not under a federation,,10069109.0,,Not applicable,04-06-2019,23-04-2024,Church Street,Cliffe,,Rochester,Kent,ME3 7PU,www.sthelens.medway.sch.uk/,1634220246.0,Mrs,Stephanie,Jarvis,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood Rural,Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,573629.0,176192.0,Medway 002,Medway 002A,,,,,Good,South-East England and South London,,44018290.0,,Not applicable,Not applicable,,,E02003315,E01016142,39.0,
118643,887,Medway,3102,St Nicholas CEVC Primary School,Voluntary controlled school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,120.0,No Special Classes,19-01-2023,93.0,46.0,47.0,28.0,Not applicable,,Not applicable,,Not under a federation,,10079669.0,,Not applicable,23-01-2013,26-04-2024,St Nicholas CEVC primary School,London Road,Strood,Rochester,Kent,ME2 3HU,http://www.st-nicholas.medway.sch.uk,1634717120.0,Mrs,Ruth,Gooch,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood North & Frindsbury,Rochester and Strood,(England/Wales) Urban city and town,E06000035,573257.0,169332.0,Medway 006,Medway 006E,,,,,Outstanding,South-East England and South London,,200000896704.0,,Not applicable,Not applicable,,,E02003319,E01016141,26.0,
118756,887,Medway,3712,St Michael's RC Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,460.0,No Special Classes,19-01-2023,469.0,236.0,233.0,25.6,Not applicable,,Not applicable,,Not under a federation,,10076805.0,,Not applicable,06-11-2019,08-05-2024,Hills Terrace,,,Chatham,Kent,ME4 6PX,www.stmichaelsrcp.org,1634832578.0,Mrs,Nicola,Collins,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Fort Pitt,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,575579.0,167357.0,Medway 015,Medway 015B,,,,,Good,South-East England and South London,,44040971.0,,Not applicable,Not applicable,,,E02003328,E01016017,107.0,
118766,887,Medway,3729,English Martyrs' Catholic Primary School,Voluntary aided school,Local authority maintained schools,"Open, but proposed to close",Not applicable,,Academy Converter,30-06-2024,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,202.0,101.0,101.0,15.8,Not applicable,,Not applicable,,Not under a federation,,10072742.0,,Not applicable,13-07-2023,28-05-2024,Frindsbury Road,Strood,,Rochester,Kent,ME2 4JA,http://www.englishmartyrs.medway.sch.uk,1634718964.0,Ms,Catherine,Thacker,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood North & Frindsbury,Rochester and Strood,(England/Wales) Urban city and town,E06000035,573987.0,169894.0,Medway 006,Medway 006A,,,,,Good,South-East England and South London,,100062388690.0,,Not applicable,Not applicable,,,E02003319,E01016135,32.0,
118767,887,Medway,3732,St Thomas of Canterbury RC Primary School,Voluntary aided school,Local authority maintained schools,"Open, but proposed to close",Not applicable,,Academy Converter,30-06-2024,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,236.0,No Special Classes,19-01-2023,258.0,125.0,133.0,12.1,Not applicable,,Not applicable,,Not under a federation,,10072741.0,,Not applicable,08-06-2023,28-05-2024,Romany Road,Rainham,,Gillingham,Kent,ME8 6JH,www.stthomascanterbury.org.uk/,1634234677.0,Mrs,Vicki-Louise,Gallagher,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Twydall,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,579863.0,166652.0,Medway 018,Medway 018F,,,,,Good,South-East England and South London,,44087220.0,,Not applicable,Not applicable,,,E02003331,E01016165,29.0,
118769,887,Medway,3736,St Thomas More Roman Catholic Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,420.0,No Special Classes,19-01-2023,417.0,188.0,229.0,11.3,Not applicable,,Not applicable,,Not under a federation,,10072739.0,,Not applicable,08-02-2013,09-02-2024,Bleakwood Road,,,Chatham,Kent,ME5 0NF,www.st-thomasmore.medway.sch.uk/,1634864701.0,Mrs,Victoria,Ebdon,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Wayfield & Weeds Wood,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576043.0,164020.0,Medway 033,Medway 033D,,,,,Outstanding,South-East England and South London,,44045642.0,,Not applicable,Not applicable,,,E02003346,E01016173,47.0,
118775,887,Medway,3746,St William of Perth Roman Catholic Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,208.0,106.0,102.0,7.7,Not applicable,,Not applicable,,Not under a federation,,10072738.0,,Not applicable,18-10-2023,10-05-2024,Canon Close,Maidstone Road,,Rochester,Kent,ME1 3EN,www.stwilliamofperth.org.uk/,1634404267.0,Mr,James,Willis,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester West & Borstal,Rochester and Strood,(England/Wales) Urban city and town,E06000035,573973.0,166819.0,Medway 024,Medway 024D,,,,,Good,South-East England and South London,,44010893.0,,Not applicable,Not applicable,,,E02003337,E01016132,16.0,
118779,887,Medway,3752,St Augustine of Canterbury Catholic Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,19-01-2023,199.0,101.0,98.0,13.6,Not applicable,,Not applicable,,Not under a federation,,10072736.0,,Not applicable,07-02-2024,20-05-2024,Deanwood Drive,Rainham,,Gillingham,Kent,ME8 9NP,www.staccp.org.uk/,1634371892.0,Mrs,Louise,Prestidge,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham South East,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,580898.0,163428.0,Medway 036,Medway 036C,,,,,Good,South-East England and South London,,200000901485.0,,Not applicable,Not applicable,,,E02003349,E01016100,27.0,
118782,887,Medway,3755,St Mary's Catholic Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,480.0,No Special Classes,19-01-2023,433.0,235.0,198.0,15.6,Not applicable,,Not applicable,,Not under a federation,,10072734.0,,Not applicable,26-04-2023,11-03-2024,Greenfield Road,,Https://Stmarysrcp.Medway.Sch.Uk/,Gillingham,Kent,ME7 1YH,www.stmarysrcp.medway.sch.uk/,1634855783.0,Mr,Joseph,Pomeroy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Gillingham North,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,577917.0,168572.0,Medway 010,Medway 010B,,,,,Good,South-East England and South London,,44069382.0,,Not applicable,Not applicable,,,E02003323,E01016032,61.0,
118908,887,Medway,5436,St John Fisher Catholic Comprehensive School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,,Not applicable,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Non-selective,1185.0,No Special Classes,19-01-2023,1024.0,550.0,474.0,30.1,Not applicable,,Not applicable,,Not under a federation,,10006189.0,,Not applicable,22-05-2019,23-05-2024,City Way,,,Rochester,,ME1 2FA,http://www.stjohnfisher.school,1634543123.0,Mrs,Dympna,Lennon,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Fort Pitt,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,575287.0,167305.0,Medway 021,Medway 021A,,,,,Good,South-East England and South London,United Kingdom,44082945.0,,Not applicable,Not applicable,,,E02003334,E01016020,262.0,
118948,887,Medway,6000,"King's School, Rochester",Other independent school,Independent schools,Open,Not applicable,01-01-1909,Not applicable,,Not applicable,3.0,18,Boarding school,Has Nursery Classes,Has a sixth form,Mixed,Church of England,Church of England,Not applicable,Non-selective,800.0,No Special Classes,20-01-2022,660.0,384.0,276.0,0.0,Not applicable,,Not applicable,,Not applicable,,10003660.0,,Not applicable,,06-06-2024,Satis House,Boley Hill,,Rochester,Kent,ME1 1TE,www.kings-rochester.co.uk,1634888555.0,Mr,Benjamin,Charles,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester West & Borstal,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574095.0,168504.0,Medway 014,Medway 014C,ISI,4.0,89.0,The Governors of King's School,,South-East England and South London,,44026826.0,,Not applicable,Not applicable,,,E02003327,E01016130,0.0,
118979,887,Medway,6001,Bryony School,Other independent school,Independent schools,Open,Not applicable,02-04-1958,Not applicable,,Not applicable,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Non-selective,232.0,No Special Classes,20-01-2022,128.0,60.0,68.0,0.0,Not applicable,,Not applicable,,Not applicable,,10071117.0,,Not applicable,24-11-2022,28-05-2024,157 Marshall Road,Rainham,Marshall Road,Rainham,,ME8 0AJ,www.bryonyschool.org.uk,1634231511.0,Mrs,Natalie,Gee,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham South West,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,580169.0,165278.0,Medway 030,Medway 030C,Ofsted,,1.0,Mr & Mrs Edmunds,Good,South-East England and South London,,100061264465.0,,Not applicable,Not applicable,,,E02003343,E01016091,0.0,
118985,887,Medway,6002,St Andrew's School (Rochester),Other independent school,Independent schools,Open,Not applicable,18-03-1958,Not applicable,,Not applicable,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Not applicable,360.0,No Special Classes,20-01-2022,362.0,172.0,190.0,0.0,Not applicable,,Not applicable,,Not applicable,,10080533.0,,Not applicable,,24-05-2024,24 - 26 Watts Avenue,,,Rochester,Kent,ME1 1SA,www.st-andrews.rochester.sch.uk,1634843479.0,Mrs,Emma,Steinmann-Gilbert,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester West & Borstal,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574044.0,167996.0,Medway 014,Medway 014C,ISI,,8.0,Education Development Trust,,South-East England and South London,,44022882.0,,Not applicable,Not applicable,,,E02003327,E01016130,0.0,
119006,887,Medway,6004,Rochester Independent College,Other independent school,Independent schools,Open,Not applicable,26-09-1986,Not applicable,,Not applicable,11.0,21,Boarding school,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,380.0,No Special Classes,20-01-2022,358.0,197.0,161.0,0.0,Not applicable,,Not applicable,,Not applicable,,10005511.0,,Not applicable,,21-03-2024,254 St Margaret's Banks,,,Rochester,Kent,ME1 1HY,www.rochester-college.org.uk,1634828115.0,Mr,Alistair,Brownlow,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not approved,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester West & Borstal,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574653.0,167978.0,Medway 015,Medway 015F,ISI,43.0,102.0,Dukes Education,,South-East England and South London,United Kingdom,100062373676.0,,Not applicable,Not applicable,,,E02003328,E01035296,0.0,
131527,887,Medway,3760,Burnt Oak Primary School,Community school,Local authority maintained schools,Open,Result of Amalgamation,01-09-2006,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,453.0,238.0,215.0,40.6,Not applicable,,Not applicable,,Not under a federation,,10075241.0,,Not applicable,18-05-2022,20-05-2024,Richmond Road,,,Gillingham,Kent,ME7 1LS,www.burntoak.medway.sch.uk/,1634334344.0,Mrs,Maureen,Grabski,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Gillingham North,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,577499.0,169057.0,Medway 009,Medway 009C,,,,,Good,South-East England and South London,,44027271.0,,Not applicable,Not applicable,,,E02003322,E01016037,183.0,
132056,887,Medway,3756,St Mary's Island Church of England (Aided) Primary School,Voluntary aided school,Local authority maintained schools,Open,Not applicable,01-09-1999,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,630.0,Not applicable,19-01-2023,671.0,329.0,342.0,10.3,Not applicable,,Not applicable,,Not under a federation,,10075517.0,,Not applicable,15-11-2023,23-04-2024,Island Way West,St Mary's Island,,Chatham,Kent,ME4 3ST,http://www.st-marys-island-cofe-primary-school.co.uk,1634891050.0,Mrs,Christine,Easton,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Medway,St Mary's Island,Rochester and Strood,(England/Wales) Urban city and town,E06000035,576620.0,170684.0,Medway 007,Medway 007F,,,,,Good,South-East England and South London,,200003623259.0,,Not applicable,Not applicable,,,E02003320,E01035290,69.0,
134904,887,Medway,3759,Fairview Community Primary School,Community school,Local authority maintained schools,Open,Result of Amalgamation,12-09-2005,Not applicable,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,690.0,Not applicable,19-01-2023,668.0,340.0,328.0,7.0,Not applicable,,Not applicable,,Not under a federation,,10071739.0,,Not applicable,02-04-2019,21-05-2024,Drewery Drive,Wigmore,,Gillingham,Kent,ME8 0NU,www.fairviewprimary.co.uk,1634338710.0,Mrs,Karin,Tillett,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Hempstead & Wigmore,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,580272.0,164185.0,Medway 030,Medway 030A,,,,,Good,South-East England and South London,,44013431.0,,Not applicable,Not applicable,,,E02003343,E01016085,44.0,
135964,887,Medway,6905,Strood Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2009,Not applicable,,Secondary,11.0,19,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1500.0,No Special Classes,19-01-2023,1273.0,626.0,647.0,26.8,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10027834.0,,Not applicable,02-12-2021,17-05-2024,Carnation Road,Strood,,Rochester,Kent,ME2 2SX,http://www.stroodacademy.org.uk,1634717121.0,Mr,Jon,Richardson,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision and SEN unit,5.0,25.0,5.0,25.0,South East,Medway,Strood West,Rochester and Strood,(England/Wales) Urban city and town,E06000035,571638.0,169261.0,Medway 008,Medway 008D,,,,,Good,South-East England and South London,,100062388557.0,,Not applicable,Not applicable,,,E02003321,E01016155,310.0,
136107,887,Medway,6906,Brompton Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2010,Not applicable,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,Does not apply,None,Not applicable,Non-selective,1400.0,Has Special Classes,19-01-2023,1403.0,736.0,667.0,30.4,Supported by a multi-academy trust,THE UNIVERSITY OF KENT ACADEMIES TRUST,Linked to a sponsor,University of Kent (Brompton Academy),Not applicable,,10030223.0,,Not applicable,22-09-2022,21-05-2024,Marlborough Road,,,Gillingham,Kent,ME7 5HT,http://www.bromptonacademy.org.uk,1634852341.0,Mr,Dan,Walters,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,SpLD - Specific Learning Difficulty,OTH - Other Difficulty/Disability,"SLCN - Speech, language and Communication",,,,,,,,,,,SEN unit,,,94.0,100.0,South East,Medway,Gillingham South,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,576827.0,167905.0,Medway 012,Medway 012C,,,,,Requires improvement,South-East England and South London,,44054862.0,,Not applicable,Not applicable,,,E02003325,E01016045,366.0,
136108,887,Medway,6907,The Victory Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2010,Not applicable,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,None,,Non-selective,1500.0,No Special Classes,19-01-2023,1188.0,598.0,590.0,40.1,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10030225.0,,Not applicable,03-02-2023,07-06-2024,Magpie Hall Road,,,Chatham,Kent,ME4 5JB,http://www.thevictoryacademy.org.uk/,3333602140.0,Mr,Oliver,Owen,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Luton,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576368.0,166387.0,Medway 022,Medway 022D,,,,,Good,South-East England and South London,,44051900.0,,Not applicable,Not applicable,,,E02003335,E01016062,428.0,
136313,887,Medway,5445,The Rochester Grammar School,Academy converter,Academies,Open,Academy Converter,01-11-2010,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,1110.0,No Special Classes,19-01-2023,1182.0,9.0,1173.0,7.0,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10032200.0,,Not applicable,18-01-2023,21-05-2024,Maidstone Road,,,Rochester,Kent,ME1 3BY,http://www.rochestergrammar.org.uk,3333602120.0,Mrs,Clare,Brinklow,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester East & Warren Wood,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574171.0,166566.0,Medway 017,Medway 017C,,,,,Good,South-East England and South London,,44022498.0,,Not applicable,Not applicable,,,E02003330,E01016115,70.0,
136337,887,Medway,4069,Fort Pitt Grammar School,Academy converter,Academies,Open,Academy Converter,01-11-2010,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,800.0,No Special Classes,19-01-2023,895.0,20.0,875.0,11.6,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10032192.0,,Not applicable,05-10-2022,05-03-2024,Fort Pitt Hill,,,Chatham,Kent,ME4 6TJ,http://www.fortpitt.medway.sch.uk,1634842359.0,Ms,Salena,Hirons,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Fort Pitt,Rochester and Strood,(England/Wales) Urban city and town,E06000035,575049.0,167596.0,Medway 015,Medway 015G,,,,,Outstanding,South-East England and South London,,100062392022.0,,Not applicable,Not applicable,,,E02003328,E01035297,83.0,
136456,887,Medway,4199,Rainham School for Girls,Academy converter,Academies,Open,Academy Converter,01-02-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,Does not apply,Does not apply,Not applicable,Non-selective,1558.0,No Special Classes,19-01-2023,1668.0,36.0,1632.0,17.6,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10032961.0,,Not applicable,21-04-2022,20-05-2024,Derwent Way,Rainham,,Gillingham,Kent,ME8 0BX,http://www.rainhamgirls-tkat.org/,1634362746.0,Mrs,Vicki,Shaw,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham South West,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,580560.0,165785.0,Medway 029,Medway 029B,,,,,Good,South-East England and South London,,100062395978.0,,Not applicable,Not applicable,,,E02003342,E01016088,243.0,
136594,887,Medway,4068,Holcombe Grammar School,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Boys,Does not apply,Does not apply,Not applicable,Selective,1000.0,No Special Classes,19-01-2023,1067.0,955.0,112.0,9.9,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10033242.0,,Not applicable,24-04-2018,07-06-2024,Holcombe,Maidstone Road,,Chatham,Kent,ME4 6JB,http://www.holcombegrammar.org.uk,3333602130.0,Mr,Lee,Preston,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Fort Pitt,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,575486.0,166035.0,Medway 027,Medway 027A,,,,,Good,South-East England and South London,,100062392018.0,,Not applicable,Not applicable,,,E02003340,E01016025,72.0,
136662,887,Medway,4530,Sir Joseph Williamson's Mathematical School,Academy converter,Academies,Open,Academy Converter,01-04-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Boys,None,Does not apply,Not applicable,Selective,1280.0,No Special Classes,19-01-2023,1479.0,1386.0,93.0,8.7,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10033431.0,,Not applicable,22-03-2023,07-06-2024,Maidstone Road,,,Rochester,Kent,ME1 3EL,http://www.sjwms.org.uk,1634844008.0,Mr,Eliot,Hodges,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester West & Borstal,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574020.0,166430.0,Medway 024,Medway 024C,,,,,Outstanding,South-East England and South London,,44022499.0,,Not applicable,Not applicable,,,E02003337,E01016128,92.0,
136859,887,Medway,2588,Cliffe Woods Primary School,Academy converter,Academies,Open,Academy Converter,01-07-2011,,,Primary,4.0,11,No boarders,No Nursery Classes,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,415.0,197.0,218.0,5.1,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10034067.0,,Not applicable,18-03-2015,07-05-2024,View Road,Cliffe Woods,,Rochester,Kent,ME3 8UJ,www.cliffewoods.medway.sch.uk,1634220822.0,Mrs,Karen,Connolly,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood Rural,Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,574188.0,173690.0,Medway 002,Medway 002C,,,,,Outstanding,South-East England and South London,,44030622.0,,Not applicable,Not applicable,,,E02003315,E01016145,21.0,
136864,887,Medway,5420,Rainham Mark Grammar School,Academy converter,Academies,Open,Academy Converter,01-07-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Selective,1242.0,No Special Classes,19-01-2023,1567.0,839.0,728.0,7.3,Supported by a multi-academy trust,RMET,Linked to a sponsor,RMET (Rainham Mark Education Trust),Not applicable,,10034121.0,,Not applicable,25-05-2022,29-05-2024,Pump Lane,Rainham,,Gillingham,Kent,ME8 7AJ,http://rainhammark.com/,1634364151.0,Mrs,Agnes,Hart,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham North,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,580729.0,166755.0,Medway 023,Medway 023C,,,,,Good,South-East England and South London,,44096394.0,,Not applicable,Not applicable,,,E02003336,E01016166,88.0,
137119,887,Medway,4000,The Hundred of Hoo Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2011,Not applicable,,All-through,4.0,19,No boarders,Not applicable,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,1900.0,Not applicable,19-01-2023,1702.0,844.0,858.0,22.3,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10034985.0,,Not applicable,05-07-2018,08-05-2024,Main Road,Hoo,,Rochester,Kent,ME3 9HH,https://www.hundredofhooacademy.org.uk/,1634251443.0,Mr,Carl,Guerin-Hassett,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,SEN unit,,,43.0,48.0,South East,Medway,Hoo St Werburgh & High Halstow,Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,577407.0,172277.0,Medway 003,Medway 003D,,,,,Good,South-East England and South London,,200000900015.0,,Not applicable,Not applicable,,,E02003316,E01016077,353.0,
137376,887,Medway,5451,The Thomas Aveling School,Academy converter,Academies,Open,Academy Converter,01-09-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,Does not apply,Not applicable,Non-selective,1204.0,No Special Classes,19-01-2023,1205.0,599.0,606.0,25.1,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10035084.0,,Not applicable,14-09-2022,14-05-2024,Arethusa Road,,,Rochester,Kent,ME1 2UW,http://www.thomasaveling.co.uk,1634844809.0,Mr,Paul,Jackson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,HI - Hearing Impairment,,,,,,,,,,,,,Resourced provision,20.0,20.0,,,South East,Medway,Rochester East & Warren Wood,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574327.0,165761.0,Medway 026,Medway 026B,,,,,Good,South-East England and South London,,44018933.0,,Not applicable,Not applicable,,,E02003339,E01016120,259.0,
137389,887,Medway,5429,Chatham Grammar,Academy converter,Academies,Open,Academy Converter,01-09-2011,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Girls,None,Does not apply,Not applicable,Selective,976.0,No Special Classes,19-01-2023,945.0,18.0,927.0,10.9,Supported by a multi-academy trust,THE UNIVERSITY OF KENT ACADEMIES TRUST,Linked to a sponsor,University of Kent (Brompton Academy),Not applicable,,10035160.0,,Not applicable,18-10-2023,22-05-2024,Rainham Road,,,Chatham,Kent,ME5 7EH,http://www.chathamgirlsgrammar.medway.sch.uk/,1634851262.0,Ms,Wendy,Walters,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Luton,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,577460.0,166933.0,Medway 020,Medway 020A,,,,,Good,South-East England and South London,,200000899518.0,,Not applicable,Not applicable,,,E02003333,E01016061,80.0,
137990,887,Medway,2421,High Halstow Primary Academy,Academy converter,Academies,Open,Academy Converter,01-04-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,211.0,111.0,100.0,9.5,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10036980.0,,Not applicable,21-06-2023,14-03-2024,Harrison Drive,High Halstow,,Rochester,Kent,ME3 8TF,http://www.highhalstowprimaryacademy.org.uk,1634251098.0,Mrs,Gemma,Stangroom,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Hoo St Werburgh & High Halstow,Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,578093.0,175447.0,Medway 003,Medway 003A,,,,,Outstanding,South-East England and South London,,44083531.0,,Not applicable,Not applicable,,,E02003316,E01016073,20.0,
138182,887,Medway,2600,All Faiths Children's Academy,Academy converter,Academies,Open,Academy Converter,01-06-2012,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,Has Special Classes,19-01-2023,226.0,101.0,125.0,28.4,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10037460.0,,Not applicable,29-01-2020,23-04-2024,Gun Lane,Strood,,Rochester,Kent,ME2 4UF,www.allfaithschildrensacademy.org.uk,3333602100.0,Mrs,Kirstie,Jones,Acting Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,HI - Hearing Impairment,,,,,,,,,,,,,Resourced provision and SEN unit,15.0,15.0,15.0,15.0,South East,Medway,Strood North & Frindsbury,Rochester and Strood,(England/Wales) Urban city and town,E06000035,573564.0,169506.0,Medway 006,Medway 006E,,,,,Good,South-East England and South London,,200000896787.0,,Not applicable,Not applicable,,,E02003319,E01016141,64.0,
138328,887,Medway,2209,Chattenden Primary School,Academy converter,Academies,Open,Academy Converter,01-07-2012,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,No Special Classes,19-01-2023,209.0,101.0,108.0,34.8,Supported by a multi-academy trust,PENINSULA GATEWAY ACADEMY TRUST,-,,Not applicable,,10037769.0,,Not applicable,06-11-2018,03-05-2024,Chattenden Lane,Chattenden,,Rochester,Kent,ME3 8LF,http://www.chattenden.medway.sch.uk/,1634250861.0,Miss,Julie,North,Principal,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Hoo St Werburgh & High Halstow,Rochester and Strood,(England/Wales) Rural village,E06000035,575792.0,171843.0,Medway 003,Medway 003E,,,,,Good,South-East England and South London,,200000909509.0,,Not applicable,Not applicable,,,E02003316,E01016143,72.0,
138510,887,Medway,2001,Phoenix Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2012,,,Primary,5.0,11,,Not applicable,Not applicable,Mixed,None,None,Not applicable,Not applicable,360.0,Not applicable,19-01-2023,359.0,179.0,180.0,49.3,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10038455.0,,Not applicable,21-06-2023,25-04-2024,Glencoe Road,,,Chatham,Kent,ME4 5QD,www.phoenixprimary.com,1634829009.0,Mrs,Melissa,Ireland-Hubbert,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Chatham Central & Brompton,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576075.0,166910.0,Medway 022,Medway 022A,,,,,Good,South-East England and South London,,44051781.0,,Not applicable,Not applicable,,,E02003335,E01016018,176.0,
138511,887,Medway,4001,The Robert Napier School,Academy sponsor led,Academies,Open,New Provision,01-09-2012,,,Secondary,11.0,18,No boarders,Not applicable,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,1080.0,Not applicable,19-01-2023,1037.0,561.0,476.0,43.0,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10038456.0,,Not applicable,31-01-2019,21-05-2024,Third Avenue,,,Gillingham,Kent,ME7 2LX,http://www.robertnapier.org.uk/,1634851157.0,Mrs,Jenny,Tomkins,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Medway,Watling,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,578331.0,167405.0,Medway 019,Medway 019D,,,,,Good,South-East England and South London,,44076749.0,,Not applicable,Not applicable,,,E02003332,E01016179,407.0,
138974,887,Medway,2002,St James Church of England Primary Academy,Academy sponsor led,Academies,Open,New Provision,01-12-2012,,,Primary,3.0,11,,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,None,Diocese of Rochester,Not applicable,210.0,Not applicable,19-01-2023,199.0,104.0,95.0,31.7,Supported by a multi-academy trust,MEDWAY ANGLICAN SCHOOLS TRUST,-,,Not applicable,,10039506.0,,Not applicable,24-05-2023,23-02-2024,High Street,Isle of Grain,,Rochester,Kent,ME3 0BS,http://www.stjamesisleofgrain.org.uk,1634270341.0,Miss,Fay,Cordingley,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,All Saints,Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,588751.0,176727.0,Medway 001,Medway 001B,,,,,Good,South-East England and South London,,44004798.0,,Not applicable,Not applicable,,,E02003314,E01016071,58.0,
139493,887,Medway,2412,The Academy of Woodlands,Academy converter,Academies,Open,Academy Converter,01-04-2013,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,Not applicable,19-01-2023,758.0,386.0,372.0,32.1,Supported by a multi-academy trust,RIVERMEAD INCLUSIVE TRUST,Linked to a sponsor,Rivermead Inclusive Trust,Not applicable,,10041035.0,,Not applicable,11-12-2019,01-05-2024,Woodlands Road,,,Gillingham,Kent,ME7 2DU,www.theacademyofwoodlands.co.uk,3000658200.0,Mrs,Chloe,Brown,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Watling,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,578807.0,167818.0,Medway 013,Medway 013C,,,,,Good,South-East England and South London,,100062394529.0,,Not applicable,Not applicable,,,E02003326,E01016043,243.0,
139927,887,Medway,2003,Kingfisher Community Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2013,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,219.0,103.0,116.0,40.6,Supported by a multi-academy trust,THE GRIFFIN SCHOOLS TRUST,Linked to a sponsor,The Griffin Schools Trust,Not applicable,,10042689.0,,Not applicable,12-09-2019,28-05-2024,Kingfisher Drive,Princes Park,Walderslade,Chatham,Kent,ME5 7NX,www.kingfisher-gst.org,1634661540.0,Ms,Fiona,Armstrong,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Princes Park,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,577072.0,165267.0,Medway 031,Medway 031E,,,,,Good,South-East England and South London,,100062392674.0,,Not applicable,Not applicable,,,E02003344,E01016084,89.0,
139928,887,Medway,2004,Saxon Way Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2013,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,425.0,229.0,196.0,47.2,Supported by a multi-academy trust,THE GRIFFIN SCHOOLS TRUST,Linked to a sponsor,The Griffin Schools Trust,Not applicable,,10042702.0,,Not applicable,22-01-2020,04-06-2024,,Ingram Road,,Gillingham,Kent,ME7 1SJ,http://www.saxonway-gst.org/,1634336720.0,Mrs,Jennifer,Vidler-Ironmonger,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Gillingham North,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,578169.0,168848.0,Medway 010,Medway 010B,,,,,Good,South-East England and South London,,200000900397.0,,Not applicable,Not applicable,,,E02003323,E01016032,200.0,
140040,887,Medway,2006,Oasis Academy Skinner Street,Academy sponsor led,Academies,Open,New Provision,01-09-2013,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,410.0,198.0,212.0,51.7,Supported by a multi-academy trust,OASIS COMMUNITY LEARNING,Linked to a sponsor,Oasis Community Learning,Not applicable,,10042952.0,,Not applicable,22-09-2021,19-04-2024,Skinner Street,,,Gillingham,Kent,ME7 1LG,www.oasisacademyskinnerstreet.org/,1634850213.0,Mrs,Victoria,Richmond,Interim Principal,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Gillingham South,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,577257.0,168594.0,Medway 012,Medway 012A,,,,,Good,South-East England and South London,,100062394010.0,,Not applicable,Not applicable,,,E02003325,E01016031,212.0,
140186,887,Medway,2007,Lordswood School,Academy sponsor led,Academies,Open,New Provision,01-11-2013,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,410.0,220.0,190.0,26.6,Supported by a multi-academy trust,THE GRIFFIN SCHOOLS TRUST,Linked to a sponsor,The Griffin Schools Trust,Not applicable,,10043317.0,,Not applicable,16-01-2019,28-05-2024,Lordswood Lane,,,Chatham,Kent,ME5 8NN,www.lordswood-gst.org,1634336767.0,Mrs,Jayne,Lusinski,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Lordswood & Walderslade,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576856.0,163264.0,Medway 038,Medway 038D,,,,,Good,South-East England and South London,,200000909500.0,,Not applicable,Not applicable,,,E02003351,E01016060,109.0,
140215,887,Medway,2008,New Horizons Children's Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2014,,,Primary,4.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,,Not applicable,630.0,Not applicable,19-01-2023,639.0,318.0,321.0,19.4,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10047226.0,,Not applicable,25-05-2022,03-05-2024,Park Crescent,,,Chatham,Kent,ME4 6NR,http://www.newhorizonschildrensacademy.org.uk,3333602115.0,Mr,Cormac,Murphy,Head Teacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Chatham Central & Brompton,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,575624.0,165866.0,Medway 027,Medway 027A,,,,,Good,South-East England and South London,,44036212.0,,Not applicable,Not applicable,,,E02003340,E01016025,124.0,
140606,887,Medway,2009,"Gordons Children's Academy, Junior",Academy sponsor led,Academies,Open,New Provision,01-03-2014,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,400.0,Not applicable,19-01-2023,336.0,180.0,156.0,22.9,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10044931.0,,Not applicable,28-09-2022,16-01-2024,Gordon Road,Strood,,Rochester,Kent,ME2 3HQ,https://www.gordonchildrensacademy.org.uk/,3333602110.0,Mrs,Kirstie,Jones,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood North & Frindsbury,Rochester and Strood,(England/Wales) Urban city and town,E06000035,573169.0,169601.0,Medway 006,Medway 006E,,,,,Good,South-East England and South London,United Kingdom,100062388599.0,,Not applicable,Not applicable,,,E02003319,E01016141,77.0,
140607,887,Medway,2010,"Gordons Children's Academy, Infant",Academy sponsor led,Academies,Open,New Provision,01-03-2014,,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,189.0,Not applicable,19-01-2023,164.0,83.0,81.0,25.0,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10044932.0,,Not applicable,28-09-2022,16-01-2024,Gordon Road,Strood,,Rochester,Kent,ME2 3HQ,www.gordonchildrensacademy.org.uk,3333602110.0,Mrs,Kirstie,Jones,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood North & Frindsbury,Rochester and Strood,(England/Wales) Urban city and town,E06000035,573169.0,169601.0,Medway 006,Medway 006E,,,,,Good,South-East England and South London,,100062388599.0,,Not applicable,Not applicable,,,E02003319,E01016141,41.0,
140989,887,Medway,2011,Warren Wood Primary School,Academy sponsor led,Academies,Open,New Provision,01-07-2014,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Not applicable,411.0,Has Special Classes,19-01-2023,486.0,258.0,228.0,37.8,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10046284.0,,Not applicable,16-10-2019,16-04-2024,Arethusa Road,,,Rochester,Kent,ME1 2UR,www.warrenwoodprimary.co.uk,1634401401.0,Mrs,Lucinda,Woodroof,Acting Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,"SLCN - Speech, language and Communication",,,,,,,,,,,,,SEN unit,,,30.0,34.0,South East,Medway,Rochester East & Warren Wood,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574546.0,165725.0,Medway 026,Medway 026B,,,,,Good,South-East England and South London,,44020102.0,,Not applicable,Not applicable,,,E02003339,E01016120,178.0,
141199,887,Medway,2012,Napier Community Primary and Nursery Academy,Academy sponsor led,Academies,Open,New Provision,01-09-2014,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,630.0,Not applicable,19-01-2023,585.0,282.0,303.0,34.9,Supported by a multi-academy trust,THE KEMNAL ACADEMIES TRUST,Linked to a sponsor,The Kemnal Academies Trust,Not applicable,,10046908.0,,Not applicable,04-12-2019,11-04-2024,Napier Community Primary and Nursery Academy,Napier Road,,Gillingham,Kent,ME7 4HG,www.napierprimary.org.uk,1634574920.0,Mr,Ciaran,Mc Cann,Executive Head Teacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Gillingham South,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,577675.0,167833.0,Medway 016,Medway 016B,,,,,Good,South-East England and South London,,200000909503.0,,Not applicable,Not applicable,,,E02003329,E01016046,204.0,
141224,887,Medway,2013,Cuxton Community Junior School,Academy sponsor led,Academies,Open,New Provision,01-09-2014,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,240.0,Not applicable,19-01-2023,228.0,112.0,116.0,14.9,Supported by a multi-academy trust,THE PRIMARY FIRST TRUST,Linked to a sponsor,The Primary First Trust,Not applicable,,10047013.0,,Not applicable,07-07-2022,21-05-2024,Bush Road,Cuxton,,Rochester,Kent,ME2 1EY,www.cuxtonschools.co.uk,1634337720.0,Mrs,Charlotte,Aldham Breary,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,"Cuxton, Halling & Riverside",Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,570725.0,166676.0,Medway 028,Medway 028C,,,,,Good,South-East England and South London,,44027917.0,,Not applicable,Not applicable,,,E02003341,E01016028,34.0,
141276,887,Medway,2208,Cuxton Community Infant School,Academy converter,Academies,Open,Academy Converter,01-09-2014,,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,180.0,No Special Classes,19-01-2023,180.0,97.0,83.0,8.3,Supported by a multi-academy trust,THE PRIMARY FIRST TRUST,Linked to a sponsor,The Primary First Trust,Not applicable,,10047167.0,,Not applicable,30-03-2022,21-05-2024,Bush Road,Cuxton,,Rochester,Kent,ME2 1EY,www.cuxtonschools.co.uk,1634337720.0,Mrs,Charlotte,Aldham Breary,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,"Cuxton, Halling & Riverside",Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,570781.0,166686.0,Medway 028,Medway 028C,,,,,Good,South-East England and South London,,44027917.0,,Not applicable,Not applicable,,,E02003341,E01016028,15.0,
141466,887,Medway,5457,The Howard School,Academy converter,Academies,Open,Academy Converter,01-10-2014,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,None,Does not apply,Not applicable,Non-selective,1725.0,No Special Classes,19-01-2023,1508.0,1486.0,22.0,15.3,Supported by a multi-academy trust,THE HOWARD ACADEMY TRUST,Linked to a sponsor,The Howard Academy Trust,Not applicable,,10047641.0,,Not applicable,24-11-2021,30-04-2024,Derwent Way,Rainham,,Gillingham,Kent,ME8 0BX,https://www.thehoward-that.org.uk/,1634388765.0,Mr,Jasbinder,Johal,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham South West,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,580562.0,165928.0,Medway 029,Medway 029B,,,,,Good,South-East England and South London,,100062395978.0,,Not applicable,Not applicable,,,E02003342,E01016088,193.0,
141467,887,Medway,2646,Brompton-Westbrook Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2014,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,450.0,227.0,223.0,33.5,Supported by a multi-academy trust,THE WESTBROOK TRUST,Linked to a sponsor,The Westbrook Trust,Not applicable,,10047618.0,,Not applicable,22-01-2019,21-05-2024,Kings Bastion,Brompton,,Gillingham,Kent,ME7 5DQ,http://www.bromptonwestbrook.medway.sch.uk,1634844152.0,Mrs,Sue,Mason,Head Teacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Medway,Chatham Central & Brompton,Rochester and Strood,(England/Wales) Urban city and town,E06000035,576422.0,168177.0,Medway 015,Medway 015E,,,,,Good,South-East England and South London,,44056069.0,,Not applicable,Not applicable,,,E02003328,E01016111,146.0,
141553,887,Medway,2194,Peninsula East Primary Academy,Academy converter,Academies,Open,Academy Converter,01-11-2014,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,250.0,No Special Classes,19-01-2023,248.0,127.0,121.0,26.9,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10047879.0,,Not applicable,15-01-2020,23-05-2024,Avery Way,Allhallows,,Rochester,,ME3 9HR,www.pepa.org.uk,1634270428.0,Mrs,Lorna,Rimmer,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Medway,All Saints,Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,583168.0,176220.0,Medway 001,Medway 001A,,,,,Good,South-East England and South London,United Kingdom,44108207.0,,Not applicable,Not applicable,,,E02003314,E01016070,66.0,
142137,887,Medway,3093,All Saints Church of England Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2015,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,379.0,No Special Classes,19-01-2023,353.0,176.0,177.0,33.2,Supported by a multi-academy trust,MEDWAY ANGLICAN SCHOOLS TRUST,-,,Not applicable,,10053760.0,,Not applicable,21-02-2024,20-05-2024,Magpie Hall Road,,,Chatham,Kent,ME4 5JY,http://www.allsaints.medway.sch.uk,1634338922.0,,Joanne,Strachan,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Chatham Central & Brompton,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576479.0,167253.0,Medway 015,Medway 015C,,,,,Good,South-East England and South London,,44054186.0,,Not applicable,Not applicable,,,E02003328,E01016019,111.0,
142157,887,Medway,3095,St John's Church of England Infant School,Academy converter,Academies,Open,Academy Converter,01-09-2015,,,Primary,5.0,7,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,90.0,No Special Classes,19-01-2023,46.0,21.0,25.0,34.8,Supported by a multi-academy trust,MEDWAY ANGLICAN SCHOOLS TRUST,-,,Not applicable,,10053759.0,,Not applicable,13-06-2018,12-04-2024,4 New Street,,,Chatham,Kent,ME4 6RH,https://www.stjohns.medway.sch.uk/,1634844135.0,Miss,J,Strachan,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Fort Pitt,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,575450.0,167393.0,Medway 015,Medway 015B,,,,,Good,South-East England and South London,,44029362.0,,Not applicable,Not applicable,,,E02003328,E01016017,16.0,
142160,887,Medway,3195,St Margaret's Church of England Junior School,Academy converter,Academies,Open,Academy Converter,01-09-2015,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,363.0,No Special Classes,19-01-2023,364.0,189.0,175.0,19.0,Supported by a multi-academy trust,MEDWAY ANGLICAN SCHOOLS TRUST,-,,Not applicable,,10053758.0,,Not applicable,21-09-2023,26-03-2024,Orchard Street,Rainham,,Gillingham,Kent,ME8 9AE,http://www.stmargaretsonline.net,1634230998.0,Mr,Lenny,Williams,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham South West,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,581405.0,165749.0,Medway 029,Medway 029C,,,,,Good,South-East England and South London,,200000901856.0,,Not applicable,Not applicable,,,E02003342,E01016089,69.0,
142393,887,Medway,2014,Twydall Primary School and Nursery,Academy sponsor led,Academies,Open,New Provision,01-02-2016,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,255.0,Not applicable,19-01-2023,304.0,169.0,135.0,42.7,Supported by a multi-academy trust,RMET,Linked to a sponsor,RMET (Rainham Mark Education Trust),Not applicable,,10054150.0,,,17-05-2023,29-05-2024,Twydall Lane,,,Gillingham,Kent,ME8 6JS,www.twydallprimary.org.uk,1634231761.0,Mrs,Louise,Hardie,Headteacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,PD - Physical Disability,,,,,,,,,,,,,Resourced provision,7.0,8.0,,,South East,Medway,Twydall,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,579908.0,166888.0,Medway 018,Medway 018B,,,,,Good,South-East England and South London,,44087223.0,,Not applicable,Not applicable,,,E02003331,E01016161,120.0,
142394,887,Medway,2015,Temple Mill Primary School,Academy sponsor led,Academies,Open,New Provision,01-12-2015,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,247.0,126.0,121.0,21.7,Supported by a multi-academy trust,THE HOWARD ACADEMY TRUST,Linked to a sponsor,The Howard Academy Trust,Not applicable,,10054151.0,,,17-10-2018,11-04-2024,Cliffe Road,Strood,,Rochester,Kent,ME2 3NL,https://www.templemill-that.org.uk/,1634629079.0,Mrs,Lisa,Lewis,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood Rural,Rochester and Strood,(England/Wales) Urban city and town,E06000035,573642.0,170455.0,Medway 004,Medway 004C,,,,,Good,South-East England and South London,,100062388732.0,,Not applicable,Not applicable,,,E02003317,E01016148,51.0,
142399,887,Medway,2016,Byron Primary School,Academy sponsor led,Academies,Open,New Provision,01-01-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,None,Not applicable,Not applicable,525.0,Not applicable,19-01-2023,520.0,251.0,269.0,27.5,Supported by a multi-academy trust,THE WESTBROOK TRUST,Linked to a sponsor,The Westbrook Trust,Not applicable,,10054156.0,,,15-06-2022,21-05-2024,Byron Road,,,Gillingham,Kent,ME7 5XX,,1634852981.0,Mr,Jon,Carthy,Head Teacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Gillingham South,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,577482.0,167330.0,Medway 016,Medway 016C,,,,,Requires improvement,South-East England and South London,,44067058.0,,Not applicable,Not applicable,,,E02003329,E01016047,143.0,
142568,887,Medway,6010,The GFC School,Other independent school,Independent schools,Open,New Provision,07-12-2015,,,Not applicable,11.0,16,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,None,Not applicable,Selective,50.0,Not applicable,20-01-2022,28.0,20.0,8.0,0.0,Not applicable,,Not applicable,,Not applicable,,10066496.0,,,02-05-2019,15-04-2024,Priestfield Stadium,Redfern Avenue,,Gillingham,Kent,ME7 4DD,www.thegfcschool.co.uk,1634623420.0,Mrs,Sue,Wade,Head of School,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not approved,SpLD - Specific Learning Difficulty,"SEMH - Social, Emotional and Mental Health",MLD - Moderate Learning Difficulty,,,,,,,,,,,SEN unit,,,15.0,15.0,South East,Medway,Watling,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,578373.0,168139.0,Medway 013,Medway 013B,Ofsted,16.0,12.0,Paul Scally,Good,South-East England and South London,,44007001.0,,Not applicable,Not applicable,,,E02003326,E01016042,0.0,
142817,887,Medway,2017,Cedar Children's Academy,Academy sponsor led,Academies,Open,New Provision,01-06-2016,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,,Not applicable,Not applicable,630.0,Not applicable,19-01-2023,668.0,352.0,316.0,26.9,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10056531.0,,,09-05-2019,08-01-2024,Cedar Road,Strood,,Rochester,Kent,ME2 2JP,www.cedarchildrensacademy.org.uk,3333602105.0,Ms,Tracey,Baillie,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood West,Rochester and Strood,(England/Wales) Urban city and town,E06000035,572439.0,168467.0,Medway 011,Medway 011D,,,,,Good,South-East England and South London,,200000895826.0,,Not applicable,Not applicable,,,E02003324,E01016157,180.0,
143261,887,Medway,2203,Walderslade Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2016,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,240.0,No Special Classes,19-01-2023,235.0,110.0,125.0,16.6,Supported by a multi-academy trust,RIVERMEAD INCLUSIVE TRUST,Linked to a sponsor,Rivermead Inclusive Trust,Not applicable,,10057635.0,,Not applicable,21-11-2018,30-04-2024,Dargets Road,Walderslade,,Chatham,Kent,ME5 8BJ,www.walderslade-pri.medway.sch.uk/,1634337766.0,Mrs,Amy,Rowley-Jones,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Lordswood & Walderslade,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576195.0,163447.0,Medway 037,Medway 037B,,,,,Good,South-East England and South London,,44045350.0,,Not applicable,Not applicable,,,E02003350,E01016169,39.0,
143262,887,Medway,2213,Hoo St Werburgh Primary School and the Marlborough,Academy converter,Academies,Open,Academy Converter,01-09-2016,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,525.0,Has Special Classes,19-01-2023,573.0,308.0,265.0,19.9,Supported by a multi-academy trust,RIVERMEAD INCLUSIVE TRUST,Linked to a sponsor,Rivermead Inclusive Trust,Not applicable,,10057859.0,,Not applicable,06-03-2024,22-05-2024,Pottery Road,Hoo St Werburgh,,Rochester,Kent,ME3 9BS,www.hoo-st-werburgh.medway.sch.uk,1634338040.0,Mr,Simon,McLean,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,,Resourced provision and SEN unit,80.0,80.0,80.0,80.0,South East,Medway,Hoo St Werburgh & High Halstow,Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,577642.0,172283.0,Medway 003,Medway 003D,,,,,Good,South-East England and South London,,200000900025.0,,Not applicable,Not applicable,,,E02003316,E01016077,114.0,
143458,887,Medway,2684,Deanwood Primary School,Academy converter,Academies,Open,Academy Converter,01-10-2016,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,210.0,Not applicable,19-01-2023,207.0,102.0,105.0,18.4,Supported by a multi-academy trust,THE HOWARD ACADEMY TRUST,Linked to a sponsor,The Howard Academy Trust,Not applicable,,10061378.0,,Not applicable,02-11-2018,23-05-2024,"Deanwood Primary School, Long Catlis Road",Parkwood,,Gillingham,Kent,ME8 9TX,https://www.deanwood-that.org.uk/,1634231901.0,Mrs,Jane,Wright,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham South East,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,580615.0,163584.0,Medway 036,Medway 036B,,,,,Good,South-East England and South London,,200000909507.0,,Not applicable,Not applicable,,,E02003349,E01016099,38.0,
143832,887,Medway,3758,The Pilgrim School (A Church of England Primary With Nursery),Academy converter,Academies,Open,Academy Converter,01-12-2016,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,Not applicable,19-01-2023,229.0,102.0,127.0,18.6,Supported by a multi-academy trust,THE PILGRIM MULTI ACADEMY TRUST,-,,Not applicable,,10062013.0,,Not applicable,,01-06-2024,Warwick Crescent,Borstal,,Rochester,Kent,ME1 3LF,www.thepilgrimschool.co.uk,16343975555.0,Mrs,Alison,Mepsted,,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester West & Borstal,Rochester and Strood,(England/Wales) Urban city and town,E06000035,572771.0,166724.0,Medway 024,Medway 024B,,,,,,South-East England and South London,,44010044.0,,Not applicable,Not applicable,,,E02003337,E01016127,39.0,
143880,887,Medway,2214,Balfour Junior School,Academy converter,Academies,Open,Academy Converter,01-01-2017,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,480.0,No Special Classes,19-01-2023,480.0,257.0,223.0,29.0,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10062374.0,,Not applicable,05-12-2018,23-04-2024,Balfour Road,,,Chatham,Kent,ME4 6QX,www.balfourjuniorschool.org.uk,1634843833.0,Mrs,Zoe,Mayston,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Fort Pitt,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,575169.0,166802.0,Medway 021,Medway 021D,,,,,Good,South-East England and South London,,44038129.0,,Not applicable,Not applicable,,,E02003334,E01016125,139.0,
143909,887,Medway,2018,Wayfield Primary School,Academy converter,Academies,Open,Fresh Start,01-09-2016,,,Primary,2.0,11,,Has Nursery Classes,Not applicable,Mixed,None,Does not apply,,,360.0,Not applicable,19-01-2023,392.0,212.0,180.0,39.0,Supported by a multi-academy trust,THE PRIMARY FIRST TRUST,Linked to a sponsor,The Primary First Trust,Not applicable,,10062232.0,,,22-05-2019,25-04-2024,Wayfield Road,,,Chatham,Kent,ME5 0HH,www.wayfield.medway.sch.uk,3000658230.0,Miss,Ria,Henry,Head Teacher,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Wayfield & Weeds Wood,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576192.0,165414.0,Medway 027,Medway 027E,,,,,Good,South-East England and South London,,,,Not applicable,Not applicable,,,E02003340,E01016068,135.0,
144132,887,Medway,2592,Thames View Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2017,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,450.0,No Special Classes,19-01-2023,449.0,224.0,225.0,18.0,Supported by a multi-academy trust,THE HOWARD ACADEMY TRUST,Linked to a sponsor,The Howard Academy Trust,Not applicable,,10063038.0,,Not applicable,17-05-2023,23-05-2024,Bloors Lane,Rainham,,Gillingham,Kent,ME8 7DX,https://www.thamesview-that.org.uk/,1634629080.0,Mrs,Leanna,Rogers,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham North,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,581008.0,166754.0,Medway 023,Medway 023C,,,,,Good,South-East England and South London,,44103856.0,,Not applicable,Not applicable,,,E02003336,E01016166,74.0,
144133,887,Medway,2479,St Margaret's Infant School,Academy converter,Academies,Open,Academy Converter,01-04-2017,,,Primary,3.0,7,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,300.0,155.0,145.0,10.6,Supported by a multi-academy trust,THE WESTBROOK TRUST,Linked to a sponsor,The Westbrook Trust,Not applicable,,10063037.0,,Not applicable,13-02-2020,21-05-2024,"St Margaret's Infant School, Orchard Street",Orchard Street,Rainham,Gillingham,Kent,ME8 9AE,http://www.stmargaretsinf.medway.sch.uk,1634231327.0,Mrs,Paula,Fewtrell,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham South West,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,581405.0,165749.0,Medway 029,Medway 029C,,,,,Good,South-East England and South London,,100062396976.0,,Not applicable,Not applicable,,,E02003342,E01016089,30.0,
144134,887,Medway,1107,The Rowans,Academy alternative provision converter,Academies,Open,Academy Converter,01-06-2017,,,Not applicable,5.0,16,No boarders,Not applicable,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,65.0,Not applicable,19-01-2023,26.0,18.0,8.0,65.4,Supported by a multi-academy trust,THE INSPIRING CHANGE MULTI-ACADEMY TRUST,-,,Not applicable,,10063925.0,,Not applicable,10-11-2021,19-03-2024,Silverbank,Churchill Avenue,,Chatham,Kent,ME5 0LB,www.therowans.org,1634338803.0,Mrs,Fiona,May,Headteacher,Not applicable,,,,Not applicable,,Does not have child care facilities,PRU Does have Provision for SEN,PRU Does have EBD provision,66.0,PRU offers full time provision,Does not offer tuition by another provider,Not applicable,"SEMH - Social, Emotional and Mental Health",,,,,,,,,,,,,Resourced provision,65.0,65.0,,,South East,Medway,Wayfield & Weeds Wood,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576044.0,164885.0,Medway 027,Medway 027E,,,,,Outstanding,South-East England and South London,,44112005.0,,Not applicable,Not applicable,,,E02003340,E01016068,17.0,
144135,887,Medway,3757,Riverside Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2017,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,390.0,Not applicable,19-01-2023,406.0,220.0,186.0,32.5,Supported by a multi-academy trust,RMET,Linked to a sponsor,RMET (Rainham Mark Education Trust),Not applicable,,10063036.0,,Not applicable,13-11-2019,29-05-2024,St Edmunds Way,Rainham,,Gillingham,Kent,ME8 8ET,www.riverside.medway.sch.uk/,1634623500.0,Mrs,Helen,Robson,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,VI - Visual Impairment,ASD - Autistic Spectrum Disorder,,,,,,,,,,,,Resourced provision,17.0,15.0,,,South East,Medway,Rainham North,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,582416.0,166196.0,Medway 025,Medway 025C,,,,,Good,South-East England and South London,,44110167.0,,Not applicable,Not applicable,,,E02003338,E01016097,117.0,
144423,887,Medway,2396,Barnsole Primary School,Academy converter,Academies,Open,Academy Converter,01-05-2017,,,Primary,2.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,19-01-2023,671.0,336.0,335.0,25.9,Supported by a multi-academy trust,MARITIME ACADEMY TRUST,Linked to a sponsor,Maritime Academy Trust,Not applicable,,10063725.0,,Not applicable,29-02-2024,22-05-2024,Barnsole Road,,,Gillingham,Kent,ME7 2JG,www.barnsoleprimary.medway.sch.uk,1634333400.0,Mr,Jonathan,Smales,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Watling,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,578041.0,167976.0,Medway 013,Medway 013D,,,,,Good,South-East England and South London,,44076748.0,,Not applicable,Not applicable,,,E02003326,E01016177,168.0,
144566,887,Medway,2492,Bligh Primary School (Juniors),Academy converter,Academies,Open,Academy Converter,01-10-2017,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,330.0,No Special Classes,19-01-2023,328.0,159.0,169.0,35.7,Supported by a multi-academy trust,MARITIME ACADEMY TRUST,Linked to a sponsor,Maritime Academy Trust,Not applicable,,10064767.0,,Not applicable,22-06-2023,04-06-2024,Bligh Way,Strood,,Rochester,Kent,ME2 2XJ,www.blighprimaryschool.co.uk,1634336220.0,Mr,Christian,Markham,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood West,Rochester and Strood,(England/Wales) Urban city and town,E06000035,571407.0,169082.0,Medway 008,Medway 008D,,,,,Good,South-East England and South London,,100062388554.0,,Not applicable,Not applicable,,,E02003321,E01016155,117.0,
144639,887,Medway,2623,Miers Court Primary School,Academy converter,Academies,Open,Academy Converter,01-08-2017,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,394.0,200.0,194.0,14.2,Supported by a multi-academy trust,THE HOWARD ACADEMY TRUST,Linked to a sponsor,The Howard Academy Trust,Not applicable,,10064690.0,,Not applicable,03-11-2021,17-04-2024,Silverspot Close,,,Rainham,Kent,ME8 8JR,https://www.mierscourt-that.org.uk/,1634388943.0,Mrs,Susan,Chapman,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham South East,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,581647.0,165162.0,Medway 032,Medway 032C,,,,,Good,South-East England and South London,,44101008.0,,Not applicable,Not applicable,,,E02003345,E01016104,56.0,
144914,887,Medway,3293,St Margaret's at Troy Town CofE Voluntary Controlled Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2017,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Does not apply,Diocese of Rochester,Not applicable,210.0,No Special Classes,19-01-2023,225.0,119.0,106.0,37.3,Supported by a multi-academy trust,THE PILGRIM MULTI ACADEMY TRUST,-,,Not applicable,,10065034.0,,Not applicable,02-12-2021,05-02-2024,King Street,,,Rochester,Kent,ME1 1YF,http://www.stmargaretsattroytown.co.uk,1634843843.0,Miss,Katie,Willis,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,Not applicable,,,,,South East,Medway,Rochester East & Warren Wood,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574390.0,167980.0,Medway 014,Medway 014A,,,,,Good,South-East England and South London,,44023621.0,,Not applicable,Not applicable,,,E02003327,E01016117,76.0,
144915,887,Medway,2537,Bligh Primary School (Infants),Academy converter,Academies,Open,Academy Converter,01-10-2017,,,Primary,2.0,7,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,325.0,157.0,168.0,27.9,Supported by a multi-academy trust,MARITIME ACADEMY TRUST,Linked to a sponsor,Maritime Academy Trust,Not applicable,,10065035.0,,Not applicable,,04-06-2024,Bligh Way,Strood,,Rochester,Kent,ME2 2XJ,www.blighprimaryschool.co.uk,1634336220.0,Mr,Christian,Markham,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood West,Rochester and Strood,(England/Wales) Urban city and town,E06000035,571407.0,169082.0,Medway 008,Medway 008D,,,,,,South-East England and South London,,100062388554.0,,Not applicable,Not applicable,,,E02003321,E01016155,80.0,
144969,887,Medway,2019,Featherby Junior School,Academy sponsor led,Academies,Open,New Provision,01-09-2017,,,Primary,7.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,,Not applicable,Not applicable,360.0,Not applicable,19-01-2023,339.0,165.0,174.0,34.2,Supported by a multi-academy trust,MARITIME ACADEMY TRUST,Linked to a sponsor,Maritime Academy Trust,Not applicable,,10065102.0,,,29-06-2022,07-05-2024,Chilham Road,,Featherby Junior School,Gillingham,Kent,ME8 6BT,www.featherby-jun.medway.sch.uk,1634231984.0,Mrs,Emma,Pape,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Twydall,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,579316.0,167170.0,Medway 018,Medway 018D,,,,,Good,South-East England and South London,,44088972.0,,Not applicable,Not applicable,,,E02003331,E01016163,116.0,
145042,887,Medway,2401,Featherby Infant and Nursery School,Academy converter,Academies,Open,Academy Converter,01-09-2017,,,Primary,3.0,7,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,270.0,No Special Classes,19-01-2023,297.0,155.0,142.0,32.1,Supported by a multi-academy trust,MARITIME ACADEMY TRUST,Linked to a sponsor,Maritime Academy Trust,Not applicable,,10065161.0,,Not applicable,17-11-2021,07-05-2024,Allington Road,,,Gillingham,Kent,ME8 6PD,http://www.featherby-inf.medway.sch.uk,1634231072.0,Mrs,Emma,Pape,Head of School,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Twydall,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,579330.0,167352.0,Medway 018,Medway 018D,,,,,Good,South-East England and South London,,44088976.0,,Not applicable,Not applicable,,,E02003331,E01016163,93.0,
145112,887,Medway,2020,Maundene School,Academy sponsor led,Academies,Open,New Provision,01-01-2018,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,,Not applicable,Not applicable,420.0,Not applicable,19-01-2023,395.0,187.0,208.0,22.0,Supported by a multi-academy trust,INSPIRE PARTNERSHIP ACADEMY TRUST,Linked to a sponsor,Inspire Partnership Academy Trust,Not applicable,,10065460.0,,,15-06-2022,02-05-2024,Swallow Rise,Walderslade,,Chatham,Kent,ME5 7QB,https://www.maundene.medway.sch.uk/,1634864721.0,Miss,Joanne,Capes,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Princes Park,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576557.0,164396.0,Medway 034,Medway 034A,,,,,Good,South-East England and South London,,44047176.0,,Not applicable,Not applicable,,,E02003347,E01016078,87.0,
145440,887,Medway,2499,Hilltop Primary School,Academy converter,Academies,Open,Academy Converter,01-02-2018,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,448.0,No Special Classes,19-01-2023,436.0,242.0,194.0,14.3,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10066627.0,,Not applicable,29-06-2022,23-04-2024,Hilltop Road,Frindsbury,,Rochester,Kent,ME2 4QN,www.hilltopprimary.co.uk,1634710312.0,Mrs,Ewa,Eddy,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood Rural,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574043.0,170333.0,Medway 004,Medway 004C,,,,,Good,South-East England and South London,,100062389240.0,,Not applicable,Not applicable,,,E02003317,E01016148,61.0,
145926,887,Medway,2021,Elaine Primary School,Academy sponsor led,Academies,Open,Fresh Start,01-05-2018,,,Primary,3.0,11,No boarders,Has Nursery Classes,Not applicable,Mixed,None,None,,,350.0,Has Special Classes,19-01-2023,301.0,148.0,153.0,56.1,Supported by a multi-academy trust,INSPIRE PARTNERSHIP ACADEMY TRUST,Linked to a sponsor,Inspire Partnership Academy Trust,Not applicable,,10067319.0,,,22-09-2022,16-04-2024,Elaine Avenue,,,Rochester,,ME2 2YN,http://www.elaine.medway.sch.uk/,1634294817.0,Mrs,Sarah,Martin,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,"SEMH - Social, Emotional and Mental Health",,,,,,,,,,,,,SEN unit,,,20.0,11.0,South East,Medway,Strood West,Rochester and Strood,(England/Wales) Urban city and town,E06000035,572443.0,168984.0,Medway 011,Medway 011A,,,,,Good,South-East England and South London,United Kingdom,200000895803.0,,Not applicable,Not applicable,,,E02003324,E01016150,169.0,
146648,887,Medway,4003,Waterfront UTC,University technical college,Free Schools,Open,,01-04-2019,,,Secondary,14.0,19,,No Nursery Classes,Has a sixth form,Mixed,Does not apply,Does not apply,,Non-selective,250.0,Not applicable,19-01-2023,267.0,190.0,77.0,31.3,Supported by a multi-academy trust,THE HOWARD ACADEMY TRUST,Linked to a sponsor,The Howard Academy Trust,Not applicable,,10082095.0,,,11-01-2023,14-09-2023,South Side Three Road,,,Chatham,Kent,ME4 4FQ,www.waterfront-that.org.uk,1634505800.0,Mrs,Fiona,McLean,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,St Mary's Island,Rochester and Strood,(England/Wales) Urban city and town,E06000035,577382.0,169573.0,Medway 007,Medway 007H,,,,,Good,South-East England and South London,United Kingdom,44039551.0,,Not applicable,Not applicable,,,E02003320,E01035292,66.0,
146872,887,Medway,2211,Halling Primary School,Academy converter,Academies,Open,Academy Converter,01-04-2019,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,420.0,No Special Classes,19-01-2023,376.0,188.0,188.0,17.3,Supported by a multi-academy trust,ALETHEIA ACADEMIES TRUST,Linked to a sponsor,Aletheia Academies Trust,Not applicable,,10082988.0,,Not applicable,07-06-2023,14-05-2024,Howlsmere Close,Halling,,Rochester,Kent,ME2 1ER,http://www.halling.medway.sch.uk/,1634240258.0,Ms,Lisa,Taylor,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,"Cuxton, Halling & Riverside",Rochester and Strood,(England/Wales) Rural town and fringe,E06000035,570607.0,163387.0,Medway 028,Medway 028A,,,,,Good,South-East England and South London,,44000585.0,,Not applicable,Not applicable,,,E02003341,E01016026,65.0,
147446,887,Medway,2022,Wainscott Primary School,Academy sponsor led,Academies,Open,New Provision,01-09-2019,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,446.0,No Special Classes,19-01-2023,455.0,235.0,220.0,17.6,Supported by a multi-academy trust,THE PRIMARY FIRST TRUST,Linked to a sponsor,The Primary First Trust,Not applicable,,10084146.0,,,,21-05-2024,Wainscott Road,Wainscott,,Rochester,Kent,ME2 4JX,www.wainscott.medway.sch.uk,1634332550.0,Mrs,Monique,Clark,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Strood Rural,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574754.0,170678.0,Medway 004,Medway 004E,,,,,,South-East England and South London,United Kingdom,44028647.0,,Not applicable,Not applicable,,,E02003317,E01035289,80.0,
147769,887,Medway,2023,Delce Academy,Academy converter,Academies,Open,Fresh Start,01-03-2020,,,Primary,5.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,None,Does not apply,,,360.0,Has Special Classes,19-01-2023,359.0,193.0,166.0,44.0,Supported by a multi-academy trust,INSPIRE PARTNERSHIP ACADEMY TRUST,Linked to a sponsor,Inspire Partnership Academy Trust,Not applicable,,10085699.0,,,,28-05-2024,The Tideway,,,Rochester,Kent,ME1 2NJ,www.delceacademy.co.uk,1634845242.0,Miss,Loni,Stevens,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,"SEMH - Social, Emotional and Mental Health",,,,,,,,,,,,,SEN unit,,,15.0,15.0,South East,Medway,Rochester East & Warren Wood,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574455.0,166524.0,Medway 017,Medway 017C,,,,,,South-East England and South London,United Kingdom,44022435.0,,Not applicable,Not applicable,,,E02003330,E01016115,158.0,
148117,887,Medway,2433,Oaklands School,Academy converter,Academies,Open,Academy Converter,01-09-2020,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,450.0,No Special Classes,19-01-2023,430.0,208.0,222.0,42.2,Supported by a multi-academy trust,THE WESTBROOK TRUST,Linked to a sponsor,The Westbrook Trust,Not applicable,,10086851.0,,,04-07-2023,21-05-2024,Weedswood Road,Walderslade,,Chatham,Kent,ME5 0QS,http://www.oaklands.medway.sch.uk,1634333820.0,Mrs,Louisa,Jones,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Wayfield & Weeds Wood,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,575761.0,163898.0,Medway 033,Medway 033D,Not applicable,,,,Good,South-East England and South London,,44033912.0,,Not applicable,Not applicable,,,E02003346,E01016173,175.0,
148577,887,Medway,4004,Leigh Academy Rainham,Free schools,Free Schools,Open,New Provision,01-09-2021,,,Secondary,11.0,19,,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,1150.0,Not applicable,19-01-2023,405.0,223.0,182.0,16.8,Supported by a multi-academy trust,LEIGH ACADEMIES TRUST,Linked to a sponsor,Leigh Academies Trust,Not applicable,,10088768.0,,,28-02-2024,22-05-2024,Otterham Quay Lane,Rainham,,Gillingham,Kent,ME8 8GS,https://leighacademyrainham.org.uk/,1634412440.0,Miss,Alexandra,Millward,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rainham North,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,582774.0,165824.0,Medway 025,Medway 025E,,,,,Good,South-East England and South London,United Kingdom,44073878.0,,Not applicable,Not applicable,,,E02003338,E01016102,68.0,
149009,887,Medway,1108,Will Adams Academy,Academy alternative provision converter,Academies,Open,Academy Converter,01-04-2022,,,Not applicable,14.0,17,No boarders,Not applicable,Not applicable,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,,Not applicable,19-01-2023,39.0,21.0,18.0,39.5,Supported by a multi-academy trust,ALTERNATIVE LEARNING TRUST,Linked to a sponsor,Alternative Learning Trust,Not applicable,,10090191.0,,,,16-04-2024,Woodlands Road,,,Gillingham,Kent,ME7 2BX,www.willadamsacademy.org.uk,1634337111.0,Ms,Marie,Woolston,HeadTeacher,Not applicable,,,,Not applicable,,Not applicable,PRU Does not have Provision for SEN,Not applicable,,Not applicable,Not applicable,Not applicable,"SEMH - Social, Emotional and Mental Health",,,,,,,,,,,,,Resourced provision,45.0,45.0,,,South East,Medway,Watling,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,578774.0,167623.0,Medway 019,Medway 019A,Not applicable,,,,,South-East England and South London,,200003623419.0,,Not applicable,Not applicable,,,E02003332,E01016159,15.0,
149069,887,Medway,2025,Rochester Riverside Church of England Primary School,Free schools,Free Schools,Open,Academy Free School,01-09-2022,,,Primary,3.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Church of England,Christian,,Non-selective,446.0,Not applicable,19-01-2023,26.0,16.0,10.0,0.0,Supported by a multi-academy trust,THE PILGRIM MULTI ACADEMY TRUST,-,,Not applicable,,10090885.0,,,,29-05-2024,Gas House Road,,,Rochester,Kent,ME1 1US,rrcoe.medway.sch.uk,1634471697.0,Mrs,Alison,Mepsted,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Rochester West & Borstal,Rochester and Strood,(England/Wales) Urban city and town,E06000035,574334.0,168802.0,Medway 015,Medway 015F,,,,,,South-East England and South London,United Kingdom,44076556.0,,Not applicable,Not applicable,,,E02003328,E01035296,0.0,
149075,887,Medway,4005,Maritime Academy,Free schools,Free Schools,Open,Academy Free School,01-09-2022,,,Secondary,11.0,19,No boarders,No Nursery Classes,Has a sixth form,Mixed,None,None,Not applicable,Non-selective,1150.0,Not applicable,19-01-2023,142.0,77.0,65.0,27.5,Supported by a multi-academy trust,THE THINKING SCHOOLS ACADEMY TRUST,Linked to a sponsor,The Thinking Schools Academy Trust,Not applicable,,10090894.0,,,,24-05-2024,Frindsbury Hill,Rochester,Kent,Medway,,,https://www.maritimeacademy.org.uk/,3333602150.0,,Jody,Murphy,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Twydall,Gillingham and Rainham,(England/Wales) Urban city and town,E06000035,579947.0,166841.0,Medway 018,Medway 018B,,,,,,South-East England and South London,,,,Not applicable,Not applicable,,,E02003331,E01016161,39.0,
149979,887,Medway,3753,St Benedict's Catholic Primary School,Academy converter,Academies,Open,Academy Converter,01-09-2023,,,Primary,4.0,11,No boarders,No Nursery Classes,Does not have a sixth form,Mixed,Roman Catholic,Does not apply,Archdiocese of Southwark,Not applicable,210.0,No Special Classes,,,,,,Supported by a multi-academy trust,KENT CATHOLIC SCHOOLS' PARTNERSHIP,Linked to a sponsor,Kent Catholic Schools' Partnership,Not applicable,,10092965.0,,,,06-03-2024,Lambourn Way,Lordswood,,Chatham,Kent,ME5 8PU,www.st-benedicts.medway.sch.uk/,1634669700.0,Mrs,Sarah,McAlpine,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Lordswood & Walderslade,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,577291.0,162859.0,Medway 038,Medway 038D,Not applicable,,,,,South-East England and South London,,44058733.0,,Not applicable,Not applicable,,,E02003351,E01016060,,
150154,887,Medway,4007,Oasis Restore,Academy secure 16 to 19,Academies,Open,New Provision,15-04-2024,,,16 plus,12.0,17,,Not applicable,Not applicable,Mixed,,,,,49.0,Not applicable,,,,,,Not applicable,OASIS RESTORE TRUST,Not applicable,,Not applicable,,10094342.0,,,,15-04-2024,1 Kennington Road,,,London,,SE1 7QP,https://www.oasisrestore.org/,2079214200.0,Mr,Andrew,Willetts,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Lambeth,Waterloo & South Bank,Vauxhall,(England/Wales) Urban major conurbation,E06000035,531156.0,179383.0,Lambeth 036,Lambeth 036B,,,,,,,United Kingdom,100023225318.0,,Not applicable,Not applicable,,,E02006801,E01003014,,
150218,887,Medway,2199,Luton Primary School,Academy converter,Academies,Open,Academy Converter,01-11-2023,,,Primary,4.0,11,No boarders,Has Nursery Classes,Does not have a sixth form,Mixed,Does not apply,Does not apply,Not applicable,Not applicable,630.0,No Special Classes,,,,,,Supported by a multi-academy trust,RIVERMEAD INCLUSIVE TRUST,Linked to a sponsor,Rivermead Inclusive Trust,Not applicable,,10093456.0,,,,03-06-2024,Luton Road,,,Chatham,Kent,ME4 5AW,www.lutonprimaryschool.co.uk,1634336900.0,Mrs,Karen,Major,Headteacher,Not applicable,,,,Not applicable,,Not applicable,Not applicable,Not applicable,,Not applicable,Not applicable,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Luton,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,577119.0,166655.0,Medway 020,Medway 020A,Not applicable,,,,,South-East England and South London,,100062391815.0,,Not applicable,Not applicable,,,E02003333,E01016061,,
150869,887,Medway,4008,Walderslade School,Academy converter,Academies,Open,Fresh Start,01-04-2024,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Girls,None,Does not apply,,,949.0,Not applicable,,,,,,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10095249.0,,,,04-04-2024,Bradfields Avenue,Walderslade,,Chatham,Kent,ME5 0LE,,,Mrs,Louise,Campbell,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Wayfield & Weeds Wood,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,575885.0,164367.0,Medway 027,Medway 027D,,,,,,South-East England and South London,United Kingdom,44033058.0,,Not applicable,Not applicable,,,E02003340,E01016067,,
150870,887,Medway,4009,Greenacre School,Academy converter,Academies,Open,Fresh Start,01-04-2024,,,Secondary,11.0,18,No boarders,No Nursery Classes,Has a sixth form,Boys,None,Does not apply,,,969.0,Not applicable,,,,,,Supported by a multi-academy trust,BEYOND SCHOOLS TRUST,Linked to a sponsor,FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School),Not applicable,,10095250.0,,,,04-04-2024,157 Walderslade Road,Walderslade,,Chatham,Kent,ME5 0LP,,,Mrs,Louise,Campbell,,Not applicable,,,,Not applicable,,,Not applicable,Not applicable,,,,Not applicable,,,,,,,,,,,,,,,,,,,South East,Medway,Wayfield & Weeds Wood,Chatham and Aylesford,(England/Wales) Urban city and town,E06000035,576000.0,164283.0,Medway 034,Medway 034C,,,,,,South-East England and South London,United Kingdom,44026624.0,,Not applicable,Not applicable,,,E02003347,E01016081,,
1 URN LA (code) LA (name) EstablishmentNumber EstablishmentName TypeOfEstablishment (name) EstablishmentTypeGroup (name) EstablishmentStatus (name) ReasonEstablishmentOpened (name) OpenDate ReasonEstablishmentClosed (name) CloseDate PhaseOfEducation (name) StatutoryLowAge StatutoryHighAge Boarders (name) NurseryProvision (name) OfficialSixthForm (name) Gender (name) ReligiousCharacter (name) ReligiousEthos (name) Diocese (name) AdmissionsPolicy (name) SchoolCapacity SpecialClasses (name) CensusDate NumberOfPupils NumberOfBoys NumberOfGirls PercentageFSM TrustSchoolFlag (name) Trusts (name) SchoolSponsorFlag (name) SchoolSponsors (name) FederationFlag (name) Federations (name) UKPRN FEHEIdentifier FurtherEducationType (name) OfstedLastInsp LastChangedDate Street Locality Address3 Town County (name) Postcode SchoolWebsite TelephoneNum HeadTitle (name) HeadFirstName HeadLastName HeadPreferredJobTitle BSOInspectorateName (name) InspectorateReport DateOfLastInspectionVisit NextInspectionVisit TeenMoth (name) TeenMothPlaces CCF (name) SENPRU (name) EBD (name) PlacesPRU FTProv (name) EdByOther (name) Section41Approved (name) SEN1 (name) SEN2 (name) SEN3 (name) SEN4 (name) SEN5 (name) SEN6 (name) SEN7 (name) SEN8 (name) SEN9 (name) SEN10 (name) SEN11 (name) SEN12 (name) SEN13 (name) TypeOfResourcedProvision (name) ResourcedProvisionOnRoll ResourcedProvisionCapacity SenUnitOnRoll SenUnitCapacity GOR (name) DistrictAdministrative (name) AdministrativeWard (name) ParliamentaryConstituency (name) UrbanRural (name) GSSLACode (name) Easting Northing MSOA (name) LSOA (name) InspectorateName (name) SENStat SENNoStat PropsName OfstedRating (name) RSCRegion (name) Country (name) UPRN SiteName QABName (name) EstablishmentAccredited (name) QABReport CHNumber MSOA (code) LSOA (code) FSM AccreditationExpiryDate
2 118317 887 Medway 2198 Greenvale Primary School Community school Local authority maintained schools Open Not applicable Not applicable Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 120.0 No Special Classes 19-01-2023 110.0 58.0 52.0 39.1 Not applicable Not applicable Not under a federation 10074076.0 Not applicable 22-11-2023 22-04-2024 Symons Avenue Chatham Kent ME4 5UP www.greenvale.medway.sch.uk 1634409521.0 Mrs Amanda Allnutt Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Chatham Central & Brompton Chatham and Aylesford (England/Wales) Urban city and town E06000035 576183.0 166676.0 Medway 022 Medway 022B Good South-East England and South London 100062391942.0 Not applicable Not applicable E02003335 E01016023 43.0
3 118320 887 Medway 2202 New Road Primary School Community school Local authority maintained schools Open Not applicable Not applicable Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 360.0 No Special Classes 19-01-2023 360.0 187.0 173.0 38.6 Not applicable Not applicable Not under a federation 10076230.0 Not applicable 19-04-2023 04-06-2024 Bryant Street Chatham Kent ME4 5QN http://www.newroad.medway.sch.uk 1634843084.0 Mrs Samantha Cooper Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Chatham Central & Brompton Chatham and Aylesford (England/Wales) Urban city and town E06000035 576251.0 167414.0 Medway 015 Medway 015C Good South-East England and South London 44054185.0 Not applicable Not applicable E02003328 E01016019 139.0
4 118329 887 Medway 2215 Balfour Infant School Community school Local authority maintained schools Open Not applicable Not applicable Primary 5.0 7 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 270.0 No Special Classes 19-01-2023 266.0 140.0 126.0 23.8 Not applicable Not applicable Not under a federation 10074074.0 Not applicable 04-06-2019 12-04-2024 Pattens Lane Rochester Kent ME1 2QT http://www.balfourinf.medway.sch.uk 1634338280.0 Ms Donna Atkinson Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Fort Pitt Rochester and Strood (England/Wales) Urban city and town E06000035 575083.0 166460.0 Medway 026 Medway 026C Good South-East England and South London 44035930.0 Not applicable Not applicable E02003339 E01016124 63.0
5 118330 887 Medway 2216 Crest Infant School Community school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 7 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 270.0 No Special Classes 19-01-2023 177.0 83.0 94.0 34.5 Not applicable Not applicable Not under a federation 10074073.0 Not applicable 12-02-2020 29-04-2024 Fleet Road Rochester Kent ME1 2QA www.crestinfants.co.uk 1634844127.0 Mrs Kerry Seales Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rochester East & Warren Wood Rochester and Strood (England/Wales) Urban city and town E06000035 574568.0 166523.0 Medway 024 Medway 024A Good South-East England and South London 200000909496.0 Not applicable Not applicable E02003337 E01016116 60.0
6 118423 887 Medway 2403 Hempstead Junior School Community school Local authority maintained schools Open Not applicable Not applicable Primary 7.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 360.0 No Special Classes 19-01-2023 353.0 193.0 160.0 7.9 Not applicable Not applicable Not under a federation 10079033.0 Not applicable 20-06-2018 06-06-2024 Birch Grove Hempstead Gillingham Kent ME7 3HJ www.hempsteadjnr.medway.sch.uk/ 1634336963.0 Mr Paul Cross Head Teacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Hempstead & Wigmore Gillingham and Rainham (England/Wales) Urban city and town E06000035 579226.0 164022.0 Medway 035 Medway 035A Good South-East England and South London 100062394567.0 Not applicable Not applicable E02003348 E01016050 28.0
7 118442 887 Medway 2439 Horsted Infant School Community school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 7 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 180.0 No Special Classes 19-01-2023 177.0 93.0 84.0 10.2 Not applicable Not applicable Supported by a federation The Bluebell Federation 10074065.0 Not applicable 11-10-2023 03-06-2024 Barberry Avenue Chatham Kent ME5 9TF www.horstedschool.co.uk/ 1634335400.0 Mrs Sarah Steer Executive Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Fort Horsted Rochester and Strood (England/Wales) Urban city and town E06000035 574928.0 164210.0 Medway 033 Medway 033C Good South-East England and South London 200000909501.0 Not applicable Not applicable E02003346 E01016123 18.0
8 118472 887 Medway 2494 Parkwood Primary School Community school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 540.0 No Special Classes 19-01-2023 546.0 270.0 276.0 16.8 Not applicable Not applicable Not under a federation 10074063.0 Not applicable 08-06-2023 07-05-2024 Deanwood Drive Rainham Gillingham Kent ME8 9LP www.parkwoodprimary.org.uk 1634234699.0 Headteacher Lee McCormack Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham South East Gillingham and Rainham (England/Wales) Urban city and town E06000035 581085.0 164262.0 Medway 036 Medway 036D Requires improvement South-East England and South London 100062396933.0 Not applicable Not applicable E02003349 E01016105 92.0
9 118477 887 Medway 2506 Horsted Junior School Community school Local authority maintained schools Open Not applicable Not applicable Primary 7.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 248.0 No Special Classes 19-01-2023 249.0 130.0 119.0 16.5 Not applicable Not applicable Supported by a federation The Bluebell Federation 10079031.0 Not applicable 13-09-2023 03-06-2024 Barberry Avenue Chatham Kent ME5 9TF www.horstedschool.co.uk 1634335400.0 Mrs Sarah Steer Executive Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Fort Horsted Rochester and Strood (England/Wales) Urban city and town E06000035 575006.0 164184.0 Medway 033 Medway 033C Good South-East England and South London 44018867.0 Not applicable Not applicable E02003346 E01016123 41.0
10 118509 887 Medway 2549 Swingate Primary School Community school Local authority maintained schools Open Not applicable Not applicable Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 630.0 No Special Classes 19-01-2023 659.0 335.0 324.0 12.0 Not applicable Not applicable Not under a federation 10076224.0 Not applicable 08-11-2018 21-05-2024 Sultan Road Lordswood Chatham Kent ME5 8TJ www.swingate.medway.sch.uk/ 1634863778.0 Mr Steven Geary Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Lordswood & Walderslade Chatham and Aylesford (England/Wales) Urban city and town E06000035 577377.0 162361.0 Medway 038 Medway 038B Good South-East England and South London 44058696.0 Not applicable Not applicable E02003351 E01016056 76.0
11 118555 887 Medway 2638 Hempstead Infant School Community school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 7 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 270.0 No Special Classes 19-01-2023 270.0 149.0 121.0 5.2 Not applicable Not applicable Not under a federation 10074059.0 Not applicable 13-03-2024 22-05-2024 Hempstead Road Hempstead Gillingham Kent ME7 3QG www.hempsteadschoolsfederation.org.uk 1634336963.0 Mr Paul Cross Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Hempstead & Wigmore Gillingham and Rainham (England/Wales) Urban city and town E06000035 579161.0 164155.0 Medway 035 Medway 035B Good South-East England and South London 200000901137.0 Not applicable Not applicable E02003348 E01016051 14.0
12 118576 887 Medway 2665 St Peter's Infant School Community school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 7 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 100.0 No Special Classes 19-01-2023 94.0 53.0 41.0 32.3 Not applicable Not applicable Not under a federation 10074058.0 Not applicable 13-12-2018 02-06-2024 Holcombe Road Rochester Kent ME1 2HU http://www.stpetersinfants.co.uk/ 1634843590.0 Mrs Joanna Worrall (Interim) Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rochester East & Warren Wood Rochester and Strood (England/Wales) Urban city and town E06000035 574398.0 167163.0 Medway 017 Medway 017D Good South-East England and South London 44025555.0 Not applicable Not applicable E02003330 E01016118 30.0
13 118641 887 Medway 3096 St Helen's Church of England Primary School, Cliffe Voluntary controlled school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Church of England Does not apply Diocese of Rochester Not applicable 210.0 No Special Classes 19-01-2023 211.0 107.0 104.0 18.5 Not applicable Not applicable Not under a federation 10069109.0 Not applicable 04-06-2019 23-04-2024 Church Street Cliffe Rochester Kent ME3 7PU www.sthelens.medway.sch.uk/ 1634220246.0 Mrs Stephanie Jarvis Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood Rural Rochester and Strood (England/Wales) Rural town and fringe E06000035 573629.0 176192.0 Medway 002 Medway 002A Good South-East England and South London 44018290.0 Not applicable Not applicable E02003315 E01016142 39.0
14 118643 887 Medway 3102 St Nicholas CEVC Primary School Voluntary controlled school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Church of England Does not apply Diocese of Rochester Not applicable 120.0 No Special Classes 19-01-2023 93.0 46.0 47.0 28.0 Not applicable Not applicable Not under a federation 10079669.0 Not applicable 23-01-2013 26-04-2024 St Nicholas CEVC primary School London Road Strood Rochester Kent ME2 3HU http://www.st-nicholas.medway.sch.uk 1634717120.0 Mrs Ruth Gooch Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood North & Frindsbury Rochester and Strood (England/Wales) Urban city and town E06000035 573257.0 169332.0 Medway 006 Medway 006E Outstanding South-East England and South London 200000896704.0 Not applicable Not applicable E02003319 E01016141 26.0
15 118756 887 Medway 3712 St Michael's RC Primary School Voluntary aided school Local authority maintained schools Open Not applicable Not applicable Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Roman Catholic Does not apply Archdiocese of Southwark Not applicable 460.0 No Special Classes 19-01-2023 469.0 236.0 233.0 25.6 Not applicable Not applicable Not under a federation 10076805.0 Not applicable 06-11-2019 08-05-2024 Hills Terrace Chatham Kent ME4 6PX www.stmichaelsrcp.org 1634832578.0 Mrs Nicola Collins Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Fort Pitt Chatham and Aylesford (England/Wales) Urban city and town E06000035 575579.0 167357.0 Medway 015 Medway 015B Good South-East England and South London 44040971.0 Not applicable Not applicable E02003328 E01016017 107.0
16 118766 887 Medway 3729 English Martyrs' Catholic Primary School Voluntary aided school Local authority maintained schools Open, but proposed to close Not applicable Academy Converter 30-06-2024 Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Roman Catholic Does not apply Archdiocese of Southwark Not applicable 210.0 No Special Classes 19-01-2023 202.0 101.0 101.0 15.8 Not applicable Not applicable Not under a federation 10072742.0 Not applicable 13-07-2023 28-05-2024 Frindsbury Road Strood Rochester Kent ME2 4JA http://www.englishmartyrs.medway.sch.uk 1634718964.0 Ms Catherine Thacker Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood North & Frindsbury Rochester and Strood (England/Wales) Urban city and town E06000035 573987.0 169894.0 Medway 006 Medway 006A Good South-East England and South London 100062388690.0 Not applicable Not applicable E02003319 E01016135 32.0
17 118767 887 Medway 3732 St Thomas of Canterbury RC Primary School Voluntary aided school Local authority maintained schools Open, but proposed to close Not applicable Academy Converter 30-06-2024 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Roman Catholic Does not apply Archdiocese of Southwark Not applicable 236.0 No Special Classes 19-01-2023 258.0 125.0 133.0 12.1 Not applicable Not applicable Not under a federation 10072741.0 Not applicable 08-06-2023 28-05-2024 Romany Road Rainham Gillingham Kent ME8 6JH www.stthomascanterbury.org.uk/ 1634234677.0 Mrs Vicki-Louise Gallagher Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Twydall Gillingham and Rainham (England/Wales) Urban city and town E06000035 579863.0 166652.0 Medway 018 Medway 018F Good South-East England and South London 44087220.0 Not applicable Not applicable E02003331 E01016165 29.0
18 118769 887 Medway 3736 St Thomas More Roman Catholic Primary School Voluntary aided school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Roman Catholic Does not apply Archdiocese of Southwark Not applicable 420.0 No Special Classes 19-01-2023 417.0 188.0 229.0 11.3 Not applicable Not applicable Not under a federation 10072739.0 Not applicable 08-02-2013 09-02-2024 Bleakwood Road Chatham Kent ME5 0NF www.st-thomasmore.medway.sch.uk/ 1634864701.0 Mrs Victoria Ebdon Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Wayfield & Weeds Wood Chatham and Aylesford (England/Wales) Urban city and town E06000035 576043.0 164020.0 Medway 033 Medway 033D Outstanding South-East England and South London 44045642.0 Not applicable Not applicable E02003346 E01016173 47.0
19 118775 887 Medway 3746 St William of Perth Roman Catholic Primary School Voluntary aided school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Roman Catholic Does not apply Archdiocese of Southwark Not applicable 210.0 No Special Classes 19-01-2023 208.0 106.0 102.0 7.7 Not applicable Not applicable Not under a federation 10072738.0 Not applicable 18-10-2023 10-05-2024 Canon Close Maidstone Road Rochester Kent ME1 3EN www.stwilliamofperth.org.uk/ 1634404267.0 Mr James Willis Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rochester West & Borstal Rochester and Strood (England/Wales) Urban city and town E06000035 573973.0 166819.0 Medway 024 Medway 024D Good South-East England and South London 44010893.0 Not applicable Not applicable E02003337 E01016132 16.0
20 118779 887 Medway 3752 St Augustine of Canterbury Catholic Primary School Voluntary aided school Local authority maintained schools Open Not applicable Not applicable Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Roman Catholic Does not apply Archdiocese of Southwark Not applicable 210.0 No Special Classes 19-01-2023 199.0 101.0 98.0 13.6 Not applicable Not applicable Not under a federation 10072736.0 Not applicable 07-02-2024 20-05-2024 Deanwood Drive Rainham Gillingham Kent ME8 9NP www.staccp.org.uk/ 1634371892.0 Mrs Louise Prestidge Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham South East Gillingham and Rainham (England/Wales) Urban city and town E06000035 580898.0 163428.0 Medway 036 Medway 036C Good South-East England and South London 200000901485.0 Not applicable Not applicable E02003349 E01016100 27.0
21 118782 887 Medway 3755 St Mary's Catholic Primary School Voluntary aided school Local authority maintained schools Open Not applicable Not applicable Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Roman Catholic Does not apply Archdiocese of Southwark Not applicable 480.0 No Special Classes 19-01-2023 433.0 235.0 198.0 15.6 Not applicable Not applicable Not under a federation 10072734.0 Not applicable 26-04-2023 11-03-2024 Greenfield Road Https://Stmarysrcp.Medway.Sch.Uk/ Gillingham Kent ME7 1YH www.stmarysrcp.medway.sch.uk/ 1634855783.0 Mr Joseph Pomeroy Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Gillingham North Gillingham and Rainham (England/Wales) Urban city and town E06000035 577917.0 168572.0 Medway 010 Medway 010B Good South-East England and South London 44069382.0 Not applicable Not applicable E02003323 E01016032 61.0
22 118908 887 Medway 5436 St John Fisher Catholic Comprehensive School Voluntary aided school Local authority maintained schools Open Not applicable Not applicable Secondary 11.0 18 No boarders No Nursery Classes Has a sixth form Mixed Roman Catholic Does not apply Archdiocese of Southwark Non-selective 1185.0 No Special Classes 19-01-2023 1024.0 550.0 474.0 30.1 Not applicable Not applicable Not under a federation 10006189.0 Not applicable 22-05-2019 23-05-2024 City Way Rochester ME1 2FA http://www.stjohnfisher.school 1634543123.0 Mrs Dympna Lennon Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Fort Pitt Chatham and Aylesford (England/Wales) Urban city and town E06000035 575287.0 167305.0 Medway 021 Medway 021A Good South-East England and South London United Kingdom 44082945.0 Not applicable Not applicable E02003334 E01016020 262.0
23 118948 887 Medway 6000 King's School, Rochester Other independent school Independent schools Open Not applicable 01-01-1909 Not applicable Not applicable 3.0 18 Boarding school Has Nursery Classes Has a sixth form Mixed Church of England Church of England Not applicable Non-selective 800.0 No Special Classes 20-01-2022 660.0 384.0 276.0 0.0 Not applicable Not applicable Not applicable 10003660.0 Not applicable 06-06-2024 Satis House Boley Hill Rochester Kent ME1 1TE www.kings-rochester.co.uk 1634888555.0 Mr Benjamin Charles Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not approved South East Medway Rochester West & Borstal Rochester and Strood (England/Wales) Urban city and town E06000035 574095.0 168504.0 Medway 014 Medway 014C ISI 4.0 89.0 The Governors of King's School South-East England and South London 44026826.0 Not applicable Not applicable E02003327 E01016130 0.0
24 118979 887 Medway 6001 Bryony School Other independent school Independent schools Open Not applicable 02-04-1958 Not applicable Not applicable 2.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed None None Not applicable Non-selective 232.0 No Special Classes 20-01-2022 128.0 60.0 68.0 0.0 Not applicable Not applicable Not applicable 10071117.0 Not applicable 24-11-2022 28-05-2024 157 Marshall Road Rainham Marshall Road Rainham ME8 0AJ www.bryonyschool.org.uk 1634231511.0 Mrs Natalie Gee Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not approved South East Medway Rainham South West Gillingham and Rainham (England/Wales) Urban city and town E06000035 580169.0 165278.0 Medway 030 Medway 030C Ofsted 1.0 Mr & Mrs Edmunds Good South-East England and South London 100061264465.0 Not applicable Not applicable E02003343 E01016091 0.0
25 118985 887 Medway 6002 St Andrew's School (Rochester) Other independent school Independent schools Open Not applicable 18-03-1958 Not applicable Not applicable 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed None None Not applicable Not applicable 360.0 No Special Classes 20-01-2022 362.0 172.0 190.0 0.0 Not applicable Not applicable Not applicable 10080533.0 Not applicable 24-05-2024 24 - 26 Watts Avenue Rochester Kent ME1 1SA www.st-andrews.rochester.sch.uk 1634843479.0 Mrs Emma Steinmann-Gilbert Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not approved South East Medway Rochester West & Borstal Rochester and Strood (England/Wales) Urban city and town E06000035 574044.0 167996.0 Medway 014 Medway 014C ISI 8.0 Education Development Trust South-East England and South London 44022882.0 Not applicable Not applicable E02003327 E01016130 0.0
26 119006 887 Medway 6004 Rochester Independent College Other independent school Independent schools Open Not applicable 26-09-1986 Not applicable Not applicable 11.0 21 Boarding school No Nursery Classes Has a sixth form Mixed None None Not applicable Non-selective 380.0 No Special Classes 20-01-2022 358.0 197.0 161.0 0.0 Not applicable Not applicable Not applicable 10005511.0 Not applicable 21-03-2024 254 St Margaret's Banks Rochester Kent ME1 1HY www.rochester-college.org.uk 1634828115.0 Mr Alistair Brownlow Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not approved South East Medway Rochester West & Borstal Rochester and Strood (England/Wales) Urban city and town E06000035 574653.0 167978.0 Medway 015 Medway 015F ISI 43.0 102.0 Dukes Education South-East England and South London United Kingdom 100062373676.0 Not applicable Not applicable E02003328 E01035296 0.0
27 131527 887 Medway 3760 Burnt Oak Primary School Community school Local authority maintained schools Open Result of Amalgamation 01-09-2006 Not applicable Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 420.0 Not applicable 19-01-2023 453.0 238.0 215.0 40.6 Not applicable Not applicable Not under a federation 10075241.0 Not applicable 18-05-2022 20-05-2024 Richmond Road Gillingham Kent ME7 1LS www.burntoak.medway.sch.uk/ 1634334344.0 Mrs Maureen Grabski Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Gillingham North Gillingham and Rainham (England/Wales) Urban city and town E06000035 577499.0 169057.0 Medway 009 Medway 009C Good South-East England and South London 44027271.0 Not applicable Not applicable E02003322 E01016037 183.0
28 132056 887 Medway 3756 St Mary's Island Church of England (Aided) Primary School Voluntary aided school Local authority maintained schools Open Not applicable 01-09-1999 Not applicable Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Church of England Does not apply Diocese of Rochester Not applicable 630.0 Not applicable 19-01-2023 671.0 329.0 342.0 10.3 Not applicable Not applicable Not under a federation 10075517.0 Not applicable 15-11-2023 23-04-2024 Island Way West St Mary's Island Chatham Kent ME4 3ST http://www.st-marys-island-cofe-primary-school.co.uk 1634891050.0 Mrs Christine Easton Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway St Mary's Island Rochester and Strood (England/Wales) Urban city and town E06000035 576620.0 170684.0 Medway 007 Medway 007F Good South-East England and South London 200003623259.0 Not applicable Not applicable E02003320 E01035290 69.0
29 134904 887 Medway 3759 Fairview Community Primary School Community school Local authority maintained schools Open Result of Amalgamation 12-09-2005 Not applicable Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 690.0 Not applicable 19-01-2023 668.0 340.0 328.0 7.0 Not applicable Not applicable Not under a federation 10071739.0 Not applicable 02-04-2019 21-05-2024 Drewery Drive Wigmore Gillingham Kent ME8 0NU www.fairviewprimary.co.uk 1634338710.0 Mrs Karin Tillett Head Teacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Hempstead & Wigmore Gillingham and Rainham (England/Wales) Urban city and town E06000035 580272.0 164185.0 Medway 030 Medway 030A Good South-East England and South London 44013431.0 Not applicable Not applicable E02003343 E01016085 44.0
30 135964 887 Medway 6905 Strood Academy Academy sponsor led Academies Open New Provision 01-09-2009 Not applicable Secondary 11.0 19 No boarders Not applicable Has a sixth form Mixed Does not apply None Not applicable Non-selective 1500.0 No Special Classes 19-01-2023 1273.0 626.0 647.0 26.8 Supported by a multi-academy trust LEIGH ACADEMIES TRUST Linked to a sponsor Leigh Academies Trust Not applicable 10027834.0 Not applicable 02-12-2021 17-05-2024 Carnation Road Strood Rochester Kent ME2 2SX http://www.stroodacademy.org.uk 1634717121.0 Mr Jon Richardson Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable ASD - Autistic Spectrum Disorder Resourced provision and SEN unit 5.0 25.0 5.0 25.0 South East Medway Strood West Rochester and Strood (England/Wales) Urban city and town E06000035 571638.0 169261.0 Medway 008 Medway 008D Good South-East England and South London 100062388557.0 Not applicable Not applicable E02003321 E01016155 310.0
31 136107 887 Medway 6906 Brompton Academy Academy sponsor led Academies Open New Provision 01-09-2010 Not applicable Secondary 11.0 18 No boarders Not applicable Has a sixth form Mixed Does not apply None Not applicable Non-selective 1400.0 Has Special Classes 19-01-2023 1403.0 736.0 667.0 30.4 Supported by a multi-academy trust THE UNIVERSITY OF KENT ACADEMIES TRUST Linked to a sponsor University of Kent (Brompton Academy) Not applicable 10030223.0 Not applicable 22-09-2022 21-05-2024 Marlborough Road Gillingham Kent ME7 5HT http://www.bromptonacademy.org.uk 1634852341.0 Mr Dan Walters Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable SpLD - Specific Learning Difficulty OTH - Other Difficulty/Disability SLCN - Speech, language and Communication SEN unit 94.0 100.0 South East Medway Gillingham South Gillingham and Rainham (England/Wales) Urban city and town E06000035 576827.0 167905.0 Medway 012 Medway 012C Requires improvement South-East England and South London 44054862.0 Not applicable Not applicable E02003325 E01016045 366.0
32 136108 887 Medway 6907 The Victory Academy Academy sponsor led Academies Open New Provision 01-09-2010 Not applicable Secondary 11.0 18 No boarders Not applicable Has a sixth form Mixed None None Non-selective 1500.0 No Special Classes 19-01-2023 1188.0 598.0 590.0 40.1 Supported by a multi-academy trust THE THINKING SCHOOLS ACADEMY TRUST Linked to a sponsor The Thinking Schools Academy Trust Not applicable 10030225.0 Not applicable 03-02-2023 07-06-2024 Magpie Hall Road Chatham Kent ME4 5JB http://www.thevictoryacademy.org.uk/ 3333602140.0 Mr Oliver Owen Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Luton Chatham and Aylesford (England/Wales) Urban city and town E06000035 576368.0 166387.0 Medway 022 Medway 022D Good South-East England and South London 44051900.0 Not applicable Not applicable E02003335 E01016062 428.0
33 136313 887 Medway 5445 The Rochester Grammar School Academy converter Academies Open Academy Converter 01-11-2010 Secondary 11.0 18 No boarders Not applicable Has a sixth form Girls None Does not apply Not applicable Selective 1110.0 No Special Classes 19-01-2023 1182.0 9.0 1173.0 7.0 Supported by a multi-academy trust THE THINKING SCHOOLS ACADEMY TRUST Linked to a sponsor The Thinking Schools Academy Trust Not applicable 10032200.0 Not applicable 18-01-2023 21-05-2024 Maidstone Road Rochester Kent ME1 3BY http://www.rochestergrammar.org.uk 3333602120.0 Mrs Clare Brinklow Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rochester East & Warren Wood Rochester and Strood (England/Wales) Urban city and town E06000035 574171.0 166566.0 Medway 017 Medway 017C Good South-East England and South London 44022498.0 Not applicable Not applicable E02003330 E01016115 70.0
34 136337 887 Medway 4069 Fort Pitt Grammar School Academy converter Academies Open Academy Converter 01-11-2010 Secondary 11.0 18 No boarders Not applicable Has a sixth form Girls None Does not apply Not applicable Selective 800.0 No Special Classes 19-01-2023 895.0 20.0 875.0 11.6 Supported by a multi-academy trust BEYOND SCHOOLS TRUST Linked to a sponsor FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School) Not applicable 10032192.0 Not applicable 05-10-2022 05-03-2024 Fort Pitt Hill Chatham Kent ME4 6TJ http://www.fortpitt.medway.sch.uk 1634842359.0 Ms Salena Hirons Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Fort Pitt Rochester and Strood (England/Wales) Urban city and town E06000035 575049.0 167596.0 Medway 015 Medway 015G Outstanding South-East England and South London 100062392022.0 Not applicable Not applicable E02003328 E01035297 83.0
35 136456 887 Medway 4199 Rainham School for Girls Academy converter Academies Open Academy Converter 01-02-2011 Secondary 11.0 18 No boarders Not applicable Has a sixth form Girls Does not apply Does not apply Not applicable Non-selective 1558.0 No Special Classes 19-01-2023 1668.0 36.0 1632.0 17.6 Supported by a multi-academy trust THE KEMNAL ACADEMIES TRUST Linked to a sponsor The Kemnal Academies Trust Not applicable 10032961.0 Not applicable 21-04-2022 20-05-2024 Derwent Way Rainham Gillingham Kent ME8 0BX http://www.rainhamgirls-tkat.org/ 1634362746.0 Mrs Vicki Shaw Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham South West Gillingham and Rainham (England/Wales) Urban city and town E06000035 580560.0 165785.0 Medway 029 Medway 029B Good South-East England and South London 100062395978.0 Not applicable Not applicable E02003342 E01016088 243.0
36 136594 887 Medway 4068 Holcombe Grammar School Academy converter Academies Open Academy Converter 01-04-2011 Secondary 11.0 18 No boarders Not applicable Has a sixth form Boys Does not apply Does not apply Not applicable Selective 1000.0 No Special Classes 19-01-2023 1067.0 955.0 112.0 9.9 Supported by a multi-academy trust THE THINKING SCHOOLS ACADEMY TRUST Linked to a sponsor The Thinking Schools Academy Trust Not applicable 10033242.0 Not applicable 24-04-2018 07-06-2024 Holcombe Maidstone Road Chatham Kent ME4 6JB http://www.holcombegrammar.org.uk 3333602130.0 Mr Lee Preston Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Fort Pitt Chatham and Aylesford (England/Wales) Urban city and town E06000035 575486.0 166035.0 Medway 027 Medway 027A Good South-East England and South London 100062392018.0 Not applicable Not applicable E02003340 E01016025 72.0
37 136662 887 Medway 4530 Sir Joseph Williamson's Mathematical School Academy converter Academies Open Academy Converter 01-04-2011 Secondary 11.0 18 No boarders Not applicable Has a sixth form Boys None Does not apply Not applicable Selective 1280.0 No Special Classes 19-01-2023 1479.0 1386.0 93.0 8.7 Supported by a multi-academy trust LEIGH ACADEMIES TRUST Linked to a sponsor Leigh Academies Trust Not applicable 10033431.0 Not applicable 22-03-2023 07-06-2024 Maidstone Road Rochester Kent ME1 3EL http://www.sjwms.org.uk 1634844008.0 Mr Eliot Hodges Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rochester West & Borstal Rochester and Strood (England/Wales) Urban city and town E06000035 574020.0 166430.0 Medway 024 Medway 024C Outstanding South-East England and South London 44022499.0 Not applicable Not applicable E02003337 E01016128 92.0
38 136859 887 Medway 2588 Cliffe Woods Primary School Academy converter Academies Open Academy Converter 01-07-2011 Primary 4.0 11 No boarders No Nursery Classes Not applicable Mixed Does not apply Does not apply Not applicable Not applicable 420.0 No Special Classes 19-01-2023 415.0 197.0 218.0 5.1 Supported by a multi-academy trust ALETHEIA ACADEMIES TRUST Linked to a sponsor Aletheia Academies Trust Not applicable 10034067.0 Not applicable 18-03-2015 07-05-2024 View Road Cliffe Woods Rochester Kent ME3 8UJ www.cliffewoods.medway.sch.uk 1634220822.0 Mrs Karen Connolly Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood Rural Rochester and Strood (England/Wales) Rural town and fringe E06000035 574188.0 173690.0 Medway 002 Medway 002C Outstanding South-East England and South London 44030622.0 Not applicable Not applicable E02003315 E01016145 21.0
39 136864 887 Medway 5420 Rainham Mark Grammar School Academy converter Academies Open Academy Converter 01-07-2011 Secondary 11.0 18 No boarders Not applicable Has a sixth form Mixed None Does not apply Not applicable Selective 1242.0 No Special Classes 19-01-2023 1567.0 839.0 728.0 7.3 Supported by a multi-academy trust RMET Linked to a sponsor RMET (Rainham Mark Education Trust) Not applicable 10034121.0 Not applicable 25-05-2022 29-05-2024 Pump Lane Rainham Gillingham Kent ME8 7AJ http://rainhammark.com/ 1634364151.0 Mrs Agnes Hart Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham North Gillingham and Rainham (England/Wales) Urban city and town E06000035 580729.0 166755.0 Medway 023 Medway 023C Good South-East England and South London 44096394.0 Not applicable Not applicable E02003336 E01016166 88.0
40 137119 887 Medway 4000 The Hundred of Hoo Academy Academy sponsor led Academies Open New Provision 01-09-2011 Not applicable All-through 4.0 19 No boarders Not applicable Has a sixth form Mixed None None Not applicable Non-selective 1900.0 Not applicable 19-01-2023 1702.0 844.0 858.0 22.3 Supported by a multi-academy trust LEIGH ACADEMIES TRUST Linked to a sponsor Leigh Academies Trust Not applicable 10034985.0 Not applicable 05-07-2018 08-05-2024 Main Road Hoo Rochester Kent ME3 9HH https://www.hundredofhooacademy.org.uk/ 1634251443.0 Mr Carl Guerin-Hassett Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable ASD - Autistic Spectrum Disorder SEN unit 43.0 48.0 South East Medway Hoo St Werburgh & High Halstow Rochester and Strood (England/Wales) Rural town and fringe E06000035 577407.0 172277.0 Medway 003 Medway 003D Good South-East England and South London 200000900015.0 Not applicable Not applicable E02003316 E01016077 353.0
41 137376 887 Medway 5451 The Thomas Aveling School Academy converter Academies Open Academy Converter 01-09-2011 Secondary 11.0 18 No boarders Not applicable Has a sixth form Mixed None Does not apply Not applicable Non-selective 1204.0 No Special Classes 19-01-2023 1205.0 599.0 606.0 25.1 Supported by a multi-academy trust BEYOND SCHOOLS TRUST Linked to a sponsor FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School) Not applicable 10035084.0 Not applicable 14-09-2022 14-05-2024 Arethusa Road Rochester Kent ME1 2UW http://www.thomasaveling.co.uk 1634844809.0 Mr Paul Jackson Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable HI - Hearing Impairment Resourced provision 20.0 20.0 South East Medway Rochester East & Warren Wood Rochester and Strood (England/Wales) Urban city and town E06000035 574327.0 165761.0 Medway 026 Medway 026B Good South-East England and South London 44018933.0 Not applicable Not applicable E02003339 E01016120 259.0
42 137389 887 Medway 5429 Chatham Grammar Academy converter Academies Open Academy Converter 01-09-2011 Secondary 11.0 18 No boarders Not applicable Has a sixth form Girls None Does not apply Not applicable Selective 976.0 No Special Classes 19-01-2023 945.0 18.0 927.0 10.9 Supported by a multi-academy trust THE UNIVERSITY OF KENT ACADEMIES TRUST Linked to a sponsor University of Kent (Brompton Academy) Not applicable 10035160.0 Not applicable 18-10-2023 22-05-2024 Rainham Road Chatham Kent ME5 7EH http://www.chathamgirlsgrammar.medway.sch.uk/ 1634851262.0 Ms Wendy Walters Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Luton Chatham and Aylesford (England/Wales) Urban city and town E06000035 577460.0 166933.0 Medway 020 Medway 020A Good South-East England and South London 200000899518.0 Not applicable Not applicable E02003333 E01016061 80.0
43 137990 887 Medway 2421 High Halstow Primary Academy Academy converter Academies Open Academy Converter 01-04-2012 Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed None Does not apply Not applicable Not applicable 210.0 No Special Classes 19-01-2023 211.0 111.0 100.0 9.5 Supported by a multi-academy trust LEIGH ACADEMIES TRUST Linked to a sponsor Leigh Academies Trust Not applicable 10036980.0 Not applicable 21-06-2023 14-03-2024 Harrison Drive High Halstow Rochester Kent ME3 8TF http://www.highhalstowprimaryacademy.org.uk 1634251098.0 Mrs Gemma Stangroom Head of School Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Hoo St Werburgh & High Halstow Rochester and Strood (England/Wales) Rural town and fringe E06000035 578093.0 175447.0 Medway 003 Medway 003A Outstanding South-East England and South London 44083531.0 Not applicable Not applicable E02003316 E01016073 20.0
44 138182 887 Medway 2600 All Faiths Children's Academy Academy converter Academies Open Academy Converter 01-06-2012 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 210.0 Has Special Classes 19-01-2023 226.0 101.0 125.0 28.4 Supported by a multi-academy trust THE THINKING SCHOOLS ACADEMY TRUST Linked to a sponsor The Thinking Schools Academy Trust Not applicable 10037460.0 Not applicable 29-01-2020 23-04-2024 Gun Lane Strood Rochester Kent ME2 4UF www.allfaithschildrensacademy.org.uk 3333602100.0 Mrs Kirstie Jones Acting Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable HI - Hearing Impairment Resourced provision and SEN unit 15.0 15.0 15.0 15.0 South East Medway Strood North & Frindsbury Rochester and Strood (England/Wales) Urban city and town E06000035 573564.0 169506.0 Medway 006 Medway 006E Good South-East England and South London 200000896787.0 Not applicable Not applicable E02003319 E01016141 64.0
45 138328 887 Medway 2209 Chattenden Primary School Academy converter Academies Open Academy Converter 01-07-2012 Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 210.0 No Special Classes 19-01-2023 209.0 101.0 108.0 34.8 Supported by a multi-academy trust PENINSULA GATEWAY ACADEMY TRUST - Not applicable 10037769.0 Not applicable 06-11-2018 03-05-2024 Chattenden Lane Chattenden Rochester Kent ME3 8LF http://www.chattenden.medway.sch.uk/ 1634250861.0 Miss Julie North Principal Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Hoo St Werburgh & High Halstow Rochester and Strood (England/Wales) Rural village E06000035 575792.0 171843.0 Medway 003 Medway 003E Good South-East England and South London 200000909509.0 Not applicable Not applicable E02003316 E01016143 72.0
46 138510 887 Medway 2001 Phoenix Primary School Academy sponsor led Academies Open New Provision 01-09-2012 Primary 5.0 11 Not applicable Not applicable Mixed None None Not applicable Not applicable 360.0 Not applicable 19-01-2023 359.0 179.0 180.0 49.3 Supported by a multi-academy trust BEYOND SCHOOLS TRUST Linked to a sponsor FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School) Not applicable 10038455.0 Not applicable 21-06-2023 25-04-2024 Glencoe Road Chatham Kent ME4 5QD www.phoenixprimary.com 1634829009.0 Mrs Melissa Ireland-Hubbert Head of School Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Chatham Central & Brompton Chatham and Aylesford (England/Wales) Urban city and town E06000035 576075.0 166910.0 Medway 022 Medway 022A Good South-East England and South London 44051781.0 Not applicable Not applicable E02003335 E01016018 176.0
47 138511 887 Medway 4001 The Robert Napier School Academy sponsor led Academies Open New Provision 01-09-2012 Secondary 11.0 18 No boarders Not applicable Has a sixth form Mixed None None Not applicable Non-selective 1080.0 Not applicable 19-01-2023 1037.0 561.0 476.0 43.0 Supported by a multi-academy trust BEYOND SCHOOLS TRUST Linked to a sponsor FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School) Not applicable 10038456.0 Not applicable 31-01-2019 21-05-2024 Third Avenue Gillingham Kent ME7 2LX http://www.robertnapier.org.uk/ 1634851157.0 Mrs Jenny Tomkins Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Watling Gillingham and Rainham (England/Wales) Urban city and town E06000035 578331.0 167405.0 Medway 019 Medway 019D Good South-East England and South London 44076749.0 Not applicable Not applicable E02003332 E01016179 407.0
48 138974 887 Medway 2002 St James Church of England Primary Academy Academy sponsor led Academies Open New Provision 01-12-2012 Primary 3.0 11 Has Nursery Classes Does not have a sixth form Mixed Church of England None Diocese of Rochester Not applicable 210.0 Not applicable 19-01-2023 199.0 104.0 95.0 31.7 Supported by a multi-academy trust MEDWAY ANGLICAN SCHOOLS TRUST - Not applicable 10039506.0 Not applicable 24-05-2023 23-02-2024 High Street Isle of Grain Rochester Kent ME3 0BS http://www.stjamesisleofgrain.org.uk 1634270341.0 Miss Fay Cordingley Head of School Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway All Saints Rochester and Strood (England/Wales) Rural town and fringe E06000035 588751.0 176727.0 Medway 001 Medway 001B Good South-East England and South London 44004798.0 Not applicable Not applicable E02003314 E01016071 58.0
49 139493 887 Medway 2412 The Academy of Woodlands Academy converter Academies Open Academy Converter 01-04-2013 Primary 2.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 630.0 Not applicable 19-01-2023 758.0 386.0 372.0 32.1 Supported by a multi-academy trust RIVERMEAD INCLUSIVE TRUST Linked to a sponsor Rivermead Inclusive Trust Not applicable 10041035.0 Not applicable 11-12-2019 01-05-2024 Woodlands Road Gillingham Kent ME7 2DU www.theacademyofwoodlands.co.uk 3000658200.0 Mrs Chloe Brown Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Watling Gillingham and Rainham (England/Wales) Urban city and town E06000035 578807.0 167818.0 Medway 013 Medway 013C Good South-East England and South London 100062394529.0 Not applicable Not applicable E02003326 E01016043 243.0
50 139927 887 Medway 2003 Kingfisher Community Primary School Academy sponsor led Academies Open New Provision 01-09-2013 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 210.0 Not applicable 19-01-2023 219.0 103.0 116.0 40.6 Supported by a multi-academy trust THE GRIFFIN SCHOOLS TRUST Linked to a sponsor The Griffin Schools Trust Not applicable 10042689.0 Not applicable 12-09-2019 28-05-2024 Kingfisher Drive Princes Park Walderslade Chatham Kent ME5 7NX www.kingfisher-gst.org 1634661540.0 Ms Fiona Armstrong Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Princes Park Chatham and Aylesford (England/Wales) Urban city and town E06000035 577072.0 165267.0 Medway 031 Medway 031E Good South-East England and South London 100062392674.0 Not applicable Not applicable E02003344 E01016084 89.0
51 139928 887 Medway 2004 Saxon Way Primary School Academy sponsor led Academies Open New Provision 01-09-2013 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 420.0 Not applicable 19-01-2023 425.0 229.0 196.0 47.2 Supported by a multi-academy trust THE GRIFFIN SCHOOLS TRUST Linked to a sponsor The Griffin Schools Trust Not applicable 10042702.0 Not applicable 22-01-2020 04-06-2024 Ingram Road Gillingham Kent ME7 1SJ http://www.saxonway-gst.org/ 1634336720.0 Mrs Jennifer Vidler-Ironmonger Head of School Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Gillingham North Gillingham and Rainham (England/Wales) Urban city and town E06000035 578169.0 168848.0 Medway 010 Medway 010B Good South-East England and South London 200000900397.0 Not applicable Not applicable E02003323 E01016032 200.0
52 140040 887 Medway 2006 Oasis Academy Skinner Street Academy sponsor led Academies Open New Provision 01-09-2013 Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 420.0 Not applicable 19-01-2023 410.0 198.0 212.0 51.7 Supported by a multi-academy trust OASIS COMMUNITY LEARNING Linked to a sponsor Oasis Community Learning Not applicable 10042952.0 Not applicable 22-09-2021 19-04-2024 Skinner Street Gillingham Kent ME7 1LG www.oasisacademyskinnerstreet.org/ 1634850213.0 Mrs Victoria Richmond Interim Principal Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Gillingham South Gillingham and Rainham (England/Wales) Urban city and town E06000035 577257.0 168594.0 Medway 012 Medway 012A Good South-East England and South London 100062394010.0 Not applicable Not applicable E02003325 E01016031 212.0
53 140186 887 Medway 2007 Lordswood School Academy sponsor led Academies Open New Provision 01-11-2013 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 420.0 Not applicable 19-01-2023 410.0 220.0 190.0 26.6 Supported by a multi-academy trust THE GRIFFIN SCHOOLS TRUST Linked to a sponsor The Griffin Schools Trust Not applicable 10043317.0 Not applicable 16-01-2019 28-05-2024 Lordswood Lane Chatham Kent ME5 8NN www.lordswood-gst.org 1634336767.0 Mrs Jayne Lusinski Head of School Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Lordswood & Walderslade Chatham and Aylesford (England/Wales) Urban city and town E06000035 576856.0 163264.0 Medway 038 Medway 038D Good South-East England and South London 200000909500.0 Not applicable Not applicable E02003351 E01016060 109.0
54 140215 887 Medway 2008 New Horizons Children's Academy Academy sponsor led Academies Open New Provision 01-09-2014 Primary 4.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed None None Not applicable 630.0 Not applicable 19-01-2023 639.0 318.0 321.0 19.4 Supported by a multi-academy trust THE THINKING SCHOOLS ACADEMY TRUST Linked to a sponsor The Thinking Schools Academy Trust Not applicable 10047226.0 Not applicable 25-05-2022 03-05-2024 Park Crescent Chatham Kent ME4 6NR http://www.newhorizonschildrensacademy.org.uk 3333602115.0 Mr Cormac Murphy Head Teacher Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Chatham Central & Brompton Chatham and Aylesford (England/Wales) Urban city and town E06000035 575624.0 165866.0 Medway 027 Medway 027A Good South-East England and South London 44036212.0 Not applicable Not applicable E02003340 E01016025 124.0
55 140606 887 Medway 2009 Gordons Children's Academy, Junior Academy sponsor led Academies Open New Provision 01-03-2014 Primary 7.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 400.0 Not applicable 19-01-2023 336.0 180.0 156.0 22.9 Supported by a multi-academy trust THE THINKING SCHOOLS ACADEMY TRUST Linked to a sponsor The Thinking Schools Academy Trust Not applicable 10044931.0 Not applicable 28-09-2022 16-01-2024 Gordon Road Strood Rochester Kent ME2 3HQ https://www.gordonchildrensacademy.org.uk/ 3333602110.0 Mrs Kirstie Jones Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood North & Frindsbury Rochester and Strood (England/Wales) Urban city and town E06000035 573169.0 169601.0 Medway 006 Medway 006E Good South-East England and South London United Kingdom 100062388599.0 Not applicable Not applicable E02003319 E01016141 77.0
56 140607 887 Medway 2010 Gordons Children's Academy, Infant Academy sponsor led Academies Open New Provision 01-03-2014 Primary 5.0 7 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 189.0 Not applicable 19-01-2023 164.0 83.0 81.0 25.0 Supported by a multi-academy trust THE THINKING SCHOOLS ACADEMY TRUST Linked to a sponsor The Thinking Schools Academy Trust Not applicable 10044932.0 Not applicable 28-09-2022 16-01-2024 Gordon Road Strood Rochester Kent ME2 3HQ www.gordonchildrensacademy.org.uk 3333602110.0 Mrs Kirstie Jones Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood North & Frindsbury Rochester and Strood (England/Wales) Urban city and town E06000035 573169.0 169601.0 Medway 006 Medway 006E Good South-East England and South London 100062388599.0 Not applicable Not applicable E02003319 E01016141 41.0
57 140989 887 Medway 2011 Warren Wood Primary School Academy sponsor led Academies Open New Provision 01-07-2014 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed None None Not applicable Not applicable 411.0 Has Special Classes 19-01-2023 486.0 258.0 228.0 37.8 Supported by a multi-academy trust BEYOND SCHOOLS TRUST Linked to a sponsor FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School) Not applicable 10046284.0 Not applicable 16-10-2019 16-04-2024 Arethusa Road Rochester Kent ME1 2UR www.warrenwoodprimary.co.uk 1634401401.0 Mrs Lucinda Woodroof Acting Head of School Not applicable Not applicable Not applicable Not applicable Not applicable SLCN - Speech, language and Communication SEN unit 30.0 34.0 South East Medway Rochester East & Warren Wood Rochester and Strood (England/Wales) Urban city and town E06000035 574546.0 165725.0 Medway 026 Medway 026B Good South-East England and South London 44020102.0 Not applicable Not applicable E02003339 E01016120 178.0
58 141199 887 Medway 2012 Napier Community Primary and Nursery Academy Academy sponsor led Academies Open New Provision 01-09-2014 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 630.0 Not applicable 19-01-2023 585.0 282.0 303.0 34.9 Supported by a multi-academy trust THE KEMNAL ACADEMIES TRUST Linked to a sponsor The Kemnal Academies Trust Not applicable 10046908.0 Not applicable 04-12-2019 11-04-2024 Napier Community Primary and Nursery Academy Napier Road Gillingham Kent ME7 4HG www.napierprimary.org.uk 1634574920.0 Mr Ciaran Mc Cann Executive Head Teacher Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Gillingham South Gillingham and Rainham (England/Wales) Urban city and town E06000035 577675.0 167833.0 Medway 016 Medway 016B Good South-East England and South London 200000909503.0 Not applicable Not applicable E02003329 E01016046 204.0
59 141224 887 Medway 2013 Cuxton Community Junior School Academy sponsor led Academies Open New Provision 01-09-2014 Primary 7.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 240.0 Not applicable 19-01-2023 228.0 112.0 116.0 14.9 Supported by a multi-academy trust THE PRIMARY FIRST TRUST Linked to a sponsor The Primary First Trust Not applicable 10047013.0 Not applicable 07-07-2022 21-05-2024 Bush Road Cuxton Rochester Kent ME2 1EY www.cuxtonschools.co.uk 1634337720.0 Mrs Charlotte Aldham Breary Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Cuxton, Halling & Riverside Rochester and Strood (England/Wales) Rural town and fringe E06000035 570725.0 166676.0 Medway 028 Medway 028C Good South-East England and South London 44027917.0 Not applicable Not applicable E02003341 E01016028 34.0
60 141276 887 Medway 2208 Cuxton Community Infant School Academy converter Academies Open Academy Converter 01-09-2014 Primary 5.0 7 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 180.0 No Special Classes 19-01-2023 180.0 97.0 83.0 8.3 Supported by a multi-academy trust THE PRIMARY FIRST TRUST Linked to a sponsor The Primary First Trust Not applicable 10047167.0 Not applicable 30-03-2022 21-05-2024 Bush Road Cuxton Rochester Kent ME2 1EY www.cuxtonschools.co.uk 1634337720.0 Mrs Charlotte Aldham Breary Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Cuxton, Halling & Riverside Rochester and Strood (England/Wales) Rural town and fringe E06000035 570781.0 166686.0 Medway 028 Medway 028C Good South-East England and South London 44027917.0 Not applicable Not applicable E02003341 E01016028 15.0
61 141466 887 Medway 5457 The Howard School Academy converter Academies Open Academy Converter 01-10-2014 Secondary 11.0 18 No boarders No Nursery Classes Has a sixth form Boys None Does not apply Not applicable Non-selective 1725.0 No Special Classes 19-01-2023 1508.0 1486.0 22.0 15.3 Supported by a multi-academy trust THE HOWARD ACADEMY TRUST Linked to a sponsor The Howard Academy Trust Not applicable 10047641.0 Not applicable 24-11-2021 30-04-2024 Derwent Way Rainham Gillingham Kent ME8 0BX https://www.thehoward-that.org.uk/ 1634388765.0 Mr Jasbinder Johal Head of School Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham South West Gillingham and Rainham (England/Wales) Urban city and town E06000035 580562.0 165928.0 Medway 029 Medway 029B Good South-East England and South London 100062395978.0 Not applicable Not applicable E02003342 E01016088 193.0
62 141467 887 Medway 2646 Brompton-Westbrook Primary School Academy converter Academies Open Academy Converter 01-10-2014 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 420.0 No Special Classes 19-01-2023 450.0 227.0 223.0 33.5 Supported by a multi-academy trust THE WESTBROOK TRUST Linked to a sponsor The Westbrook Trust Not applicable 10047618.0 Not applicable 22-01-2019 21-05-2024 Kings Bastion Brompton Gillingham Kent ME7 5DQ http://www.bromptonwestbrook.medway.sch.uk 1634844152.0 Mrs Sue Mason Head Teacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Chatham Central & Brompton Rochester and Strood (England/Wales) Urban city and town E06000035 576422.0 168177.0 Medway 015 Medway 015E Good South-East England and South London 44056069.0 Not applicable Not applicable E02003328 E01016111 146.0
63 141553 887 Medway 2194 Peninsula East Primary Academy Academy converter Academies Open Academy Converter 01-11-2014 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 250.0 No Special Classes 19-01-2023 248.0 127.0 121.0 26.9 Supported by a multi-academy trust LEIGH ACADEMIES TRUST Linked to a sponsor Leigh Academies Trust Not applicable 10047879.0 Not applicable 15-01-2020 23-05-2024 Avery Way Allhallows Rochester ME3 9HR www.pepa.org.uk 1634270428.0 Mrs Lorna Rimmer Head of School Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway All Saints Rochester and Strood (England/Wales) Rural town and fringe E06000035 583168.0 176220.0 Medway 001 Medway 001A Good South-East England and South London United Kingdom 44108207.0 Not applicable Not applicable E02003314 E01016070 66.0
64 142137 887 Medway 3093 All Saints Church of England Primary School Academy converter Academies Open Academy Converter 01-09-2015 Primary 2.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Church of England Does not apply Diocese of Rochester Not applicable 379.0 No Special Classes 19-01-2023 353.0 176.0 177.0 33.2 Supported by a multi-academy trust MEDWAY ANGLICAN SCHOOLS TRUST - Not applicable 10053760.0 Not applicable 21-02-2024 20-05-2024 Magpie Hall Road Chatham Kent ME4 5JY http://www.allsaints.medway.sch.uk 1634338922.0 Joanne Strachan Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Chatham Central & Brompton Chatham and Aylesford (England/Wales) Urban city and town E06000035 576479.0 167253.0 Medway 015 Medway 015C Good South-East England and South London 44054186.0 Not applicable Not applicable E02003328 E01016019 111.0
65 142157 887 Medway 3095 St John's Church of England Infant School Academy converter Academies Open Academy Converter 01-09-2015 Primary 5.0 7 No boarders No Nursery Classes Does not have a sixth form Mixed Church of England Does not apply Diocese of Rochester Not applicable 90.0 No Special Classes 19-01-2023 46.0 21.0 25.0 34.8 Supported by a multi-academy trust MEDWAY ANGLICAN SCHOOLS TRUST - Not applicable 10053759.0 Not applicable 13-06-2018 12-04-2024 4 New Street Chatham Kent ME4 6RH https://www.stjohns.medway.sch.uk/ 1634844135.0 Miss J Strachan Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Fort Pitt Chatham and Aylesford (England/Wales) Urban city and town E06000035 575450.0 167393.0 Medway 015 Medway 015B Good South-East England and South London 44029362.0 Not applicable Not applicable E02003328 E01016017 16.0
66 142160 887 Medway 3195 St Margaret's Church of England Junior School Academy converter Academies Open Academy Converter 01-09-2015 Primary 7.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Church of England Does not apply Diocese of Rochester Not applicable 363.0 No Special Classes 19-01-2023 364.0 189.0 175.0 19.0 Supported by a multi-academy trust MEDWAY ANGLICAN SCHOOLS TRUST - Not applicable 10053758.0 Not applicable 21-09-2023 26-03-2024 Orchard Street Rainham Gillingham Kent ME8 9AE http://www.stmargaretsonline.net 1634230998.0 Mr Lenny Williams Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham South West Gillingham and Rainham (England/Wales) Urban city and town E06000035 581405.0 165749.0 Medway 029 Medway 029C Good South-East England and South London 200000901856.0 Not applicable Not applicable E02003342 E01016089 69.0
67 142393 887 Medway 2014 Twydall Primary School and Nursery Academy sponsor led Academies Open New Provision 01-02-2016 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 255.0 Not applicable 19-01-2023 304.0 169.0 135.0 42.7 Supported by a multi-academy trust RMET Linked to a sponsor RMET (Rainham Mark Education Trust) Not applicable 10054150.0 17-05-2023 29-05-2024 Twydall Lane Gillingham Kent ME8 6JS www.twydallprimary.org.uk 1634231761.0 Mrs Louise Hardie Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable PD - Physical Disability Resourced provision 7.0 8.0 South East Medway Twydall Gillingham and Rainham (England/Wales) Urban city and town E06000035 579908.0 166888.0 Medway 018 Medway 018B Good South-East England and South London 44087223.0 Not applicable Not applicable E02003331 E01016161 120.0
68 142394 887 Medway 2015 Temple Mill Primary School Academy sponsor led Academies Open New Provision 01-12-2015 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 210.0 Not applicable 19-01-2023 247.0 126.0 121.0 21.7 Supported by a multi-academy trust THE HOWARD ACADEMY TRUST Linked to a sponsor The Howard Academy Trust Not applicable 10054151.0 17-10-2018 11-04-2024 Cliffe Road Strood Rochester Kent ME2 3NL https://www.templemill-that.org.uk/ 1634629079.0 Mrs Lisa Lewis Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood Rural Rochester and Strood (England/Wales) Urban city and town E06000035 573642.0 170455.0 Medway 004 Medway 004C Good South-East England and South London 100062388732.0 Not applicable Not applicable E02003317 E01016148 51.0
69 142399 887 Medway 2016 Byron Primary School Academy sponsor led Academies Open New Provision 01-01-2016 Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply None Not applicable Not applicable 525.0 Not applicable 19-01-2023 520.0 251.0 269.0 27.5 Supported by a multi-academy trust THE WESTBROOK TRUST Linked to a sponsor The Westbrook Trust Not applicable 10054156.0 15-06-2022 21-05-2024 Byron Road Gillingham Kent ME7 5XX 1634852981.0 Mr Jon Carthy Head Teacher Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Gillingham South Gillingham and Rainham (England/Wales) Urban city and town E06000035 577482.0 167330.0 Medway 016 Medway 016C Requires improvement South-East England and South London 44067058.0 Not applicable Not applicable E02003329 E01016047 143.0
70 142568 887 Medway 6010 The GFC School Other independent school Independent schools Open New Provision 07-12-2015 Not applicable 11.0 16 No boarders No Nursery Classes Does not have a sixth form Mixed None None Not applicable Selective 50.0 Not applicable 20-01-2022 28.0 20.0 8.0 0.0 Not applicable Not applicable Not applicable 10066496.0 02-05-2019 15-04-2024 Priestfield Stadium Redfern Avenue Gillingham Kent ME7 4DD www.thegfcschool.co.uk 1634623420.0 Mrs Sue Wade Head of School Not applicable Not applicable Not applicable Not applicable Not approved SpLD - Specific Learning Difficulty SEMH - Social, Emotional and Mental Health MLD - Moderate Learning Difficulty SEN unit 15.0 15.0 South East Medway Watling Gillingham and Rainham (England/Wales) Urban city and town E06000035 578373.0 168139.0 Medway 013 Medway 013B Ofsted 16.0 12.0 Paul Scally Good South-East England and South London 44007001.0 Not applicable Not applicable E02003326 E01016042 0.0
71 142817 887 Medway 2017 Cedar Children's Academy Academy sponsor led Academies Open New Provision 01-06-2016 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Not applicable Not applicable 630.0 Not applicable 19-01-2023 668.0 352.0 316.0 26.9 Supported by a multi-academy trust THE THINKING SCHOOLS ACADEMY TRUST Linked to a sponsor The Thinking Schools Academy Trust Not applicable 10056531.0 09-05-2019 08-01-2024 Cedar Road Strood Rochester Kent ME2 2JP www.cedarchildrensacademy.org.uk 3333602105.0 Ms Tracey Baillie Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood West Rochester and Strood (England/Wales) Urban city and town E06000035 572439.0 168467.0 Medway 011 Medway 011D Good South-East England and South London 200000895826.0 Not applicable Not applicable E02003324 E01016157 180.0
72 143261 887 Medway 2203 Walderslade Primary School Academy converter Academies Open Academy Converter 01-09-2016 Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 240.0 No Special Classes 19-01-2023 235.0 110.0 125.0 16.6 Supported by a multi-academy trust RIVERMEAD INCLUSIVE TRUST Linked to a sponsor Rivermead Inclusive Trust Not applicable 10057635.0 Not applicable 21-11-2018 30-04-2024 Dargets Road Walderslade Chatham Kent ME5 8BJ www.walderslade-pri.medway.sch.uk/ 1634337766.0 Mrs Amy Rowley-Jones Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Lordswood & Walderslade Chatham and Aylesford (England/Wales) Urban city and town E06000035 576195.0 163447.0 Medway 037 Medway 037B Good South-East England and South London 44045350.0 Not applicable Not applicable E02003350 E01016169 39.0
73 143262 887 Medway 2213 Hoo St Werburgh Primary School and the Marlborough Academy converter Academies Open Academy Converter 01-09-2016 Primary 2.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 525.0 Has Special Classes 19-01-2023 573.0 308.0 265.0 19.9 Supported by a multi-academy trust RIVERMEAD INCLUSIVE TRUST Linked to a sponsor Rivermead Inclusive Trust Not applicable 10057859.0 Not applicable 06-03-2024 22-05-2024 Pottery Road Hoo St Werburgh Rochester Kent ME3 9BS www.hoo-st-werburgh.medway.sch.uk 1634338040.0 Mr Simon McLean Head of School Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable ASD - Autistic Spectrum Disorder Resourced provision and SEN unit 80.0 80.0 80.0 80.0 South East Medway Hoo St Werburgh & High Halstow Rochester and Strood (England/Wales) Rural town and fringe E06000035 577642.0 172283.0 Medway 003 Medway 003D Good South-East England and South London 200000900025.0 Not applicable Not applicable E02003316 E01016077 114.0
74 143458 887 Medway 2684 Deanwood Primary School Academy converter Academies Open Academy Converter 01-10-2016 Primary 2.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 210.0 Not applicable 19-01-2023 207.0 102.0 105.0 18.4 Supported by a multi-academy trust THE HOWARD ACADEMY TRUST Linked to a sponsor The Howard Academy Trust Not applicable 10061378.0 Not applicable 02-11-2018 23-05-2024 Deanwood Primary School, Long Catlis Road Parkwood Gillingham Kent ME8 9TX https://www.deanwood-that.org.uk/ 1634231901.0 Mrs Jane Wright Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham South East Gillingham and Rainham (England/Wales) Urban city and town E06000035 580615.0 163584.0 Medway 036 Medway 036B Good South-East England and South London 200000909507.0 Not applicable Not applicable E02003349 E01016099 38.0
75 143832 887 Medway 3758 The Pilgrim School (A Church of England Primary With Nursery) Academy converter Academies Open Academy Converter 01-12-2016 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Church of England Does not apply Diocese of Rochester Not applicable 210.0 Not applicable 19-01-2023 229.0 102.0 127.0 18.6 Supported by a multi-academy trust THE PILGRIM MULTI ACADEMY TRUST - Not applicable 10062013.0 Not applicable 01-06-2024 Warwick Crescent Borstal Rochester Kent ME1 3LF www.thepilgrimschool.co.uk 16343975555.0 Mrs Alison Mepsted Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rochester West & Borstal Rochester and Strood (England/Wales) Urban city and town E06000035 572771.0 166724.0 Medway 024 Medway 024B South-East England and South London 44010044.0 Not applicable Not applicable E02003337 E01016127 39.0
76 143880 887 Medway 2214 Balfour Junior School Academy converter Academies Open Academy Converter 01-01-2017 Primary 7.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 480.0 No Special Classes 19-01-2023 480.0 257.0 223.0 29.0 Supported by a multi-academy trust BEYOND SCHOOLS TRUST Linked to a sponsor FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School) Not applicable 10062374.0 Not applicable 05-12-2018 23-04-2024 Balfour Road Chatham Kent ME4 6QX www.balfourjuniorschool.org.uk 1634843833.0 Mrs Zoe Mayston Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Fort Pitt Chatham and Aylesford (England/Wales) Urban city and town E06000035 575169.0 166802.0 Medway 021 Medway 021D Good South-East England and South London 44038129.0 Not applicable Not applicable E02003334 E01016125 139.0
77 143909 887 Medway 2018 Wayfield Primary School Academy converter Academies Open Fresh Start 01-09-2016 Primary 2.0 11 Has Nursery Classes Not applicable Mixed None Does not apply 360.0 Not applicable 19-01-2023 392.0 212.0 180.0 39.0 Supported by a multi-academy trust THE PRIMARY FIRST TRUST Linked to a sponsor The Primary First Trust Not applicable 10062232.0 22-05-2019 25-04-2024 Wayfield Road Chatham Kent ME5 0HH www.wayfield.medway.sch.uk 3000658230.0 Miss Ria Henry Head Teacher Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Wayfield & Weeds Wood Chatham and Aylesford (England/Wales) Urban city and town E06000035 576192.0 165414.0 Medway 027 Medway 027E Good South-East England and South London Not applicable Not applicable E02003340 E01016068 135.0
78 144132 887 Medway 2592 Thames View Primary School Academy converter Academies Open Academy Converter 01-04-2017 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 450.0 No Special Classes 19-01-2023 449.0 224.0 225.0 18.0 Supported by a multi-academy trust THE HOWARD ACADEMY TRUST Linked to a sponsor The Howard Academy Trust Not applicable 10063038.0 Not applicable 17-05-2023 23-05-2024 Bloors Lane Rainham Gillingham Kent ME8 7DX https://www.thamesview-that.org.uk/ 1634629080.0 Mrs Leanna Rogers Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham North Gillingham and Rainham (England/Wales) Urban city and town E06000035 581008.0 166754.0 Medway 023 Medway 023C Good South-East England and South London 44103856.0 Not applicable Not applicable E02003336 E01016166 74.0
79 144133 887 Medway 2479 St Margaret's Infant School Academy converter Academies Open Academy Converter 01-04-2017 Primary 3.0 7 No boarders Has Nursery Classes Does not have a sixth form Mixed None Does not apply Not applicable Not applicable 270.0 No Special Classes 19-01-2023 300.0 155.0 145.0 10.6 Supported by a multi-academy trust THE WESTBROOK TRUST Linked to a sponsor The Westbrook Trust Not applicable 10063037.0 Not applicable 13-02-2020 21-05-2024 St Margaret's Infant School, Orchard Street Orchard Street Rainham Gillingham Kent ME8 9AE http://www.stmargaretsinf.medway.sch.uk 1634231327.0 Mrs Paula Fewtrell Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham South West Gillingham and Rainham (England/Wales) Urban city and town E06000035 581405.0 165749.0 Medway 029 Medway 029C Good South-East England and South London 100062396976.0 Not applicable Not applicable E02003342 E01016089 30.0
80 144134 887 Medway 1107 The Rowans Academy alternative provision converter Academies Open Academy Converter 01-06-2017 Not applicable 5.0 16 No boarders Not applicable Not applicable Mixed Does not apply Does not apply Not applicable Not applicable 65.0 Not applicable 19-01-2023 26.0 18.0 8.0 65.4 Supported by a multi-academy trust THE INSPIRING CHANGE MULTI-ACADEMY TRUST - Not applicable 10063925.0 Not applicable 10-11-2021 19-03-2024 Silverbank Churchill Avenue Chatham Kent ME5 0LB www.therowans.org 1634338803.0 Mrs Fiona May Headteacher Not applicable Not applicable Does not have child care facilities PRU Does have Provision for SEN PRU Does have EBD provision 66.0 PRU offers full time provision Does not offer tuition by another provider Not applicable SEMH - Social, Emotional and Mental Health Resourced provision 65.0 65.0 South East Medway Wayfield & Weeds Wood Chatham and Aylesford (England/Wales) Urban city and town E06000035 576044.0 164885.0 Medway 027 Medway 027E Outstanding South-East England and South London 44112005.0 Not applicable Not applicable E02003340 E01016068 17.0
81 144135 887 Medway 3757 Riverside Primary School Academy converter Academies Open Academy Converter 01-04-2017 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 390.0 Not applicable 19-01-2023 406.0 220.0 186.0 32.5 Supported by a multi-academy trust RMET Linked to a sponsor RMET (Rainham Mark Education Trust) Not applicable 10063036.0 Not applicable 13-11-2019 29-05-2024 St Edmunds Way Rainham Gillingham Kent ME8 8ET www.riverside.medway.sch.uk/ 1634623500.0 Mrs Helen Robson Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable VI - Visual Impairment ASD - Autistic Spectrum Disorder Resourced provision 17.0 15.0 South East Medway Rainham North Gillingham and Rainham (England/Wales) Urban city and town E06000035 582416.0 166196.0 Medway 025 Medway 025C Good South-East England and South London 44110167.0 Not applicable Not applicable E02003338 E01016097 117.0
82 144423 887 Medway 2396 Barnsole Primary School Academy converter Academies Open Academy Converter 01-05-2017 Primary 2.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 630.0 No Special Classes 19-01-2023 671.0 336.0 335.0 25.9 Supported by a multi-academy trust MARITIME ACADEMY TRUST Linked to a sponsor Maritime Academy Trust Not applicable 10063725.0 Not applicable 29-02-2024 22-05-2024 Barnsole Road Gillingham Kent ME7 2JG www.barnsoleprimary.medway.sch.uk 1634333400.0 Mr Jonathan Smales Head of School Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Watling Gillingham and Rainham (England/Wales) Urban city and town E06000035 578041.0 167976.0 Medway 013 Medway 013D Good South-East England and South London 44076748.0 Not applicable Not applicable E02003326 E01016177 168.0
83 144566 887 Medway 2492 Bligh Primary School (Juniors) Academy converter Academies Open Academy Converter 01-10-2017 Primary 7.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 330.0 No Special Classes 19-01-2023 328.0 159.0 169.0 35.7 Supported by a multi-academy trust MARITIME ACADEMY TRUST Linked to a sponsor Maritime Academy Trust Not applicable 10064767.0 Not applicable 22-06-2023 04-06-2024 Bligh Way Strood Rochester Kent ME2 2XJ www.blighprimaryschool.co.uk 1634336220.0 Mr Christian Markham Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood West Rochester and Strood (England/Wales) Urban city and town E06000035 571407.0 169082.0 Medway 008 Medway 008D Good South-East England and South London 100062388554.0 Not applicable Not applicable E02003321 E01016155 117.0
84 144639 887 Medway 2623 Miers Court Primary School Academy converter Academies Open Academy Converter 01-08-2017 Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 420.0 No Special Classes 19-01-2023 394.0 200.0 194.0 14.2 Supported by a multi-academy trust THE HOWARD ACADEMY TRUST Linked to a sponsor The Howard Academy Trust Not applicable 10064690.0 Not applicable 03-11-2021 17-04-2024 Silverspot Close Rainham Kent ME8 8JR https://www.mierscourt-that.org.uk/ 1634388943.0 Mrs Susan Chapman Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham South East Gillingham and Rainham (England/Wales) Urban city and town E06000035 581647.0 165162.0 Medway 032 Medway 032C Good South-East England and South London 44101008.0 Not applicable Not applicable E02003345 E01016104 56.0
85 144914 887 Medway 3293 St Margaret's at Troy Town CofE Voluntary Controlled Primary School Academy converter Academies Open Academy Converter 01-09-2017 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Church of England Does not apply Diocese of Rochester Not applicable 210.0 No Special Classes 19-01-2023 225.0 119.0 106.0 37.3 Supported by a multi-academy trust THE PILGRIM MULTI ACADEMY TRUST - Not applicable 10065034.0 Not applicable 02-12-2021 05-02-2024 King Street Rochester Kent ME1 1YF http://www.stmargaretsattroytown.co.uk 1634843843.0 Miss Katie Willis Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rochester East & Warren Wood Rochester and Strood (England/Wales) Urban city and town E06000035 574390.0 167980.0 Medway 014 Medway 014A Good South-East England and South London 44023621.0 Not applicable Not applicable E02003327 E01016117 76.0
86 144915 887 Medway 2537 Bligh Primary School (Infants) Academy converter Academies Open Academy Converter 01-10-2017 Primary 2.0 7 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 270.0 No Special Classes 19-01-2023 325.0 157.0 168.0 27.9 Supported by a multi-academy trust MARITIME ACADEMY TRUST Linked to a sponsor Maritime Academy Trust Not applicable 10065035.0 Not applicable 04-06-2024 Bligh Way Strood Rochester Kent ME2 2XJ www.blighprimaryschool.co.uk 1634336220.0 Mr Christian Markham Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood West Rochester and Strood (England/Wales) Urban city and town E06000035 571407.0 169082.0 Medway 008 Medway 008D South-East England and South London 100062388554.0 Not applicable Not applicable E02003321 E01016155 80.0
87 144969 887 Medway 2019 Featherby Junior School Academy sponsor led Academies Open New Provision 01-09-2017 Primary 7.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Not applicable Not applicable 360.0 Not applicable 19-01-2023 339.0 165.0 174.0 34.2 Supported by a multi-academy trust MARITIME ACADEMY TRUST Linked to a sponsor Maritime Academy Trust Not applicable 10065102.0 29-06-2022 07-05-2024 Chilham Road Featherby Junior School Gillingham Kent ME8 6BT www.featherby-jun.medway.sch.uk 1634231984.0 Mrs Emma Pape Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Twydall Gillingham and Rainham (England/Wales) Urban city and town E06000035 579316.0 167170.0 Medway 018 Medway 018D Good South-East England and South London 44088972.0 Not applicable Not applicable E02003331 E01016163 116.0
88 145042 887 Medway 2401 Featherby Infant and Nursery School Academy converter Academies Open Academy Converter 01-09-2017 Primary 3.0 7 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 270.0 No Special Classes 19-01-2023 297.0 155.0 142.0 32.1 Supported by a multi-academy trust MARITIME ACADEMY TRUST Linked to a sponsor Maritime Academy Trust Not applicable 10065161.0 Not applicable 17-11-2021 07-05-2024 Allington Road Gillingham Kent ME8 6PD http://www.featherby-inf.medway.sch.uk 1634231072.0 Mrs Emma Pape Head of School Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Twydall Gillingham and Rainham (England/Wales) Urban city and town E06000035 579330.0 167352.0 Medway 018 Medway 018D Good South-East England and South London 44088976.0 Not applicable Not applicable E02003331 E01016163 93.0
89 145112 887 Medway 2020 Maundene School Academy sponsor led Academies Open New Provision 01-01-2018 Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Not applicable Not applicable 420.0 Not applicable 19-01-2023 395.0 187.0 208.0 22.0 Supported by a multi-academy trust INSPIRE PARTNERSHIP ACADEMY TRUST Linked to a sponsor Inspire Partnership Academy Trust Not applicable 10065460.0 15-06-2022 02-05-2024 Swallow Rise Walderslade Chatham Kent ME5 7QB https://www.maundene.medway.sch.uk/ 1634864721.0 Miss Joanne Capes Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Princes Park Chatham and Aylesford (England/Wales) Urban city and town E06000035 576557.0 164396.0 Medway 034 Medway 034A Good South-East England and South London 44047176.0 Not applicable Not applicable E02003347 E01016078 87.0
90 145440 887 Medway 2499 Hilltop Primary School Academy converter Academies Open Academy Converter 01-02-2018 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 448.0 No Special Classes 19-01-2023 436.0 242.0 194.0 14.3 Supported by a multi-academy trust BEYOND SCHOOLS TRUST Linked to a sponsor FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School) Not applicable 10066627.0 Not applicable 29-06-2022 23-04-2024 Hilltop Road Frindsbury Rochester Kent ME2 4QN www.hilltopprimary.co.uk 1634710312.0 Mrs Ewa Eddy Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood Rural Rochester and Strood (England/Wales) Urban city and town E06000035 574043.0 170333.0 Medway 004 Medway 004C Good South-East England and South London 100062389240.0 Not applicable Not applicable E02003317 E01016148 61.0
91 145926 887 Medway 2021 Elaine Primary School Academy sponsor led Academies Open Fresh Start 01-05-2018 Primary 3.0 11 No boarders Has Nursery Classes Not applicable Mixed None None 350.0 Has Special Classes 19-01-2023 301.0 148.0 153.0 56.1 Supported by a multi-academy trust INSPIRE PARTNERSHIP ACADEMY TRUST Linked to a sponsor Inspire Partnership Academy Trust Not applicable 10067319.0 22-09-2022 16-04-2024 Elaine Avenue Rochester ME2 2YN http://www.elaine.medway.sch.uk/ 1634294817.0 Mrs Sarah Martin Not applicable Not applicable Not applicable Not applicable Not applicable SEMH - Social, Emotional and Mental Health SEN unit 20.0 11.0 South East Medway Strood West Rochester and Strood (England/Wales) Urban city and town E06000035 572443.0 168984.0 Medway 011 Medway 011A Good South-East England and South London United Kingdom 200000895803.0 Not applicable Not applicable E02003324 E01016150 169.0
92 146648 887 Medway 4003 Waterfront UTC University technical college Free Schools Open 01-04-2019 Secondary 14.0 19 No Nursery Classes Has a sixth form Mixed Does not apply Does not apply Non-selective 250.0 Not applicable 19-01-2023 267.0 190.0 77.0 31.3 Supported by a multi-academy trust THE HOWARD ACADEMY TRUST Linked to a sponsor The Howard Academy Trust Not applicable 10082095.0 11-01-2023 14-09-2023 South Side Three Road Chatham Kent ME4 4FQ www.waterfront-that.org.uk 1634505800.0 Mrs Fiona McLean Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway St Mary's Island Rochester and Strood (England/Wales) Urban city and town E06000035 577382.0 169573.0 Medway 007 Medway 007H Good South-East England and South London United Kingdom 44039551.0 Not applicable Not applicable E02003320 E01035292 66.0
93 146872 887 Medway 2211 Halling Primary School Academy converter Academies Open Academy Converter 01-04-2019 Primary 5.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 420.0 No Special Classes 19-01-2023 376.0 188.0 188.0 17.3 Supported by a multi-academy trust ALETHEIA ACADEMIES TRUST Linked to a sponsor Aletheia Academies Trust Not applicable 10082988.0 Not applicable 07-06-2023 14-05-2024 Howlsmere Close Halling Rochester Kent ME2 1ER http://www.halling.medway.sch.uk/ 1634240258.0 Ms Lisa Taylor Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Cuxton, Halling & Riverside Rochester and Strood (England/Wales) Rural town and fringe E06000035 570607.0 163387.0 Medway 028 Medway 028A Good South-East England and South London 44000585.0 Not applicable Not applicable E02003341 E01016026 65.0
94 147446 887 Medway 2022 Wainscott Primary School Academy sponsor led Academies Open New Provision 01-09-2019 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 446.0 No Special Classes 19-01-2023 455.0 235.0 220.0 17.6 Supported by a multi-academy trust THE PRIMARY FIRST TRUST Linked to a sponsor The Primary First Trust Not applicable 10084146.0 21-05-2024 Wainscott Road Wainscott Rochester Kent ME2 4JX www.wainscott.medway.sch.uk 1634332550.0 Mrs Monique Clark Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Strood Rural Rochester and Strood (England/Wales) Urban city and town E06000035 574754.0 170678.0 Medway 004 Medway 004E South-East England and South London United Kingdom 44028647.0 Not applicable Not applicable E02003317 E01035289 80.0
95 147769 887 Medway 2023 Delce Academy Academy converter Academies Open Fresh Start 01-03-2020 Primary 5.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed None Does not apply 360.0 Has Special Classes 19-01-2023 359.0 193.0 166.0 44.0 Supported by a multi-academy trust INSPIRE PARTNERSHIP ACADEMY TRUST Linked to a sponsor Inspire Partnership Academy Trust Not applicable 10085699.0 28-05-2024 The Tideway Rochester Kent ME1 2NJ www.delceacademy.co.uk 1634845242.0 Miss Loni Stevens Not applicable Not applicable Not applicable Not applicable Not applicable SEMH - Social, Emotional and Mental Health SEN unit 15.0 15.0 South East Medway Rochester East & Warren Wood Rochester and Strood (England/Wales) Urban city and town E06000035 574455.0 166524.0 Medway 017 Medway 017C South-East England and South London United Kingdom 44022435.0 Not applicable Not applicable E02003330 E01016115 158.0
96 148117 887 Medway 2433 Oaklands School Academy converter Academies Open Academy Converter 01-09-2020 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 450.0 No Special Classes 19-01-2023 430.0 208.0 222.0 42.2 Supported by a multi-academy trust THE WESTBROOK TRUST Linked to a sponsor The Westbrook Trust Not applicable 10086851.0 04-07-2023 21-05-2024 Weedswood Road Walderslade Chatham Kent ME5 0QS http://www.oaklands.medway.sch.uk 1634333820.0 Mrs Louisa Jones Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Wayfield & Weeds Wood Chatham and Aylesford (England/Wales) Urban city and town E06000035 575761.0 163898.0 Medway 033 Medway 033D Not applicable Good South-East England and South London 44033912.0 Not applicable Not applicable E02003346 E01016173 175.0
97 148577 887 Medway 4004 Leigh Academy Rainham Free schools Free Schools Open New Provision 01-09-2021 Secondary 11.0 19 No Nursery Classes Has a sixth form Mixed None None Not applicable Non-selective 1150.0 Not applicable 19-01-2023 405.0 223.0 182.0 16.8 Supported by a multi-academy trust LEIGH ACADEMIES TRUST Linked to a sponsor Leigh Academies Trust Not applicable 10088768.0 28-02-2024 22-05-2024 Otterham Quay Lane Rainham Gillingham Kent ME8 8GS https://leighacademyrainham.org.uk/ 1634412440.0 Miss Alexandra Millward Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rainham North Gillingham and Rainham (England/Wales) Urban city and town E06000035 582774.0 165824.0 Medway 025 Medway 025E Good South-East England and South London United Kingdom 44073878.0 Not applicable Not applicable E02003338 E01016102 68.0
98 149009 887 Medway 1108 Will Adams Academy Academy alternative provision converter Academies Open Academy Converter 01-04-2022 Not applicable 14.0 17 No boarders Not applicable Not applicable Mixed Does not apply Does not apply Not applicable Not applicable Not applicable 19-01-2023 39.0 21.0 18.0 39.5 Supported by a multi-academy trust ALTERNATIVE LEARNING TRUST Linked to a sponsor Alternative Learning Trust Not applicable 10090191.0 16-04-2024 Woodlands Road Gillingham Kent ME7 2BX www.willadamsacademy.org.uk 1634337111.0 Ms Marie Woolston HeadTeacher Not applicable Not applicable Not applicable PRU Does not have Provision for SEN Not applicable Not applicable Not applicable Not applicable SEMH - Social, Emotional and Mental Health Resourced provision 45.0 45.0 South East Medway Watling Gillingham and Rainham (England/Wales) Urban city and town E06000035 578774.0 167623.0 Medway 019 Medway 019A Not applicable South-East England and South London 200003623419.0 Not applicable Not applicable E02003332 E01016159 15.0
99 149069 887 Medway 2025 Rochester Riverside Church of England Primary School Free schools Free Schools Open Academy Free School 01-09-2022 Primary 3.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Church of England Christian Non-selective 446.0 Not applicable 19-01-2023 26.0 16.0 10.0 0.0 Supported by a multi-academy trust THE PILGRIM MULTI ACADEMY TRUST - Not applicable 10090885.0 29-05-2024 Gas House Road Rochester Kent ME1 1US rrcoe.medway.sch.uk 1634471697.0 Mrs Alison Mepsted Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Rochester West & Borstal Rochester and Strood (England/Wales) Urban city and town E06000035 574334.0 168802.0 Medway 015 Medway 015F South-East England and South London United Kingdom 44076556.0 Not applicable Not applicable E02003328 E01035296 0.0
100 149075 887 Medway 4005 Maritime Academy Free schools Free Schools Open Academy Free School 01-09-2022 Secondary 11.0 19 No boarders No Nursery Classes Has a sixth form Mixed None None Not applicable Non-selective 1150.0 Not applicable 19-01-2023 142.0 77.0 65.0 27.5 Supported by a multi-academy trust THE THINKING SCHOOLS ACADEMY TRUST Linked to a sponsor The Thinking Schools Academy Trust Not applicable 10090894.0 24-05-2024 Frindsbury Hill Rochester Kent Medway https://www.maritimeacademy.org.uk/ 3333602150.0 Jody Murphy Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Twydall Gillingham and Rainham (England/Wales) Urban city and town E06000035 579947.0 166841.0 Medway 018 Medway 018B South-East England and South London Not applicable Not applicable E02003331 E01016161 39.0
101 149979 887 Medway 3753 St Benedict's Catholic Primary School Academy converter Academies Open Academy Converter 01-09-2023 Primary 4.0 11 No boarders No Nursery Classes Does not have a sixth form Mixed Roman Catholic Does not apply Archdiocese of Southwark Not applicable 210.0 No Special Classes Supported by a multi-academy trust KENT CATHOLIC SCHOOLS' PARTNERSHIP Linked to a sponsor Kent Catholic Schools' Partnership Not applicable 10092965.0 06-03-2024 Lambourn Way Lordswood Chatham Kent ME5 8PU www.st-benedicts.medway.sch.uk/ 1634669700.0 Mrs Sarah McAlpine Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Lordswood & Walderslade Chatham and Aylesford (England/Wales) Urban city and town E06000035 577291.0 162859.0 Medway 038 Medway 038D Not applicable South-East England and South London 44058733.0 Not applicable Not applicable E02003351 E01016060
102 150154 887 Medway 4007 Oasis Restore Academy secure 16 to 19 Academies Open New Provision 15-04-2024 16 plus 12.0 17 Not applicable Not applicable Mixed 49.0 Not applicable Not applicable OASIS RESTORE TRUST Not applicable Not applicable 10094342.0 15-04-2024 1 Kennington Road London SE1 7QP https://www.oasisrestore.org/ 2079214200.0 Mr Andrew Willetts Not applicable Not applicable Not applicable Not applicable Not applicable South East Lambeth Waterloo & South Bank Vauxhall (England/Wales) Urban major conurbation E06000035 531156.0 179383.0 Lambeth 036 Lambeth 036B United Kingdom 100023225318.0 Not applicable Not applicable E02006801 E01003014
103 150218 887 Medway 2199 Luton Primary School Academy converter Academies Open Academy Converter 01-11-2023 Primary 4.0 11 No boarders Has Nursery Classes Does not have a sixth form Mixed Does not apply Does not apply Not applicable Not applicable 630.0 No Special Classes Supported by a multi-academy trust RIVERMEAD INCLUSIVE TRUST Linked to a sponsor Rivermead Inclusive Trust Not applicable 10093456.0 03-06-2024 Luton Road Chatham Kent ME4 5AW www.lutonprimaryschool.co.uk 1634336900.0 Mrs Karen Major Headteacher Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Luton Chatham and Aylesford (England/Wales) Urban city and town E06000035 577119.0 166655.0 Medway 020 Medway 020A Not applicable South-East England and South London 100062391815.0 Not applicable Not applicable E02003333 E01016061
104 150869 887 Medway 4008 Walderslade School Academy converter Academies Open Fresh Start 01-04-2024 Secondary 11.0 18 No boarders No Nursery Classes Has a sixth form Girls None Does not apply 949.0 Not applicable Supported by a multi-academy trust BEYOND SCHOOLS TRUST Linked to a sponsor FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School) Not applicable 10095249.0 04-04-2024 Bradfields Avenue Walderslade Chatham Kent ME5 0LE Mrs Louise Campbell Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Wayfield & Weeds Wood Chatham and Aylesford (England/Wales) Urban city and town E06000035 575885.0 164367.0 Medway 027 Medway 027D South-East England and South London United Kingdom 44033058.0 Not applicable Not applicable E02003340 E01016067
105 150870 887 Medway 4009 Greenacre School Academy converter Academies Open Fresh Start 01-04-2024 Secondary 11.0 18 No boarders No Nursery Classes Has a sixth form Boys None Does not apply 969.0 Not applicable Supported by a multi-academy trust BEYOND SCHOOLS TRUST Linked to a sponsor FPTA Academies (Fort Pitt Grammar School and The Thomas Aveling School) Not applicable 10095250.0 04-04-2024 157 Walderslade Road Walderslade Chatham Kent ME5 0LP Mrs Louise Campbell Not applicable Not applicable Not applicable Not applicable Not applicable South East Medway Wayfield & Weeds Wood Chatham and Aylesford (England/Wales) Urban city and town E06000035 576000.0 164283.0 Medway 034 Medway 034C South-East England and South London United Kingdom 44026624.0 Not applicable Not applicable E02003347 E01016081

View File

@ -1,12 +1,11 @@
services:
backend:
container_name: cc-api
container_name: api
build:
context: .
dockerfile: Dockerfile
env_file:
- .env
- .env.app.prod
ports:
- 8000:8000
networks:

356
main.py
View File

@ -1,20 +1,22 @@
import os
import argparse
import sys
import subprocess
import signal
import atexit
import time
from modules.logger_tool import initialise_logger
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
from fastapi import FastAPI, HTTPException
import uvicorn
import requests
from typing import Dict, Any
from typing import Dict, Any, Optional
from modules.database.tools.neo4j_driver_tools import get_driver
from run.initialization.initialization import InitializationSystem
import time
import ssl
from run.setup import setup_cors
from run.routers import register_routes
from run.initialization import initialize_system
from modules.task_processors import get_processor
from modules.queue_system import ServiceType
# FastAPI App Setup
app = FastAPI()
@ -28,7 +30,8 @@ async def health_check() -> Dict[str, Any]:
"status": "healthy",
"services": {
"neo4j": {"status": "healthy", "message": "Connected"},
"supabase": {"status": "healthy", "message": "Connected"}
"supabase": {"status": "healthy", "message": "Connected"},
"redis": {"status": "healthy", "message": "Connected"}
}
}
@ -70,6 +73,35 @@ async def health_check() -> Dict[str, Any]:
}
health_status["status"] = "unhealthy"
try:
# Check Redis using new Redis manager
from modules.redis_manager import get_redis_manager
# Determine environment
environment = 'dev' if os.getenv('BACKEND_DEV_MODE', 'true').lower() == 'true' else 'prod'
redis_manager = get_redis_manager(environment)
# Get comprehensive health check
redis_health = redis_manager.health_check()
health_status["services"]["redis"] = {
"status": redis_health['status'],
"message": redis_health.get('error', f"Connected to {environment} environment (db={redis_health['database']})"),
"environment": redis_health['environment'],
"database": redis_health['database'],
"queue_stats": redis_health.get('queue_stats', {})
}
if redis_health['status'] != 'healthy':
health_status["status"] = "unhealthy"
except Exception as e:
health_status["services"]["redis"] = {
"status": "unhealthy",
"message": f"Error checking Redis: {str(e)}"
}
health_status["status"] = "unhealthy"
if health_status["status"] == "unhealthy":
raise HTTPException(status_code=503, detail=health_status)
@ -78,71 +110,253 @@ async def health_check() -> Dict[str, Any]:
# Register routes
register_routes(app)
# Initialize system with retry logic
def initialize_with_retry(max_attempts: int = 3, initial_delay: int = 5) -> bool:
"""Initialize the system with retry logic"""
attempt = 0
delay = initial_delay
while attempt < max_attempts:
try:
logger.info(f"Attempting system initialization (attempt {attempt + 1}/{max_attempts})")
initialize_system()
logger.info("System initialization completed successfully")
return True
except Exception as e:
attempt += 1
if attempt == max_attempts:
logger.error(f"System initialization failed after {max_attempts} attempts: {str(e)}")
return False
logger.warning(f"Initialization attempt {attempt} failed: {str(e)}. Retrying in {delay} seconds...")
time.sleep(delay)
delay *= 2 # Exponential backoff
return False
# Start workers in the application process to avoid uvicorn reload issues
@app.on_event("startup")
async def _start_workers_event():
try:
if os.getenv('AUTO_START_QUEUE_WORKERS', 'true').lower() != 'true':
logger.info("AUTO_START_QUEUE_WORKERS=false, not starting in-process workers")
return
workers = int(os.getenv('QUEUE_WORKERS', '3'))
services_csv = os.getenv('QUEUE_SERVICES', 'tika,docling,split_map,document_analysis,page_images')
service_names = [s.strip().lower() for s in services_csv.split(',') if s.strip()]
service_enums = []
for name in service_names:
try:
service_enums.append(ServiceType(name))
except Exception:
pass
if not service_enums:
service_enums = list(ServiceType)
processor = get_processor()
started = []
for i in range(workers):
wid = processor.start_worker(worker_id=f"app-worker-{i+1}", services=service_enums)
started.append(wid)
logger.info(f"In-process queue workers started: {started} for services {[s.value for s in service_enums]}")
except Exception as e:
logger.error(f"Failed to start in-process workers: {e}")
def run_initialization_mode():
"""Run only the initialization process"""
logger.info("Running in initialization mode")
logger.info("Starting system initialization...")
@app.on_event("shutdown")
async def _shutdown_workers_event():
try:
processor = get_processor()
processor.shutdown(timeout=30)
except Exception as e:
logger.warning(f"Error during workers shutdown: {e}")
# Global subprocess handles (only for workers now)
workers_process: Optional[subprocess.Popen] = None
# Global Redis manager for cleanup
redis_manager = None
def start_queue_workers():
"""Start queue workers as a subprocess (tied to API lifecycle)."""
global workers_process
if os.getenv('AUTO_START_QUEUE_WORKERS', 'true').lower() != 'true':
logger.info("AUTO_START_QUEUE_WORKERS=false, not starting workers")
return
# If already started, skip
if workers_process is not None and workers_process.poll() is None:
logger.info("Queue workers already running")
return
services = os.getenv(
'QUEUE_SERVICES',
'tika,docling,split_map,document_analysis,page_images'
)
workers = int(os.getenv('QUEUE_WORKERS', '3'))
check_interval = os.getenv('QUEUE_CHECK_INTERVAL', '15')
cmd = [
sys.executable,
'start_queue_workers.py',
'--workers', str(workers),
'--services', services,
'--check-interval', check_interval,
]
# Workers will auto-detect environment and use appropriate Redis database
log_path = os.getenv('QUEUE_WORKERS_LOG', './queue_workers.log')
try:
log_file = open(log_path, 'a')
logger.info(f"Starting queue workers ({workers}) for services [{services}] → {log_path}")
workers_process = subprocess.Popen(
cmd,
stdout=log_file,
stderr=log_file,
preexec_fn=os.setsid if os.name != 'nt' else None
)
except Exception as e:
logger.error(f"Failed to start queue workers: {e}")
def stop_queue_workers():
"""Stop queue workers subprocess."""
global workers_process
if workers_process is not None:
try:
logger.info("Stopping queue workers...")
if os.name != 'nt':
os.killpg(os.getpgid(workers_process.pid), signal.SIGTERM)
else:
workers_process.terminate()
try:
workers_process.wait(timeout=10)
logger.info("Queue workers stopped gracefully")
except subprocess.TimeoutExpired:
logger.warning("Queue workers did not stop gracefully, forcing shutdown...")
if os.name != 'nt':
os.killpg(os.getpgid(workers_process.pid), signal.SIGKILL)
else:
workers_process.kill()
workers_process.wait()
logger.info("Queue workers force stopped")
except Exception as e:
logger.error(f"Error stopping queue workers: {e}")
finally:
workers_process = None
def _install_signal_handlers():
def signal_handler(signum, frame):
logger.info(f"Received signal {signum}, shutting down...")
stop_queue_workers()
# Gracefully shutdown Redis manager if it exists
global redis_manager
if redis_manager:
redis_manager.shutdown()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
def run_infrastructure_mode():
"""Run infrastructure setup: Neo4j schema, calendar, and Supabase buckets"""
logger.info("Running in infrastructure mode")
logger.info("Starting infrastructure setup...")
if initialize_with_retry():
logger.info("Initialization completed successfully")
try:
from run.initialization import initialize_infrastructure_mode
initialize_infrastructure_mode()
logger.info("Infrastructure setup completed successfully")
return True
else:
logger.error("Initialization failed after multiple attempts")
except Exception as e:
logger.error(f"Infrastructure setup failed: {str(e)}")
return False
def run_demo_school_mode():
"""Run demo school creation"""
logger.info("Running in demo school mode")
logger.info("Starting demo school creation...")
try:
from run.initialization import initialize_demo_school_mode
initialize_demo_school_mode()
logger.info("Demo school creation completed successfully")
return True
except Exception as e:
logger.error(f"Demo school creation failed: {str(e)}")
return False
def run_demo_users_mode():
"""Run demo users creation"""
logger.info("Running in demo users mode")
logger.info("Starting demo users creation...")
try:
from run.initialization import initialize_demo_users_mode
initialize_demo_users_mode()
logger.info("Demo users creation completed successfully")
return True
except Exception as e:
logger.error(f"Demo users creation failed: {str(e)}")
return False
def run_gais_data_mode():
"""Run GAIS data import"""
logger.info("Running in GAIS data import mode")
logger.info("Starting GAIS data import...")
try:
from run.initialization import initialize_gais_data_mode
initialize_gais_data_mode()
logger.info("GAIS data import completed successfully")
return True
except Exception as e:
logger.error(f"GAIS data import failed: {str(e)}")
return False
# Old clear_dev_redis_queue function removed - now handled by Redis Manager
def run_development_mode():
"""Run the server in development mode with auto-reload"""
logger.info("Running in development mode")
# Initialize Redis manager for development (auto-clears data)
global redis_manager
from modules.redis_manager import get_redis_manager
redis_manager = get_redis_manager('dev')
if not redis_manager.initialize_environment():
logger.error("Failed to initialize Redis for development")
return False
# Workers are started in app startup event
logger.info("Starting uvicorn server with auto-reload...")
uvicorn.run(
"main:app",
host="0.0.0.0",
port=int(os.getenv('UVICORN_PORT', 8000)),
log_level=os.getenv('LOG_LEVEL', 'info'),
proxy_headers=True,
timeout_keep_alive=10,
reload=True
)
# Install signal handlers for graceful shutdown
_install_signal_handlers()
try:
uvicorn.run(
"main:app",
host="0.0.0.0",
port=int(os.getenv('UVICORN_PORT', 8080)),
log_level=os.getenv('LOG_LEVEL', 'info'),
proxy_headers=True,
timeout_keep_alive=10,
reload=True
)
finally:
stop_queue_workers()
if redis_manager:
redis_manager.shutdown()
def run_production_mode():
"""Run the server in production mode"""
logger.info("Running in production mode")
# Initialize Redis manager for production (preserves data, recovers tasks)
global redis_manager
from modules.redis_manager import get_redis_manager
redis_manager = get_redis_manager('prod')
if not redis_manager.initialize_environment():
logger.error("Failed to initialize Redis for production")
return False
# Workers are started in app startup event
logger.info("Starting uvicorn server in production mode...")
uvicorn.run(
"main:app",
host="0.0.0.0",
port=int(os.getenv('UVICORN_PORT', 8000)),
log_level=os.getenv('LOG_LEVEL', 'info'),
proxy_headers=True,
timeout_keep_alive=10,
workers=int(os.getenv('UVICORN_WORKERS', '1'))
)
# Install signal handlers for graceful shutdown
_install_signal_handlers()
try:
uvicorn.run(
"main:app",
host="0.0.0.0",
port=int(os.getenv('UVICORN_PORT', 8080)),
log_level=os.getenv('LOG_LEVEL', 'info'),
proxy_headers=True,
timeout_keep_alive=10,
workers=int(os.getenv('UVICORN_WORKERS', '1'))
)
finally:
stop_queue_workers()
if redis_manager:
redis_manager.shutdown()
def parse_arguments():
"""Parse command line arguments"""
@ -151,15 +365,18 @@ def parse_arguments():
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Startup modes:
init - Run initialization scripts (database setup, etc.)
dev - Run development server with auto-reload
prod - Run production server (for Docker/containerized deployment)
infra - Setup infrastructure (Neo4j schema, calendar, Supabase buckets)
demo-school - Create demo school (KevlarAI)
demo-users - Create demo users
gais-data - Import GAIS data (Edubase, etc.)
dev - Run development server with auto-reload
prod - Run production server (for Docker/containerized deployment)
"""
)
parser.add_argument(
'--mode', '-m',
choices=['init', 'dev', 'prod'],
choices=['infra', 'demo-school', 'demo-users', 'gais-data', 'dev', 'prod'],
default='dev',
help='Startup mode (default: dev)'
)
@ -177,9 +394,24 @@ if __name__ == "__main__":
logger.info(f"Starting ClassroomCopilot API in {args.mode} mode")
if args.mode == 'init':
# Run initialization only
success = run_initialization_mode()
if args.mode == 'infra':
# Run infrastructure setup
success = run_infrastructure_mode()
sys.exit(0 if success else 1)
elif args.mode == 'demo-school':
# Run demo school creation
success = run_demo_school_mode()
sys.exit(0 if success else 1)
elif args.mode == 'demo-users':
# Run demo users creation
success = run_demo_users_mode()
sys.exit(0 if success else 1)
elif args.mode == 'gais-data':
# Run GAIS data import
success = run_gais_data_mode()
sys.exit(0 if success else 1)
elif args.mode == 'dev':

View File

@ -18,13 +18,14 @@ class SupabaseBearer(HTTPBearer):
try:
token = credentials.credentials
payload = verify_supabase_token(token)
# Decode using the string-based verifier to avoid async dependency conflicts
payload = verify_supabase_jwt_str(token)
return payload
except Exception as e:
logger.error(f"Token verification failed: {str(e)}")
raise HTTPException(status_code=403, detail="Invalid token or expired token.")
def verify_supabase_token(token: str) -> dict:
def verify_supabase_jwt_str(token: str) -> dict:
"""Verify a Supabase JWT token and return its payload."""
try:
jwt_secret = os.getenv("JWT_SECRET")
@ -63,7 +64,7 @@ def decodeSupabaseJWT(token: str) -> dict:
# Initialize the security instance
security = HTTPBearer()
async def verify_supabase_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
async def verify_supabase_token_dep(credentials: HTTPAuthorizationCredentials = Depends(security)):
try:
token = credentials.credentials
# Verify token using your Supabase JWT secret

571
modules/bundle_metadata.py Normal file
View File

@ -0,0 +1,571 @@
"""
Uniform Bundle Metadata Architecture
This module defines standardized metadata structures for all document processing pipelines
to ensure consistency and interoperability across OCR, No-OCR, and VLM bundles.
Features:
- Uniform metadata schema for all pipeline types
- Consistent grouping and ordering mechanisms
- Pipeline-agnostic bundle identification
- Enhanced metadata for frontend display
- Backward compatibility with existing bundles
"""
import uuid
import hashlib
import json
from datetime import datetime
from typing import Dict, Any, Optional, List, Union, Literal
from dataclasses import dataclass, asdict
from enum import Enum
class PipelineType(Enum):
"""Supported pipeline types"""
STANDARD = "standard"
VLM = "vlm"
ASR = "asr"
class ProcessingMode(Enum):
"""How content was processed"""
WHOLE_DOCUMENT = "whole_document"
SPLIT_SECTIONS = "split_sections"
INDIVIDUAL_PAGES = "individual_pages"
PAGE_BUNDLE = "page_bundle"
class BundleType(Enum):
"""Type of bundle created"""
SINGLE_ARTEFACT = "single_artefact"
SPLIT_PACK = "split_pack"
PAGE_BUNDLE = "page_bundle"
VLM_SECTION_BUNDLE = "vlm_section_bundle"
# New unified bundle types
DOCLING_BUNDLE = "docling_bundle" # Single coherent processing unit
DOCLING_BUNDLE_SPLIT = "docling_bundle_split" # Container for multi-unit processing
@dataclass
class BundleMetadata:
"""
Standardized metadata structure for all document processing bundles.
This ensures consistency across OCR, No-OCR, and VLM pipelines while
maintaining backward compatibility.
"""
# Core identification
bundle_id: str
file_id: str
pipeline: PipelineType
processing_mode: ProcessingMode
bundle_type: BundleType
# Grouping and ordering
group_id: Optional[str] = None
split_order: Optional[int] = None
split_total: Optional[int] = None
split_heading: Optional[str] = None
# Content information
page_range: Optional[List[int]] = None # [start_page, end_page]
page_count: Optional[int] = None
section_title: Optional[str] = None
section_level: Optional[int] = None
# Processing details
config: Optional[Dict[str, Any]] = None
settings_fingerprint: Optional[str] = None
processing_time: Optional[float] = None
# Pipeline-specific metadata
pipeline_metadata: Optional[Dict[str, Any]] = None
# Producer information
producer: str = "manual" # manual, auto_phase2, auto_split, etc.
created_at: Optional[str] = None
# Status and quality
status: str = "completed"
quality_score: Optional[float] = None
def __post_init__(self):
"""Set defaults and compute derived fields"""
if self.created_at is None:
self.created_at = datetime.utcnow().isoformat()
if self.bundle_id is None:
self.bundle_id = str(uuid.uuid4())
# Compute settings fingerprint if config provided
if self.config and not self.settings_fingerprint:
self.settings_fingerprint = self._compute_settings_fingerprint(self.config)
def _compute_settings_fingerprint(self, config: Dict[str, Any]) -> str:
"""Compute a fingerprint for configuration settings (excluding page_range)"""
try:
config_for_hash = dict(config)
config_for_hash.pop('page_range', None) # Exclude page ranges from fingerprint
config_str = json.dumps(config_for_hash, sort_keys=True, ensure_ascii=False)
return hashlib.sha1(config_str.encode('utf-8')).hexdigest()[:16]
except Exception:
return str(uuid.uuid4())[:16]
def to_artefact_extra(self) -> Dict[str, Any]:
"""Convert to format suitable for document_artefacts.extra field"""
extra = {}
# Core fields
extra['bundle_metadata_version'] = '1.0'
extra['pipeline'] = self.pipeline.value
extra['processing_mode'] = self.processing_mode.value
extra['bundle_type'] = self.bundle_type.value
# Store original pipeline type for UI differentiation
if hasattr(self, 'original_pipeline_type'):
extra['original_pipeline'] = self.original_pipeline_type
# Grouping fields
if self.group_id:
extra['group_id'] = self.group_id
if self.split_order is not None:
extra['split_order'] = self.split_order
if self.split_total is not None:
extra['split_total'] = self.split_total
if self.split_heading:
extra['split_heading'] = self.split_heading
# Content fields
if self.page_range:
extra['page_range'] = self.page_range
if self.page_count is not None:
extra['page_count'] = self.page_count
if self.section_title:
extra['section_title'] = self.section_title
if self.section_level is not None:
extra['section_level'] = self.section_level
# Processing fields
if self.config:
extra['config'] = self.config
if self.settings_fingerprint:
extra['settings_fingerprint'] = self.settings_fingerprint
if self.processing_time is not None:
extra['processing_time'] = self.processing_time
# Pipeline-specific metadata
if self.pipeline_metadata:
extra['pipeline_metadata'] = self.pipeline_metadata
# Producer and quality
extra['producer'] = self.producer
if self.quality_score is not None:
extra['quality_score'] = self.quality_score
return extra
@classmethod
def from_artefact_extra(cls, file_id: str, artefact_id: str, extra: Dict[str, Any]) -> 'BundleMetadata':
"""Create BundleMetadata from document_artefacts.extra field"""
# Extract core fields with fallbacks for backward compatibility
pipeline_str = extra.get('pipeline', 'standard')
try:
pipeline = PipelineType(pipeline_str)
except ValueError:
pipeline = PipelineType.STANDARD
processing_mode_str = extra.get('processing_mode', 'whole_document')
try:
processing_mode = ProcessingMode(processing_mode_str)
except ValueError:
processing_mode = ProcessingMode.WHOLE_DOCUMENT
bundle_type_str = extra.get('bundle_type', 'single_artefact')
try:
bundle_type = BundleType(bundle_type_str)
except ValueError:
bundle_type = BundleType.SINGLE_ARTEFACT
return cls(
bundle_id=artefact_id,
file_id=file_id,
pipeline=pipeline,
processing_mode=processing_mode,
bundle_type=bundle_type,
group_id=extra.get('group_id'),
split_order=extra.get('split_order'),
split_total=extra.get('split_total'),
split_heading=extra.get('split_heading'),
page_range=extra.get('page_range'),
page_count=extra.get('page_count'),
section_title=extra.get('section_title'),
section_level=extra.get('section_level'),
config=extra.get('config'),
settings_fingerprint=extra.get('settings_fingerprint'),
processing_time=extra.get('processing_time'),
pipeline_metadata=extra.get('pipeline_metadata'),
producer=extra.get('producer', 'manual'),
created_at=extra.get('created_at'),
quality_score=extra.get('quality_score')
)
class BundleMetadataBuilder:
"""Helper class to build standardized bundle metadata"""
def __init__(self, file_id: str, pipeline: PipelineType):
self.file_id = file_id
self.pipeline = pipeline
self.metadata = BundleMetadata(
bundle_id=str(uuid.uuid4()),
file_id=file_id,
pipeline=pipeline,
processing_mode=ProcessingMode.WHOLE_DOCUMENT,
bundle_type=BundleType.SINGLE_ARTEFACT
)
def set_processing_mode(self, mode: ProcessingMode) -> 'BundleMetadataBuilder':
"""Set processing mode"""
self.metadata.processing_mode = mode
return self
def set_bundle_type(self, bundle_type: BundleType) -> 'BundleMetadataBuilder':
"""Set bundle type"""
self.metadata.bundle_type = bundle_type
return self
def set_group_info(self, group_id: str, split_order: int = None,
split_total: int = None, split_heading: str = None) -> 'BundleMetadataBuilder':
"""Set grouping information for split documents"""
self.metadata.group_id = group_id
self.metadata.split_order = split_order
self.metadata.split_total = split_total
self.metadata.split_heading = split_heading
return self
def set_page_info(self, page_range: List[int] = None,
page_count: int = None) -> 'BundleMetadataBuilder':
"""Set page information"""
self.metadata.page_range = page_range
self.metadata.page_count = page_count
return self
def set_section_info(self, title: str = None, level: int = None) -> 'BundleMetadataBuilder':
"""Set section information"""
self.metadata.section_title = title
self.metadata.section_level = level
return self
def set_config(self, config: Dict[str, Any]) -> 'BundleMetadataBuilder':
"""Set processing configuration"""
self.metadata.config = config
self.metadata.settings_fingerprint = self.metadata._compute_settings_fingerprint(config)
return self
def set_producer(self, producer: str) -> 'BundleMetadataBuilder':
"""Set producer information"""
self.metadata.producer = producer
return self
def set_pipeline_metadata(self, metadata: Dict[str, Any]) -> 'BundleMetadataBuilder':
"""Set pipeline-specific metadata"""
self.metadata.pipeline_metadata = metadata
return self
def set_quality_score(self, score: float) -> 'BundleMetadataBuilder':
"""Set quality score"""
self.metadata.quality_score = score
return self
def build(self) -> BundleMetadata:
"""Build the final metadata"""
return self.metadata
def create_standard_metadata(
file_id: str,
pipeline: Literal["ocr", "no_ocr", "vlm"] = "no_ocr",
processing_mode: Literal["whole_document", "split_sections", "individual_pages", "pages", "sections", "chunks"] = "split_sections",
config: Dict[str, Any] = None,
group_id: str = None,
split_order: int = None,
split_total: int = None,
split_heading: str = None,
page_range: List[int] = None,
producer: str = "auto_phase2"
) -> BundleMetadata:
"""
Convenience function to create standardized metadata for common use cases.
"""
# Map pipeline strings to enums
pipeline_map = {
"ocr": PipelineType.STANDARD,
"no_ocr": PipelineType.STANDARD,
"vlm": PipelineType.VLM
}
# Enhanced processing mode mapping with new bundle architecture
processing_mode_map = {
"whole_document": ProcessingMode.WHOLE_DOCUMENT,
"split_sections": ProcessingMode.SPLIT_SECTIONS,
"individual_pages": ProcessingMode.INDIVIDUAL_PAGES,
"split_by_pages": ProcessingMode.INDIVIDUAL_PAGES, # Split by pages processing
"split_by_sections": ProcessingMode.SPLIT_SECTIONS, # Split by sections processing
"split_by_chunks": ProcessingMode.SPLIT_SECTIONS, # Split by chunks processing
"pages": ProcessingMode.INDIVIDUAL_PAGES, # Alias for page-based processing
"sections": ProcessingMode.SPLIT_SECTIONS, # Alias for section-based processing
"chunks": ProcessingMode.SPLIT_SECTIONS, # Chunks treated as sections
}
# Determine bundle type based on processing mode and grouping
if processing_mode == "whole_document":
bundle_type = BundleType.DOCLING_BUNDLE
else:
bundle_type = BundleType.DOCLING_BUNDLE_SPLIT
builder = BundleMetadataBuilder(file_id, pipeline_map[pipeline])
builder.set_processing_mode(processing_mode_map[processing_mode])
builder.set_bundle_type(bundle_type)
builder.set_producer(producer)
# Store original pipeline type for UI differentiation
builder.metadata.original_pipeline_type = pipeline
if config:
# Add pipeline-specific config markers
enhanced_config = dict(config)
if pipeline == "ocr":
enhanced_config["do_ocr"] = True
elif pipeline == "no_ocr":
enhanced_config["do_ocr"] = False
elif pipeline == "vlm":
enhanced_config["pipeline"] = "vlm"
builder.set_config(enhanced_config)
if group_id:
builder.set_group_info(group_id, split_order, split_total, split_heading)
if page_range:
builder.set_page_info(page_range)
# Set section info if we have a heading
if split_heading:
builder.set_section_info(split_heading)
return builder.build()
def create_bundle_split_metadata(
file_id: str,
pipeline: Literal["ocr", "no_ocr", "vlm"] = "no_ocr",
split_mode: Literal["split_by_pages", "split_by_sections", "split_by_chunks"] = "split_by_sections",
config: Dict[str, Any] = None,
group_id: str = None,
producer: str = "auto_phase2",
processing_data: Dict[str, Any] = None
) -> BundleMetadata:
"""
Create metadata specifically for split bundle processing.
This is used for the new docling_bundle_split task type.
"""
# Map split modes to processing modes
mode_map = {
"split_by_pages": "pages",
"split_by_sections": "sections",
"split_by_chunks": "sections" # Chunks treated as sections
}
processing_mode = mode_map[split_mode]
metadata = create_standard_metadata(
file_id=file_id,
pipeline=pipeline,
processing_mode=processing_mode,
config=config,
group_id=group_id,
producer=producer
)
# Add split-specific metadata
if processing_data:
split_metadata = {
'split_mode': split_mode,
'processing_data': processing_data
}
if metadata.pipeline_metadata:
metadata.pipeline_metadata.update(split_metadata)
else:
metadata.pipeline_metadata = split_metadata
return metadata
def get_bundle_display_name(metadata: BundleMetadata) -> str:
"""Generate a user-friendly display name for a bundle"""
# Use explicit display name if available
if hasattr(metadata, 'display_name') and metadata.display_name:
return metadata.display_name
# Generate based on bundle type and processing mode
if metadata.bundle_type == BundleType.DOCLING_BUNDLE:
return "Complete Document"
elif metadata.bundle_type == BundleType.DOCLING_BUNDLE_SPLIT:
if metadata.processing_mode == ProcessingMode.INDIVIDUAL_PAGES:
if metadata.page_range:
return f"Page {metadata.page_range[0]}"
return "Page Bundle"
elif metadata.processing_mode == ProcessingMode.SPLIT_SECTIONS:
if metadata.section_title:
order_prefix = f"{metadata.split_order:02d}. " if metadata.split_order else ""
page_suffix = ""
if metadata.page_range and len(metadata.page_range) >= 2:
page_suffix = f" (p{metadata.page_range[0]}-{metadata.page_range[1]})"
return f"{order_prefix}{metadata.section_title}{page_suffix}"
return f"Section {metadata.split_order or 1}"
else:
return "Document Bundle"
# Fallback
return metadata.section_title or metadata.split_heading or f"Bundle {metadata.bundle_id[:8]}"
def create_organized_bundle_manifest(bundles: list, split_mode: str, pipeline: str) -> dict:
"""
Create an organized master manifest for split bundles with proper labeling and ordering.
Args:
bundles: List of individual bundle data
split_mode: The splitting mode used (pages, sections, chunks)
pipeline: The pipeline type (no_ocr, ocr, vlm)
Returns:
Enhanced manifest with organization metadata
"""
# Sort bundles by their ordering key
if split_mode == 'split_by_pages':
sorted_bundles = sorted(bundles, key=lambda x: x.get('page_number', 0))
display_name = f"{pipeline.upper()} Document Pages ({len(bundles)} pages)"
organization = {
'type': 'pages',
'sort_field': 'page_number',
'sort_order': 'asc',
'grouping': 'individual_pages'
}
elif split_mode == 'split_by_sections':
sorted_bundles = sorted(bundles, key=lambda x: x.get('split_order', 0))
display_name = f"{pipeline.upper()} Document Sections ({len(bundles)} sections)"
organization = {
'type': 'sections',
'sort_field': 'split_order',
'sort_order': 'asc',
'grouping': 'split_map_sections',
'has_titles': True,
'ordering_preserved': True
}
elif split_mode == 'split_by_chunks':
sorted_bundles = sorted(bundles, key=lambda x: x.get('split_order', 0))
display_name = f"{pipeline.upper()} Document Chunks ({len(bundles)} chunks)"
organization = {
'type': 'chunks',
'sort_field': 'split_order',
'sort_order': 'asc',
'grouping': 'fallback_chunks'
}
else:
sorted_bundles = bundles
display_name = f"{pipeline.upper()} Document Bundles"
organization = {
'type': 'unknown',
'sort_field': 'split_order',
'sort_order': 'asc'
}
return {
'bundles': sorted_bundles,
'display_name': display_name,
'organization': organization,
'total_bundles': len(bundles),
'pipeline': pipeline,
'split_mode': split_mode
}
# Pipeline display names
pipeline_names = {
PipelineType.STANDARD: "Standard",
PipelineType.VLM: "VLM",
PipelineType.ASR: "ASR"
}
pipeline_name = pipeline_names.get(metadata.pipeline, metadata.pipeline.value)
# OCR indication for standard pipeline
if metadata.pipeline == PipelineType.STANDARD and metadata.config:
ocr_enabled = metadata.config.get('do_ocr', False)
pipeline_name = f"{pipeline_name} ({'OCR' if ocr_enabled else 'No-OCR'})"
# Processing mode indication
if metadata.processing_mode == ProcessingMode.INDIVIDUAL_PAGES:
mode = "Page-by-page"
elif metadata.processing_mode == ProcessingMode.SPLIT_SECTIONS:
mode = "Sections"
else:
mode = "Whole doc"
# Section or page info
content_info = ""
if metadata.split_heading:
content_info = f" - {metadata.split_heading}"
elif metadata.page_range and len(metadata.page_range) == 2:
if metadata.page_range[0] == metadata.page_range[1]:
content_info = f" - Page {metadata.page_range[0]}"
else:
content_info = f" - Pages {metadata.page_range[0]}-{metadata.page_range[1]}"
# Producer info
producer_info = ""
if metadata.producer == "auto_phase2":
producer_info = " (Auto)"
elif metadata.producer.startswith("auto"):
producer_info = " (Auto)"
return f"{pipeline_name} {mode}{content_info}{producer_info}"
def group_bundles_by_metadata(bundles: List[Dict[str, Any]]) -> Dict[str, List[Dict[str, Any]]]:
"""
Group bundles by their metadata for display purposes.
Returns a dictionary mapping group keys to lists of bundles.
"""
groups = {}
ungrouped = []
for bundle in bundles:
extra = bundle.get('extra', {})
# Skip bundles without the new metadata format
if not extra.get('bundle_metadata_version'):
ungrouped.append(bundle)
continue
metadata = BundleMetadata.from_artefact_extra(
bundle['file_id'],
bundle['id'],
extra
)
if metadata.group_id:
group_key = f"group:{metadata.group_id}"
if group_key not in groups:
groups[group_key] = []
groups[group_key].append(bundle)
else:
ungrouped.append(bundle)
# Add ungrouped bundles as individual groups
for bundle in ungrouped:
single_key = f"single:{bundle['id']}"
groups[single_key] = [bundle]
return groups

View File

@ -1,280 +0,0 @@
import os
from modules.logger_tool import initialise_logger
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
import modules.database.schemas.nodes.calendars as calendar_schemas
import modules.database.schemas.entities as entities
import modules.database.schemas.relationships.calendars as cal_rels
import modules.database.tools.neontology_tools as neon
from modules.database.tools.filesystem_tools import ClassroomCopilotFilesystem
from datetime import timedelta, datetime
def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False, entity_node=None, time_chunk_node=None):
logger.info(f"Creating calendar for {start_date} to {end_date}")
logger.info("Initializing Neontology connection")
neon.init_neontology_connection()
filesystem = ClassroomCopilotFilesystem(db_name, init_run_type="school")
def create_tldraw_file_for_node(node, node_path):
node_data = {
"unique_id": node.unique_id,
"type": node.__class__.__name__,
"name": node.name if hasattr(node, 'name') else 'Unnamed Node'
}
logger.debug(f"Creating tldraw file for node: {node_data}")
filesystem.create_default_tldraw_file(node_path, node_data)
created_years = {}
created_months = {}
created_weeks = {}
created_days = {}
last_year_node = None
last_month_node = None
last_week_node = None
last_day_node = None
calendar_nodes = {
'calendar_node': None,
'calendar_year_nodes': [],
'calendar_month_nodes': [],
'calendar_week_nodes': [],
'calendar_day_nodes': []
}
calendar_type = None
if attach_to_calendar_node and entity_node:
calendar_type = "entity_calendar"
logger.info(f"Attaching calendar to entity node: {entity_node.unique_id}")
entity_unique_id = entity_node.unique_id
calendar_unique_id = f"Calendar_{entity_unique_id}"
calendar_name = f"{start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}"
calendar_path = os.path.join(entity_node.path, "calendar")
calendar_node = calendar_schemas.CalendarNode(
unique_id=calendar_unique_id,
name=calendar_name,
start_date=start_date,
end_date=end_date,
path=calendar_path
)
neon.create_or_merge_neontology_node(calendar_node, database=db_name, operation='merge')
calendar_nodes['calendar_node'] = calendar_node
logger.info(f"Calendar node created: {calendar_node.unique_id}")
# Create a node tldraw file for the calendar node
create_tldraw_file_for_node(calendar_node, calendar_path)
import backend.modules.database.schemas.relationships.owner_relationships as entity_cal_rels
neon.create_or_merge_neontology_relationship(
entity_cal_rels.EntityHasCalendar(source=entity_node, target=calendar_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {entity_node.unique_id} to {calendar_node.unique_id}")
if entity_node and not attach_to_calendar_node:
calendar_type = "time_entity"
else:
logger.error("Invalid combination of parameters for calendar creation.")
raise ValueError("Invalid combination of parameters for calendar creation.")
current_date = start_date
while current_date <= end_date:
year = current_date.year
month = current_date.month
day = current_date.day
iso_year, iso_week, iso_weekday = current_date.isocalendar()
# Create directories for year, month, week, and day
_, year_path = filesystem.create_year_directory(year, calendar_path)
_, month_path = filesystem.create_month_directory(year, month, calendar_path)
_, week_path = filesystem.create_week_directory(year, iso_week, calendar_path)
_, day_path = filesystem.create_day_directory(year, month, day, calendar_path)
calendar_year_unique_id = f"CalendarYear_{year}"
if year not in created_years:
year_node = calendar_schemas.CalendarYearNode(
unique_id=calendar_year_unique_id,
year=str(year),
path=year_path
)
neon.create_or_merge_neontology_node(year_node, database=db_name, operation='merge')
calendar_nodes['calendar_year_nodes'].append(year_node)
created_years[year] = year_node
create_tldraw_file_for_node(year_node, year_path)
logger.info(f"Year node created: {year_node.unique_id}")
if attach_to_calendar_node:
neon.create_or_merge_neontology_relationship(
cal_rels.CalendarIncludesYear(source=calendar_node, target=year_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {calendar_node.unique_id} to {year_node.unique_id}")
if last_year_node:
neon.create_or_merge_neontology_relationship(
cal_rels.YearFollowsYear(source=last_year_node, target=year_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_year_node.unique_id} to {year_node.unique_id}")
last_year_node = year_node
calendar_month_unique_id = f"CalendarMonth_{year}_{month}"
month_key = f"{year}-{month}"
if month_key not in created_months:
month_node = calendar_schemas.CalendarMonthNode(
unique_id=calendar_month_unique_id,
year=str(year),
month=str(month),
month_name=datetime(year, month, 1).strftime('%B'),
path=month_path
)
neon.create_or_merge_neontology_node(month_node, database=db_name, operation='merge')
calendar_nodes['calendar_month_nodes'].append(month_node)
created_months[month_key] = month_node
create_tldraw_file_for_node(month_node, month_path)
logger.info(f"Month node created: {month_node.unique_id}")
# Check for the end of year transition for months
if last_month_node:
if int(month) == 1 and int(last_month_node.month) == 12 and int(last_month_node.year) == year - 1:
neon.create_or_merge_neontology_relationship(
cal_rels.MonthFollowsMonth(source=last_month_node, target=month_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_month_node.unique_id} to {month_node.unique_id}")
elif int(month) == int(last_month_node.month) + 1:
neon.create_or_merge_neontology_relationship(
cal_rels.MonthFollowsMonth(source=last_month_node, target=month_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_month_node.unique_id} to {month_node.unique_id}")
last_month_node = month_node
neon.create_or_merge_neontology_relationship(
cal_rels.YearIncludesMonth(source=year_node, target=month_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {year_node.unique_id} to {month_node.unique_id}")
calendar_week_unique_id = f"CalendarWeek_{iso_year}_{iso_week}"
week_key = f"{iso_year}-W{iso_week}"
if week_key not in created_weeks:
# Get the date of the first monday of the week
week_start_date = current_date - timedelta(days=current_date.weekday())
week_node = calendar_schemas.CalendarWeekNode(
unique_id=calendar_week_unique_id,
start_date=week_start_date,
week_number=str(iso_week),
iso_week=f"{iso_year}-W{iso_week:02}",
path=week_path
)
neon.create_or_merge_neontology_node(week_node, database=db_name, operation='merge')
calendar_nodes['calendar_week_nodes'].append(week_node)
created_weeks[week_key] = week_node
create_tldraw_file_for_node(week_node, week_path)
logger.info(f"Week node created: {week_node.unique_id}")
if last_week_node and ((last_week_node.iso_week.split('-')[0] == str(iso_year) and int(last_week_node.week_number) == int(iso_week) - 1) or
(last_week_node.iso_week.split('-')[0] != str(iso_year) and int(last_week_node.week_number) == 52 and int(iso_week) == 1)):
neon.create_or_merge_neontology_relationship(
cal_rels.WeekFollowsWeek(source=last_week_node, target=week_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_week_node.unique_id} to {week_node.unique_id}")
last_week_node = week_node
neon.create_or_merge_neontology_relationship(
cal_rels.YearIncludesWeek(source=year_node, target=week_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {year_node.unique_id} to {week_node.unique_id}")
calendar_day_unique_id = f"CalendarDay_{year}_{month}_{day}"
day_key = f"{year}-{month}-{day}"
day_node = calendar_schemas.CalendarDayNode(
unique_id=calendar_day_unique_id,
date=current_date,
day_of_week=current_date.strftime('%A'),
iso_day=f"{year}-{month:02}-{day:02}",
path=day_path
)
neon.create_or_merge_neontology_node(day_node, database=db_name, operation='merge')
calendar_nodes['calendar_day_nodes'].append(day_node)
created_days[day_key] = day_node
create_tldraw_file_for_node(day_node, day_path)
logger.info(f"Day node created: {day_node.unique_id}")
if last_day_node:
neon.create_or_merge_neontology_relationship(
cal_rels.DayFollowsDay(source=last_day_node, target=day_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_day_node.unique_id} to {day_node.unique_id}")
last_day_node = day_node
neon.create_or_merge_neontology_relationship(
cal_rels.MonthIncludesDay(source=month_node, target=day_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {month_node.unique_id} to {day_node.unique_id}")
neon.create_or_merge_neontology_relationship(
cal_rels.WeekIncludesDay(source=week_node, target=day_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {week_node.unique_id} to {day_node.unique_id}")
current_date += timedelta(days=1)
if time_chunk_node:
time_chunk_interval = time_chunk_node
# Get every calendar day node and create time chunks of length time_chunk_node minutes for the whole day
for day_node in calendar_nodes['calendar_day_nodes']:
day_path = day_node.path
total_time_chunks_in_day = (24 * 60) / time_chunk_interval
for i in range(total_time_chunks_in_day):
time_chunk_unique_id = f"CalendarTimeChunk_{day_node.unique_id}_{i}"
time_chunk_start_time = day_node.date.time() + timedelta(minutes=i * time_chunk_interval)
time_chunk_end_time = time_chunk_start_time + timedelta(minutes=time_chunk_interval)
time_chunk_node = calendar_schemas.CalendarTimeChunkNode(
unique_id=time_chunk_unique_id,
start_time=time_chunk_start_time,
end_time=time_chunk_end_time,
path=day_path
)
neon.create_or_merge_neontology_node(time_chunk_node, database=db_name, operation='merge')
calendar_nodes['calendar_time_chunk_nodes'].append(time_chunk_node)
logger.info(f"Time chunk node created: {time_chunk_node.unique_id}")
# Create a relationship between the time chunk node and the day node
neon.create_or_merge_neontology_relationship(
cal_rels.DayIncludesTimeChunk(source=day_node, target=time_chunk_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {day_node.unique_id} to {time_chunk_node.unique_id}")
# Create sequential relationship between the time chunk nodes
if i > 0:
neon.create_or_merge_neontology_relationship(
cal_rels.TimeChunkFollowsTimeChunk(source=calendar_nodes['calendar_time_chunk_nodes'][i-1], target=time_chunk_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {calendar_nodes['calendar_time_chunk_nodes'][i-1].unique_id} to {time_chunk_node.unique_id}")
logger.info(f'Created calendar: {calendar_nodes["calendar_node"].unique_id}')
return calendar_nodes

View File

@ -1,401 +0,0 @@
from enum import Enum
from typing import Optional, List, Dict, Any
import logging
from modules.database.admin.neontology_provider import NeontologyProvider
class NodeLabels(Enum):
SCHOOL = "School"
DEPARTMENT_STRUCTURE = "DepartmentStructure"
CURRICULUM_STRUCTURE = "CurriculumStructure"
PASTORAL_STRUCTURE = "PastoralStructure"
DEPARTMENT = "Department"
KEY_STAGE = "KeyStage"
YEAR_GROUP = "YearGroup"
class RelationshipTypes(Enum):
HAS_DEPARTMENT_STRUCTURE = "HAS_DEPARTMENT_STRUCTURE"
HAS_CURRICULUM_STRUCTURE = "HAS_CURRICULUM_STRUCTURE"
HAS_PASTORAL_STRUCTURE = "HAS_PASTORAL_STRUCTURE"
HAS_DEPARTMENT = "HAS_DEPARTMENT"
INCLUDES_KEY_STAGE = "INCLUDES_KEY_STAGE"
INCLUDES_YEAR_GROUP = "INCLUDES_YEAR_GROUP"
class PropertyKeys(Enum):
UNIQUE_ID = "unique_id"
PATH = "path"
URN = "urn"
ESTABLISHMENT_NUMBER = "establishment_number"
ESTABLISHMENT_NAME = "establishment_name"
ESTABLISHMENT_TYPE = "establishment_type"
ESTABLISHMENT_STATUS = "establishment_status"
PHASE_OF_EDUCATION = "phase_of_education"
STATUTORY_LOW_AGE = "statutory_low_age"
STATUTORY_HIGH_AGE = "statutory_high_age"
RELIGIOUS_CHARACTER = "religious_character"
SCHOOL_CAPACITY = "school_capacity"
SCHOOL_WEBSITE = "school_website"
OFSTED_RATING = "ofsted_rating"
DEPARTMENT_NAME = "department_name"
KEY_STAGE = "key_stage"
KEY_STAGE_NAME = "key_stage_name"
YEAR_GROUP = "year_group"
YEAR_GROUP_NAME = "year_group_name"
CREATED = "created"
MERGED = "merged"
class SchemaDefinition:
"""Class to hold schema definition queries and information"""
@staticmethod
def get_schema_info() -> Dict[str, List[Dict]]:
"""Returns a dictionary containing the schema definition for nodes and relationships."""
return {
"nodes": [
{
"label": "School",
"description": "Represents a school entity",
"required_properties": ["unique_id", "urn", "name"],
"optional_properties": ["address", "postcode", "phone", "email", "website"]
},
{
"label": "DepartmentStructure",
"description": "Represents the department structure of a school",
"required_properties": ["unique_id", "name"],
"optional_properties": ["description", "head_of_department"]
},
{
"label": "CurriculumStructure",
"description": "Represents the curriculum structure of a school",
"required_properties": ["unique_id", "name"],
"optional_properties": ["description", "key_stage", "subject"]
},
{
"label": "PastoralStructure",
"description": "Represents the pastoral structure of a school",
"required_properties": ["unique_id", "name"],
"optional_properties": ["description", "year_group", "form_group"]
}
],
"relationships": [
{
"type": "HAS_DEPARTMENT_STRUCTURE",
"description": "Links a school to its department structure",
"source": "School",
"target": "DepartmentStructure",
"properties": ["created_at"]
},
{
"type": "HAS_CURRICULUM_STRUCTURE",
"description": "Links a school to its curriculum structure",
"source": "School",
"target": "CurriculumStructure",
"properties": ["created_at"]
},
{
"type": "HAS_PASTORAL_STRUCTURE",
"description": "Links a school to its pastoral structure",
"source": "School",
"target": "PastoralStructure",
"properties": ["created_at"]
}
]
}
@staticmethod
def get_schema_creation_queries() -> List[str]:
"""Returns a list of Cypher queries to create the schema."""
return [
# Node Uniqueness Constraints
f"CREATE CONSTRAINT school_unique_id IF NOT EXISTS FOR (n:{NodeLabels.SCHOOL.value}) REQUIRE n.{PropertyKeys.UNIQUE_ID.value} IS UNIQUE",
f"CREATE CONSTRAINT department_unique_id IF NOT EXISTS FOR (n:{NodeLabels.DEPARTMENT_STRUCTURE.value}) REQUIRE n.{PropertyKeys.UNIQUE_ID.value} IS UNIQUE",
f"CREATE CONSTRAINT curriculum_unique_id IF NOT EXISTS FOR (n:{NodeLabels.CURRICULUM_STRUCTURE.value}) REQUIRE n.{PropertyKeys.UNIQUE_ID.value} IS UNIQUE",
f"CREATE CONSTRAINT pastoral_unique_id IF NOT EXISTS FOR (n:{NodeLabels.PASTORAL_STRUCTURE.value}) REQUIRE n.{PropertyKeys.UNIQUE_ID.value} IS UNIQUE",
# Indexes for Performance
f"CREATE INDEX school_urn IF NOT EXISTS FOR (n:{NodeLabels.SCHOOL.value}) ON (n.{PropertyKeys.URN.value})",
f"CREATE INDEX school_name IF NOT EXISTS FOR (n:{NodeLabels.SCHOOL.value}) ON (n.{PropertyKeys.ESTABLISHMENT_NAME.value})",
f"CREATE INDEX department_name IF NOT EXISTS FOR (n:{NodeLabels.DEPARTMENT_STRUCTURE.value}) ON (n.{PropertyKeys.DEPARTMENT_NAME.value})",
f"CREATE INDEX curriculum_name IF NOT EXISTS FOR (n:{NodeLabels.CURRICULUM_STRUCTURE.value}) ON (n.name)",
f"CREATE INDEX pastoral_name IF NOT EXISTS FOR (n:{NodeLabels.PASTORAL_STRUCTURE.value}) ON (n.name)",
]
@staticmethod
def get_schema_verification_queries() -> Dict[str, str]:
"""Returns a dictionary of queries to verify the schema state."""
return {
"constraints": "SHOW CONSTRAINTS",
"indexes": "SHOW INDEXES",
"labels": "CALL db.labels()"
}
class GraphNamingProvider:
@staticmethod
def get_school_unique_id(urn: str) -> str:
"""Generate unique ID for a school node."""
return f"School_{urn}"
@staticmethod
def get_department_structure_unique_id(school_unique_id: str) -> str:
"""Generate unique ID for a department structure node."""
return f"DepartmentStructure_{school_unique_id}"
@staticmethod
def get_curriculum_structure_unique_id(school_unique_id: str) -> str:
"""Generate unique ID for a curriculum structure node."""
return f"CurriculumStructure_{school_unique_id}"
@staticmethod
def get_pastoral_structure_unique_id(school_unique_id: str) -> str:
"""Generate unique ID for a pastoral structure node."""
return f"PastoralStructure_{school_unique_id}"
@staticmethod
def get_department_unique_id(school_unique_id: str, department_name: str) -> str:
"""Generate unique ID for a department node."""
return f"Department_{school_unique_id}_{department_name.replace(' ', '_')}"
@staticmethod
def get_key_stage_unique_id(curriculum_structure_unique_id: str, key_stage: str) -> str:
"""Generate unique ID for a key stage node."""
return f"KeyStage_{curriculum_structure_unique_id}_KStg{key_stage}"
@staticmethod
def get_year_group_unique_id(school_unique_id: str, year_group: int) -> str:
"""Generate unique ID for a year group node."""
return f"YearGroup_{school_unique_id}_YGrp{year_group}"
@staticmethod
def get_school_path(database_name: str, urn: str) -> str:
"""Generate path for a school node."""
return f"/schools/{database_name}/{urn}"
@staticmethod
def get_department_path(school_path: str, department_name: str) -> str:
"""Generate path for a department node."""
return f"{school_path}/departments/{department_name}"
@staticmethod
def get_department_structure_path(school_path: str) -> str:
"""Generate path for a department structure node."""
return f"{school_path}/departments"
@staticmethod
def get_curriculum_path(school_path: str) -> str:
"""Generate path for a curriculum structure node."""
return f"{school_path}/curriculum"
@staticmethod
def get_pastoral_path(school_path: str) -> str:
"""Generate path for a pastoral structure node."""
return f"{school_path}/pastoral"
@staticmethod
def get_key_stage_path(curriculum_path: str, key_stage: str) -> str:
"""Generate path for a key stage node."""
return f"{curriculum_path}/key_stage_{key_stage}"
@staticmethod
def get_year_group_path(pastoral_path: str, year_group: int) -> str:
"""Generate path for a year group node."""
return f"{pastoral_path}/year_{year_group}"
@staticmethod
def get_cypher_match_school(unique_id: str) -> str:
"""Generate Cypher MATCH clause for finding a school node."""
return f"MATCH (s:{NodeLabels.SCHOOL.value} {{{PropertyKeys.UNIQUE_ID.value}: $school_id}})"
@staticmethod
def get_cypher_check_basic_structure() -> str:
"""Generate Cypher query for checking basic structure existence and validity."""
return """
// Find the school node
MATCH (s:{school})
// Check for department structure with any relationship
OPTIONAL MATCH (s)-[r1]-(dept_struct:{dept_struct})
// Check for curriculum structure with any relationship
OPTIONAL MATCH (s)-[r2]-(curr_struct:{curr_struct})
// Check for pastoral structure with any relationship
OPTIONAL MATCH (s)-[r3]-(past_struct:{past_struct})
// Return structure information
RETURN {{
has_basic:
dept_struct IS NOT NULL AND r1 IS NOT NULL AND
curr_struct IS NOT NULL AND r2 IS NOT NULL AND
past_struct IS NOT NULL AND r3 IS NOT NULL,
department_structure: {{
exists: dept_struct IS NOT NULL AND r1 IS NOT NULL
}},
curriculum_structure: {{
exists: curr_struct IS NOT NULL AND r2 IS NOT NULL
}},
pastoral_structure: {{
exists: past_struct IS NOT NULL AND r3 IS NOT NULL
}}
}} as status
""".format(
school=NodeLabels.SCHOOL.value,
dept_struct=NodeLabels.DEPARTMENT_STRUCTURE.value,
curr_struct=NodeLabels.CURRICULUM_STRUCTURE.value,
past_struct=NodeLabels.PASTORAL_STRUCTURE.value
)
@staticmethod
def get_cypher_check_detailed_structure() -> str:
"""Generate Cypher query for checking detailed structure existence and validity."""
return """
// Find the school node
MATCH (s:{school} {{unique_id: $school_id}})
// Check for department structure and departments
OPTIONAL MATCH (s)-[r1]-(dept_struct:{dept_struct})
WHERE dept_struct.unique_id = 'DepartmentStructure_' + s.unique_id
WITH s, dept_struct, r1,
CASE WHEN dept_struct IS NOT NULL
THEN [(dept_struct)-[r]-(d:{dept}) | d]
ELSE []
END as departments
// Check for curriculum structure and key stages
OPTIONAL MATCH (s)-[r2]-(curr_struct:{curr_struct})
WHERE curr_struct.unique_id = 'CurriculumStructure_' + s.unique_id
WITH s, dept_struct, r1, departments, curr_struct, r2,
CASE WHEN curr_struct IS NOT NULL
THEN [(curr_struct)-[r]-(k:{key_stage}) | k]
ELSE []
END as key_stages
// Check for pastoral structure and year groups
OPTIONAL MATCH (s)-[r3]-(past_struct:{past_struct})
WHERE past_struct.unique_id = 'PastoralStructure_' + s.unique_id
WITH dept_struct, r1, departments, curr_struct, r2, key_stages, past_struct, r3,
CASE WHEN past_struct IS NOT NULL
THEN [(past_struct)-[r]-(y:{year_group}) | y]
ELSE []
END as year_groups
// Return structure information
RETURN {{
has_detailed:
dept_struct IS NOT NULL AND r1 IS NOT NULL AND size(departments) > 0 AND
curr_struct IS NOT NULL AND r2 IS NOT NULL AND size(key_stages) > 0 AND
past_struct IS NOT NULL AND r3 IS NOT NULL AND size(year_groups) > 0,
department_structure: {{
exists: dept_struct IS NOT NULL AND r1 IS NOT NULL,
has_departments: size(departments) > 0,
department_count: size(departments),
node_id: dept_struct.unique_id
}},
curriculum_structure: {{
exists: curr_struct IS NOT NULL AND r2 IS NOT NULL,
has_key_stages: size(key_stages) > 0,
key_stage_count: size(key_stages),
node_id: curr_struct.unique_id
}},
pastoral_structure: {{
exists: past_struct IS NOT NULL AND r3 IS NOT NULL,
has_year_groups: size(year_groups) > 0,
year_group_count: size(year_groups),
node_id: past_struct.unique_id
}}
}} as status
""".format(
school=NodeLabels.SCHOOL.value,
dept_struct=NodeLabels.DEPARTMENT_STRUCTURE.value,
curr_struct=NodeLabels.CURRICULUM_STRUCTURE.value,
past_struct=NodeLabels.PASTORAL_STRUCTURE.value,
dept=NodeLabels.DEPARTMENT.value,
key_stage=NodeLabels.KEY_STAGE.value,
year_group=NodeLabels.YEAR_GROUP.value
)
@staticmethod
def get_schema_definition() -> SchemaDefinition:
"""Get the schema definition instance"""
return SchemaDefinition()
@staticmethod
def get_schema_creation_queries() -> List[str]:
"""Get queries to create the schema"""
return SchemaDefinition.get_schema_creation_queries()
@staticmethod
def get_schema_verification_queries() -> Dict[str, str]:
"""Get queries to verify schema state"""
return SchemaDefinition.get_schema_verification_queries()
@staticmethod
def get_schema_info() -> Dict[str, List[Dict]]:
"""Get human-readable schema information"""
return SchemaDefinition.get_schema_info()
class GraphProvider:
def __init__(self):
"""Initialize the graph provider with Neo4j connection."""
self.neontology = NeontologyProvider()
self.graph_naming = GraphNamingProvider()
self.logger = logging.getLogger(__name__)
def check_schema_status(self, database_name: str) -> Dict[str, Any]:
"""
Checks the current state of the schema in the specified database.
Returns a dictionary containing information about constraints, indexes, and labels.
"""
try:
verification_queries = SchemaDefinition.get_schema_verification_queries()
expected_schema = SchemaDefinition.get_schema_info()
# Get current schema state
constraints = self.neontology.run_query(verification_queries["constraints"], {}, database_name)
indexes = self.neontology.run_query(verification_queries["indexes"], {}, database_name)
labels = self.neontology.run_query(verification_queries["labels"], {}, database_name)
# Process results
current_constraints = [c["name"] for c in constraints]
current_indexes = [i["name"] for i in indexes]
current_labels = [l["label"] for l in labels]
# Expected values
expected_labels = [node["label"] for node in expected_schema["nodes"]]
return {
"constraints": current_constraints,
"constraints_valid": len(current_constraints) >= 4, # We expect at least 4 unique constraints
"indexes": current_indexes,
"indexes_valid": len(current_indexes) >= 5, # We expect at least 5 indexes
"labels": current_labels,
"labels_valid": all(label in current_labels for label in expected_labels)
}
except Exception as e:
self.logger.error(f"Error checking schema status: {str(e)}")
return {
"constraints": [], "constraints_valid": False,
"indexes": [], "indexes_valid": False,
"labels": [], "labels_valid": False
}
def initialize_schema(self, database_name: str) -> None:
"""
Initializes the schema for the specified database by creating all necessary
constraints and indexes.
"""
try:
creation_queries = SchemaDefinition.get_schema_creation_queries()
for query in creation_queries:
self.neontology.cypher_write(query, {}, database_name)
self.logger.info(f"Schema initialized successfully for database {database_name}")
except Exception as e:
self.logger.error(f"Error initializing schema: {str(e)}")
raise
def get_schema_info(self) -> Dict[str, Any]:
"""
Returns the schema definition information.
"""
return SchemaDefinition.get_schema_info()

View File

@ -1,212 +0,0 @@
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
import os
import modules.logger_tool as logger
from modules.database.tools.neontology.graphconnection import GraphConnection, init_neontology
from modules.database.tools.neontology.basenode import BaseNode
from modules.database.tools.neontology.baserelationship import BaseRelationship
from typing import Optional, Dict, Any, List
from neo4j import Record as Neo4jRecord
import re
log_name = 'api_modules_database_admin_neontology_provider'
log_dir = os.getenv("LOG_PATH", "/logs") # Default path as fallback
logging = logger.get_logger(
name=log_name,
log_level=os.getenv("LOG_LEVEL", "DEBUG"),
log_path=log_dir,
log_file=log_name,
runtime=True,
log_format='default'
)
class NeontologyProvider:
"""Provider class for managing Neontology connections and operations."""
def __init__(self):
"""Initialize the provider with Neo4j connection details from environment."""
self.bolt_url = os.getenv("APP_BOLT_URL")
self.user = os.getenv("USER_NEO4J")
self.password = os.getenv("PASSWORD_NEO4J")
self.connection = None
self.current_database = None
def _validate_database_name(self, database: str) -> str:
"""
Validate and format database name to handle special characters.
Args:
database: The database name to validate
Returns:
str: The validated database name
Raises:
ValueError: If database name is invalid
"""
if not database:
raise ValueError("Database name cannot be empty")
# Check for valid database name pattern
# Allow letters, numbers, underscores, and dots
if not re.match(r'^[a-zA-Z0-9_\.]+$', database):
raise ValueError("Database name contains invalid characters")
# For database names with multiple dots, we need to handle them specially
# Neo4j treats dots as special characters in some contexts
if database.count('.') > 1:
# Replace dots with underscores except for the first one
parts = database.split('.')
if len(parts) > 2:
# Keep the first dot, replace others with underscore
formatted_name = f"{parts[0]}.{'.'.join(parts[1:])}"
logging.info(f"Reformatted database name from {database} to {formatted_name}")
return formatted_name
return database
def connect(self, database: str = 'neo4j') -> None:
"""Establish connection to Neo4j using Neontology."""
try:
# Validate and format database name
formatted_database = self._validate_database_name(database)
# If we're switching databases, ensure we close the old connection
if self.current_database != formatted_database and self.connection is not None:
self.close()
# Initialize Neontology connection if needed
if self.connection is None:
init_neontology(
neo4j_uri=self.bolt_url,
neo4j_username=self.user,
neo4j_password=self.password
)
# Get the GraphConnection instance
self.connection = GraphConnection()
self.current_database = formatted_database
logging.info(f"Neontology connection initialized with host: {self.host}, port: {self.port}, database: {formatted_database}")
except Exception as e:
logging.error(f"Failed to initialize Neontology connection: {str(e)}")
raise
def reset_connection(self) -> None:
"""Reset the connection, forcing a new one to be created on next use."""
if self.connection:
self.close()
def create_or_merge_node(self, node: BaseNode, database: str = 'neo4j', operation: str = "merge") -> None:
"""Create or merge a node in the Neo4j database."""
try:
if not self.connection or self.current_database != database:
self.connect(database)
if operation == "create":
node.create(database=database)
elif operation == "merge":
node.merge(database=database)
else:
logging.error(f"Invalid operation: {operation}")
raise ValueError(f"Invalid operation: {operation}")
except Exception as e:
logging.error(f"Error in processing node: {e}")
raise
def create_or_merge_relationship(self, relationship: BaseRelationship, database: str = 'neo4j', operation: str = "merge") -> None:
"""Create or merge a relationship in the Neo4j database."""
try:
if not self.connection or self.current_database != database:
self.connect(database)
if operation == "create":
relationship.create(database=database)
elif operation == "merge":
relationship.merge(database=database)
else:
logging.error(f"Invalid operation: {operation}")
raise ValueError(f"Invalid operation: {operation}")
except Exception as e:
logging.error(f"Error in processing relationship: {e}")
raise
def cypher_write(self, cypher: str, params: Dict[str, Any] = {}, database: str = 'neo4j') -> None:
"""Execute a write transaction."""
try:
if not self.connection or self.current_database != database:
self.connect(database)
self.connection.cypher_write(cypher, params)
except Exception as e:
logging.error(f"Error in cypher write: {e}")
raise
def cypher_read(self, cypher: str, params: Dict[str, Any] = {}, database: str = 'neo4j') -> Optional[Neo4jRecord]:
"""Execute a read transaction returning a single record."""
try:
if not self.connection or self.current_database != database:
self.connect(database)
return self.connection.cypher_read(cypher, params)
except Exception as e:
logging.error(f"Error in cypher read: {e}")
raise
def cypher_read_many(self, cypher: str, params: Dict[str, Any] = {}, database: str = 'neo4j') -> List[Neo4jRecord]:
"""Execute a read transaction returning multiple records."""
try:
if not self.connection or self.current_database != database:
self.connect(database)
return self.connection.cypher_read_many(cypher, params)
except Exception as e:
logging.error(f"Error in cypher read many: {e}")
raise
def run_query(self, cypher: str, params: Dict[str, Any] = {}, database: str = 'neo4j') -> List[Dict[str, Any]]:
"""
Execute a Cypher query and return results as a list of dictionaries.
This is a convenience method that handles both single and multiple record results.
Args:
cypher: The Cypher query to execute
params: Query parameters
database: Target database name
Returns:
List[Dict[str, Any]]: Query results as a list of dictionaries
"""
try:
if not self.connection or self.current_database != database:
self.connect(database)
# Use cypher_read_many for consistent return type
records = self.connection.cypher_read_many(cypher, params)
# Convert Neo4j records to dictionaries
results = []
for record in records:
# Handle both Record and dict types
if isinstance(record, Neo4jRecord):
results.append(dict(record))
else:
results.append(record)
return results
except Exception as e:
logging.error(f"Error in run_query: {e}")
raise
def close(self) -> None:
"""Close the Neontology connection."""
if self.connection:
# The connection will be closed when the GraphConnection instance is deleted
self.connection = None
self.current_database = None
logging.info("Neontology connection closed")
def __enter__(self):
"""Context manager entry."""
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Context manager exit."""
self.close()

View File

@ -1,797 +0,0 @@
import os
from modules.logger_tool import initialise_logger
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
import backend.modules.database.schemas.entities as neo_entity
import modules.database.schemas.curriculum_neo as neo_curriculum
import modules.database.schemas.relationships.curriculum_relationships as curriculum_relationships
import modules.database.schemas.relationships.entity_relationships as ent_rels
import modules.database.schemas.relationships.entity_curriculum_rels as ent_cur_rels
from modules.database.tools.filesystem_tools import ClassroomCopilotFilesystem
import modules.database.tools.neontology_tools as neon
import pandas as pd
# Default values for nodes
default_topic_values = {
'topic_assessment_type': 'Null',
'topic_type': 'Null',
'total_number_of_lessons_for_topic': '1',
'topic_title': 'Null'
}
default_topic_lesson_values = {
'topic_lesson_title': 'Null',
'topic_lesson_type': 'Null',
'topic_lesson_length': '1',
'topic_lesson_suggested_activities': 'Null',
'topic_lesson_skills_learned': 'Null',
'topic_lesson_weblinks': 'Null',
}
default_learning_statement_values = {
'lesson_learning_statement': 'Null',
'lesson_learning_statement_type': 'Student learning outcome'
}
# Helper function to sort year groups numerically where possible
def sort_year_groups(df):
df = df.copy()
df['YearGroupNumeric'] = pd.to_numeric(df['YearGroup'], errors='coerce')
return df.sort_values(by='YearGroupNumeric')
def create_curriculum(dataframes, school_db_name, curriculum_db_name, school_node):
fs_handler = ClassroomCopilotFilesystem(school_db_name, init_run_type="school")
logger.info(f"Initialising neo4j connection...")
neon.init_neontology_connection()
keystagesyllabus_df = dataframes['keystagesyllabuses']
yeargroupsyllabus_df = dataframes['yeargroupsyllabuses']
topic_df = dataframes['topics']
lesson_df = dataframes['lessons']
statement_df = dataframes['statements']
# resource_df = dataframes['resources'] # TODO
node_library = {}
node_library['key_stage_nodes'] = {}
node_library['year_group_nodes'] = {}
node_library['key_stage_syllabus_nodes'] = {}
node_library['year_group_syllabus_nodes'] = {}
node_library['topic_nodes'] = {}
node_library['topic_lesson_nodes'] = {}
node_library['statement_nodes'] = {}
node_library['department_nodes'] = {}
node_library['subject_nodes'] = {}
curriculum_node = None
pastoral_node = None
key_stage_nodes_created = {}
year_group_nodes_created = {}
last_year_group_node = None
last_key_stage_node = None
# Create Curriculum and Pastoral nodes and relationships with School in both databases
_, curriculum_path = fs_handler.create_school_curriculum_directory(school_node.path)
_, pastoral_path = fs_handler.create_school_pastoral_directory(school_node.path)
# Create Department Structure node
department_structure_node_unique_id = f"DepartmentStructure_{school_node.unique_id}"
department_structure_node = neo_entity.DepartmentStructureNode(
unique_id=department_structure_node_unique_id,
path=os.path.join(school_node.path, "departments")
)
# Create in school database only
neon.create_or_merge_neontology_node(department_structure_node, database=school_db_name, operation='merge')
fs_handler.create_default_tldraw_file(department_structure_node.path, department_structure_node.to_dict())
node_library['department_structure_node'] = department_structure_node
# Link Department Structure to School
neon.create_or_merge_neontology_relationship(
ent_rels.SchoolHasDepartmentStructure(source=school_node, target=department_structure_node),
database=school_db_name, operation='merge'
)
logger.info(f"Created department structure node and linked to school")
# Create Curriculum Structure node
curriculum_structure_node_unique_id = f"CurriculumStructure_{school_node.unique_id}"
curriculum_node = neo_curriculum.CurriculumStructureNode(
unique_id=curriculum_structure_node_unique_id,
path=curriculum_path
)
# Create in school database only
neon.create_or_merge_neontology_node(curriculum_node, database=school_db_name, operation='merge')
fs_handler.create_default_tldraw_file(curriculum_node.path, curriculum_node.to_dict())
node_library['curriculum_node'] = curriculum_node
# Create relationship in school database only
neon.create_or_merge_neontology_relationship(
ent_cur_rels.SchoolHasCurriculumStructure(source=school_node, target=curriculum_node),
database=school_db_name, operation='merge'
)
logger.info(f"Created curriculum node and relationship with school")
# Create Pastoral Structure node
pastoral_structure_node_unique_id = f"PastoralStructure_{school_node.unique_id}"
pastoral_node = neo_curriculum.PastoralStructureNode(
unique_id=pastoral_structure_node_unique_id,
path=pastoral_path
)
neon.create_or_merge_neontology_node(pastoral_node, database=school_db_name, operation='merge')
fs_handler.create_default_tldraw_file(pastoral_node.path, pastoral_node.to_dict())
node_library['pastoral_node'] = pastoral_node
neon.create_or_merge_neontology_relationship(
ent_cur_rels.SchoolHasPastoralStructure(source=school_node, target=pastoral_node),
database=school_db_name, operation='merge'
)
logger.info(f"Created pastoral node and relationship with school")
# Create departments and subjects
# First get unique departments
unique_departments = keystagesyllabus_df['Department'].dropna().unique()
for department_name in unique_departments:
department_unique_id = f"Department_{school_node.unique_id}_{department_name.replace(' ', '_')}"
_, department_path = fs_handler.create_school_department_directory(school_node.path, department_name)
department_node = neo_entity.DepartmentNode(
unique_id=department_unique_id,
department_name=department_name,
path=department_path
)
# Create department in school database only
neon.create_or_merge_neontology_node(department_node, database=school_db_name, operation='merge')
fs_handler.create_default_tldraw_file(department_node.path, department_node.to_dict())
node_library['department_nodes'][department_name] = department_node
# Link department to department structure in school database
neon.create_or_merge_neontology_relationship(
ent_rels.DepartmentStructureHasDepartment(source=department_structure_node, target=department_node),
database=school_db_name, operation='merge'
)
logger.info(f"Created department node for {department_name} and linked to department structure")
# Create subjects and link to departments
# First get unique subjects from key stage syllabuses (which have department info)
unique_subjects = keystagesyllabus_df[['Subject', 'SubjectCode', 'Department']].drop_duplicates()
# Then add any additional subjects from year group syllabuses (without department info)
additional_subjects = yeargroupsyllabus_df[['Subject', 'SubjectCode']].drop_duplicates()
additional_subjects = additional_subjects[~additional_subjects['SubjectCode'].isin(unique_subjects['SubjectCode'])]
# Process subjects from key stage syllabuses first (these have department info)
for _, subject_row in unique_subjects.iterrows():
subject_unique_id = f"Subject_{school_node.unique_id}_{subject_row['SubjectCode']}"
department_node = node_library['department_nodes'].get(subject_row['Department'])
if not department_node:
logger.warning(f"No department found for subject {subject_row['Subject']} with code {subject_row['SubjectCode']}")
continue
_, subject_path = fs_handler.create_department_subject_directory(
department_node.path,
subject_row['Subject'] # Use full subject name instead of SubjectCode
)
logger.info(f"Created subject directory for {subject_path}")
subject_node = neo_curriculum.SubjectNode(
unique_id=subject_unique_id,
subject_code=subject_row['SubjectCode'],
subject_name=subject_row['Subject'],
path=subject_path
)
# Create subject in both databases
neon.create_or_merge_neontology_node(subject_node, database=school_db_name, operation='merge')
neon.create_or_merge_neontology_node(subject_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(subject_node.path, subject_node.to_dict())
node_library['subject_nodes'][subject_row['Subject']] = subject_node
# Link subject to department in school database only
neon.create_or_merge_neontology_relationship(
ent_rels.DepartmentManagesSubject(source=department_node, target=subject_node),
database=school_db_name, operation='merge'
)
logger.info(f"Created subject node for {subject_row['Subject']} and linked to department {subject_row['Department']}")
# Process any additional subjects from year group syllabuses (these won't have department info)
for _, subject_row in additional_subjects.iterrows():
subject_unique_id = f"Subject_{school_node.unique_id}_{subject_row['SubjectCode']}"
# Create in a special "Unassigned" department
unassigned_dept_name = "Unassigned Department"
if unassigned_dept_name not in node_library['department_nodes']:
_, dept_path = fs_handler.create_school_department_directory(school_node.path, unassigned_dept_name)
department_node = neo_entity.DepartmentNode(
unique_id=f"Department_{school_node.unique_id}_Unassigned",
department_name=unassigned_dept_name,
path=dept_path
)
neon.create_or_merge_neontology_node(department_node, database=school_db_name, operation='merge')
fs_handler.create_default_tldraw_file(department_node.path, department_node.to_dict())
node_library['department_nodes'][unassigned_dept_name] = department_node
# Link unassigned department to department structure
neon.create_or_merge_neontology_relationship(
ent_rels.DepartmentStructureHasDepartment(source=department_structure_node, target=department_node),
database=school_db_name, operation='merge'
)
logger.info(f"Created unassigned department node and linked to department structure")
_, subject_path = fs_handler.create_department_subject_directory(
node_library['department_nodes'][unassigned_dept_name].path,
subject_row['Subject']
)
subject_node = neo_curriculum.SubjectNode(
unique_id=subject_unique_id,
subject_code=subject_row['SubjectCode'],
subject_name=subject_row['Subject'],
path=subject_path
)
# Create subject in both databases
neon.create_or_merge_neontology_node(subject_node, database=school_db_name, operation='merge')
neon.create_or_merge_neontology_node(subject_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(subject_node.path, subject_node.to_dict())
node_library['subject_nodes'][subject_row['Subject']] = subject_node
# Link subject to unassigned department in school database only
neon.create_or_merge_neontology_relationship(
ent_rels.DepartmentManagesSubject(
source=node_library['department_nodes'][unassigned_dept_name],
target=subject_node
),
database=school_db_name, operation='merge'
)
logger.warning(f"Created subject node for {subject_row['Subject']} in unassigned department")
# Process key stages and syllabuses
logger.info(f"Processing key stages")
last_key_stage_node = None
# Track last syllabus nodes per subject
last_key_stage_syllabus_nodes = {} # Dictionary to track last key stage syllabus node per subject
last_year_group_syllabus_nodes = {} # Dictionary to track last year group syllabus node per subject
topics_processed = set() # Track which topics have been processed
lessons_processed = set() # Track which lessons have been processed
statements_processed = set() # Track which statements have been processed
# First create all key stage nodes and key stage syllabus nodes
for index, ks_row in keystagesyllabus_df.sort_values('KeyStage').iterrows():
key_stage = str(ks_row['KeyStage'])
logger.debug(f"Processing key stage syllabus row - Subject: {ks_row['Subject']}, Key Stage: {key_stage}")
subject_node = node_library['subject_nodes'].get(ks_row['Subject'])
if not subject_node:
logger.warning(f"No subject node found for subject {ks_row['Subject']}")
continue
if key_stage not in key_stage_nodes_created:
key_stage_node_unique_id = f"KeyStage_{curriculum_node.unique_id}_KStg{key_stage}"
key_stage_node = neo_curriculum.KeyStageNode(
unique_id=key_stage_node_unique_id,
key_stage_name=f"Key Stage {key_stage}",
key_stage=str(key_stage),
path=os.path.join(curriculum_node.path, "key_stages", f"KS{key_stage}")
)
# Create key stage node in both databases
neon.create_or_merge_neontology_node(key_stage_node, database=school_db_name, operation='merge')
neon.create_or_merge_neontology_node(key_stage_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(key_stage_node.path, key_stage_node.to_dict())
key_stage_nodes_created[key_stage] = key_stage_node
node_library['key_stage_nodes'][key_stage] = key_stage_node
# Create relationship with curriculum structure in school database only
neon.create_or_merge_neontology_relationship(
curriculum_relationships.CurriculumStructureIncludesKeyStage(source=curriculum_node, target=key_stage_node),
database=school_db_name, operation='merge'
)
logger.info(f"Created key stage node {key_stage_node_unique_id} and relationship with curriculum structure")
# Create sequential relationship between key stages in both databases
if last_key_stage_node:
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageFollowsKeyStage(source=last_key_stage_node, target=key_stage_node),
database=school_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageFollowsKeyStage(source=last_key_stage_node, target=key_stage_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between key stages {last_key_stage_node.unique_id} and {key_stage_node.unique_id}")
last_key_stage_node = key_stage_node
# Create key stage syllabus under the subject's curriculum directory
_, key_stage_syllabus_path = fs_handler.create_curriculum_key_stage_syllabus_directory(
curriculum_node.path,
key_stage,
ks_row['Subject'],
ks_row['ID']
)
logger.debug(f"Creating key stage syllabus node for {ks_row['Subject']} KS{key_stage} with ID {ks_row['ID']}")
key_stage_syllabus_node_unique_id = f"KeyStageSyllabus_{curriculum_node.unique_id}_{ks_row['Title'].replace(' ', '')}"
key_stage_syllabus_node = neo_curriculum.KeyStageSyllabusNode(
unique_id=key_stage_syllabus_node_unique_id,
ks_syllabus_id=ks_row['ID'],
ks_syllabus_name=ks_row['Title'],
ks_syllabus_key_stage=str(ks_row['KeyStage']),
ks_syllabus_subject=ks_row['Subject'],
ks_syllabus_subject_code=ks_row['Subject'],
path=key_stage_syllabus_path
)
# Create key stage syllabus node in both databases
neon.create_or_merge_neontology_node(key_stage_syllabus_node, database=school_db_name, operation='merge')
neon.create_or_merge_neontology_node(key_stage_syllabus_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(key_stage_syllabus_node.path, key_stage_syllabus_node.to_dict())
node_library['key_stage_syllabus_nodes'][ks_row['ID']] = key_stage_syllabus_node
logger.debug(f"Created key stage syllabus node {key_stage_syllabus_node_unique_id} for {ks_row['Subject']} KS{key_stage}")
# Link key stage syllabus to its subject in both databases
if subject_node:
neon.create_or_merge_neontology_relationship(
curriculum_relationships.SubjectHasKeyStageSyllabus(source=subject_node, target=key_stage_syllabus_node),
database=school_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.SubjectHasKeyStageSyllabus(source=subject_node, target=key_stage_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between subject {subject_node.unique_id} and key stage syllabus {key_stage_syllabus_node.unique_id}")
# Link key stage syllabus to its key stage in both databases
key_stage_node = key_stage_nodes_created.get(key_stage)
if key_stage_node:
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageIncludesKeyStageSyllabus(source=key_stage_node, target=key_stage_syllabus_node),
database=school_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageIncludesKeyStageSyllabus(source=key_stage_node, target=key_stage_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between key stage {key_stage_node.unique_id} and key stage syllabus {key_stage_syllabus_node.unique_id}")
# Create sequential relationship between key stage syllabuses in both databases
last_key_stage_syllabus_node = last_key_stage_syllabus_nodes.get(ks_row['Subject'])
if last_key_stage_syllabus_node:
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageSyllabusFollowsKeyStageSyllabus(source=last_key_stage_syllabus_node, target=key_stage_syllabus_node),
database=school_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageSyllabusFollowsKeyStageSyllabus(source=last_key_stage_syllabus_node, target=key_stage_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between key stage syllabuses {last_key_stage_syllabus_node.unique_id} and {key_stage_syllabus_node.unique_id}")
last_key_stage_syllabus_nodes[ks_row['Subject']] = key_stage_syllabus_node
# Now process year groups and their syllabuses
for index, ks_row in keystagesyllabus_df.sort_values('KeyStage').iterrows():
key_stage = str(ks_row['KeyStage'])
related_yeargroups = sort_year_groups(yeargroupsyllabus_df[yeargroupsyllabus_df['KeyStage'] == ks_row['KeyStage']])
logger.info(f"Processing year groups for key stage {key_stage}")
for yg_index, yg_row in related_yeargroups.iterrows():
year_group = yg_row['YearGroup']
subject_code = yg_row['SubjectCode']
numeric_year_group = pd.to_numeric(year_group, errors='coerce')
if pd.notna(numeric_year_group):
numeric_year_group = int(numeric_year_group)
if numeric_year_group not in year_group_nodes_created:
# Create year group directory under pastoral structure
_, year_group_path = fs_handler.create_pastoral_year_group_directory(pastoral_node.path, year_group)
logger.info(f"Created year group directory for {year_group_path}")
year_group_node_unique_id = f"YearGroup_{school_node.unique_id}_YGrp{numeric_year_group}"
year_group_node = neo_curriculum.YearGroupNode(
unique_id=year_group_node_unique_id,
year_group=str(numeric_year_group),
year_group_name=f"Year {numeric_year_group}",
path=year_group_path
)
# Create year group node in both databases but use same directory
neon.create_or_merge_neontology_node(year_group_node, database=school_db_name, operation='merge')
neon.create_or_merge_neontology_node(year_group_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(year_group_node.path, year_group_node.to_dict())
# Create sequential relationship between year groups in both databases
if last_year_group_node:
neon.create_or_merge_neontology_relationship(
curriculum_relationships.YearGroupFollowsYearGroup(source=last_year_group_node, target=year_group_node),
database=school_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.YearGroupFollowsYearGroup(source=last_year_group_node, target=year_group_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between year groups {last_year_group_node.unique_id} and {year_group_node.unique_id} across key stages")
last_year_group_node = year_group_node
# Create relationship with Pastoral Structure in school database only
neon.create_or_merge_neontology_relationship(
curriculum_relationships.PastoralStructureIncludesYearGroup(source=pastoral_node, target=year_group_node),
database=school_db_name, operation='merge'
)
logger.info(f"Created year group node {year_group_node_unique_id} and relationship with pastoral structure")
year_group_nodes_created[numeric_year_group] = year_group_node
node_library['year_group_nodes'][str(numeric_year_group)] = year_group_node
# Curriculum specific database initialisation begins here
# Create year group syllabus nodes in both databases
year_group_node = year_group_nodes_created.get(numeric_year_group)
if year_group_node:
# Create syllabus directory under curriculum structure
_, year_group_syllabus_path = fs_handler.create_curriculum_year_group_syllabus_directory(
curriculum_node.path,
yg_row['Subject'],
year_group,
yg_row['ID']
)
logger.info(f"Created year group syllabus directory for {year_group_syllabus_path}")
year_group_syllabus_node_unique_id = f"YearGroupSyllabus_{school_node.unique_id}_{yg_row['ID']}"
year_group_syllabus_node = neo_curriculum.YearGroupSyllabusNode(
unique_id=year_group_syllabus_node_unique_id,
yr_syllabus_id=yg_row['ID'],
yr_syllabus_name=yg_row['Title'],
yr_syllabus_year_group=str(yg_row['YearGroup']),
yr_syllabus_subject=yg_row['Subject'],
yr_syllabus_subject_code=yg_row['Subject'],
path=year_group_syllabus_path
)
# Create year group syllabus node in both databases but use same directory
neon.create_or_merge_neontology_node(year_group_syllabus_node, database=school_db_name, operation='merge')
neon.create_or_merge_neontology_node(year_group_syllabus_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(year_group_syllabus_node.path, year_group_syllabus_node.to_dict())
node_library['year_group_syllabus_nodes'][yg_row['ID']] = year_group_syllabus_node
# Create sequential relationship between year group syllabuses in both databases
last_year_group_syllabus_node = last_year_group_syllabus_nodes.get(yg_row['Subject'])
# Only create sequential relationship if this year group is higher than the last one
if last_year_group_syllabus_node:
last_year = pd.to_numeric(last_year_group_syllabus_node.yr_syllabus_year_group, errors='coerce')
current_year = pd.to_numeric(year_group_syllabus_node.yr_syllabus_year_group, errors='coerce')
if pd.notna(last_year) and pd.notna(current_year) and current_year > last_year:
neon.create_or_merge_neontology_relationship(
curriculum_relationships.YearGroupSyllabusFollowsYearGroupSyllabus(source=last_year_group_syllabus_node, target=year_group_syllabus_node),
database=school_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.YearGroupSyllabusFollowsYearGroupSyllabus(source=last_year_group_syllabus_node, target=year_group_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between year group syllabuses {last_year_group_syllabus_node.unique_id} and {year_group_syllabus_node.unique_id}")
last_year_group_syllabus_nodes[yg_row['Subject']] = year_group_syllabus_node
# Create relationships in both databases using MATCH to avoid cartesian products
subject_node = node_library['subject_nodes'].get(yg_row['Subject'])
if subject_node:
# Link to subject
neon.create_or_merge_neontology_relationship(
curriculum_relationships.SubjectHasYearGroupSyllabus(source=subject_node, target=year_group_syllabus_node),
database=school_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.SubjectHasYearGroupSyllabus(source=subject_node, target=year_group_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between subject {subject_node.unique_id} and year group syllabus {year_group_syllabus_node_unique_id}")
# Link to year group
neon.create_or_merge_neontology_relationship(
curriculum_relationships.YearGroupHasYearGroupSyllabus(source=year_group_node, target=year_group_syllabus_node),
database=school_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.YearGroupHasYearGroupSyllabus(source=year_group_node, target=year_group_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between year group {year_group_node.unique_id} and year group syllabus {year_group_syllabus_node_unique_id}")
# Link to key stage syllabus if it exists for the same subject
key_stage_syllabus_node = node_library['key_stage_syllabus_nodes'].get(ks_row['ID'])
if key_stage_syllabus_node and yg_row['Subject'] == ks_row['Subject']:
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageSyllabusIncludesYearGroupSyllabus(source=key_stage_syllabus_node, target=year_group_syllabus_node),
database=school_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageSyllabusIncludesYearGroupSyllabus(source=key_stage_syllabus_node, target=year_group_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between key stage syllabus {key_stage_syllabus_node.unique_id} and year group syllabus {year_group_syllabus_node_unique_id}")
# Processing of curriculum topic begins here
# Process topics for this year group syllabus only if not already processed
topics_for_syllabus = topic_df[topic_df['SyllabusYearID'] == yg_row['ID']]
for _, topic_row in topics_for_syllabus.iterrows():
if topic_row['TopicID'] in topics_processed:
continue
topics_processed.add(topic_row['TopicID'])
# Get the correct subject from the topic row
topic_subject = topic_row['SyllabusSubject']
topic_key_stage = topic_row['SyllabusKeyStage']
logger.debug(f"Processing topic {topic_row['TopicID']} for subject {topic_subject} and key stage {topic_key_stage}")
logger.debug(f"Available key stage syllabus nodes: {[node.ks_syllabus_subject + '_KS' + node.ks_syllabus_key_stage for node in node_library['key_stage_syllabus_nodes'].values()]}")
# Find the key stage syllabus node by iterating through all nodes
matching_syllabus_node = None
for syllabus_node in node_library['key_stage_syllabus_nodes'].values():
logger.debug(f"Checking syllabus node - Subject: {syllabus_node.ks_syllabus_subject}, Key Stage: {syllabus_node.ks_syllabus_key_stage}")
logger.debug(f"Comparing with - Subject: {topic_subject}, Key Stage: {str(topic_key_stage)}")
logger.debug(f"Types - Node Subject: {type(syllabus_node.ks_syllabus_subject)}, Topic Subject: {type(topic_subject)}")
logger.debug(f"Types - Node Key Stage: {type(syllabus_node.ks_syllabus_key_stage)}, Topic Key Stage: {type(str(topic_key_stage))}")
if (syllabus_node.ks_syllabus_subject == topic_subject and
syllabus_node.ks_syllabus_key_stage == str(topic_key_stage)):
matching_syllabus_node = syllabus_node
logger.debug(f"Found matching syllabus node: {syllabus_node.unique_id}")
break
if not matching_syllabus_node:
logger.warning(f"No key stage syllabus node found for subject {topic_subject} and key stage {topic_key_stage}, skipping topic creation")
continue
_, topic_path = fs_handler.create_curriculum_topic_directory(matching_syllabus_node.path, topic_row['TopicID'])
logger.info(f"Created topic directory for {topic_path}")
topic_node_unique_id = f"Topic_{matching_syllabus_node.unique_id}_{topic_row['TopicID']}"
topic_node = neo_curriculum.TopicNode(
unique_id=topic_node_unique_id,
topic_id=topic_row['TopicID'],
topic_title=topic_row.get('TopicTitle', default_topic_values['topic_title']),
total_number_of_lessons_for_topic=str(topic_row.get('TotalNumberOfLessonsForTopic', default_topic_values['total_number_of_lessons_for_topic'])),
topic_type=topic_row.get('TopicType', default_topic_values['topic_type']),
topic_assessment_type=topic_row.get('TopicAssessmentType', default_topic_values['topic_assessment_type']),
path=topic_path
)
# Create topic node in curriculum database only
neon.create_or_merge_neontology_node(topic_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(topic_node.path, topic_node.to_dict())
node_library['topic_nodes'][topic_row['TopicID']] = topic_node
# Link topic to key stage syllabus as well as year group syllabus
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageSyllabusIncludesTopic(source=matching_syllabus_node, target=topic_node),
database=curriculum_db_name, operation='merge'
)
neon.create_or_merge_neontology_relationship(
curriculum_relationships.YearGroupSyllabusIncludesTopic(source=year_group_syllabus_node, target=topic_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationships between topic {topic_node_unique_id} and key stage syllabus {matching_syllabus_node.unique_id} and year group syllabus {year_group_syllabus_node_unique_id}")
# Process lessons for this topic only if not already processed
lessons_for_topic = lesson_df[
(lesson_df['TopicID'] == topic_row['TopicID']) &
(lesson_df['SyllabusSubject'] == topic_subject)
].copy()
lessons_for_topic.loc[:, 'Lesson'] = lessons_for_topic['Lesson'].astype(str)
lessons_for_topic = lessons_for_topic.sort_values('Lesson')
previous_lesson_node = None
for _, lesson_row in lessons_for_topic.iterrows():
if lesson_row['LessonID'] in lessons_processed:
continue
lessons_processed.add(lesson_row['LessonID'])
_, lesson_path = fs_handler.create_curriculum_lesson_directory(topic_path, lesson_row['LessonID'])
logger.info(f"Created lesson directory for {lesson_path}")
lesson_data = {
'unique_id': f"TopicLesson_{topic_node_unique_id}_{lesson_row['LessonID']}",
'topic_lesson_id': lesson_row['LessonID'],
'topic_lesson_title': lesson_row.get('LessonTitle', default_topic_lesson_values['topic_lesson_title']),
'topic_lesson_type': lesson_row.get('LessonType', default_topic_lesson_values['topic_lesson_type']),
'topic_lesson_length': str(lesson_row.get('SuggestedNumberOfPeriodsForLesson', default_topic_lesson_values['topic_lesson_length'])),
'topic_lesson_suggested_activities': lesson_row.get('SuggestedActivities', default_topic_lesson_values['topic_lesson_suggested_activities']),
'topic_lesson_skills_learned': lesson_row.get('SkillsLearned', default_topic_lesson_values['topic_lesson_skills_learned']),
'topic_lesson_weblinks': lesson_row.get('WebLinks', default_topic_lesson_values['topic_lesson_weblinks']),
'path': lesson_path
}
for key, value in lesson_data.items():
if pd.isna(value):
lesson_data[key] = default_topic_lesson_values.get(key, 'Null')
lesson_node = neo_curriculum.TopicLessonNode(**lesson_data)
# Create lesson node in curriculum database only
neon.create_or_merge_neontology_node(lesson_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(lesson_node.path, lesson_node.to_dict())
node_library['topic_lesson_nodes'][lesson_row['LessonID']] = lesson_node
# Link lesson to topic
neon.create_or_merge_neontology_relationship(
curriculum_relationships.TopicIncludesTopicLesson(source=topic_node, target=lesson_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created lesson node {lesson_node.unique_id} and relationship with topic {topic_node.unique_id}")
# Create sequential relationships between lessons
if lesson_row['Lesson'].isdigit() and previous_lesson_node:
neon.create_or_merge_neontology_relationship(
curriculum_relationships.TopicLessonFollowsTopicLesson(source=previous_lesson_node, target=lesson_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between lessons {previous_lesson_node.unique_id} and {lesson_node.unique_id}")
previous_lesson_node = lesson_node
# Process learning statements for this lesson only if not already processed
statements_for_lesson = statement_df[
(statement_df['LessonID'] == lesson_row['LessonID']) &
(statement_df['SyllabusSubject'] == topic_subject)
]
for _, statement_row in statements_for_lesson.iterrows():
if statement_row['StatementID'] in statements_processed:
continue
statements_processed.add(statement_row['StatementID'])
_, statement_path = fs_handler.create_curriculum_learning_statement_directory(lesson_path, statement_row['StatementID'])
statement_data = {
'unique_id': f"LearningStatement_{lesson_node.unique_id}_{statement_row['StatementID']}",
'lesson_learning_statement_id': statement_row['StatementID'],
'lesson_learning_statement': statement_row.get('LearningStatement', default_learning_statement_values['lesson_learning_statement']),
'lesson_learning_statement_type': statement_row.get('StatementType', default_learning_statement_values['lesson_learning_statement_type']),
'path': statement_path
}
for key in statement_data:
if pd.isna(statement_data[key]):
statement_data[key] = default_learning_statement_values.get(key, 'Null')
statement_node = neo_curriculum.LearningStatementNode(**statement_data)
# Create statement node in curriculum database only
neon.create_or_merge_neontology_node(statement_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(statement_node.path, statement_node.to_dict())
node_library['statement_nodes'][statement_row['StatementID']] = statement_node
# Link learning statement to lesson
neon.create_or_merge_neontology_relationship(
curriculum_relationships.LessonIncludesLearningStatement(source=lesson_node, target=statement_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created learning statement node {statement_node.unique_id} and relationship with lesson {lesson_node.unique_id}")
else:
logger.warning(f"No year group node found for year group {year_group}, skipping syllabus creation")
# After processing all year groups and their syllabuses, process any remaining topics
logger.info("Processing topics without year groups")
for _, topic_row in topic_df.iterrows():
if topic_row['TopicID'] in topics_processed:
continue
topic_subject = topic_row['SyllabusSubject']
topic_key_stage = topic_row['SyllabusKeyStage']
logger.debug(f"Processing topic {topic_row['TopicID']} for subject {topic_subject} and key stage {topic_key_stage} without year group")
# Find the key stage syllabus node
matching_syllabus_node = None
for syllabus_node in node_library['key_stage_syllabus_nodes'].values():
if (syllabus_node.ks_syllabus_subject == topic_subject and
syllabus_node.ks_syllabus_key_stage == str(topic_key_stage)):
matching_syllabus_node = syllabus_node
break
if not matching_syllabus_node:
logger.warning(f"No key stage syllabus node found for subject {topic_subject} and key stage {topic_key_stage}, skipping topic creation")
continue
_, topic_path = fs_handler.create_curriculum_topic_directory(matching_syllabus_node.path, topic_row['TopicID'])
logger.info(f"Created topic directory for {topic_path}")
topic_node_unique_id = f"Topic_{matching_syllabus_node.unique_id}_{topic_row['TopicID']}"
topic_node = neo_curriculum.TopicNode(
unique_id=topic_node_unique_id,
topic_id=topic_row['TopicID'],
topic_title=topic_row.get('TopicTitle', default_topic_values['topic_title']),
total_number_of_lessons_for_topic=str(topic_row.get('TotalNumberOfLessonsForTopic', default_topic_values['total_number_of_lessons_for_topic'])),
topic_type=topic_row.get('TopicType', default_topic_values['topic_type']),
topic_assessment_type=topic_row.get('TopicAssessmentType', default_topic_values['topic_assessment_type']),
path=topic_path
)
# Create topic node in curriculum database only
neon.create_or_merge_neontology_node(topic_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(topic_node.path, topic_node.to_dict())
node_library['topic_nodes'][topic_row['TopicID']] = topic_node
topics_processed.add(topic_row['TopicID'])
# Link topic to key stage syllabus
neon.create_or_merge_neontology_relationship(
curriculum_relationships.KeyStageSyllabusIncludesTopic(source=matching_syllabus_node, target=topic_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between topic {topic_node_unique_id} and key stage syllabus {matching_syllabus_node.unique_id}")
# Process lessons for this topic
lessons_for_topic = lesson_df[
(lesson_df['TopicID'] == topic_row['TopicID']) &
(lesson_df['SyllabusSubject'] == topic_subject)
].copy()
lessons_for_topic.loc[:, 'Lesson'] = lessons_for_topic['Lesson'].astype(str)
lessons_for_topic = lessons_for_topic.sort_values('Lesson')
previous_lesson_node = None
for _, lesson_row in lessons_for_topic.iterrows():
if lesson_row['LessonID'] in lessons_processed:
continue
lessons_processed.add(lesson_row['LessonID'])
_, lesson_path = fs_handler.create_curriculum_lesson_directory(topic_path, lesson_row['LessonID'])
logger.info(f"Created lesson directory for {lesson_path}")
lesson_data = {
'unique_id': f"TopicLesson_{topic_node_unique_id}_{lesson_row['LessonID']}",
'topic_lesson_id': lesson_row['LessonID'],
'topic_lesson_title': lesson_row.get('LessonTitle', default_topic_lesson_values['topic_lesson_title']),
'topic_lesson_type': lesson_row.get('LessonType', default_topic_lesson_values['topic_lesson_type']),
'topic_lesson_length': str(lesson_row.get('SuggestedNumberOfPeriodsForLesson', default_topic_lesson_values['topic_lesson_length'])),
'topic_lesson_suggested_activities': lesson_row.get('SuggestedActivities', default_topic_lesson_values['topic_lesson_suggested_activities']),
'topic_lesson_skills_learned': lesson_row.get('SkillsLearned', default_topic_lesson_values['topic_lesson_skills_learned']),
'topic_lesson_weblinks': lesson_row.get('WebLinks', default_topic_lesson_values['topic_lesson_weblinks']),
'path': lesson_path
}
for key, value in lesson_data.items():
if pd.isna(value):
lesson_data[key] = default_topic_lesson_values.get(key, 'Null')
lesson_node = neo_curriculum.TopicLessonNode(**lesson_data)
# Create lesson node in curriculum database only
neon.create_or_merge_neontology_node(lesson_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(lesson_node.path, lesson_node.to_dict())
node_library['topic_lesson_nodes'][lesson_row['LessonID']] = lesson_node
# Link lesson to topic
neon.create_or_merge_neontology_relationship(
curriculum_relationships.TopicIncludesTopicLesson(source=topic_node, target=lesson_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created lesson node {lesson_node.unique_id} and relationship with topic {topic_node.unique_id}")
# Create sequential relationships between lessons
if lesson_row['Lesson'].isdigit() and previous_lesson_node:
neon.create_or_merge_neontology_relationship(
curriculum_relationships.TopicLessonFollowsTopicLesson(source=previous_lesson_node, target=lesson_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between lessons {previous_lesson_node.unique_id} and {lesson_node.unique_id}")
previous_lesson_node = lesson_node
# Process learning statements for this lesson
statements_for_lesson = statement_df[
(statement_df['LessonID'] == lesson_row['LessonID']) &
(statement_df['SyllabusSubject'] == topic_subject)
]
for _, statement_row in statements_for_lesson.iterrows():
if statement_row['StatementID'] in statements_processed:
continue
statements_processed.add(statement_row['StatementID'])
_, statement_path = fs_handler.create_curriculum_learning_statement_directory(lesson_path, statement_row['StatementID'])
statement_data = {
'unique_id': f"LearningStatement_{lesson_node.unique_id}_{statement_row['StatementID']}",
'lesson_learning_statement_id': statement_row['StatementID'],
'lesson_learning_statement': statement_row.get('LearningStatement', default_learning_statement_values['lesson_learning_statement']),
'lesson_learning_statement_type': statement_row.get('StatementType', default_learning_statement_values['lesson_learning_statement_type']),
'path': statement_path
}
for key in statement_data:
if pd.isna(statement_data[key]):
statement_data[key] = default_learning_statement_values.get(key, 'Null')
statement_node = neo_curriculum.LearningStatementNode(**statement_data)
# Create statement node in curriculum database only
neon.create_or_merge_neontology_node(statement_node, database=curriculum_db_name, operation='merge')
fs_handler.create_default_tldraw_file(statement_node.path, statement_node.to_dict())
node_library['statement_nodes'][statement_row['StatementID']] = statement_node
# Link learning statement to lesson
neon.create_or_merge_neontology_relationship(
curriculum_relationships.LessonIncludesLearningStatement(source=lesson_node, target=statement_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created learning statement node {statement_node.unique_id} and relationship with lesson {lesson_node.unique_id}")
return node_library

View File

@ -1,512 +0,0 @@
import os
from modules.logger_tool import initialise_logger
from supabase import create_client
import json
import pandas as pd
import modules.database.init.xl_tools as xl
from modules.database.tools.filesystem_tools import ClassroomCopilotFilesystem
import modules.database.tools.neo4j_driver_tools as driver_tools
import modules.database.tools.neo4j_session_tools as session_tools
import modules.database.schemas.nodes.schools.schools as school_schemas
import modules.database.schemas.nodes.schools.curriculum as curriculum_schemas
import modules.database.schemas.nodes.schools.pastoral as pastoral_schemas
import modules.database.schemas.nodes.structures.schools as school_structures
import modules.database.schemas.entities as entities
from modules.database.admin.neontology_provider import NeontologyProvider
from modules.database.admin.graph_provider import GraphNamingProvider
from modules.database.schemas.relationships import curriculum_relationships, entity_relationships, entity_curriculum_rels
class SchoolManager:
def __init__(self):
self.driver = driver_tools.get_driver()
self.logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
self.neontology = NeontologyProvider()
self.graph_naming = GraphNamingProvider()
# Initialize Supabase client with correct URL and service role key
supabase_url = os.getenv("SUPABASE_URL")
service_role_key = os.getenv("SERVICE_ROLE_KEY")
self.logger.info(f"Initializing Supabase client with URL: {supabase_url}")
self.supabase = create_client(supabase_url, service_role_key)
# Set headers for admin operations
self.supabase.headers = {
"apiKey": service_role_key,
"Authorization": f"Bearer {service_role_key}",
"Content-Type": "application/json"
}
# Set storage client headers explicitly
self.supabase.storage._client.headers.update({
"apiKey": service_role_key,
"Authorization": f"Bearer {service_role_key}",
"Content-Type": "application/json"
})
def create_schools_database(self):
"""Creates the main cc.institutes database in Neo4j"""
try:
db_name = "cc.institutes"
with self.driver.session() as session:
return self._extracted_from_create_private_database(
session, db_name, f'Created database {db_name}'
)
except Exception as e:
self.logger.error(f"Error creating schools database: {str(e)}")
return {"status": "error", "message": str(e)}
def create_school_node(self, school_data):
"""Creates a school node in cc.institutes database and stores TLDraw file in Supabase"""
try:
# Convert Supabase school data to SchoolNode using GraphNamingProvider
school_unique_id = self.graph_naming.get_school_unique_id(school_data['urn'])
school_path = self.graph_naming.get_school_path("cc.institutes", school_data['urn'])
school_node = entities.school_schemas.SchoolNode(
unique_id=school_unique_id,
path=school_path,
urn=school_data['urn'],
establishment_number=school_data['establishment_number'],
establishment_name=school_data['establishment_name'],
establishment_type=school_data['establishment_type'],
establishment_status=school_data['establishment_status'],
phase_of_education=school_data['phase_of_education'] if school_data['phase_of_education'] not in [None, ''] else None,
statutory_low_age=int(school_data['statutory_low_age']) if school_data.get('statutory_low_age') is not None else 0,
statutory_high_age=int(school_data['statutory_high_age']) if school_data.get('statutory_high_age') is not None else 0,
religious_character=school_data.get('religious_character') if school_data.get('religious_character') not in [None, ''] else None,
school_capacity=int(school_data['school_capacity']) if school_data.get('school_capacity') is not None else 0,
school_website=school_data.get('school_website', ''),
ofsted_rating=school_data.get('ofsted_rating') if school_data.get('ofsted_rating') not in [None, ''] else None
)
# Create default tldraw file data
tldraw_data = {
"document": {
"version": 1,
"id": school_data['urn'],
"name": school_data['establishment_name'],
"meta": {
"created_at": "",
"updated_at": "",
"creator_id": "",
"is_template": False,
"is_snapshot": False,
"is_draft": False,
"template_id": None,
"snapshot_id": None,
"draft_id": None
}
},
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 22
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"cc-school-node": 1
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"store": {
"document:document": {
"gridSize": 10,
"name": school_data['establishment_name'],
"meta": {},
"id": school_data['urn'],
"typeName": "document"
},
"page:page": {
"meta": {},
"id": "page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
"shape:school-node": {
"x": 0,
"y": 0,
"rotation": 0,
"type": "cc-school-node",
"id": school_unique_id,
"parentId": "page",
"index": "a1",
"props": school_node.to_dict(),
"typeName": "shape"
},
"instance:instance": {
"id": "instance",
"currentPageId": "page",
"typeName": "instance"
},
"camera:camera": {
"x": 0,
"y": 0,
"z": 1,
"id": "camera",
"typeName": "camera"
}
}
}
# Store tldraw file in Supabase storage
file_path = f"{school_data['urn']}/tldraw.json"
file_options = {
"content-type": "application/json",
"x-upsert": "true", # Update if exists
"metadata": {
"establishment_urn": school_data['urn'],
"establishment_name": school_data['establishment_name']
}
}
try:
# Create a fresh service role client for storage operations
self.logger.info("Creating fresh service role client for storage operations")
service_client = create_client(
os.getenv("SUPABASE_URL"),
os.getenv("SERVICE_ROLE_KEY")
)
self.logger.debug(f"Service client created with URL: {os.getenv('SUPABASE_URL')}")
service_client.headers = {
"apiKey": os.getenv("SERVICE_ROLE_KEY"),
"Authorization": f"Bearer {os.getenv('SERVICE_ROLE_KEY')}",
"Content-Type": "application/json"
}
service_client.storage._client.headers.update({
"apiKey": os.getenv("SERVICE_ROLE_KEY"),
"Authorization": f"Bearer {os.getenv('SERVICE_ROLE_KEY')}",
"Content-Type": "application/json"
})
self.logger.debug("Headers set for service client and storage client")
# Upload to Supabase storage using service role client
self.logger.info(f"Uploading tldraw file for school {school_data['urn']}")
self.logger.debug(f"File path: {file_path}")
self.logger.debug(f"File options: {file_options}")
# First, ensure the bucket exists
self.logger.info("Checking if bucket cc.institutes exists")
try:
bucket = service_client.storage.get_bucket("cc.institutes")
self.logger.info("Bucket cc.institutes exists")
except Exception as bucket_error:
self.logger.error(f"Error checking bucket: {str(bucket_error)}")
if hasattr(bucket_error, 'response'):
self.logger.error(f"Bucket error response: {bucket_error.response.text if hasattr(bucket_error.response, 'text') else bucket_error.response}")
raise bucket_error
# Attempt the upload
self.logger.info("Attempting file upload")
result = service_client.storage.from_("cc.institutes").upload(
path=file_path,
file=json.dumps(tldraw_data).encode(),
file_options=file_options
)
self.logger.info(f"Upload successful. Result: {result}")
except Exception as upload_error:
self.logger.error(f"Error uploading tldraw file: {str(upload_error)}")
if hasattr(upload_error, 'response'):
self.logger.error(f"Upload error response: {upload_error.response.text if hasattr(upload_error.response, 'text') else upload_error.response}")
raise upload_error
# Create node in Neo4j using Neontology
with self.neontology as neo:
self.logger.info(f"Creating school node in Neo4j: {school_node.to_dict()}")
neo.create_or_merge_node(school_node, database="cc.institutes", operation="merge")
return {"status": "success", "node": school_node}
except Exception as e:
self.logger.error(f"Error creating school node: {str(e)}")
return {"status": "error", "message": str(e)}
def create_private_database(self, school_data):
"""Creates a private database for a specific school"""
try:
private_db_name = f"cc.institutes.{school_data['urn']}"
with self.driver.session() as session:
return self._extracted_from_create_private_database(
session, private_db_name, 'Created private database '
)
except Exception as e:
self.logger.error(f"Error creating private database: {str(e)}")
return {"status": "error", "message": str(e)}
# TODO Rename this here and in `create_schools_database` and `create_private_database`
def _extracted_from_create_private_database(self, session, arg1, arg2):
session_tools.create_database(session, arg1)
self.logger.info(f"{arg2}{arg1}")
return {
"status": "success",
"message": f"Database {arg1} created successfully",
}
def create_basic_structure(self, school_node, database_name):
"""Creates basic structural nodes in the specified database"""
try:
# Create filesystem paths
fs_handler = ClassroomCopilotFilesystem(database_name, init_run_type="school")
# Create Department Structure node
department_structure_node_unique_id = f"DepartmentStructure_{school_node.unique_id}"
_, department_path = fs_handler.create_school_department_directory(school_node.path, "departments")
department_structure_node = entities.school_schemas.DepartmentNode(
unique_id=department_structure_node_unique_id,
path=department_path
)
# Create Curriculum Structure node
_, curriculum_path = fs_handler.create_school_curriculum_directory(school_node.path)
curriculum_node = school_structures.CurriculumStructureNode(
unique_id=f"CurriculumStructure_{school_node.unique_id}",
path=curriculum_path
)
# Create Pastoral Structure node
_, pastoral_path = fs_handler.create_school_pastoral_directory(school_node.path)
pastoral_node = school_structures.PastoralStructureNode(
unique_id=f"PastoralStructure_{school_node.unique_id}",
path=pastoral_path
)
with self.neontology as neo:
# Create nodes
neo.create_or_merge_node(department_structure_node, database=str(database_name), operation='merge')
fs_handler.create_default_tldraw_file(department_structure_node.path, department_structure_node.to_dict())
neo.create_or_merge_node(curriculum_node, database=str(database_name), operation='merge')
fs_handler.create_default_tldraw_file(curriculum_node.path, curriculum_node.to_dict())
neo.create_or_merge_node(pastoral_node, database=database_name, operation='merge')
fs_handler.create_default_tldraw_file(pastoral_node.path, pastoral_node.to_dict())
# Create relationships
neo.create_or_merge_relationship(
entity_relationships.SchoolHasDepartmentStructure(source=school_node, target=department_structure_node),
database=database_name, operation='merge'
)
neo.create_or_merge_relationship(
entity_curriculum_rels.SchoolHasCurriculumStructure(source=school_node, target=curriculum_node),
database=database_name, operation='merge'
)
neo.create_or_merge_relationship(
entity_curriculum_rels.SchoolHasPastoralStructure(source=school_node, target=pastoral_node),
database=database_name, operation='merge'
)
return {
"status": "success",
"message": "Basic structure created successfully",
"nodes": {
"department_structure": department_structure_node,
"curriculum_structure": curriculum_node,
"pastoral_structure": pastoral_node
}
}
except Exception as e:
self.logger.error(f"Error creating basic structure: {str(e)}")
return {"status": "error", "message": str(e)}
def create_detailed_structure(self, school_node, database_name, excel_file):
"""Creates detailed structural nodes from Excel file"""
try:
# First, store the Excel file in Supabase
file_path = f"{school_node.urn}/structure.xlsx"
file_options = {
"content-type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"x-upsert": "true"
}
# Upload Excel file to storage
self.supabase.storage.from_("cc.institutes").upload(
path=file_path,
file=excel_file,
file_options=file_options
)
# Process Excel file
dataframes = xl.create_dataframes(excel_file)
# Get existing basic structure nodes
with self.neontology as neo:
result = neo.cypher_read("""
MATCH (s:School {unique_id: $school_id})
OPTIONAL MATCH (s)-[:HAS_DEPARTMENT_STRUCTURE]->(ds:DepartmentStructure)
OPTIONAL MATCH (s)-[:HAS_CURRICULUM_STRUCTURE]->(cs:CurriculumStructure)
OPTIONAL MATCH (s)-[:HAS_PASTORAL_STRUCTURE]->(ps:PastoralStructure)
RETURN ds, cs, ps
""", {"school_id": school_node.unique_id}, database=database_name)
if not result:
raise Exception("Basic structure not found")
department_structure = result['ds']
curriculum_structure = result['cs']
pastoral_structure = result['ps']
# Create departments and subjects
unique_departments = dataframes['keystagesyllabuses']['Department'].dropna().unique()
fs_handler = ClassroomCopilotFilesystem(database_name, init_run_type="school")
node_library = {}
with self.neontology as neo:
for department_name in unique_departments:
_, department_path = fs_handler.create_school_department_directory(school_node.path, department_name)
department_node = school_schemas.DepartmentNode(
unique_id=f"Department_{school_node.unique_id}_{department_name.replace(' ', '_')}",
department_name=department_name,
path=department_path
)
neo.create_or_merge_node(department_node, database=database_name, operation='merge')
fs_handler.create_default_tldraw_file(department_node.path, department_node.to_dict())
node_library[f'department_{department_name}'] = department_node
# Link to department structure
neo.create_or_merge_relationship(
entity_relationships.DepartmentStructureHasDepartment(
source=department_structure,
target=department_node
),
database=database_name,
operation='merge'
)
# Create year groups
year_groups = self.sort_year_groups(dataframes['yeargroupsyllabuses'])['YearGroup'].unique()
last_year_group_node = None
for year_group in year_groups:
numeric_year_group = pd.to_numeric(year_group, errors='coerce')
if pd.notna(numeric_year_group):
_, year_group_path = fs_handler.create_pastoral_year_group_directory(
pastoral_structure.path,
str(int(numeric_year_group))
)
year_group_node = pastoral_schemas.YearGroupNode(
unique_id=f"YearGroup_{school_node.unique_id}_YGrp{int(numeric_year_group)}",
year_group=str(int(numeric_year_group)),
year_group_name=f"Year {int(numeric_year_group)}",
path=year_group_path
)
neo.create_or_merge_node(year_group_node, database=database_name, operation='merge')
fs_handler.create_default_tldraw_file(year_group_node.path, year_group_node.to_dict())
node_library[f'year_group_{int(numeric_year_group)}'] = year_group_node
# Create sequential relationship
if last_year_group_node:
neo.create_or_merge_relationship(
curriculum_relationships.YearGroupFollowsYearGroup(
source=last_year_group_node,
target=year_group_node
),
database=database_name,
operation='merge'
)
last_year_group_node = year_group_node
# Link to pastoral structure
neo.create_or_merge_relationship(
curriculum_relationships.PastoralStructureIncludesYearGroup(
source=pastoral_structure,
target=year_group_node
),
database=database_name,
operation='merge'
)
# Create key stages
key_stages = dataframes['keystagesyllabuses']['KeyStage'].unique()
last_key_stage_node = None
for key_stage in sorted(key_stages):
_, key_stage_path = fs_handler.create_curriculum_key_stage_directory(
curriculum_structure.path,
str(key_stage)
)
key_stage_node = curriculum_schemas.KeyStageNode(
unique_id=f"KeyStage_{curriculum_structure.unique_id}_KStg{key_stage}",
key_stage_name=f"Key Stage {key_stage}",
key_stage=str(key_stage),
path=key_stage_path
)
neo.create_or_merge_node(key_stage_node, database=database_name, operation='merge')
fs_handler.create_default_tldraw_file(key_stage_node.path, key_stage_node.to_dict())
node_library[f'key_stage_{key_stage}'] = key_stage_node
# Create sequential relationship
if last_key_stage_node:
neo.create_or_merge_relationship(
curriculum_relationships.KeyStageFollowsKeyStage(
source=last_key_stage_node,
target=key_stage_node
),
database=database_name,
operation='merge'
)
last_key_stage_node = key_stage_node
# Link to curriculum structure
neo.create_or_merge_relationship(
curriculum_relationships.CurriculumStructureIncludesKeyStage(
source=curriculum_structure,
target=key_stage_node
),
database=database_name,
operation='merge'
)
return {
"status": "success",
"message": "Detailed structure created successfully",
"node_library": node_library
}
except Exception as e:
self.logger.error(f"Error creating detailed structure: {str(e)}")
return {"status": "error", "message": str(e)}
def sort_year_groups(self, df):
df = df.copy()
df['YearGroupNumeric'] = pd.to_numeric(df['YearGroup'], errors='coerce')
return df.sort_values(by='YearGroupNumeric')

View File

@ -1,54 +0,0 @@
import os
from modules.logger_tool import initialise_logger
import modules.database.tools.neo4j_driver_tools as driver_tools
import modules.database.tools.neo4j_session_tools as session_tools
import modules.database.tools.neontology_tools as neon
import modules.database.schemas.entities as neo_entity
import modules.database.schemas.nodes.schools.curriculum as curriculum_schemas
import modules.database.schemas.relationships.curriculum_relationships as curriculum_relationships
import modules.database.schemas.relationships.entity_relationships as ent_rels
import modules.database.schemas.relationships.entity_curriculum_rels as ent_cur_rels
import pandas as pd
class SchoolSyllabusProvider:
def __init__(self):
self.driver = driver_tools.get_driver()
self.logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
def process_syllabus_data(self, school_node, database_name, dataframes):
"""Process syllabus data from Excel file and create nodes in the database"""
try:
# This method will contain the syllabus-specific processing code from the
# original SchoolCurriculumProvider, starting from where the comment
# "# Curriculum specific database initialisation begins here" was placed
# We'll implement this in the next iteration after confirming the basic
# structure changes work correctly
return {
"status": "success",
"message": "Syllabus data processed successfully"
}
except Exception as e:
self.logger.error(f"Error processing syllabus data: {str(e)}")
return {"status": "error", "message": str(e)}
def check_syllabus_status(self, school_node, database_name):
"""Check if syllabus data exists in the database"""
try:
with self.driver.session(database=database_name) as session:
result = session.run("""
MATCH (s:School {unique_id: $school_id})
OPTIONAL MATCH (s)-[:HAS_CURRICULUM_STRUCTURE]->(:CurriculumStructure)-[:INCLUDES_KEY_STAGE]->(:KeyStage)-[:INCLUDES_KEY_STAGE_SYLLABUS]->(ks:KeyStageSyllabus)
OPTIONAL MATCH (s)-[:HAS_CURRICULUM_STRUCTURE]->(:CurriculumStructure)-[:INCLUDES_KEY_STAGE]->(:KeyStage)-[:INCLUDES_YEAR_GROUP_SYLLABUS]->(ys:YearGroupSyllabus)
RETURN count(ks) > 0 OR count(ys) > 0 as has_syllabus
""", school_id=school_node.unique_id)
has_syllabus = result.single()["has_syllabus"]
return {"has_syllabus": has_syllabus}
except Exception as e:
self.logger.error(f"Error checking syllabus status: {str(e)}")
raise

View File

@ -1,526 +0,0 @@
import os
from modules.logger_tool import initialise_logger
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
import modules.database.init.init_calendar as init_calendar
import modules.database.schemas.nodes.schools.timetable as timetable
import modules.database.schemas.relationships.timetables as tt_rels
import modules.database.schemas.relationships.entity_timetable_rels as entity_tt_rels
import modules.database.schemas.relationships.calendar_timetable_rels as cal_tt_rels
import modules.database.tools.neontology_tools as neon
from modules.database.tools.filesystem_tools import ClassroomCopilotFilesystem
from datetime import timedelta, datetime
import pandas as pd
def create_school_timetable_from_dataframes(dataframes, db_name, school_node=None):
logger.info(f"Creating school timetable for {db_name}")
if dataframes is None:
raise ValueError("Data is required to create the calendar and timetable.")
logger.info("Initialising neo4j connection...")
neon.init_neontology_connection()
# Initialize the filesystem handler
fs_handler = ClassroomCopilotFilesystem(db_name, init_run_type="school")
school_df = dataframes['school']
if school_node is None:
logger.info("School node is None, using school data from dataframe")
school_unique_id = school_df[school_df['Identifier'] == 'SchoolID']['Data'].iloc[0]
else:
logger.info(f"School node is not None, using school data from school node: {school_node}")
school_unique_id = school_node.unique_id
terms_df = dataframes['terms']
weeks_df = dataframes['weeks']
days_df = dataframes['days']
periods_df = dataframes['periods']
school_df_year_start = school_df[school_df['Identifier'] == 'AcademicYearStart']['Data'].iloc[0]
school_df_year_end = school_df[school_df['Identifier'] == 'AcademicYearEnd']['Data'].iloc[0]
if isinstance(school_df_year_start, str):
school_year_start_date = datetime.strptime(school_df_year_start, '%Y-%m-%d')
else:
school_year_start_date = school_df_year_start
if isinstance(school_df_year_end, str):
school_year_end_date = datetime.strptime(school_df_year_end, '%Y-%m-%d')
else:
school_year_end_date = school_df_year_end
# Create a dictionary to store the timetable nodes
timetable_nodes = {
'timetable_node': None,
'academic_year_nodes': [],
'academic_term_nodes': [],
'academic_week_nodes': [],
'academic_day_nodes': [],
'academic_period_nodes': []
}
if school_node:
# Create the root timetable directory
_, timetable_path = fs_handler.create_school_timetable_directory(school_node.path)
else:
# Create the root timetable directory
_, timetable_path = fs_handler.create_school_timetable_directory()
# Create AcademicTimetable Node
school_timetable_unique_id = f"SchoolTimetable_{school_unique_id}_{school_year_start_date.year}_{school_year_end_date.year}"
school_timetable_node = timetable.SchoolTimetableNode(
unique_id=school_timetable_unique_id,
start_date=school_year_start_date,
end_date=school_year_end_date,
path=timetable_path
)
neon.create_or_merge_neontology_node(school_timetable_node, database=db_name, operation='merge')
# Create the tldraw file for the node
fs_handler.create_default_tldraw_file(school_timetable_node.path, school_timetable_node.to_dict())
timetable_nodes['timetable_node'] = school_timetable_node
if school_node:
logger.info(f"Creating calendar for {school_unique_id} from Neo4j SchoolNode: {school_node.unique_id}")
calendar_nodes = init_calendar.create_calendar(db_name, school_year_start_date, school_year_end_date, attach_to_calendar_node=True, entity_node=school_node)
# Link the school node to the timetable node
neon.create_or_merge_neontology_relationship(
entity_tt_rels.SchoolHasTimetable(source=school_node, target=school_timetable_node),
database=db_name, operation='merge'
)
timetable_nodes['calendar_nodes'] = calendar_nodes
else:
logger.info(f"Creating calendar for {school_unique_id} from dataframe SchoolID: {school_unique_id}")
calendar_nodes = init_calendar.create_calendar(db_name, school_year_start_date, school_year_end_date, attach_to_calendar_node=False, entity_node=None)
# Create AcademicYear nodes for each year within the range
for year in range(school_year_start_date.year, school_year_end_date.year + 1):
_, timetable_year_path = fs_handler.create_school_timetable_year_directory(timetable_path, year)
year_str = str(year)
academic_year_unique_id = f"AcademicYear_{school_timetable_unique_id}_{year}"
academic_year_node = timetable.AcademicYearNode(
unique_id=academic_year_unique_id,
year=year_str,
path=timetable_year_path
)
neon.create_or_merge_neontology_node(academic_year_node, database=db_name, operation='merge')
# Create the tldraw file for the node
fs_handler.create_default_tldraw_file(academic_year_node.path, academic_year_node.to_dict())
timetable_nodes['academic_year_nodes'].append(academic_year_node)
logger.info(f'Created academic year node: {academic_year_node.unique_id}')
neon.create_or_merge_neontology_relationship(
tt_rels.AcademicTimetableHasAcademicYear(source=school_timetable_node, target=academic_year_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {school_timetable_node.unique_id} to {academic_year_node.unique_id}")
# Link the academic year with the corresponding calendar year node
for year_node in calendar_nodes['calendar_year_nodes']:
if year_node.year == year:
neon.create_or_merge_neontology_relationship(
cal_tt_rels.AcademicYearIsCalendarYear(source=academic_year_node, target=year_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {academic_year_node.unique_id} to {year_node.unique_id}")
break
# Create Term and TermBreak nodes linked to AcademicYear
term_number = 1
academic_term_number = 1
for _, term_row in terms_df.iterrows():
term_node_class = timetable.AcademicTermNode if term_row['TermType'] == 'Term' else timetable.AcademicTermBreakNode
term_name = term_row['TermName']
term_name_no_spaces = term_name.replace(' ', '')
term_start_date = term_row['StartDate']
if isinstance(term_start_date, pd.Timestamp):
term_start_date = term_start_date.strftime('%Y-%m-%d')
term_end_date = term_row['EndDate']
if isinstance(term_end_date, pd.Timestamp):
term_end_date = term_end_date.strftime('%Y-%m-%d')
if term_row['TermType'] == 'Term':
_, timetable_term_path = fs_handler.create_school_timetable_academic_term_directory(
timetable_path=timetable_path,
term_name=term_name,
term_number=academic_term_number
)
term_node_unique_id = f"AcademicTerm_{school_timetable_unique_id}_{academic_term_number}_{term_name_no_spaces}"
academic_term_number_str = str(academic_term_number)
term_node = term_node_class(
unique_id=term_node_unique_id,
term_name=term_name,
term_number=academic_term_number_str,
start_date=datetime.strptime(term_start_date, '%Y-%m-%d'),
end_date=datetime.strptime(term_end_date, '%Y-%m-%d'),
path=timetable_term_path
)
academic_term_number += 1
else:
term_break_node_unique_id = f"AcademicTermBreak_{school_timetable_unique_id}_{term_name_no_spaces}"
term_node = term_node_class(
unique_id=term_break_node_unique_id,
term_break_name=term_name,
start_date=datetime.strptime(term_start_date, '%Y-%m-%d'),
end_date=datetime.strptime(term_end_date, '%Y-%m-%d')
)
neon.create_or_merge_neontology_node(term_node, database=db_name, operation='merge')
if isinstance(term_node, timetable.AcademicTermNode):
# Create the tldraw file for the node
fs_handler.create_default_tldraw_file(term_node.path, term_node.to_dict())
logger.info(f'Created academic term break node: {term_node.unique_id}')
timetable_nodes['academic_term_nodes'].append(term_node)
term_number += 1 # We don't use this but we could
# Link term node to the correct academic year
term_years = set()
term_years.update([term_node.start_date.year, term_node.end_date.year])
for academic_year_node in timetable_nodes['academic_year_nodes']:
if int(academic_year_node.year) in term_years:
relationship_class = tt_rels.AcademicYearHasAcademicTerm if term_row['TermType'] == 'Term' else tt_rels.AcademicYearHasAcademicTermBreak
neon.create_or_merge_neontology_relationship(
relationship_class(source=academic_year_node, target=term_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {academic_year_node.unique_id} to {term_node.unique_id}")
# Create Week nodes
academic_week_number = 1
for _, week_row in weeks_df.iterrows():
week_node_class = timetable.HolidayWeekNode if week_row['WeekType'] == 'Holiday' else timetable.AcademicWeekNode
week_start_date = week_row['WeekStart']
if isinstance(week_start_date, pd.Timestamp):
week_start_date = week_start_date.strftime('%Y-%m-%d')
if week_row['WeekType'] == 'Holiday':
week_node_unique_id = f"{week_row['WeekType']}Week_{school_timetable_unique_id}_Week_{week_row['WeekNumber']}"
week_node = week_node_class(
unique_id=week_node_unique_id,
start_date=datetime.strptime(week_start_date, '%Y-%m-%d')
)
else:
_, timetable_week_path = fs_handler.create_school_timetable_academic_week_directory(
timetable_path=timetable_path,
week_number=academic_week_number
)
week_node_unique_id = f"AcademicWeek_{school_timetable_unique_id}_Week_{week_row['WeekNumber']}"
academic_week_number_str = str(academic_week_number)
week_type = week_row['WeekType']
week_node = week_node_class(
unique_id=week_node_unique_id,
academic_week_number=academic_week_number_str,
start_date=datetime.strptime(week_start_date, '%Y-%m-%d'),
week_type=week_type,
path=timetable_week_path
)
academic_week_number += 1
neon.create_or_merge_neontology_node(week_node, database=db_name, operation='merge')
timetable_nodes['academic_week_nodes'].append(week_node)
logger.info(f"Created week node: {week_node.unique_id}")
if isinstance(week_node, timetable.AcademicWeekNode):
# Create the tldraw file for the node
fs_handler.create_default_tldraw_file(week_node.path, week_node.to_dict())
for calendar_node in calendar_nodes['calendar_week_nodes']:
if calendar_node.start_date == week_node.start_date:
if isinstance(week_node, timetable.AcademicWeekNode):
neon.create_or_merge_neontology_relationship(
cal_tt_rels.AcademicWeekIsCalendarWeek(source=week_node, target=calendar_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {calendar_node.unique_id} to {week_node.unique_id}")
elif isinstance(week_node, timetable.HolidayWeekNode):
neon.create_or_merge_neontology_relationship(
cal_tt_rels.HolidayWeekIsCalendarWeek(source=week_node, target=calendar_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {calendar_node.unique_id} to {week_node.unique_id}")
break
# Link week node to the correct academic term
for term_node in timetable_nodes['academic_term_nodes']:
if term_node.start_date <= week_node.start_date <= term_node.end_date:
relationship_class = tt_rels.AcademicTermHasAcademicWeek if week_row['WeekType'] != 'Holiday' else tt_rels.AcademicTermBreakHasHolidayWeek
neon.create_or_merge_neontology_relationship(
relationship_class(source=term_node, target=week_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {term_node.unique_id} to {week_node.unique_id}")
break
# Link week node to the correct academic year
for academic_year_node in timetable_nodes['academic_year_nodes']:
if int(academic_year_node.year) == week_node.start_date.year:
relationship_class = tt_rels.AcademicYearHasAcademicWeek if week_row['WeekType'] != 'Holiday' else tt_rels.AcademicYearHasHolidayWeek
neon.create_or_merge_neontology_relationship(
relationship_class(source=academic_year_node, target=week_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {academic_year_node.unique_id} to {week_node.unique_id}")
break
# Create Day nodes
day_number = 1
academic_day_number = 1
for _, day_row in days_df.iterrows():
date_str = day_row['Date']
if isinstance(date_str, pd.Timestamp):
date_str = date_str.strftime('%Y-%m-%d')
day_node_class = {
'Academic': timetable.AcademicDayNode,
'Holiday': timetable.HolidayDayNode,
'OffTimetable': timetable.OffTimetableDayNode,
'StaffDay': timetable.StaffDayNode
}[day_row['DayType']]
# Format the unique ID as {day_node_class.__name__}Day
day_node_data = {
'unique_id': f"{day_node_class.__name__}Day_{school_timetable_unique_id}_{day_number}",
'date': datetime.strptime(date_str, '%Y-%m-%d'),
'day_of_week': datetime.strptime(date_str, '%Y-%m-%d').strftime('%A')
}
if day_row['DayType'] == 'Academic':
day_node_data['academic_day'] = str(academic_day_number)
day_node_data['day_type'] = day_row['WeekType']
_, timetable_day_path = fs_handler.create_school_timetable_academic_day_directory(
timetable_path=timetable_path,
academic_day=academic_day_number
)
day_node_data['path'] = timetable_day_path
day_node = day_node_class(**day_node_data)
for calendar_node in calendar_nodes['calendar_day_nodes']:
if calendar_node.date == day_node.date:
neon.create_or_merge_neontology_node(day_node, database=db_name, operation='merge')
timetable_nodes['academic_day_nodes'].append(day_node)
logger.info(f"Created day node: {day_node.unique_id}")
if isinstance(day_node, timetable.AcademicDayNode):
fs_handler.create_default_tldraw_file(day_node.path, day_node.to_dict())
relationship_class = cal_tt_rels.AcademicDayIsCalendarDay
elif isinstance(day_node, timetable.HolidayDayNode):
relationship_class = cal_tt_rels.HolidayDayIsCalendarDay
elif isinstance(day_node, timetable.OffTimetableDayNode):
relationship_class = cal_tt_rels.OffTimetableDayIsCalendarDay
elif isinstance(day_node, timetable.StaffDayNode):
relationship_class = cal_tt_rels.StaffDayIsCalendarDay
neon.create_or_merge_neontology_relationship(
relationship_class(source=day_node, target=calendar_node),
database=db_name, operation='merge'
)
logger.info(f'Created relationship from {calendar_node.unique_id} to {day_node.unique_id}')
break
# Link day node to the correct academic week
for academic_week_node in timetable_nodes['academic_week_nodes']:
if academic_week_node.start_date <= day_node.date <= (academic_week_node.start_date + timedelta(days=6)):
if day_row['DayType'] == 'Academic':
relationship_class = tt_rels.AcademicWeekHasAcademicDay
elif day_row['DayType'] == 'Holiday':
if hasattr(academic_week_node, 'week_type') and academic_week_node.week_type in ['A', 'B']:
relationship_class = tt_rels.AcademicWeekHasHolidayDay
else:
relationship_class = tt_rels.HolidayWeekHasHolidayDay
elif day_row['DayType'] == 'OffTimetable':
relationship_class = tt_rels.AcademicWeekHasOffTimetableDay
elif day_row['DayType'] == 'Staff':
relationship_class = tt_rels.AcademicWeekHasStaffDay
else:
continue # Skip linking for other day types
neon.create_or_merge_neontology_relationship(
relationship_class(source=academic_week_node, target=day_node),
database=db_name, operation='merge'
)
logger.info(f"Created relationship from {academic_week_node.unique_id} to {day_node.unique_id}")
break
# Link day node to the correct academic term
for term_node in timetable_nodes['academic_term_nodes']:
if term_node.start_date <= day_node.date <= term_node.end_date:
if day_row['DayType'] == 'Academic':
relationship_class = tt_rels.AcademicTermHasAcademicDay
elif day_row['DayType'] == 'Holiday':
if isinstance(term_node, timetable.AcademicTermNode):
relationship_class = tt_rels.AcademicTermHasHolidayDay
else:
relationship_class = tt_rels.AcademicTermBreakHasHolidayDay
elif day_row['DayType'] == 'OffTimetable':
relationship_class = tt_rels.AcademicTermHasOffTimetableDay
elif day_row['DayType'] == 'Staff':
relationship_class = tt_rels.AcademicTermHasStaffDay
else:
continue # Skip linking for other day types
neon.create_or_merge_neontology_relationship(
relationship_class(source=term_node, target=day_node),
database=db_name, operation='merge'
)
logger.info(f"Created relationship from {term_node.unique_id} to {day_node.unique_id}")
break
# Create Period nodes for each academic day
if day_row['DayType'] == 'Academic':
logger.info(f"Creating periods for {day_node.unique_id}")
period_of_day = 1
academic_or_registration_period_of_day = 1
for _, period_row in periods_df.iterrows():
period_node_class = {
'Academic': timetable.AcademicPeriodNode,
'Registration': timetable.RegistrationPeriodNode,
'Break': timetable.BreakPeriodNode,
'OffTimetable': timetable.OffTimetablePeriodNode
}[period_row['PeriodType']]
logger.info(f"Creating period node for {period_node_class.__name__} Period: {period_of_day}")
period_node_unique_id = f"{period_node_class.__name__}_{school_timetable_unique_id}_Day_{academic_day_number}_Period_{period_of_day}"
logger.debug(f"Period node unique id: {period_node_unique_id}")
period_node_data = {
'unique_id': period_node_unique_id,
'name': period_row['PeriodName'],
'date': day_node.date,
'start_time': datetime.combine(day_node.date, period_row['StartTime']),
'end_time': datetime.combine(day_node.date, period_row['EndTime'])
}
logger.debug(f"Period node data: {period_node_data}")
if period_row['PeriodType'] in ['Academic', 'Registration']:
_, timetable_period_path = fs_handler.create_school_timetable_period_directory(
timetable_path=timetable_path,
academic_day=academic_day_number,
period_dir=f"{academic_or_registration_period_of_day}_{period_row['PeriodName'].replace(' ', '_')}"
)
week_type = day_row['WeekType']
day_name_short = day_node.day_of_week[:3]
period_code = period_row['PeriodCode']
period_code_formatted = f"{week_type}{day_name_short}{period_code}"
period_node_data['period_code'] = period_code_formatted
period_node_data['path'] = timetable_period_path
academic_or_registration_period_of_day += 1
period_node = period_node_class(**period_node_data)
neon.create_or_merge_neontology_node(period_node, database=db_name, operation='merge')
if isinstance(period_node, timetable.AcademicPeriodNode) or isinstance(period_node, timetable.RegistrationPeriodNode):
# Create the tldraw file for the node
fs_handler.create_default_tldraw_file(period_node.path, period_node.to_dict())
timetable_nodes['academic_period_nodes'].append(period_node)
logger.info(f'Created period node: {period_node.unique_id}')
relationship_class = {
'Academic': tt_rels.AcademicDayHasAcademicPeriod,
'Registration': tt_rels.AcademicDayHasRegistrationPeriod,
'Break': tt_rels.AcademicDayHasBreakPeriod,
'OffTimetable': tt_rels.AcademicDayHasOffTimetablePeriod
}[period_row['PeriodType']]
neon.create_or_merge_neontology_relationship(
relationship_class(source=day_node, target=period_node),
database=db_name, operation='merge'
)
logger.info(f"Created relationship from {day_node.unique_id} to {period_node.unique_id}")
period_of_day += 1 # We don't use this but we could
academic_day_number += 1 # This is a bit of a hack but it works to keep the directories aligned (reorganise)
day_number += 1 # We don't use this but we could
def create_school_timetable_node_sequence_rels(timetable_nodes):
def sort_and_create_relationships(nodes, relationship_map, sort_key):
sorted_nodes = sorted(nodes, key=sort_key)
for i in range(len(sorted_nodes) - 1):
source_node = sorted_nodes[i]
target_node = sorted_nodes[i + 1]
node_type_pair = (type(source_node), type(target_node))
relationship_class = relationship_map.get(node_type_pair)
if relationship_class:
# Avoid self-referential relationships
if source_node.unique_id != target_node.unique_id:
neon.create_or_merge_neontology_relationship(
relationship_class(
source=source_node,
target=target_node
),
database=db_name, operation='merge'
)
logger.info(f"Created relationship from {source_node.unique_id} to {target_node.unique_id}")
else:
logger.warning(f"Skipped self-referential relationship for node {source_node.unique_id}")
# Relationship maps for different node types
academic_year_relationship_map = {
(timetable.AcademicYearNode, timetable.AcademicYearNode): tt_rels.AcademicYearFollowsAcademicYear
}
academic_term_relationship_map = {
(timetable.AcademicTermNode, timetable.AcademicTermBreakNode): tt_rels.AcademicTermBreakFollowsAcademicTerm,
(timetable.AcademicTermBreakNode, timetable.AcademicTermNode): tt_rels.AcademicTermFollowsAcademicTermBreak
}
academic_week_relationship_map = {
(timetable.AcademicWeekNode, timetable.AcademicWeekNode): tt_rels.AcademicWeekFollowsAcademicWeek,
(timetable.HolidayWeekNode, timetable.HolidayWeekNode): tt_rels.HolidayWeekFollowsHolidayWeek,
(timetable.AcademicWeekNode, timetable.HolidayWeekNode): tt_rels.HolidayWeekFollowsAcademicWeek,
(timetable.HolidayWeekNode, timetable.AcademicWeekNode): tt_rels.AcademicWeekFollowsHolidayWeek
}
academic_day_relationship_map = {
(timetable.AcademicDayNode, timetable.AcademicDayNode): tt_rels.AcademicDayFollowsAcademicDay,
(timetable.HolidayDayNode, timetable.HolidayDayNode): tt_rels.HolidayDayFollowsHolidayDay,
(timetable.OffTimetableDayNode, timetable.OffTimetableDayNode): tt_rels.OffTimetableDayFollowsOffTimetableDay,
(timetable.StaffDayNode, timetable.StaffDayNode): tt_rels.StaffDayFollowsStaffDay,
(timetable.AcademicDayNode, timetable.HolidayDayNode): tt_rels.HolidayDayFollowsAcademicDay,
(timetable.AcademicDayNode, timetable.OffTimetableDayNode): tt_rels.OffTimetableDayFollowsAcademicDay,
(timetable.AcademicDayNode, timetable.StaffDayNode): tt_rels.StaffDayFollowsAcademicDay,
(timetable.HolidayDayNode, timetable.AcademicDayNode): tt_rels.AcademicDayFollowsHolidayDay,
(timetable.HolidayDayNode, timetable.OffTimetableDayNode): tt_rels.OffTimetableDayFollowsHolidayDay,
(timetable.HolidayDayNode, timetable.StaffDayNode): tt_rels.StaffDayFollowsHolidayDay,
(timetable.OffTimetableDayNode, timetable.AcademicDayNode): tt_rels.AcademicDayFollowsOffTimetableDay,
(timetable.OffTimetableDayNode, timetable.HolidayDayNode): tt_rels.HolidayDayFollowsOffTimetableDay,
(timetable.OffTimetableDayNode, timetable.StaffDayNode): tt_rels.StaffDayFollowsOffTimetableDay,
(timetable.StaffDayNode, timetable.AcademicDayNode): tt_rels.AcademicDayFollowsStaffDay,
(timetable.StaffDayNode, timetable.HolidayDayNode): tt_rels.HolidayDayFollowsStaffDay,
(timetable.StaffDayNode, timetable.OffTimetableDayNode): tt_rels.OffTimetableDayFollowsStaffDay,
}
academic_period_relationship_map = {
(timetable.AcademicPeriodNode, timetable.AcademicPeriodNode): tt_rels.AcademicPeriodFollowsAcademicPeriod,
(timetable.AcademicPeriodNode, timetable.BreakPeriodNode): tt_rels.BreakPeriodFollowsAcademicPeriod,
(timetable.AcademicPeriodNode, timetable.RegistrationPeriodNode): tt_rels.RegistrationPeriodFollowsAcademicPeriod,
(timetable.AcademicPeriodNode, timetable.OffTimetablePeriodNode): tt_rels.OffTimetablePeriodFollowsAcademicPeriod,
(timetable.BreakPeriodNode, timetable.AcademicPeriodNode): tt_rels.AcademicPeriodFollowsBreakPeriod,
(timetable.BreakPeriodNode, timetable.BreakPeriodNode): tt_rels.BreakPeriodFollowsBreakPeriod,
(timetable.BreakPeriodNode, timetable.RegistrationPeriodNode): tt_rels.RegistrationPeriodFollowsBreakPeriod,
(timetable.BreakPeriodNode, timetable.OffTimetablePeriodNode): tt_rels.OffTimetablePeriodFollowsBreakPeriod,
(timetable.RegistrationPeriodNode, timetable.AcademicPeriodNode): tt_rels.AcademicPeriodFollowsRegistrationPeriod,
(timetable.RegistrationPeriodNode, timetable.RegistrationPeriodNode): tt_rels.RegistrationPeriodFollowsRegistrationPeriod,
(timetable.RegistrationPeriodNode, timetable.BreakPeriodNode): tt_rels.BreakPeriodFollowsRegistrationPeriod,
(timetable.RegistrationPeriodNode, timetable.OffTimetablePeriodNode): tt_rels.OffTimetablePeriodFollowsRegistrationPeriod,
(timetable.OffTimetablePeriodNode, timetable.OffTimetablePeriodNode): tt_rels.OffTimetablePeriodFollowsOffTimetablePeriod,
(timetable.OffTimetablePeriodNode, timetable.AcademicPeriodNode): tt_rels.AcademicPeriodFollowsOffTimetablePeriod,
(timetable.OffTimetablePeriodNode, timetable.BreakPeriodNode): tt_rels.BreakPeriodFollowsOffTimetablePeriod,
(timetable.OffTimetablePeriodNode, timetable.RegistrationPeriodNode): tt_rels.RegistrationPeriodFollowsOffTimetablePeriod,
}
# Sort and create relationships
sort_and_create_relationships(timetable_nodes['academic_year_nodes'], academic_year_relationship_map, lambda x: int(x.year))
sort_and_create_relationships(timetable_nodes['academic_term_nodes'], academic_term_relationship_map, lambda x: x.start_date)
sort_and_create_relationships(timetable_nodes['academic_week_nodes'], academic_week_relationship_map, lambda x: x.start_date)
sort_and_create_relationships(timetable_nodes['academic_day_nodes'], academic_day_relationship_map, lambda x: x.date)
sort_and_create_relationships(timetable_nodes['academic_period_nodes'], academic_period_relationship_map, lambda x: (x.start_time, x.end_time))
# Call the function with the created timetable nodes
create_school_timetable_node_sequence_rels(timetable_nodes)
logger.info(f'Created timetable: {timetable_nodes["timetable_node"].unique_id}')
# Log the directory structure after creation
# root_timetable_directory = fs_handler.root_path # Access the root directory of the filesystem handler
# fs_handler.log_directory_structure(root_timetable_directory)
return {
'school_node': school_node,
'school_calendar_nodes': calendar_nodes,
'school_timetable_nodes': timetable_nodes
}

View File

@ -4,12 +4,25 @@ logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH
import modules.database.schemas.nodes.calendars as calendar_schemas
import modules.database.schemas.relationships.calendars as calendar_relationships
import modules.database.schemas.relationships.calendar_sequence as calendar_sequence_relationships
import modules.database.schemas.relationships.owner_relationships as owner_relationships
import modules.database.tools.supabase_storage_tools as storage_tools
import modules.database.tools.neontology_tools as neon
from datetime import timedelta, datetime
def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False, owner_node=None, time_chunk_node_length: int = None):
logger.info(f"Creating calendar for {start_date} to {end_date}")
def create_calendar(db_name, start_date, end_date, time_chunk_node_length: int = None, storage_tools=None):
"""
Create calendar structure with years, months, weeks, and days
Args:
db_name: Database name to create calendar in
start_date: Start date for calendar
end_date: End date for calendar
time_chunk_node_length: Optional time chunk length in minutes
storage_tools: Optional Supabase storage tools for generating storage paths
Returns:
dict: Dictionary containing created calendar nodes
"""
logger.info(f"Creating calendar structure for {start_date} to {end_date} in database: {db_name}")
logger.info(f"Initializing Neontology connection")
neon.init_neontology_connection()
@ -25,52 +38,13 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
last_day_node = None
calendar_nodes = {
'calendar_node': None,
'calendar_year_nodes': [],
'calendar_month_nodes': [],
'calendar_week_nodes': [],
'calendar_day_nodes': []
'calendar_day_nodes': [],
'calendar_time_chunk_nodes': []
}
if attach_to_calendar_node and owner_node:
logger.info(f"Attaching calendar to owner's node {owner_node.unique_id} in database: {db_name}")
owner_unique_id = owner_node.unique_id
calendar_unique_id = f"{start_date.strftime('%Y-%m-%d')}_{end_date.strftime('%Y-%m-%d')}"
calendar_node = calendar_schemas.CalendarNode(
unique_id=calendar_unique_id,
name=f"{start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}",
start_date=start_date,
end_date=end_date,
tldraw_snapshot=""
)
neon.create_or_merge_neontology_node(calendar_node, database=db_name, operation='merge')
calendar_nodes['calendar_node'] = calendar_node
logger.info(f"Calendar node created: {calendar_node.unique_id}")
import modules.database.schemas.relationships.owner_relationships as owner_relationships
neon.create_or_merge_neontology_relationship(
owner_relationships.OwnerHasCalendar(source=owner_node, target=calendar_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {owner_node.unique_id} to {calendar_node.unique_id}")
elif attach_to_calendar_node and not owner_node:
logger.info(f"Creating calendar for {start_date} to {end_date} in database: {db_name}")
calendar_node = calendar_schemas.CalendarNode(
unique_id=f"{start_date.strftime('%Y-%m-%d')}_{end_date.strftime('%Y-%m-%d')}",
name=f"{start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}",
start_date=start_date,
end_date=end_date,
tldraw_snapshot=""
)
neon.create_or_merge_neontology_node(calendar_node, database=db_name, operation='merge')
calendar_nodes['calendar_node'] = calendar_node
logger.info(f"Calendar node created: {calendar_node.unique_id}")
else:
logger.error("Invalid combination of parameters for calendar creation.")
raise ValueError("Invalid combination of parameters for calendar creation.")
current_date = start_date
while current_date <= end_date:
year = current_date.year
@ -78,50 +52,55 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
day = current_date.day
iso_year, iso_week, iso_weekday = current_date.isocalendar()
calendar_year_unique_id = f"{year}"
calendar_year_uuid_string = f"{year}"
if year not in created_years:
# Generate storage path for year node using Supabase Storage
if storage_tools:
year_dir_created, node_storage_path = storage_tools.create_calendar_year_storage_path(year)
else:
node_storage_path = ""
year_node = calendar_schemas.CalendarYearNode(
unique_id=calendar_year_unique_id,
uuid_string=calendar_year_uuid_string,
year=str(year),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(year_node, database=db_name, operation='merge')
calendar_nodes['calendar_year_nodes'].append(year_node)
created_years[year] = year_node
logger.info(f"Year node created: {year_node.unique_id}")
logger.info(f"Year node created: {year_node.uuid_string}")
if attach_to_calendar_node:
neon.create_or_merge_neontology_relationship(
calendar_relationships.CalendarIncludesYear(source=calendar_node, target=year_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {calendar_node.unique_id} to {year_node.unique_id}")
if last_year_node:
neon.create_or_merge_neontology_relationship(
calendar_sequence_relationships.YearFollowsYear(source=last_year_node, target=year_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_year_node.unique_id} to {year_node.unique_id}")
logger.info(f"Relationship created from {last_year_node.uuid_string} to {year_node.uuid_string}")
last_year_node = year_node
calendar_month_unique_id = f"{year}_{month}"
calendar_month_uuid_string = f"{year}_{month}"
month_key = f"{year}-{month}"
if month_key not in created_months:
# Generate storage path for month node using Supabase Storage
if storage_tools:
month_dir_created, node_storage_path = storage_tools.create_calendar_month_storage_path(year, month)
else:
node_storage_path = ""
month_node = calendar_schemas.CalendarMonthNode(
unique_id=calendar_month_unique_id,
uuid_string=calendar_month_uuid_string,
year=str(year),
month=str(month),
month_name=datetime(year, month, 1).strftime('%B'),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(month_node, database=db_name, operation='merge')
calendar_nodes['calendar_month_nodes'].append(month_node)
created_months[month_key] = month_node
logger.info(f"Month node created: {month_node.unique_id}")
logger.info(f"Month node created: {month_node.uuid_string}")
# Check for the end of year transition for months
if last_month_node:
@ -131,14 +110,14 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_month_node.unique_id} to {month_node.unique_id}")
logger.info(f"Relationship created from {last_month_node.uuid_string} to {month_node.uuid_string}")
elif int(month) == int(last_month_node.month) + 1:
neon.create_or_merge_neontology_relationship(
calendar_sequence_relationships.MonthFollowsMonth(source=last_month_node, target=month_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_month_node.unique_id} to {month_node.unique_id}")
logger.info(f"Relationship created from {last_month_node.uuid_string} to {month_node.uuid_string}")
last_month_node = month_node
neon.create_or_merge_neontology_relationship(
@ -146,25 +125,31 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {year_node.unique_id} to {month_node.unique_id}")
logger.info(f"Relationship created from {year_node.uuid_string} to {month_node.uuid_string}")
calendar_week_unique_id = f"{iso_year}_{iso_week}"
calendar_week_uuid_string = f"{iso_year}_{iso_week}"
week_key = f"{iso_year}-W{iso_week}"
if week_key not in created_weeks:
# Get the date of the first monday of the week
week_start_date = current_date - timedelta(days=current_date.weekday())
# Generate storage path for week node using Supabase Storage
if storage_tools:
week_dir_created, node_storage_path = storage_tools.create_calendar_week_storage_path(iso_year, iso_week)
else:
node_storage_path = ""
week_node = calendar_schemas.CalendarWeekNode(
unique_id=calendar_week_unique_id,
uuid_string=calendar_week_uuid_string,
start_date=week_start_date,
week_number=str(iso_week),
iso_week=f"{iso_year}-W{iso_week:02}",
tldraw_snapshot=""
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(week_node, database=db_name, operation='merge')
calendar_nodes['calendar_week_nodes'].append(week_node)
created_weeks[week_key] = week_node
logger.info(f"Week node created: {week_node.unique_id}")
logger.info(f"Week node created: {week_node.uuid_string}")
if last_week_node and ((last_week_node.iso_week.split('-')[0] == str(iso_year) and int(last_week_node.week_number) == int(iso_week) - 1) or
(last_week_node.iso_week.split('-')[0] != str(iso_year) and int(last_week_node.week_number) == 52 and int(iso_week) == 1)):
@ -173,7 +158,7 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_week_node.unique_id} to {week_node.unique_id}")
logger.info(f"Relationship created from {last_week_node.uuid_string} to {week_node.uuid_string}")
last_week_node = week_node
neon.create_or_merge_neontology_relationship(
@ -181,23 +166,32 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {year_node.unique_id} to {week_node.unique_id}")
logger.info(f"Relationship created from {year_node.uuid_string} to {week_node.uuid_string}")
# Day node management
calendar_day_unique_id = f"{year}_{month}_{day}"
calendar_day_uuid_string = f"{year}_{month}_{day}"
day_key = f"{year}-{month}-{day}"
# Generate storage path for day node using Supabase Storage
if storage_tools:
day_dir_created, node_storage_path = storage_tools.create_calendar_day_storage_path(year, month, day)
# Store day path for later use in time chunks
created_days[day_key] = {'node': None, 'path': node_storage_path}
else:
node_storage_path = ""
created_days[day_key] = {'node': None, 'path': None}
day_node = calendar_schemas.CalendarDayNode(
unique_id=calendar_day_unique_id,
uuid_string=calendar_day_uuid_string,
date=current_date,
day_of_week=current_date.strftime('%A'),
iso_day=f"{year}-{month:02}-{day:02}",
tldraw_snapshot=""
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(day_node, database=db_name, operation='merge')
calendar_nodes['calendar_day_nodes'].append(day_node)
created_days[day_key] = day_node
logger.info(f"Day node created: {day_node.unique_id}")
created_days[day_key]['node'] = day_node
logger.info(f"Day node created: {day_node.uuid_string}")
if last_day_node:
neon.create_or_merge_neontology_relationship(
@ -205,7 +199,7 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {last_day_node.unique_id} to {day_node.unique_id}")
logger.info(f"Relationship created from {last_day_node.uuid_string} to {day_node.uuid_string}")
last_day_node = day_node
neon.create_or_merge_neontology_relationship(
@ -213,13 +207,13 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {month_node.unique_id} to {day_node.unique_id}")
logger.info(f"Relationship created from {month_node.uuid_string} to {day_node.uuid_string}")
neon.create_or_merge_neontology_relationship(
calendar_relationships.WeekIncludesDay(source=week_node, target=day_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {week_node.unique_id} to {day_node.unique_id}")
logger.info(f"Relationship created from {week_node.uuid_string} to {day_node.uuid_string}")
current_date += timedelta(days=1)
if time_chunk_node_length:
@ -228,25 +222,32 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
for day_node in calendar_nodes['calendar_day_nodes']:
total_time_chunks_in_day = (24 * 60) / time_chunk_interval
for i in range(total_time_chunks_in_day):
time_chunk_unique_id = f"{day_node.unique_id}_{i}"
time_chunk_uuid_string = f"{day_node.uuid_string}_{i}"
time_chunk_start_time = day_node.date.time() + timedelta(minutes=i * time_chunk_interval)
time_chunk_end_time = time_chunk_start_time + timedelta(minutes=time_chunk_interval)
# Generate storage path for time chunk node using Supabase Storage
if storage_tools:
chunk_id = f"{day_node.uuid_string}_{i:02d}"
chunk_dir_created, node_storage_path = storage_tools.create_calendar_time_chunk_storage_path(day_node.uuid_string, i)
else:
node_storage_path = ""
time_chunk_node = calendar_schemas.CalendarTimeChunkNode(
unique_id=time_chunk_unique_id,
uuid_string=time_chunk_uuid_string,
start_time=time_chunk_start_time,
end_time=time_chunk_end_time,
tldraw_snapshot=""
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(time_chunk_node, database=db_name, operation='merge')
calendar_nodes['calendar_time_chunk_nodes'].append(time_chunk_node)
logger.info(f"Time chunk node created: {time_chunk_node.unique_id}")
logger.info(f"Time chunk node created: {time_chunk_node.uuid_string}")
# Create a relationship between the time chunk node and the day node
neon.create_or_merge_neontology_relationship(
calendar_relationships.DayIncludesTimeChunk(source=day_node, target=time_chunk_node),
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {day_node.unique_id} to {time_chunk_node.unique_id}")
logger.info(f"Relationship created from {day_node.uuid_string} to {time_chunk_node.uuid_string}")
# Create sequential relationship between the time chunk nodes
if i > 0:
neon.create_or_merge_neontology_relationship(
@ -254,7 +255,7 @@ def create_calendar(db_name, start_date, end_date, attach_to_calendar_node=False
database=db_name,
operation='merge'
)
logger.info(f"Relationship created from {calendar_nodes['calendar_time_chunk_nodes'][i-1].unique_id} to {time_chunk_node.unique_id}")
logger.info(f"Relationship created from {calendar_nodes['calendar_time_chunk_nodes'][i-1].uuid_string} to {time_chunk_node.uuid_string}")
logger.info(f'Created calendar: {calendar_nodes["calendar_node"].unique_id}')
logger.info(f'Calendar structure created successfully for {start_date} to {end_date}')
return calendar_nodes

View File

@ -2,115 +2,31 @@ import os
from modules.logger_tool import initialise_logger
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
from modules.database.schemas.nodes.schools.schools import SchoolNode
from modules.database.supabase.utils.client import SupabaseServiceRoleClient, CreateBucketOptions
import modules.database.init.init_school_timetable as init_school_timetable
import modules.database.tools.neontology_tools as neon
import modules.database.tools.supabase_storage_tools as storage_tools
def create_school_buckets(school_id: str, school_type: str, school_name: str, admin_access_token: str) -> dict:
"""Create storage buckets for a school
Args:
school_id: The unique identifier for the school
school_type: The type of school (e.g., 'development')
school_name: The display name of the school
admin_access_token: The admin access token for Supabase operations
Returns:
Dictionary containing results of bucket creation operations
"""
logger.info(f"Creating storage buckets for school {school_name} ({school_type}/{school_id})")
def create_school(db_name: str, uuid_string: str, name: str, website: str, school_type: str, is_public: bool = True, school_node: SchoolNode | None = None, dataframes=None):
if not name or not uuid_string or not website or not school_type:
logger.error("School name, uuid_string, website and school_type are required to create a school.")
raise ValueError("School name, uuid_string, website and school_type are required to create a school.")
storage_client = SupabaseServiceRoleClient.for_admin(admin_access_token)
base_path = f"cc.institutes.{school_type}.{school_id}"
buckets = [
# Main school buckets
{
"id": f"{base_path}.public",
"options": CreateBucketOptions(
name=f"{school_type.title()} School Files - {school_name} - Public Files",
public=True,
file_size_limit=50 * 1024 * 1024,
allowed_mime_types=[
'image/*', 'video/*', 'application/pdf',
'application/msword', 'application/vnd.openxmlformats-officedocument.*',
'text/plain', 'text/csv', 'application/json'
]
)
},
{
"id": f"{base_path}.private",
"options": CreateBucketOptions(
name=f"{school_type.title()} School Files - {school_name} - Private Files",
public=False,
file_size_limit=50 * 1024 * 1024,
allowed_mime_types=[
'image/*', 'video/*', 'application/pdf',
'application/msword', 'application/vnd.openxmlformats-officedocument.*',
'text/plain', 'text/csv', 'application/json'
]
)
},
# Curriculum buckets
{
"id": f"{base_path}.curriculum.public",
"options": CreateBucketOptions(
name=f"{school_type.title()} School Files - {school_name} - Curriculum Public Files",
public=True,
file_size_limit=50 * 1024 * 1024,
allowed_mime_types=[
'image/*', 'video/*', 'application/pdf',
'application/msword', 'application/vnd.openxmlformats-officedocument.*',
'text/plain', 'text/csv', 'application/json'
]
)
},
{
"id": f"{base_path}.curriculum.private",
"options": CreateBucketOptions(
name=f"{school_type.title()} School Files - {school_name} - Curriculum Private Files",
public=False,
file_size_limit=50 * 1024 * 1024,
allowed_mime_types=[
'image/*', 'video/*', 'application/pdf',
'application/msword', 'application/vnd.openxmlformats-officedocument.*',
'text/plain', 'text/csv', 'application/json'
]
)
}
]
results = {}
for bucket in buckets:
try:
result = storage_client.create_bucket(bucket["id"], bucket["options"])
results[bucket["id"]] = {
"status": "success",
"result": result
}
logger.info(f"Successfully created bucket {bucket['id']}")
except Exception as e:
logger.error(f"Error creating school bucket {bucket['id']}: {str(e)}")
results[bucket["id"]] = {
"status": "error",
"error": str(e)
}
return results
def create_school(db_name: str, id: str, name: str, website: str, school_type: str, is_public: bool = True, school_node: SchoolNode | None = None, dataframes=None):
if not name or not id or not website or not school_type:
logger.error("School name, id, website and school_type are required to create a school.")
raise ValueError("School name, id, website and school_type are required to create a school.")
logger.info(f"Initialising neo4j connection...")
logger.info(f"Initialising Neontology connection...")
neon.init_neontology_connection()
# Initialize storage tools for school
storage_tools_instance = storage_tools.SupabaseStorageTools(db_name, init_run_type="school")
# Generate the storage path for the school node
school_dir_created, node_storage_path = storage_tools_instance.create_school_storage_path(uuid_string)
logger.info(f"Generated school storage path: {node_storage_path}")
# Create School Node if not provided
if not school_node:
if is_public:
school_node = SchoolNode(
unique_id=f'School_{id}',
tldraw_snapshot="",
id=id,
uuid_string=uuid_string,
node_storage_path=node_storage_path,
name=name,
website=website,
school_type=school_type
@ -118,9 +34,8 @@ def create_school(db_name: str, id: str, name: str, website: str, school_type: s
else:
# Create private school node with default values
school_node = SchoolNode(
unique_id=f'School_{id}',
tldraw_snapshot="",
id=id,
uuid_string=uuid_string,
node_storage_path=node_storage_path,
name=name,
website=website,
school_type=school_type,
@ -133,6 +48,9 @@ def create_school(db_name: str, id: str, name: str, website: str, school_type: s
statutory_high_age=18,
school_capacity=1000
)
else:
# Update existing school node with the storage path
school_node.node_storage_path = node_storage_path
# First create/merge the school node in the main cc.institutes database
logger.info(f"Creating school node in main cc.institutes database...")
@ -144,15 +62,16 @@ def create_school(db_name: str, id: str, name: str, website: str, school_type: s
school_nodes = {
'school_node': school_node,
'db_name': db_name
'db_name': db_name,
'storage_path': node_storage_path
}
if dataframes is not None:
logger.info(f"Creating school timetable for {name} with {len(dataframes)} dataframes...")
school_timetable_nodes = init_school_timetable.create_school_timetable(dataframes, db_name, school_node)
school_timetable_nodes = init_school_timetable.create_school_timetable(dataframes, db_name, school_node, storage_tools_instance)
school_nodes['school_timetable_nodes'] = school_timetable_nodes
else:
logger.warning(f"No dataframes provided for {name}, skipping school timetable...")
logger.info(f"School {name} created successfully...")
logger.info(f"School {name} created successfully with storage path: {node_storage_path}")
return school_nodes

View File

@ -4,6 +4,7 @@ logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH
import pandas as pd
import modules.database.tools.neontology_tools as neon
import modules.database.tools.supabase_storage_tools as storage_tools
import modules.database.schemas.nodes.schools.schools as school_nodes
import modules.database.schemas.nodes.schools.curriculum as curriculum_nodes
import modules.database.schemas.nodes.schools.pastoral as pastoral_nodes
@ -40,7 +41,7 @@ def sort_year_groups(df):
df['YearGroupNumeric'] = pd.to_numeric(df['YearGroup'], errors='coerce')
return df.sort_values(by='YearGroupNumeric')
def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_node: school_nodes.SchoolNode):
def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_node: school_nodes.SchoolNode, storage_tools=None):
logger.info(f"Initialising neo4j connection...")
neon.init_neontology_connection()
@ -70,10 +71,20 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
last_key_stage_node = None
# Create Department Structure node
department_structure_node_unique_id = f"DepartmentStructure_{school_node.unique_id}"
department_structure_node_uuid_string = f"DepartmentStructure_{school_node.uuid_string}"
# For structure nodes, we can use a simple path or leave empty for consistency
# Since this is just an organizational node, we'll use a simple path
if storage_tools:
# Use the school's base department directory as the structure node path
dept_structure_path = f"cc.public.snapshots/DepartmentStructure/{school_node.uuid_string}"
node_storage_path = dept_structure_path
else:
node_storage_path = ""
department_structure_node = school_structures.DepartmentStructureNode(
unique_id=department_structure_node_unique_id,
tldraw_snapshot=""
uuid_string=department_structure_node_uuid_string,
node_storage_path=node_storage_path
)
# Create in school database only
neon.create_or_merge_neontology_node(department_structure_node, database=db_name, operation='merge')
@ -86,10 +97,17 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
)
logger.info(f"Created department structure node and linked to school")
curriculum_structure_node_unique_id = f"CurriculumStructure_{school_node.unique_id}"
curriculum_structure_node_uuid_string = f"CurriculumStructure_{school_node.uuid_string}"
# Generate storage path for curriculum structure node
if storage_tools:
curriculum_dir_created, node_storage_path = storage_tools.create_curriculum_storage_path(curriculum_structure_node_uuid_string)
else:
node_storage_path = ""
curriculum_node = school_structures.CurriculumStructureNode(
unique_id=curriculum_structure_node_unique_id,
tldraw_snapshot=""
uuid_string=curriculum_structure_node_uuid_string,
node_storage_path=node_storage_path
)
# Create in school database only
neon.create_or_merge_neontology_node(curriculum_node, database=db_name, operation='merge')
@ -102,10 +120,17 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
)
logger.info(f"Created curriculum node and relationship with school")
pastoral_structure_node_unique_id = f"PastoralStructure_{school_node.unique_id}"
pastoral_structure_node_uuid_string = f"PastoralStructure_{school_node.uuid_string}"
# Generate storage path for pastoral structure node
if storage_tools:
pastoral_dir_created, node_storage_path = storage_tools.create_pastoral_storage_path(pastoral_structure_node_uuid_string)
else:
node_storage_path = ""
pastoral_node = school_structures.PastoralStructureNode(
unique_id=pastoral_structure_node_unique_id,
tldraw_snapshot=""
uuid_string=pastoral_structure_node_uuid_string,
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(pastoral_node, database=db_name, operation='merge')
node_library['pastoral_node'] = pastoral_node
@ -120,11 +145,20 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
unique_departments = keystagesyllabus_df['Department'].dropna().unique()
for department_name in unique_departments:
department_unique_id = f"Department_{school_node.unique_id}_{department_name.replace(' ', '_')}"
department_uuid_string = f"Department_{school_node.uuid_string}_{department_name.replace(' ', '_')}"
# Generate storage path for department node using the storage tools
if storage_tools:
# Create department directory under the school's department structure
dept_path = f"cc.public.snapshots/Department/{department_uuid_string}"
node_storage_path = dept_path
else:
node_storage_path = ""
department_node = school_nodes.DepartmentNode(
unique_id=department_unique_id,
uuid_string=department_uuid_string,
name=department_name,
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create department in school database only
neon.create_or_merge_neontology_node(department_node, database=db_name, operation='merge')
@ -147,17 +181,25 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
# Process subjects from key stage syllabuses first (these have department info)
for _, subject_row in unique_subjects.iterrows():
subject_unique_id = f"Subject_{school_node.unique_id}_{subject_row['SubjectCode']}"
subject_uuid_string = f"Subject_{school_node.uuid_string}_{subject_row['SubjectCode']}"
department_node = node_library['department_nodes'].get(subject_row['Department'])
if not department_node:
logger.warning(f"No department found for subject {subject_row['Subject']} with code {subject_row['SubjectCode']}")
continue
# Generate storage path for subject node
if storage_tools:
# Create subject directory under the specific department
subject_path = f"cc.public.snapshots/Subject/{subject_uuid_string}"
node_storage_path = subject_path
else:
node_storage_path = ""
subject_node = curriculum_nodes.SubjectNode(
unique_id=subject_unique_id,
uuid_string=subject_uuid_string,
id=subject_row['SubjectCode'],
name=subject_row['Subject'],
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create subject in both databases
neon.create_or_merge_neontology_node(subject_node, database=db_name, operation='merge')
@ -173,14 +215,23 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
# Process any additional subjects from year group syllabuses (these won't have department info)
for _, subject_row in additional_subjects.iterrows():
subject_unique_id = f"Subject_{school_node.unique_id}_{subject_row['SubjectCode']}"
subject_uuid_string = f"Subject_{school_node.uuid_string}_{subject_row['SubjectCode']}"
# Create in a special "Unassigned" department
unassigned_dept_name = "Unassigned Department"
if unassigned_dept_name not in node_library['department_nodes']:
# Generate storage path for unassigned department node
if filesystem:
# Create unassigned department directory under the school's department structure
unassigned_dept_path = os.path.join(filesystem.root_path, "departments", "Unassigned")
filesystem.create_directory(unassigned_dept_path)
node_storage_path = os.path.relpath(unassigned_dept_path, filesystem.base_path)
else:
node_storage_path = ""
department_node = school_nodes.DepartmentNode(
unique_id=f"Department_{school_node.unique_id}_Unassigned",
uuid_string=f"Department_{school_node.uuid_string}_Unassigned",
name=unassigned_dept_name,
tldraw_snapshot=""
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(department_node, database=db_name, operation='merge')
node_library['department_nodes'][unassigned_dept_name] = department_node
@ -192,11 +243,20 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
)
logger.info(f"Created unassigned department node and linked to department structure")
# Generate storage path for subject node
if filesystem:
# Create subject directory under the unassigned department
subject_path = os.path.join(filesystem.root_path, "departments", "Unassigned", subject_row['Subject'].replace(' ', '_'))
filesystem.create_directory(subject_path)
node_storage_path = os.path.relpath(subject_path, filesystem.base_path)
else:
node_storage_path = ""
subject_node = curriculum_nodes.SubjectNode(
unique_id=subject_unique_id,
uuid_string=subject_uuid_string,
id=subject_row['SubjectCode'],
name=subject_row['Subject'],
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create subject in both databases
neon.create_or_merge_neontology_node(subject_node, database=db_name, operation='merge')
@ -226,20 +286,29 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
# First create all key stage nodes and key stage syllabus nodes
for index, ks_row in keystagesyllabus_df.sort_values('KeyStage').iterrows():
key_stage = str(ks_row['KeyStage'])
logger.debug(f"Processing key stage syllabus row - Subject: {ks_row['Subject']}, Key Stage: {key_stage}")
subject = str(ks_row['Subject'])
syllabus_id = str(ks_row['ID'])
logger.debug(f"Processing key stage syllabus row - Subject: {subject}, Key Stage: {key_stage}, Syllabus ID: {syllabus_id}")
subject_node = node_library['subject_nodes'].get(ks_row['Subject'])
subject_node = node_library['subject_nodes'].get(subject)
if not subject_node:
logger.warning(f"No subject node found for subject {ks_row['Subject']}")
logger.warning(f"No subject node found for subject {subject}")
continue
if key_stage not in key_stage_nodes_created:
key_stage_node_unique_id = f"KeyStage_{curriculum_node.unique_id}_KStg{key_stage}"
key_stage_node_uuid_string = f"KeyStage_{curriculum_node.uuid_string}_KStg{key_stage}"
# Generate storage path for key stage node
if filesystem:
key_stage_dir_created, key_stage_path = filesystem.create_curriculum_key_stage_syllabus_directory(curriculum_path, key_stage, subject, syllabus_id)
node_storage_path = os.path.relpath(key_stage_path, filesystem.base_path)
else:
node_storage_path = ""
key_stage_node = curriculum_nodes.KeyStageNode(
unique_id=key_stage_node_unique_id,
uuid_string=key_stage_node_uuid_string,
name=f"Key Stage {key_stage}",
key_stage=str(key_stage),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create key stage node in both databases
neon.create_or_merge_neontology_node(key_stage_node, database=db_name, operation='merge')
@ -252,7 +321,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.CurriculumStructureIncludesKeyStage(source=curriculum_node, target=key_stage_node),
database=db_name, operation='merge'
)
logger.info(f"Created key stage node {key_stage_node_unique_id} and relationship with curriculum structure")
logger.info(f"Created key stage node {key_stage_node_uuid_string} and relationship with curriculum structure")
# Create sequential relationship between key stages in both databases
if last_key_stage_node:
@ -264,27 +333,34 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.KeyStageFollowsKeyStage(source=last_key_stage_node, target=key_stage_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between key stages {last_key_stage_node.unique_id} and {key_stage_node.unique_id}")
logger.info(f"Created sequential relationship between key stages {last_key_stage_node.uuid_string} and {key_stage_node.uuid_string}")
last_key_stage_node = key_stage_node
# Create key stage syllabus under the subject's curriculum directory
key_stage_syllabus_node_unique_id = f"KeyStageSyllabus_{curriculum_node.unique_id}_{ks_row['Title'].replace(' ', '')}"
key_stage_syllabus_node_uuid_string = f"KeyStageSyllabus_{curriculum_node.uuid_string}_{ks_row['Title'].replace(' ', '')}"
logger.debug(f"Creating key stage syllabus node for {ks_row['Subject']} KS{key_stage} with ID {ks_row['ID']}")
key_stage_syllabus_node_unique_id = f"KeyStageSyllabus_{curriculum_node.unique_id}_{ks_row['Title'].replace(' ', '')}"
key_stage_syllabus_node_uuid_string = f"KeyStageSyllabus_{curriculum_node.uuid_string}_{ks_row['Title'].replace(' ', '')}"
# Generate storage path for key stage syllabus node
if filesystem:
syllabus_dir_created, syllabus_path = filesystem.create_curriculum_key_stage_syllabus_directory(curriculum_path, key_stage, ks_row['Subject'], ks_row['ID'])
node_storage_path = os.path.relpath(syllabus_path, filesystem.base_path)
else:
node_storage_path = ""
key_stage_syllabus_node = curriculum_nodes.KeyStageSyllabusNode(
unique_id=key_stage_syllabus_node_unique_id,
uuid_string=key_stage_syllabus_node_uuid_string,
id=ks_row['ID'],
name=ks_row['Title'],
key_stage=str(ks_row['KeyStage']),
subject_name=ks_row['Subject'],
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create key stage syllabus node in both databases
neon.create_or_merge_neontology_node(key_stage_syllabus_node, database=db_name, operation='merge')
neon.create_or_merge_neontology_node(key_stage_syllabus_node, database=curriculum_db_name, operation='merge')
node_library['key_stage_syllabus_nodes'][ks_row['ID']] = key_stage_syllabus_node
logger.debug(f"Created key stage syllabus node {key_stage_syllabus_node_unique_id} for {ks_row['Subject']} KS{key_stage}")
logger.debug(f"Created key stage syllabus node {key_stage_syllabus_node_uuid_string} for {ks_row['Subject']} KS{key_stage}")
# Link key stage syllabus to its subject in both databases
if subject_node:
@ -296,7 +372,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.SubjectHasKeyStageSyllabus(source=subject_node, target=key_stage_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between subject {subject_node.unique_id} and key stage syllabus {key_stage_syllabus_node.unique_id}")
logger.info(f"Created relationship between subject {subject_node.uuid_string} and key stage syllabus {key_stage_syllabus_node.uuid_string}")
# Link key stage syllabus to its key stage in both databases
key_stage_node = key_stage_nodes_created.get(key_stage)
@ -309,7 +385,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.KeyStageIncludesKeyStageSyllabus(source=key_stage_node, target=key_stage_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between key stage {key_stage_node.unique_id} and key stage syllabus {key_stage_syllabus_node.unique_id}")
logger.info(f"Created relationship between key stage {key_stage_node.uuid_string} and key stage syllabus {key_stage_syllabus_node.uuid_string}")
# Create sequential relationship between key stage syllabuses in both databases
last_key_stage_syllabus_node = last_key_stage_syllabus_nodes.get(ks_row['Subject'])
@ -322,7 +398,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.KeyStageSyllabusFollowsKeyStageSyllabus(source=last_key_stage_syllabus_node, target=key_stage_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between key stage syllabuses {last_key_stage_syllabus_node.unique_id} and {key_stage_syllabus_node.unique_id}")
logger.info(f"Created sequential relationship between key stage syllabuses {last_key_stage_syllabus_node.uuid_string} and {key_stage_syllabus_node.uuid_string}")
last_key_stage_syllabus_nodes[ks_row['Subject']] = key_stage_syllabus_node
# Now process year groups and their syllabuses
@ -339,12 +415,19 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
if pd.notna(numeric_year_group):
numeric_year_group = int(numeric_year_group)
if numeric_year_group not in year_group_nodes_created:
year_group_node_unique_id = f"YearGroup_{school_node.unique_id}_YGrp{numeric_year_group}"
year_group_node_uuid_string = f"YearGroup_{school_node.uuid_string}_YGrp{numeric_year_group}"
# Generate storage path for year group node
if filesystem:
year_group_dir_created, year_group_path = filesystem.create_pastoral_year_group_directory(pastoral_path, numeric_year_group)
node_storage_path = os.path.relpath(year_group_path, filesystem.base_path)
else:
node_storage_path = ""
year_group_node = pastoral_nodes.YearGroupNode(
unique_id=year_group_node_unique_id,
uuid_string=year_group_node_uuid_string,
year_group=str(numeric_year_group),
name=f"Year {numeric_year_group}, {year_group}",
tldraw_snapshot=""
name=f"Year {numeric_year_group}",
node_storage_path=node_storage_path
)
# Create year group node in both databases but use same directory
neon.create_or_merge_neontology_node(year_group_node, database=db_name, operation='merge')
@ -360,7 +443,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.YearGroupFollowsYearGroup(source=last_year_group_node, target=year_group_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between year groups {last_year_group_node.unique_id} and {year_group_node.unique_id} across key stages")
logger.info(f"Created sequential relationship between year groups {last_year_group_node.uuid_string} and {year_group_node.uuid_string} across key stages")
last_year_group_node = year_group_node
# Create relationship with Pastoral Structure in school database only
@ -368,7 +451,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.PastoralStructureIncludesYearGroup(source=pastoral_node, target=year_group_node),
database=db_name, operation='merge'
)
logger.info(f"Created year group node {year_group_node_unique_id} and relationship with pastoral structure")
logger.info(f"Created year group node {year_group_node_uuid_string} and relationship with pastoral structure")
year_group_nodes_created[numeric_year_group] = year_group_node
node_library['year_group_nodes'][str(numeric_year_group)] = year_group_node
@ -376,14 +459,21 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
# Create year group syllabus nodes in both databases
year_group_node = year_group_nodes_created.get(numeric_year_group)
if year_group_node:
year_group_syllabus_node_unique_id = f"YearGroupSyllabus_{school_node.unique_id}_{yg_row['ID']}"
year_group_syllabus_node_uuid_string = f"YearGroupSyllabus_{school_node.uuid_string}_{yg_row['ID']}"
# Generate storage path for year group syllabus node
if filesystem:
yg_syllabus_dir_created, yg_syllabus_path = filesystem.create_curriculum_year_group_syllabus_directory(curriculum_path, yg_row['Subject'], numeric_year_group, yg_row['ID'])
node_storage_path = os.path.relpath(yg_syllabus_path, filesystem.base_path)
else:
node_storage_path = ""
year_group_syllabus_node = pastoral_nodes.YearGroupSyllabusNode(
unique_id=year_group_syllabus_node_unique_id,
uuid_string=year_group_syllabus_node_uuid_string,
id=yg_row['ID'],
name=yg_row['Title'],
year_group=str(yg_row['YearGroup']),
subject_name=yg_row['Subject'],
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create year group syllabus node in both databases but use same directory
@ -406,7 +496,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.YearGroupSyllabusFollowsYearGroupSyllabus(source=last_year_group_syllabus_node, target=year_group_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between year group syllabuses {last_year_group_syllabus_node.unique_id} and {year_group_syllabus_node.unique_id}")
logger.info(f"Created sequential relationship between year group syllabuses {last_year_group_syllabus_node.uuid_string} and {year_group_syllabus_node.uuid_string}")
last_year_group_syllabus_nodes[yg_row['Subject']] = year_group_syllabus_node
# Create relationships in both databases using MATCH to avoid cartesian products
@ -421,7 +511,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.SubjectHasYearGroupSyllabus(source=subject_node, target=year_group_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between subject {subject_node.unique_id} and year group syllabus {year_group_syllabus_node_unique_id}")
logger.info(f"Created relationship between subject {subject_node.uuid_string} and year group syllabus {year_group_syllabus_node_uuid_string}")
# Link to year group
neon.create_or_merge_neontology_relationship(
@ -432,7 +522,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.YearGroupHasYearGroupSyllabus(source=year_group_node, target=year_group_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between year group {year_group_node.unique_id} and year group syllabus {year_group_syllabus_node_unique_id}")
logger.info(f"Created relationship between year group {year_group_node.uuid_string} and year group syllabus {year_group_syllabus_node_uuid_string}")
# Link to key stage syllabus if it exists for the same subject
key_stage_syllabus_node = node_library['key_stage_syllabus_nodes'].get(ks_row['ID'])
@ -445,7 +535,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.KeyStageSyllabusIncludesYearGroupSyllabus(source=key_stage_syllabus_node, target=year_group_syllabus_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between key stage syllabus {key_stage_syllabus_node.unique_id} and year group syllabus {year_group_syllabus_node_unique_id}")
logger.info(f"Created relationship between key stage syllabus {key_stage_syllabus_node.uuid_string} and year group syllabus {year_group_syllabus_node_uuid_string}")
# Process topics for this year group syllabus only if not already processed
topics_for_syllabus = topic_df[topic_df['SyllabusYearID'] == yg_row['ID']]
@ -472,22 +562,29 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
if (syllabus_node.subject_name == topic_subject and
syllabus_node.key_stage == str(topic_key_stage)):
matching_syllabus_node = syllabus_node
logger.debug(f"Found matching syllabus node: {syllabus_node.unique_id}")
logger.debug(f"Found matching syllabus node: {syllabus_node.uuid_string}")
break
if not matching_syllabus_node:
logger.warning(f"No key stage syllabus node found for subject {topic_subject} and key stage {topic_key_stage}, skipping topic creation")
continue
topic_node_unique_id = f"Topic_{matching_syllabus_node.unique_id}_{topic_row['TopicID']}"
topic_node_uuid_string = f"Topic_{matching_syllabus_node.uuid_string}_{topic_row['TopicID']}"
# Generate storage path for topic node
if filesystem:
topic_dir_created, topic_path = filesystem.create_curriculum_topic_directory(yg_syllabus_path, topic_row['TopicID'])
node_storage_path = os.path.relpath(topic_path, filesystem.base_path)
else:
node_storage_path = ""
topic_node = curriculum_nodes.TopicNode(
unique_id=topic_node_unique_id,
uuid_string=topic_node_uuid_string,
id=topic_row['TopicID'],
name=topic_row.get('TopicTitle', default_topic_values['topic_title']),
total_number_of_lessons_for_topic=str(topic_row.get('TotalNumberOfLessonsForTopic', default_topic_values['total_number_of_lessons_for_topic'])),
type=topic_row.get('TopicType', default_topic_values['topic_type']),
assessment_type=topic_row.get('TopicAssessmentType', default_topic_values['topic_assessment_type']),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create topic node in curriculum database only
neon.create_or_merge_neontology_node(topic_node, database=curriculum_db_name, operation='merge')
@ -502,7 +599,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.YearGroupSyllabusIncludesTopic(source=year_group_syllabus_node, target=topic_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationships between topic {topic_node_unique_id} and key stage syllabus {matching_syllabus_node.unique_id} and year group syllabus {year_group_syllabus_node_unique_id}")
logger.info(f"Created relationships between topic {topic_node_uuid_string} and key stage syllabus {matching_syllabus_node.uuid_string} and year group syllabus {year_group_syllabus_node_uuid_string}")
# Process lessons for this topic only if not already processed
lessons_for_topic = lesson_df[
@ -518,8 +615,15 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
continue
lessons_processed.add(lesson_row['LessonID'])
# Generate storage path for lesson node
if filesystem:
lesson_dir_created, lesson_path = filesystem.create_curriculum_lesson_directory(topic_path, lesson_row['LessonID'])
node_storage_path = os.path.relpath(lesson_path, filesystem.base_path)
else:
node_storage_path = ""
lesson_node = curriculum_nodes.TopicLessonNode(
unique_id=f"TopicLesson_{topic_node_unique_id}_{lesson_row['LessonID']}",
uuid_string=f"TopicLesson_{topic_node_uuid_string}_{lesson_row['LessonID']}",
id=lesson_row['LessonID'],
name=lesson_row.get('LessonTitle', default_topic_lesson_values['topic_lesson_title']),
type=lesson_row.get('LessonType', default_topic_lesson_values['topic_lesson_type']),
@ -527,7 +631,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
suggested_activities=str(lesson_row.get('SuggestedActivities', default_topic_lesson_values['topic_lesson_suggested_activities'])),
skills_learned=str(lesson_row.get('SkillsLearned', default_topic_lesson_values['topic_lesson_skills_learned'])),
weblinks=str(lesson_row.get('WebLinks', default_topic_lesson_values['topic_lesson_weblinks'])),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create lesson node in curriculum database only
neon.create_or_merge_neontology_node(lesson_node, database=curriculum_db_name, operation='merge')
@ -538,7 +642,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.TopicIncludesTopicLesson(source=topic_node, target=lesson_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created lesson node {lesson_node.unique_id} and relationship with topic {topic_node.unique_id}")
logger.info(f"Created lesson node {lesson_node.uuid_string} and relationship with topic {topic_node.uuid_string}")
# Create sequential relationships between lessons
if lesson_row['Lesson'].isdigit() and previous_lesson_node:
@ -546,7 +650,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.TopicLessonFollowsTopicLesson(source=previous_lesson_node, target=lesson_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between lessons {previous_lesson_node.unique_id} and {lesson_node.unique_id}")
logger.info(f"Created sequential relationship between lessons {previous_lesson_node.uuid_string} and {lesson_node.uuid_string}")
previous_lesson_node = lesson_node
# Process learning statements for this lesson only if not already processed
@ -558,12 +662,19 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
if statement_row['StatementID'] in statements_processed:
continue
statements_processed.add(statement_row['StatementID'])
# Generate storage path for learning statement node
if filesystem:
statement_dir_created, statement_path = filesystem.create_curriculum_learning_statement_directory(lesson_path, statement_row['StatementID'])
node_storage_path = os.path.relpath(statement_path, filesystem.base_path)
else:
node_storage_path = ""
statement_node = curriculum_nodes.LearningStatementNode(
unique_id=f"LearningStatement_{lesson_node.unique_id}_{statement_row['StatementID']}",
uuid_string=f"LearningStatement_{lesson_node.uuid_string}_{statement_row['StatementID']}",
id=statement_row['StatementID'],
name=statement_row.get('LearningStatement', default_learning_statement_values['lesson_learning_statement']),
type=statement_row.get('StatementType', default_learning_statement_values['lesson_learning_statement_type']),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create statement node in curriculum database only
neon.create_or_merge_neontology_node(statement_node, database=curriculum_db_name, operation='merge')
@ -574,7 +685,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.LessonIncludesLearningStatement(source=lesson_node, target=statement_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created learning statement node {statement_node.unique_id} and relationship with lesson {lesson_node.unique_id}")
logger.info(f"Created learning statement node {statement_node.uuid_string} and relationship with lesson {lesson_node.uuid_string}")
else:
logger.warning(f"No year group node found for year group {year_group}, skipping syllabus creation")
@ -601,15 +712,23 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
logger.warning(f"No key stage syllabus node found for subject {topic_subject} and key stage {topic_key_stage}, skipping topic creation")
continue
topic_node_unique_id = f"Topic_{matching_syllabus_node.unique_id}_{topic_row['TopicID']}"
topic_node_uuid_string = f"Topic_{matching_syllabus_node.uuid_string}_{topic_row['TopicID']}"
# Generate storage path for topic node
if filesystem:
syllabus_path = os.path.join(curriculum_path, "subjects", topic_subject, "key_stage_syllabuses", f"KS{topic_key_stage}", f"KS{topic_key_stage}.{topic_subject}")
topic_dir_created, keystage_topic_path = filesystem.create_curriculum_keystage_topic_directory(syllabus_path, topic_row['TopicID'])
node_storage_path = os.path.relpath(keystage_topic_path, filesystem.base_path)
else:
node_storage_path = ""
topic_node = curriculum_nodes.TopicNode(
unique_id=topic_node_unique_id,
uuid_string=topic_node_uuid_string,
id=topic_row['TopicID'],
name=topic_row.get('TopicTitle', default_topic_values['topic_title']),
total_number_of_lessons_for_topic=str(topic_row.get('TotalNumberOfLessonsForTopic', default_topic_values['total_number_of_lessons_for_topic'])),
type=topic_row.get('TopicType', default_topic_values['topic_type']),
assessment_type=topic_row.get('TopicAssessmentType', default_topic_values['topic_assessment_type']),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create topic node in curriculum database only
neon.create_or_merge_neontology_node(topic_node, database=curriculum_db_name, operation='merge')
@ -621,7 +740,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.KeyStageSyllabusIncludesTopic(source=matching_syllabus_node, target=topic_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created relationship between topic {topic_node_unique_id} and key stage syllabus {matching_syllabus_node.unique_id}")
logger.info(f"Created relationship between topic {topic_node_uuid_string} and key stage syllabus {matching_syllabus_node.uuid_string}")
# Process lessons for this topic
lessons_for_topic = lesson_df[
@ -636,8 +755,15 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
if lesson_row['LessonID'] in lessons_processed:
continue
lessons_processed.add(lesson_row['LessonID'])
# Generate storage path for lesson node
if filesystem:
lesson_dir_created, lesson_path = filesystem.create_curriculum_lesson_directory(topic_path, lesson_row['LessonID'])
node_storage_path = os.path.relpath(lesson_path, filesystem.base_path)
else:
node_storage_path = ""
lesson_node = curriculum_nodes.TopicLessonNode(
unique_id=f"TopicLesson_{topic_node_unique_id}_{lesson_row['LessonID']}",
uuid_string=f"TopicLesson_{topic_node_uuid_string}_{lesson_row['LessonID']}",
id=lesson_row['LessonID'],
name=lesson_row.get('LessonTitle', default_topic_lesson_values['topic_lesson_title']),
type=lesson_row.get('LessonType', default_topic_lesson_values['topic_lesson_type']),
@ -645,7 +771,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
suggested_activities=str(lesson_row.get('SuggestedActivities', default_topic_lesson_values['topic_lesson_suggested_activities'])),
skills_learned=str(lesson_row.get('SkillsLearned', default_topic_lesson_values['topic_lesson_skills_learned'])),
weblinks=str(lesson_row.get('WebLinks', default_topic_lesson_values['topic_lesson_weblinks'])),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create lesson node in curriculum database only
neon.create_or_merge_neontology_node(lesson_node, database=curriculum_db_name, operation='merge')
@ -656,7 +782,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.TopicIncludesTopicLesson(source=topic_node, target=lesson_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created lesson node {lesson_node.unique_id} and relationship with topic {topic_node.unique_id}")
logger.info(f"Created lesson node {lesson_node.uuid_string} and relationship with topic {topic_node.uuid_string}")
# Create sequential relationships between lessons
if lesson_row['Lesson'].isdigit() and previous_lesson_node:
@ -664,7 +790,7 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.TopicLessonFollowsTopicLesson(source=previous_lesson_node, target=lesson_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created sequential relationship between lessons {previous_lesson_node.unique_id} and {lesson_node.unique_id}")
logger.info(f"Created sequential relationship between lessons {previous_lesson_node.uuid_string} and {lesson_node.uuid_string}")
previous_lesson_node = lesson_node
# Process learning statements for this lesson
@ -676,12 +802,19 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
if statement_row['StatementID'] in statements_processed:
continue
statements_processed.add(statement_row['StatementID'])
# Generate storage path for learning statement node
if filesystem:
statement_dir_created, statement_path = filesystem.create_curriculum_learning_statement_directory(lesson_path, statement_row['StatementID'])
node_storage_path = os.path.relpath(statement_path, filesystem.base_path)
else:
node_storage_path = ""
statement_node = curriculum_nodes.LearningStatementNode(
unique_id=f"LearningStatement_{lesson_node.unique_id}_{statement_row['StatementID']}",
uuid_string=f"LearningStatement_{lesson_node.uuid_string}_{statement_row['StatementID']}",
id=statement_row['StatementID'],
name=statement_row.get('LearningStatement', default_learning_statement_values['lesson_learning_statement']),
type=statement_row.get('StatementType', default_learning_statement_values['lesson_learning_statement_type']),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Create statement node in curriculum database only
neon.create_or_merge_neontology_node(statement_node, database=curriculum_db_name, operation='merge')
@ -692,6 +825,6 @@ def create_curriculum(dataframes, db_name: str, curriculum_db_name: str, school_
curriculum_relationships.LessonIncludesLearningStatement(source=lesson_node, target=statement_node),
database=curriculum_db_name, operation='merge'
)
logger.info(f"Created learning statement node {statement_node.unique_id} and relationship with lesson {lesson_node.unique_id}")
logger.info(f"Created learning statement node {statement_node.uuid_string} and relationship with lesson {lesson_node.uuid_string}")
return node_library

View File

@ -11,7 +11,7 @@ import modules.database.schemas.relationships.calendar_timetable_rels as cal_tt_
import modules.database.init.init_calendar as init_calendar
import modules.database.tools.neontology_tools as neon
def create_school_timetable(dataframes, db_name, school_node=None):
def create_school_timetable(dataframes, db_name, school_node=None, filesystem=None):
logger.info(f"Creating school timetable for {db_name}")
if dataframes is None:
raise ValueError("Data is required to create the calendar and timetable.")
@ -22,10 +22,10 @@ def create_school_timetable(dataframes, db_name, school_node=None):
school_df = dataframes['school']
if school_node is None:
logger.info(f"School node is None, using school data from dataframe")
school_unique_id = school_df[school_df['Identifier'] == 'SchoolID']['Data'].iloc[0]
school_uuid_string = school_df[school_df['Identifier'] == 'SchoolID']['Data'].iloc[0]
else:
logger.info(f"School node is not None, using school data from school node: {school_node}")
school_unique_id = school_node.unique_id
school_uuid_string = school_node.uuid_string
terms_df = dataframes['terms']
weeks_df = dataframes['weeks']
@ -54,20 +54,30 @@ def create_school_timetable(dataframes, db_name, school_node=None):
}
# Create AcademicTimetable Node
school_timetable_unique_id = f"{school_unique_id}_{school_year_start_date.year}_{school_year_end_date.year}"
school_timetable_uuid_string = f"{school_uuid_string}_{school_year_start_date.year}_{school_year_end_date.year}"
# Generate storage path for timetable node
if filesystem:
timetable_dir_created, timetable_path = filesystem.create_school_timetable_directory()
node_storage_path = os.path.relpath(timetable_path, filesystem.base_path)
logger.info(f"Generated timetable node_storage_path: {node_storage_path}")
else:
node_storage_path = ""
logger.warning("No filesystem provided, using empty storage path")
school_timetable_node = timetable.SchoolTimetableNode(
school_timetable_id=school_timetable_unique_id,
unique_id=school_timetable_unique_id,
school_timetable_id=school_timetable_uuid_string,
uuid_string=school_timetable_uuid_string,
start_date=school_year_start_date,
end_date=school_year_end_date,
tldraw_snapshot=""
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(school_timetable_node, database=db_name, operation='merge')
timetable_nodes['timetable_node'] = school_timetable_node
if school_node:
logger.info(f"Creating calendar for {school_unique_id} from Neo4j SchoolNode: {school_node.unique_id}")
calendar_nodes = init_calendar.create_calendar(db_name, school_year_start_date, school_year_end_date, attach_to_calendar_node=True, owner_node=school_node)
logger.info(f"Creating calendar for {school_uuid_string} from Neo4j SchoolNode: {school_node.uuid_string}")
calendar_nodes = init_calendar.create_calendar(db_name, school_year_start_date, school_year_end_date, attach_to_calendar_node=True, owner_node=school_node, filesystem=filesystem)
# Link the school node to the timetable node
neon.create_or_merge_neontology_relationship(
entity_tt_rels.SchoolHasTimetable(source=school_node, target=school_timetable_node),
@ -75,26 +85,34 @@ def create_school_timetable(dataframes, db_name, school_node=None):
)
timetable_nodes['calendar_nodes'] = calendar_nodes
else:
logger.info(f"Creating calendar for {school_unique_id} from dataframe SchoolID: {school_unique_id}")
calendar_nodes = init_calendar.create_calendar(db_name, school_year_start_date, school_year_end_date, attach_to_calendar_node=False, owner_node=None)
logger.info(f"Creating calendar for {school_uuid_string} from dataframe SchoolID: {school_uuid_string}")
calendar_nodes = init_calendar.create_calendar(db_name, school_year_start_date, school_year_end_date, attach_to_calendar_node=False, owner_node=None, filesystem=filesystem)
# Create AcademicYear nodes for each year within the range
for year in range(school_year_start_date.year, school_year_end_date.year + 1):
year_str = str(year)
academic_year_unique_id = f"{school_timetable_unique_id}_{year}"
academic_year_uuid_string = f"{school_timetable_uuid_string}_{year}"
# Generate storage path for academic year node
if filesystem:
year_dir_created, year_path = filesystem.create_school_timetable_year_directory(timetable_path, year)
node_storage_path = os.path.relpath(year_path, filesystem.base_path)
else:
node_storage_path = ""
academic_year_node = timetable.AcademicYearNode(
unique_id=academic_year_unique_id,
uuid_string=academic_year_uuid_string,
year=year_str,
tldraw_snapshot=""
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(academic_year_node, database=db_name, operation='merge')
timetable_nodes['academic_year_nodes'].append(academic_year_node)
logger.info(f'Created academic year node: {academic_year_node.unique_id}')
logger.info(f'Created academic year node: {academic_year_node.uuid_string}')
neon.create_or_merge_neontology_relationship(
tt_rels.AcademicTimetableHasAcademicYear(source=school_timetable_node, target=academic_year_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {school_timetable_node.unique_id} to {academic_year_node.unique_id}")
logger.info(f"Created school timetable relationship from {school_timetable_node.uuid_string} to {academic_year_node.uuid_string}")
# Link the academic year with the corresponding calendar year node
for year_node in calendar_nodes['calendar_year_nodes']:
@ -103,7 +121,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
cal_tt_rels.AcademicYearIsCalendarYear(source=academic_year_node, target=year_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {academic_year_node.unique_id} to {year_node.unique_id}")
logger.info(f"Created school timetable relationship from {academic_year_node.uuid_string} to {year_node.uuid_string}")
break
# Create Term and TermBreak nodes linked to AcademicYear
@ -121,29 +139,39 @@ def create_school_timetable(dataframes, db_name, school_node=None):
if isinstance(term_end_date, pd.Timestamp):
term_end_date = term_end_date.strftime('%Y-%m-%d')
# Generate storage path for term node
if filesystem:
if term_row['TermType'] == 'Term':
term_dir_created, term_path = filesystem.create_school_timetable_academic_term_directory(timetable_path, term_name, academic_term_number)
else:
term_dir_created, term_path = filesystem.create_school_timetable_academic_term_break_directory(timetable_path, term_name)
node_storage_path = os.path.relpath(term_path, filesystem.base_path)
else:
node_storage_path = ""
if term_row['TermType'] == 'Term':
term_node_unique_id = f"{school_timetable_unique_id}_{academic_term_number}_{term_name_no_spaces}"
term_node_uuid_string = f"{school_timetable_uuid_string}_{academic_term_number}_{term_name_no_spaces}"
academic_term_number_str = str(academic_term_number)
term_node = term_node_class(
unique_id=term_node_unique_id,
uuid_string=term_node_uuid_string,
term_name=term_name,
term_number=academic_term_number_str,
start_date=datetime.strptime(term_start_date, '%Y-%m-%d'),
end_date=datetime.strptime(term_end_date, '%Y-%m-%d'),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
academic_term_number += 1
else:
term_break_node_unique_id = f"{school_timetable_unique_id}_{term_name_no_spaces}"
term_break_node_uuid_string = f"{school_timetable_uuid_string}_{term_name_no_spaces}"
term_node = term_node_class(
unique_id=term_break_node_unique_id,
uuid_string=term_break_node_uuid_string,
term_break_name=term_name,
start_date=datetime.strptime(term_start_date, '%Y-%m-%d'),
end_date=datetime.strptime(term_end_date, '%Y-%m-%d'),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
neon.create_or_merge_neontology_node(term_node, database=db_name, operation='merge')
logger.info(f'Created academic term break node: {term_node.unique_id}')
logger.info(f'Created academic term break node: {term_node.uuid_string}')
timetable_nodes['academic_term_nodes'].append(term_node)
term_number += 1 # We don't use this but we could
@ -158,7 +186,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
relationship_class(source=academic_year_node, target=term_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {academic_year_node.unique_id} to {term_node.unique_id}")
logger.info(f"Created school timetable relationship from {academic_year_node.uuid_string} to {term_node.uuid_string}")
# Create Week nodes
academic_week_number = 1
@ -168,28 +196,35 @@ def create_school_timetable(dataframes, db_name, school_node=None):
if isinstance(week_start_date, pd.Timestamp):
week_start_date = week_start_date.strftime('%Y-%m-%d')
week_node_unique_id = f"{school_timetable_unique_id}_{week_row['WeekNumber']}_{week_row['WeekType']}Week"
week_node_uuid_string = f"{school_timetable_uuid_string}_{week_row['WeekNumber']}_{week_row['WeekType']}Week"
# Generate storage path for week node
if filesystem:
week_dir_created, week_path = filesystem.create_school_timetable_academic_week_directory(timetable_path, week_row['WeekNumber'])
node_storage_path = os.path.relpath(week_path, filesystem.base_path)
else:
node_storage_path = ""
if week_row['WeekType'] == 'Holiday':
week_node = week_node_class(
unique_id=week_node_unique_id,
uuid_string=week_node_uuid_string,
start_date=datetime.strptime(week_start_date, '%Y-%m-%d'),
tldraw_snapshot=""
node_storage_path=node_storage_path
)
else:
academic_week_number_str = str(academic_week_number)
week_type = week_row['WeekType']
week_node = week_node_class(
unique_id=week_node_unique_id,
uuid_string=week_node_uuid_string,
academic_week_number=academic_week_number_str,
start_date=datetime.strptime(week_start_date, '%Y-%m-%d'),
week_type=week_type,
tldraw_snapshot=""
node_storage_path=node_storage_path
)
academic_week_number += 1
neon.create_or_merge_neontology_node(week_node, database=db_name, operation='merge')
timetable_nodes['academic_week_nodes'].append(week_node)
logger.info(f"Created week node: {week_node.unique_id}")
logger.info(f"Created week node: {week_node.uuid_string}")
for calendar_node in calendar_nodes['calendar_week_nodes']:
if calendar_node.start_date == week_node.start_date:
if isinstance(week_node, timetable.AcademicWeekNode):
@ -197,13 +232,13 @@ def create_school_timetable(dataframes, db_name, school_node=None):
cal_tt_rels.AcademicWeekIsCalendarWeek(source=week_node, target=calendar_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {calendar_node.unique_id} to {week_node.unique_id}")
logger.info(f"Created school timetable relationship from {calendar_node.uuid_string} to {week_node.uuid_string}")
elif isinstance(week_node, timetable.HolidayWeekNode):
neon.create_or_merge_neontology_relationship(
cal_tt_rels.HolidayWeekIsCalendarWeek(source=week_node, target=calendar_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {calendar_node.unique_id} to {week_node.unique_id}")
logger.info(f"Created school timetable relationship from {calendar_node.uuid_string} to {week_node.uuid_string}")
break
# Link week node to the correct academic term
@ -214,7 +249,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
relationship_class(source=term_node, target=week_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {term_node.unique_id} to {week_node.unique_id}")
logger.info(f"Created school timetable relationship from {term_node.uuid_string} to {week_node.uuid_string}")
break
# Link week node to the correct academic year
@ -225,7 +260,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
relationship_class(source=academic_year_node, target=week_node),
database=db_name, operation='merge'
)
logger.info(f"Created school timetable relationship from {academic_year_node.unique_id} to {week_node.unique_id}")
logger.info(f"Created school timetable relationship from {academic_year_node.uuid_string} to {week_node.uuid_string}")
break
# Create Day nodes
@ -243,18 +278,24 @@ def create_school_timetable(dataframes, db_name, school_node=None):
'StaffDay': timetable.StaffDayNode
}[day_row['DayType']]
# Generate storage path for day node
if filesystem:
day_dir_created, day_path = filesystem.create_school_timetable_academic_day_directory(timetable_path, academic_day_number)
node_storage_path = os.path.relpath(day_path, filesystem.base_path)
else:
node_storage_path = ""
# Format the unique ID as {day_node_class.__name__}Day
day_node_data = {
'unique_id': f"{school_timetable_unique_id}_{day_number}_{day_node_class.__name__}Day",
'uuid_string': f"{school_timetable_uuid_string}_{day_number}_{day_node_class.__name__}Day",
'date': datetime.strptime(date_str, '%Y-%m-%d'),
'day_of_week': datetime.strptime(date_str, '%Y-%m-%d').strftime('%A'),
'tldraw_snapshot': ""
'node_storage_path': node_storage_path
}
if day_row['DayType'] == 'Academic':
day_node_data['academic_day'] = str(academic_day_number)
day_node_data['day_type'] = day_row['WeekType']
day_node_data['tldraw_snapshot'] = ""
day_node = day_node_class(**day_node_data)
@ -262,7 +303,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
if calendar_node.date == day_node.date:
neon.create_or_merge_neontology_node(day_node, database=db_name, operation='merge')
timetable_nodes['academic_day_nodes'].append(day_node)
logger.info(f"Created day node: {day_node.unique_id}")
logger.info(f"Created day node: {day_node.uuid_string}")
if isinstance(day_node, timetable.AcademicDayNode):
relationship_class = cal_tt_rels.AcademicDayIsCalendarDay
@ -277,7 +318,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
relationship_class(source=day_node, target=calendar_node),
database=db_name, operation='merge'
)
logger.info(f'Created relationship from {calendar_node.unique_id} to {day_node.unique_id}')
logger.info(f'Created relationship from {calendar_node.uuid_string} to {day_node.uuid_string}')
break
# Link day node to the correct academic week
@ -300,7 +341,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
relationship_class(source=academic_week_node, target=day_node),
database=db_name, operation='merge'
)
logger.info(f"Created relationship from {academic_week_node.unique_id} to {day_node.unique_id}")
logger.info(f"Created relationship from {academic_week_node.uuid_string} to {day_node.uuid_string}")
break
# Link day node to the correct academic term
@ -323,12 +364,12 @@ def create_school_timetable(dataframes, db_name, school_node=None):
relationship_class(source=term_node, target=day_node),
database=db_name, operation='merge'
)
logger.info(f"Created relationship from {term_node.unique_id} to {day_node.unique_id}")
logger.info(f"Created relationship from {term_node.uuid_string} to {day_node.uuid_string}")
break
# Create Period nodes for each academic day
if day_row['DayType'] == 'Academic':
logger.info(f"Creating periods for {day_node.unique_id}")
logger.info(f"Creating periods for {day_node.uuid_string}")
period_of_day = 1
academic_or_registration_period_of_day = 1
for _, period_row in periods_df.iterrows():
@ -340,15 +381,22 @@ def create_school_timetable(dataframes, db_name, school_node=None):
}[period_row['PeriodType']]
logger.info(f"Creating period node for {period_node_class.__name__} Period: {period_of_day}")
period_node_unique_id = f"{school_timetable_unique_id}_{academic_day_number}_{period_of_day}_{period_node_class.__name__}Period"
logger.debug(f"Period node unique id: {period_node_unique_id}")
period_node_uuid_string = f"{school_timetable_uuid_string}_{academic_day_number}_{period_of_day}_{period_node_class.__name__}Period"
logger.debug(f"Period node unique id: {period_node_uuid_string}")
# Generate storage path for period node
if filesystem:
period_dir_created, period_path = filesystem.create_school_timetable_period_directory(timetable_path, academic_day_number, period_row['PeriodCode'])
node_storage_path = os.path.relpath(period_path, filesystem.base_path)
else:
node_storage_path = ""
period_node_data = {
'unique_id': period_node_unique_id,
'uuid_string': period_node_uuid_string,
'name': period_row['PeriodName'],
'date': day_node.date,
'start_time': datetime.combine(day_node.date, period_row['StartTime']),
'end_time': datetime.combine(day_node.date, period_row['EndTime']),
'tldraw_snapshot': ""
'node_storage_path': node_storage_path
}
logger.debug(f"Period node data: {period_node_data}")
if period_row['PeriodType'] in ['Academic', 'Registration']:
@ -357,14 +405,13 @@ def create_school_timetable(dataframes, db_name, school_node=None):
period_code = period_row['PeriodCode']
period_code_formatted = f"{week_type}{day_name_short}{period_code}"
period_node_data['period_code'] = period_code_formatted
period_node_data['tldraw_snapshot'] = ""
academic_or_registration_period_of_day += 1
period_node = period_node_class(**period_node_data)
neon.create_or_merge_neontology_node(period_node, database=db_name, operation='merge')
timetable_nodes['academic_period_nodes'].append(period_node)
logger.info(f'Created period node: {period_node.unique_id}')
logger.info(f'Created period node: {period_node.uuid_string}')
relationship_class = {
'Academic': tt_rels.AcademicDayHasAcademicPeriod,
@ -377,7 +424,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
relationship_class(source=day_node, target=period_node),
database=db_name, operation='merge'
)
logger.info(f"Created relationship from {day_node.unique_id} to {period_node.unique_id}")
logger.info(f"Created relationship from {day_node.uuid_string} to {period_node.uuid_string}")
period_of_day += 1 # We don't use this but we could
academic_day_number += 1 # This is a bit of a hack but it works to keep the directories aligned (reorganise)
day_number += 1 # We don't use this but we could
@ -392,7 +439,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
relationship_class = relationship_map.get(node_type_pair)
if relationship_class:
# Avoid self-referential relationships
if source_node.unique_id != target_node.unique_id:
if source_node.uuid_string != target_node.uuid_string:
neon.create_or_merge_neontology_relationship(
relationship_class(
source=source_node,
@ -400,9 +447,9 @@ def create_school_timetable(dataframes, db_name, school_node=None):
),
database=db_name, operation='merge'
)
logger.info(f"Created relationship from {source_node.unique_id} to {target_node.unique_id}")
logger.info(f"Created relationship from {source_node.uuid_string} to {target_node.uuid_string}")
else:
logger.warning(f"Skipped self-referential relationship for node {source_node.unique_id}")
logger.warning(f"Skipped self-referential relationship for node {source_node.uuid_string}")
# Relationship maps for different node types
academic_year_relationship_map = {
@ -474,7 +521,7 @@ def create_school_timetable(dataframes, db_name, school_node=None):
# Call the function with the created timetable nodes
create_school_timetable_node_sequence_rels(timetable_nodes)
logger.info(f'Created timetable: {timetable_nodes["timetable_node"].unique_id}')
logger.info(f'Created timetable: {timetable_nodes["timetable_node"].uuid_string}')
# Log the directory structure after creation
# root_timetable_directory = fs_handler.root_path # Access the root directory of the filesystem handler

View File

@ -9,6 +9,7 @@ import modules.database.schemas.nodes.workers.workers as worker_nodes
import modules.database.init.init_calendar as init_calendar
import modules.database.schemas.relationships.entity_relationships as entity_relationships
import modules.database.tools.neontology_tools as neon
import modules.database.tools.supabase_storage_tools as storage_tools
from modules.logger_tool import initialise_logger
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
@ -21,11 +22,27 @@ def create_and_check_db(db_name):
return database_status
class UserCreator(ABC):
def __init__(self, user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date):
cc_schools_db_name = "cc.institutes" # Fix the TODO
def __init__(
self,
user_id,
cc_users_db_name,
user_type,
worker_type,
user_email,
worker_email,
cc_username,
user_name,
worker_name,
calendar_start_date,
calendar_end_date,
storage_tools=None,
user_db_name: Optional[str] = None,
worker_db_name: Optional[str] = None,
cc_schools_db_name: str = "cc.institutes",
):
self.cc_users_db_name = cc_users_db_name
self.user_db_name = f"{cc_users_db_name}.{user_type}.{cc_username}"
self.worker_db_name = f"{cc_schools_db_name}.{user_type}.{cc_username}"
self.user_db_name = user_db_name or f"{cc_users_db_name}.{user_type}.{cc_username}"
self.worker_db_name = worker_db_name or f"{cc_schools_db_name}.{worker_type}.{cc_username}"
self.user_type = user_type
self.worker_type = worker_type
self.cc_username = cc_username
@ -34,6 +51,7 @@ class UserCreator(ABC):
self.user_name = user_name
self.worker_name = worker_name
self.user_id = user_id
self.storage_tools = storage_tools # Store the storage tools instance
self.user_nodes: Dict[str, Optional[Any]] = {
'default_user_node': None,
'private_user_node': None,
@ -48,6 +66,25 @@ class UserCreator(ABC):
self.calendar_start_date = datetime.now().date()
self.calendar_end_date = (datetime.now() + timedelta(days=5)).date()
def _derive_user_storage_path(self) -> str:
return os.path.join(
"users",
self.user_id,
"databases",
self.user_db_name,
self.user_id,
).replace('\\', '/')
def _derive_internal_worker_path(self, worker_kind: str) -> str:
return os.path.join(
"users",
self.user_id,
"databases",
self.user_db_name,
worker_kind,
self.user_id,
).replace('\\', '/')
@abstractmethod
def create_user(self):
pass
@ -66,9 +103,17 @@ class UserCreator(ABC):
# Ensure Neontology is initialized
neon.init_neontology_connection()
# Generate storage path for user node using Supabase Storage
if self.storage_tools:
user_dir_created, node_storage_path = self.storage_tools.create_user_storage_path(self.user_id)
self.user_path = node_storage_path # Store for later use
else:
node_storage_path = self._derive_user_storage_path()
self.user_path = None
user_node = user_nodes.UserNode(
unique_id=f"{self.user_id}",
tldraw_snapshot="",
uuid_string=f"{self.user_id}",
node_storage_path=node_storage_path,
cc_username=f"{self.cc_username}",
user_email=f"{self.user_email}",
user_name=f"{self.user_name}",
@ -76,81 +121,79 @@ class UserCreator(ABC):
user_type=f"{self.user_type}",
)
logger.debug(f"User node template created: {user_node.to_dict()}. Writing to database {db_name}")
neon.create_or_merge_neontology_node(node=user_node, database=db_name, operation='merge')
logger.info(f"User node created: {user_node.to_dict()}")
logger.debug(f"About to call create_or_merge_neontology_node with node class: {user_node.__class__.__name__}")
logger.debug(f"Node primary label: {user_node.__primarylabel__}")
logger.debug(f"Node primary property: {user_node.__primaryproperty__}")
try:
neon.create_or_merge_neontology_node(node=user_node, database=db_name, operation='merge')
logger.info(f"User node created successfully: {user_node.to_dict()}")
except Exception as e:
logger.error(f"Failed to create user node: {e}")
raise
return user_node
def create_storage_bucket(self, bucket_id: str, bucket_name: str, access_token: Optional[str] = None) -> bool:
"""Create public and private storage buckets for the user using their access token or service role during initialization"""
logger.info(f"Creating storage buckets for user {self.cc_username}")
try:
from modules.database.supabase.utils.client import SupabaseServiceRoleClient, SupabaseAnonClient, CreateBucketOptions
# During initialization (no access token provided), use service role
if not access_token:
logger.info("Using service role client for bucket creation during initialization")
supabase = SupabaseServiceRoleClient()
else:
# For regular operations, use the user's access token
logger.info("Using user token for bucket creation")
supabase = SupabaseAnonClient.for_user(access_token)
# Create both public and private buckets
buckets = [
{
"id": f"{bucket_id}.public",
"options": CreateBucketOptions(
name=f"{bucket_name} - Public Files",
public=True,
file_size_limit=50 * 1024 * 1024, # 50MB
allowed_mime_types=[
'image/*', 'video/*', 'application/pdf',
'application/msword', 'application/vnd.openxmlformats-officedocument.*',
'text/plain', 'text/csv', 'application/json'
]
)
},
{
"id": f"{bucket_id}.private",
"options": CreateBucketOptions(
name=f"{bucket_name} - Private Files",
public=False,
file_size_limit=50 * 1024 * 1024, # 50MB
allowed_mime_types=[
'image/*', 'video/*', 'application/pdf',
'application/msword', 'application/vnd.openxmlformats-officedocument.*',
'text/plain', 'text/csv', 'application/json'
]
)
}
]
success = True
for bucket in buckets:
try:
result = supabase.create_bucket(bucket["id"], bucket["options"])
if not result:
logger.error(f"Failed to create bucket {bucket['id']}")
success = False
else:
logger.info(f"Successfully created bucket {bucket['id']}")
except Exception as e:
logger.error(f"Error creating bucket {bucket['id']}: {str(e)}")
success = False
return success
except Exception as e:
logger.error(f"Error creating storage buckets: {str(e)}")
return False
"""Create storage buckets for the user - DEPRECATED: Use centralized bucket initialization instead"""
logger.warning(f"Individual user bucket creation is deprecated. Use centralized bucket initialization instead.")
logger.info(f"User {self.cc_username} will use centralized storage buckets.")
return True # Return success to avoid breaking existing code
class SchoolUserCreator(UserCreator):
def __init__(self, user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date, school_node, worker_node=None):
super().__init__(user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date)
def __init__(
self,
user_id,
cc_users_db_name,
user_type,
worker_type,
user_email,
worker_email,
cc_username,
user_name,
worker_name,
calendar_start_date,
calendar_end_date,
school_node,
worker_node=None,
storage_tools=None,
user_db_name: Optional[str] = None,
worker_db_name: Optional[str] = None,
):
super().__init__(
user_id,
cc_users_db_name,
user_type,
worker_type,
user_email,
worker_email,
cc_username,
user_name,
worker_name,
calendar_start_date,
calendar_end_date,
storage_tools,
user_db_name=user_db_name,
worker_db_name=worker_db_name or (school_node.private_database_name if hasattr(school_node, "private_database_name") else None),
cc_schools_db_name="cc.institutes",
)
self.school_node = school_node
self.worker_node = worker_node
def _derive_school_worker_path(self, worker_kind: str) -> str:
school_identifier = getattr(self.school_node, 'uuid_string', None) if self.school_node else None
if not school_identifier and self.worker_db_name:
school_identifier = self.worker_db_name.split('.')[-1]
school_identifier = school_identifier or self.user_id
db_name_segment = self.worker_db_name or f"cc.institutes.{school_identifier}"
return os.path.join(
"schools",
school_identifier,
"databases",
db_name_segment,
worker_kind,
self.user_id,
).replace('\\', '/')
def create_user(self):
# Ensure Neontology is initialized
logger.debug(f"Initializing Neontology connection. Closing any existing connection")
@ -167,7 +210,7 @@ class SchoolUserCreator(UserCreator):
self.user_nodes[f'worker_node'] = worker_node
user_node = self.create_user_node(self.cc_users_db_name)
user_node = self.create_user_node(self.user_db_name)
logger.info(f"User node created: {user_node}")
@ -190,16 +233,25 @@ class SchoolUserCreator(UserCreator):
raise ValueError(f"Error creating teacher node: {e}") from e
def _create_teacher_node(self):
# Generate storage path for teacher node using Supabase Storage
if self.storage_tools:
teacher_dir_created, node_storage_path = self.storage_tools.create_teacher_storage_path(self.user_id)
else:
node_storage_path = self._derive_school_worker_path(self.worker_type)
teacher_node = worker_nodes.TeacherNode(
unique_id=f"{self.user_id}",
tldraw_snapshot="",
uuid_string=f"{self.user_id}",
node_storage_path=node_storage_path,
worker_name=self.worker_name,
worker_email=self.worker_email,
worker_db_name=self.worker_db_name,
worker_type=self.worker_type
)
# Use the school's private database name if available
school_db = self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name') else f"cc.institutes.{self.school_node.school_type}.{self.school_node.id}"
school_db = self.worker_db_name or (
self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name')
else f"cc.institutes.{self.school_node.school_type}.{getattr(self.school_node, 'id', self.school_node.uuid_string)}"
)
logger.info(f"Teacher node template created: {teacher_node}... setting school db to {school_db}")
neon.create_or_merge_neontology_node(node=teacher_node, database=school_db, operation='merge')
@ -208,16 +260,25 @@ class SchoolUserCreator(UserCreator):
return teacher_node
def create_student_node(self):
# Generate storage path for student node using Supabase Storage
if self.storage_tools:
student_dir_created, node_storage_path = self.storage_tools.create_student_storage_path(f"Student_{self.user_id}")
else:
node_storage_path = self._derive_school_worker_path(self.worker_type)
student_node = worker_nodes.StudentNode(
unique_id=f"Student_{self.user_id}",
uuid_string=f"Student_{self.user_id}",
worker_name=self.worker_name,
worker_email=self.worker_email,
worker_db_name=self.worker_db_name,
worker_type=self.worker_type,
tldraw_snapshot=""
node_storage_path=node_storage_path
)
# Use the school's private database name if available
school_db = self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name') else f"cc.institutes.{self.school_node.school_type}.{self.school_node.id}"
school_db = self.worker_db_name or (
self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name')
else f"cc.institutes.{self.school_node.school_type}.{getattr(self.school_node, 'id', self.school_node.uuid_string)}"
)
logger.info(f"Student node template created: {student_node}... setting school db to {school_db}")
neon.create_or_merge_neontology_node(node=student_node, database=school_db, operation='merge')
@ -228,20 +289,58 @@ class SchoolUserCreator(UserCreator):
def create_user_worker_relationship(self, user_node, worker_node):
user_role_rel = entity_relationships.UserIsSchoolWorker(source=user_node, target=worker_node)
# Use the school's private database name if available
school_db = self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name') else f"cc.institutes.{self.school_node.school_type}.{self.school_node.id}"
school_db = self.worker_db_name or (
self.school_node.private_database_name if hasattr(self.school_node, 'private_database_name')
else f"cc.institutes.{self.school_node.school_type}.{getattr(self.school_node, 'id', self.school_node.uuid_string)}"
)
neon.create_or_merge_neontology_relationship(user_role_rel, database=school_db, operation='merge')
logger.info(f"Relationship created between user and worker in database {school_db}")
def create_worker_school_relationship(self, worker_node, school_node):
worker_school_rel = entity_relationships.EntityBelongsToSchool(source=worker_node, target=school_node)
# Use the school's private database name if available
school_db = school_node.private_database_name if hasattr(school_node, 'private_database_name') else f"cc.institutes.{school_node.school_type}.{school_node.id}"
school_db = self.worker_db_name or (
school_node.private_database_name if hasattr(school_node, 'private_database_name')
else f"cc.institutes.{school_node.school_type}.{getattr(school_node, 'id', school_node.uuid_string)}"
)
neon.create_or_merge_neontology_relationship(worker_school_rel, database=school_db, operation='merge')
logger.info(f"Relationship created between worker and school in database {school_db}")
class NonSchoolUserCreator(UserCreator):
def __init__(self, user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date, developer_role: str = "developer"):
super().__init__(user_id, cc_users_db_name, user_type, worker_type, user_email, worker_email, cc_username, user_name, worker_name, calendar_start_date, calendar_end_date)
def __init__(
self,
user_id,
cc_users_db_name,
user_type,
worker_type,
user_email,
worker_email,
cc_username,
user_name,
worker_name,
calendar_start_date,
calendar_end_date,
developer_role: str = "developer",
storage_tools=None,
user_db_name: Optional[str] = None,
worker_db_name: Optional[str] = None,
):
super().__init__(
user_id,
cc_users_db_name,
user_type,
worker_type,
user_email,
worker_email,
cc_username,
user_name,
worker_name,
calendar_start_date,
calendar_end_date,
storage_tools,
user_db_name=user_db_name,
worker_db_name=worker_db_name,
)
self.developer_role = developer_role
def create_user(self, access_token: Optional[str] = None):
@ -273,7 +372,8 @@ class NonSchoolUserCreator(UserCreator):
logger.debug(f"Creating developer db for {self.user_type} user {self.cc_username} in database {self.user_db_name}")
self.create_developer_db()
else:
raise ValueError(f"User type {self.user_type} not supported")
logger.warning(f"User type {self.user_type} not explicitly supported; defaulting to developer workspace")
self.create_developer_db()
logger.debug(f"User nodes after creation: {self.user_nodes}")
return self.user_nodes
@ -290,10 +390,16 @@ class NonSchoolUserCreator(UserCreator):
logger.debug(f"Creating super admin user node for {self.user_type} user {self.cc_username} in database {self.user_db_name}")
private_user_node = self.create_user_node(self.user_db_name)
# Generate storage path for super admin node using Supabase Storage
if self.storage_tools:
admin_dir_created, node_storage_path = self.storage_tools.create_super_admin_storage_path(self.user_id)
else:
node_storage_path = self._derive_internal_worker_path(self.worker_type)
super_admin_node = worker_nodes.SuperAdminNode(
unique_id=f"SuperAdmin_{self.user_id}",
uuid_string=self.user_id,
worker_email=self.worker_email,
tldraw_snapshot="",
node_storage_path=node_storage_path,
worker_name=self.worker_name,
worker_db_name=self.worker_db_name,
worker_type=self.worker_type
@ -329,11 +435,17 @@ class NonSchoolUserCreator(UserCreator):
# Create the user node again for the user db
private_user_node = self.create_user_node(self.user_db_name)
# Generate storage path for developer node using Supabase Storage
if self.storage_tools:
dev_dir_created, node_storage_path = self.storage_tools.create_developer_storage_path(self.user_id)
else:
node_storage_path = self._derive_internal_worker_path(self.worker_type)
developer_node = worker_nodes.DeveloperNode(
unique_id=f"Developer_{self.user_id}",
uuid_string=self.user_id,
worker_name=self.worker_name,
worker_email=self.worker_email,
tldraw_snapshot="",
node_storage_path=node_storage_path,
worker_db_name=self.worker_db_name,
worker_type=self.worker_type,
developer_role=self.developer_role
@ -372,8 +484,101 @@ class NonSchoolUserCreator(UserCreator):
neon.create_or_merge_neontology_relationship(specific_user_rel, database=self.user_db_name, operation='merge')
logger.info("Relationship created between user and specific node")
def create_calendar(self, user_node: user_nodes.UserNode):
calendar_nodes = init_calendar.create_calendar(self.user_db_name, self.calendar_start_date, self.calendar_end_date, attach_to_calendar_node=True, owner_node=user_node)
def create_calendar(self, user_node: user_nodes.UserNode):
calendar_nodes = init_calendar.create_calendar(self.user_db_name, self.calendar_start_date, self.calendar_end_date, attach_to_calendar_node=True, owner_node=user_node, filesystem=self.filesystem)
logger.info(f"Calendar nodes created.")
return calendar_nodes
def _default_date_range():
today = datetime.now().date()
return today, (datetime.now() + timedelta(days=365)).date()
def create_user(
*,
user_id: str,
user_type: str,
username: str,
user_email: str,
user_name: Optional[str] = None,
worker_name: Optional[str] = None,
worker_type: Optional[str] = None,
worker_email: Optional[str] = None,
cc_users_db_name: str = "cc.users",
user_db_name: Optional[str] = None,
worker_db_name: Optional[str] = None,
calendar_start_date: Optional[datetime.date] = None,
calendar_end_date: Optional[datetime.date] = None,
school_node: Optional[Any] = None,
storage_tools=None,
) -> Dict[str, Optional[Any]]:
"""Create a user graph structure in Neo4j.
Args:
user_id: Identifier used as UUID for graph nodes.
user_type: Application-level user type (e.g. email_teacher, developer).
username: Canonical username/slug.
user_email: Contact email for the user node.
user_name: Friendly display name (defaults to username).
worker_name: Friendly name for worker node (defaults to user_name).
worker_type: Worker role (teacher, student, developer, etc.).
worker_email: Email for worker node (defaults to user_email).
cc_users_db_name: Root namespace for user databases (defaults to cc.users).
user_db_name: Fully-qualified target database for the user graph.
worker_db_name: Database for worker entities (usually school private DB).
calendar_start_date/calendar_end_date: Date range for initial calendar seeding.
school_node: Optional school context; if provided a SchoolUserCreator is used.
storage_tools: Optional Supabase storage tools for generating storage paths.
Returns:
Dict describing created nodes keyed by semantic role.
"""
start_date, end_date = calendar_start_date, calendar_end_date
if not start_date or not end_date:
start_date, end_date = _default_date_range()
worker_email = worker_email or user_email
user_name = user_name or username
worker_name = worker_name or user_name
if school_node is not None:
creator = SchoolUserCreator(
user_id=user_id,
cc_users_db_name=cc_users_db_name,
user_type=user_type,
worker_type=worker_type or "teacher",
user_email=user_email,
worker_email=worker_email,
cc_username=username,
user_name=user_name,
worker_name=worker_name,
calendar_start_date=start_date,
calendar_end_date=end_date,
school_node=school_node,
worker_node=None,
storage_tools=storage_tools,
user_db_name=user_db_name,
worker_db_name=worker_db_name,
)
else:
creator = NonSchoolUserCreator(
user_id=user_id,
cc_users_db_name=cc_users_db_name,
user_type=user_type,
worker_type=worker_type or user_type,
user_email=user_email,
worker_email=worker_email,
cc_username=username,
user_name=user_name,
worker_name=worker_name,
calendar_start_date=start_date,
calendar_end_date=end_date,
storage_tools=storage_tools,
user_db_name=user_db_name,
worker_db_name=worker_db_name,
)
return creator.create_user()

View File

@ -7,10 +7,10 @@ import modules.database.tools.neontology_tools as neon
from modules.database.tools.filesystem_tools import ClassroomCopilotFilesystem
from modules.database.schemas.nodes.users import UserNode
from modules.database.schemas.nodes.schools.schools import SubjectClassNode
from modules.database.schemas.nodes.workers.workers import TeacherNode
from modules.database.schemas.nodes.workers.workers import TeacherNode,
from modules.database.schemas.nodes.calendars import CalendarDayNode
from modules.database.schemas.nodes.workers.timetable import (
UserTeacherTimetableNode
UserTeacherTimetableNode, TimetableLessonNode
)
from modules.database.schemas.relationships.entity_timetable_rels import (
EntityHasTimetable
@ -23,35 +23,35 @@ from modules.database.schemas.relationships.calendar_timetable_rels import (
CalendarDayHasPlannedLesson, PlannedLessonBelongsToCalendarDay
)
def get_school_worker_classes(school_db_name: str, user_unique_id: str, worker_unique_id: str) -> list:
def get_school_worker_classes(school_db_name: str, user_uuid_string: str, worker_uuid_string: str) -> list:
"""
Retrieve all classes for a worker from the school database.
"""
query = """
MATCH (w:Teacher {unique_id: $worker_id})-[:TEACHER_HAS_TIMETABLE]->(tt:TeacherTimetable)
MATCH (w:Teacher {uuid_string: $worker_id})-[:TEACHER_HAS_TIMETABLE]->(tt:TeacherTimetable)
-[:TIMETABLE_HAS_CLASS]->(c:SubjectClass)
RETURN c
"""
with driver.get_driver(db_name=school_db_name).session(database=school_db_name) as session:
result = session.run(query, worker_id=worker_unique_id)
result = session.run(query, worker_id=worker_uuid_string)
classes = [record['c'] for record in result]
if not classes:
logger.warning(f"No classes found for teacher {worker_unique_id} in school database")
logger.warning(f"No classes found for teacher {worker_uuid_string} in school database")
return classes
def get_school_class_periods(school_db_name: str, class_unique_id: str) -> list:
def get_school_class_periods(school_db_name: str, class_uuid_string: str) -> list:
"""
Retrieve all periods for a class from the school database.
"""
query = """
MATCH (c:SubjectClass {unique_id: $class_id})-[:CLASS_HAS_LESSON]->(l:TimetableLesson)
MATCH (c:SubjectClass {uuid_string: $class_id})-[:CLASS_HAS_LESSON]->(l:TimetableLesson)
RETURN l
"""
with driver.get_driver(db_name=school_db_name).session(database=school_db_name) as session:
result = session.run(query, class_id=class_unique_id)
result = session.run(query, class_id=class_uuid_string)
periods = [record['l'] for record in result]
if not periods:
logger.warning(f"No periods found for class {class_unique_id} in school database")
logger.warning(f"No periods found for class {class_uuid_string} in school database")
return periods
def get_user_calendar_nodes(user_db_name: str, user_node: UserNode) -> list:
@ -60,12 +60,12 @@ def get_user_calendar_nodes(user_db_name: str, user_node: UserNode) -> list:
"""
# First try to find any calendar days to verify the structure
verify_query = """
MATCH (w:User {unique_id: $user_id})
MATCH (w:User {uuid_string: $user_id})
OPTIONAL MATCH (w)-[:HAS_CALENDAR]->(c:Calendar)
OPTIONAL MATCH (c)-[:CALENDAR_INCLUDES_YEAR]->(y:CalendarYear)
OPTIONAL MATCH (y)-[:YEAR_INCLUDES_MONTH]->(m:CalendarMonth)
OPTIONAL MATCH (m)-[:MONTH_INCLUDES_DAY]->(d:CalendarDay)
RETURN w.unique_id as user_id,
RETURN w.uuid_string as user_id,
count(c) as calendar_count,
count(y) as year_count,
count(m) as month_count,
@ -76,7 +76,7 @@ def get_user_calendar_nodes(user_db_name: str, user_node: UserNode) -> list:
with driver.get_driver(db_name=user_db_name).session(database=user_db_name) as session:
# First check the calendar structure
result = session.run(verify_query, user_id=user_node.unique_id)
result = session.run(verify_query, user_id=user_node.uuid_string)
if stats := result.single():
logger.info(f"Calendar structure for user {stats['user_id']}: "
f"calendars={stats['calendar_count']}, "
@ -86,50 +86,50 @@ def get_user_calendar_nodes(user_db_name: str, user_node: UserNode) -> list:
f"available years={stats['years']}")
if stats['calendar_count'] == 0:
logger.error(f"No calendar found for user {user_node.unique_id}")
logger.error(f"No calendar found for user {user_node.uuid_string}")
return []
if stats['year_count'] == 0:
logger.error(f"No calendar years found for user {user_node.unique_id}")
logger.error(f"No calendar years found for user {user_node.uuid_string}")
return []
if stats['month_count'] == 0:
logger.error(f"No calendar months found for user {user_node.unique_id}")
logger.error(f"No calendar months found for user {user_node.uuid_string}")
return []
if stats['day_count'] == 0:
logger.error(f"No calendar days found for user {user_node.unique_id}")
logger.error(f"No calendar days found for user {user_node.uuid_string}")
return []
# Get all calendar days without year filter
query = """
MATCH (w:User {unique_id: $user_id})-[:HAS_CALENDAR]->(c:Calendar)
MATCH (w:User {uuid_string: $user_id})-[:HAS_CALENDAR]->(c:Calendar)
-[:CALENDAR_INCLUDES_YEAR]->(y:CalendarYear)
-[:YEAR_INCLUDES_MONTH]->(m:CalendarMonth)
-[:MONTH_INCLUDES_DAY]->(d:CalendarDay)
RETURN d.unique_id as unique_id,
RETURN d.uuid_string as uuid_string,
d.date as date,
d.day_of_week as day_of_week,
d.iso_day as iso_day,
d.path as path
d.node_storage_path as path
ORDER BY d.date
"""
result = session.run(query, user_id=user_node.unique_id)
result = session.run(query, user_id=user_node.uuid_string)
calendar_days = []
for record in result:
calendar_day = CalendarDayNode(
unique_id=record['unique_id'],
uuid_string=record['uuid_string'],
date=record['date'],
day_of_week=record['day_of_week'],
iso_day=record['iso_day'],
path=record['path']
node_storage_path=record['path']
)
calendar_days.append(calendar_day)
if not calendar_days:
logger.error(f"No calendar days found for user {user_node.unique_id}")
logger.error(f"No calendar days found for user {user_node.uuid_string}")
else:
# Log the date range we have
dates = sorted([day.date for day in calendar_days])
logger.info(f"Found {len(calendar_days)} calendar days for user {user_node.unique_id}")
logger.info(f"Found {len(calendar_days)} calendar days for user {user_node.uuid_string}")
logger.info(f"Calendar days range from {dates[0]} to {dates[-1]}")
return calendar_days
@ -149,7 +149,7 @@ def create_user_worker_timetable(
fs_handler = ClassroomCopilotFilesystem(db_name=user_db_name, init_run_type="user")
# Create teacher timetable directory under the worker's directory
_, worker_timetable_path = fs_handler.create_teacher_timetable_directory(user_worker_node.path)
_, worker_timetable_path = fs_handler.create_teacher_timetable_directory(user_worker_node.node_storage_path)
# Initialize neontology connection
neon.init_neontology_connection()
@ -157,7 +157,7 @@ def create_user_worker_timetable(
# Get user's calendar nodes
calendar_nodes = get_user_calendar_nodes(user_db_name, user_node)
if not calendar_nodes:
logger.warning(f"No calendar nodes found for user {user_node.unique_id}")
logger.warning(f"No calendar nodes found for user {user_node.uuid_string}")
return {
"status": "error",
"message": "No calendar nodes found for user"
@ -165,17 +165,17 @@ def create_user_worker_timetable(
try:
# Create UserTeacherTimetableNode
timetable_unique_id = f"UserTeacherTimetable_{user_worker_node.teacher_code}"
timetable_uuid_string = f"UserTeacherTimetable_{user_worker_node.teacher_code}"
worker_timetable = UserTeacherTimetableNode(
unique_id=timetable_unique_id,
uuid_string=timetable_uuid_string,
school_db_name=school_db_name,
school_timetable_id=f"TeacherTimetable_{user_worker_node.teacher_code}",
path=worker_timetable_path
node_storage_path=worker_timetable_path
)
# Create the timetable node and its tldraw file
neon.create_or_merge_neontology_node(worker_timetable, database=user_db_name, operation='merge')
fs_handler.create_default_tldraw_file(worker_timetable.path, worker_timetable.to_dict())
fs_handler.create_default_tldraw_file(worker_timetable.node_storage_path, worker_timetable.to_dict())
# Link timetable to teacher using the correct relationship structure
neon.create_or_merge_neontology_relationship(
@ -185,9 +185,9 @@ def create_user_worker_timetable(
)
# Get classes from school database
school_classes = get_school_worker_classes(school_db_name, user_node.unique_id, user_worker_node.unique_id)
school_classes = get_school_worker_classes(school_db_name, user_node.uuid_string, user_worker_node.uuid_string)
if not school_classes:
logger.warning(f"No classes found for teacher {user_worker_node.unique_id} in school database")
logger.warning(f"No classes found for teacher {user_worker_node.uuid_string} in school database")
return {
"status": "warning",
"message": "No classes found in school database"
@ -202,15 +202,15 @@ def create_user_worker_timetable(
# Create SubjectClassNode
subject_class_node = SubjectClassNode(
unique_id=class_data['unique_id'],
uuid_string=class_data['uuid_string'],
subject_class_code=class_data['subject_class_code'],
year_group=class_data['year_group'],
subject=class_data['subject'],
subject_code=class_data['subject_code'],
path=class_path
node_storage_path=class_path
)
neon.create_or_merge_neontology_node(subject_class_node, database=user_db_name, operation='merge')
fs_handler.create_default_tldraw_file(subject_class_node.path, subject_class_node.to_dict())
fs_handler.create_default_tldraw_file(subject_class_node.node_storage_path, subject_class_node.to_dict())
# Link class to timetable
neon.create_or_merge_neontology_relationship(
@ -220,27 +220,27 @@ def create_user_worker_timetable(
)
# Initialize empty list for this class's lessons
class_lessons[class_data['unique_id']] = []
class_lessons[class_data['uuid_string']] = []
# Get periods from school database
periods = get_school_class_periods(school_db_name, class_data['unique_id'])
periods = get_school_class_periods(school_db_name, class_data['uuid_string'])
if not periods:
logger.warning(f"No periods found for class {class_data['unique_id']} in school database")
logger.warning(f"No periods found for class {class_data['uuid_string']} in school database")
continue
for period_data in periods:
# Create UserTimetableLessonNode
lesson_unique_id = f"UserTimetableLesson_{timetable_unique_id}_{class_name_safe}_{period_data['date']}_{period_data['period_code']}"
timetable_lesson_node = UserTimetableLessonNode(
unique_id=lesson_unique_id,
# Create TimetableLessonNode
lesson_uuid_string = f"UserTimetableLesson_{timetable_uuid_string}_{class_name_safe}_{period_data['date']}_{period_data['period_code']}"
timetable_lesson_node = TimetableLessonNode(
uuid_string=lesson_uuid_string,
subject_class=class_data['subject_class_code'],
date=period_data['date'],
start_time=period_data['start_time'],
end_time=period_data['end_time'],
period_code=period_data['period_code'],
school_db_name=school_db_name,
school_period_id=period_data['unique_id'],
path="Not set" # Will be set after creating directories
school_period_id=period_data['uuid_string'],
node_storage_path="Not set" # Will be set after creating directories
)
if calendar_day := next(
@ -256,11 +256,11 @@ def create_user_worker_timetable(
class_path,
f"{calendar_day.date}_{period_data['period_code']}"
)
timetable_lesson_node.path = lesson_path
timetable_lesson_node.node_storage_path = lesson_path
# Create and link nodes
neon.create_or_merge_neontology_node(timetable_lesson_node, database=user_db_name, operation='merge')
fs_handler.create_default_tldraw_file(timetable_lesson_node.path, timetable_lesson_node.to_dict())
fs_handler.create_default_tldraw_file(timetable_lesson_node.node_storage_path, timetable_lesson_node.to_dict())
# Link lesson to class
neon.create_or_merge_neontology_relationship(
@ -280,7 +280,7 @@ def create_user_worker_timetable(
)
# Store the lesson node
class_lessons[class_data['unique_id']].append({
class_lessons[class_data['uuid_string']].append({
'node': timetable_lesson_node,
'date': period_data['date'],
'start_time': period_data['start_time']
@ -299,7 +299,7 @@ def create_user_worker_timetable(
next_lesson = sorted_lessons[i + 1]['node']
# Skip if current and next lesson are the same node
if current_lesson.unique_id != next_lesson.unique_id:
if current_lesson.uuid_string != next_lesson.uuid_string:
neon.create_or_merge_neontology_relationship(
TimetableLessonFollowsTimetableLesson(
source=current_lesson,

View File

@ -33,19 +33,19 @@ def init_worker_timetable(timetable_df: pd.DataFrame, school_worker_node: Teache
logging.info(f"Initialising filesystem handler...")
fs_handler = ClassroomCopilotFilesystem(db_name=worker_db_name, init_run_type="user")
_, worker_timetable_path = fs_handler.create_teacher_timetable_directory(worker_node.path)
_, worker_timetable_path = fs_handler.create_teacher_timetable_directory(worker_node.node_storage_path)
logging.info(f"Initialising neo4j connection...")
neon.init_neontology_connection()
try:
timetable_unique_id = f"TeacherTimetable_{worker_node.teacher_code}"
timetable_uuid_string = f"TeacherTimetable_{worker_node.teacher_code}"
worker_timetable = TeacherTimetableNode(
unique_id=timetable_unique_id,
path=worker_timetable_path
uuid_string=timetable_uuid_string,
node_storage_path=worker_timetable_path
)
neon.create_or_merge_neontology_node(worker_timetable, database=worker_db_name, operation='merge')
fs_handler.create_default_tldraw_file(worker_timetable.path, worker_timetable.to_dict())
fs_handler.create_default_tldraw_file(worker_timetable.node_storage_path, worker_timetable.to_dict())
neon.create_or_merge_neontology_relationship(
TeacherHasTimetable(source=worker_node, target=worker_timetable),
database=worker_db_name, operation='merge'
@ -57,28 +57,28 @@ def init_worker_timetable(timetable_df: pd.DataFrame, school_worker_node: Teache
for class_name, class_df in class_groups:
if pd.notna(class_name):
class_name_safe = re.sub(r'[^A-Za-z0-9_ ]+', '', class_name)
_, class_path = fs_handler.create_teacher_class_directory(worker_timetable.path, class_name_safe)
_, class_path = fs_handler.create_teacher_class_directory(worker_timetable.node_storage_path, class_name_safe)
subject_class_node_unique_id = f"SubjectClass_{class_name}"
subject_class_node_uuid_string = f"SubjectClass_{class_name}"
subject_class_node = SubjectClassNode(
unique_id=subject_class_node_unique_id,
uuid_string=subject_class_node_uuid_string,
subject_class_code=class_name,
year_group=str(int(class_df['YearGroup'].iloc[0])), # TODO: Hacky fix for the year group being a float
subject=str(class_df['Subject'].iloc[0]),
subject_code=str(class_df['SubjectCode'].iloc[0]),
path=class_path
node_storage_path=class_path
)
neon.create_or_merge_neontology_node(subject_class_node, database=worker_db_name, operation='merge')
logging.info(f"Class node created: {subject_class_node}")
# Create the tldraw file for the node
fs_handler.create_default_tldraw_file(subject_class_node.path, subject_class_node.to_dict())
fs_handler.create_default_tldraw_file(subject_class_node.node_storage_path, subject_class_node.to_dict())
# Link ClassNode to TeacherTimetableNode
neon.create_or_merge_neontology_relationship(
TimetableHasClass(source=worker_timetable, target=subject_class_node),
database=worker_db_name, operation='merge'
)
logging.info(f"Relationship created from {worker_timetable.unique_id} to {subject_class_node.unique_id}")
logging.info(f"Relationship created from {worker_timetable.uuid_string} to {subject_class_node.uuid_string}")
# Link class to corresponding YearGoupSyllabus
@ -92,7 +92,7 @@ def init_worker_timetable(timetable_df: pd.DataFrame, school_worker_node: Teache
SubjectClassBelongsToYearGroupSyllabus(source=subject_class_node, target=year_group_syllabus_node),
database=worker_db_name, operation='merge'
)
logging.info(f"Relationship created from {subject_class_node.unique_id} to {year_group_syllabus_node.unique_id}")
logging.info(f"Relationship created from {subject_class_node.uuid_string} to {year_group_syllabus_node.uuid_string}")
else:
logging.warning(f"No YearGroupSyllabus found for class {class_name} with year group {subject_class_node.year_group} and subject code {subject_class_node.subject_code}")
@ -125,16 +125,16 @@ def init_worker_timetable(timetable_df: pd.DataFrame, school_worker_node: Teache
date = class_lesson['date']
date_safe = date.strftime("%Y-%m-%d")
# Clean the class_name to make it directory-safe (catch all for invalid characters)
timetable_lesson_unique_id = f"TimetableLesson_{timetable_unique_id}_Class_{class_name}_Lesson_{lesson_number}_{date_safe}_{lesson_period_code}"
timetable_lesson_uuid_string = f"TimetableLesson_{timetable_uuid_string}_Class_{class_name}_Lesson_{lesson_number}_{date_safe}_{lesson_period_code}"
timetable_lesson_node = TimetableLessonNode(
unique_id=timetable_lesson_unique_id,
uuid_string=timetable_lesson_uuid_string,
subject_class=class_name,
date=date,
start_time=class_lesson['start_time'].time(), # TODO: This is probably how we should format the start and end time properties for all such nodes
end_time=class_lesson['end_time'].time(),
period_code=lesson_period_code,
path="Not set"
node_storage_path="Not set"
)
neon.create_or_merge_neontology_node(timetable_lesson_node, database=worker_db_name, operation='merge')
logging.info(f"TimetableLessonNode created: {timetable_lesson_node}")
@ -144,19 +144,19 @@ def init_worker_timetable(timetable_df: pd.DataFrame, school_worker_node: Teache
TimetableLessonBelongsToPeriod(source=timetable_lesson_node, target=period_node),
database=worker_db_name, operation='merge'
)
logging.info(f"Relationship created from {timetable_lesson_node.unique_id} to {period_node.unique_id}")
logging.info(f"Relationship created from {timetable_lesson_node.uuid_string} to {period_node.uuid_string}")
# Link TimetableLessonNode to ClassNode
neon.create_or_merge_neontology_relationship(
ClassHasLesson(source=subject_class_node, target=timetable_lesson_node),
database=worker_db_name, operation='merge'
)
logging.info(f"Relationship created from {subject_class_node.unique_id} to {timetable_lesson_node.unique_id}")
logging.info(f"Relationship created from {subject_class_node.uuid_string} to {timetable_lesson_node.uuid_string}")
# Create PlannedLessonNode
planned_lesson_unique_id = f"PlannedLesson_{timetable_unique_id}_Class_{class_name}_Lesson_{lesson_number}_{date_safe}_{lesson_period_code}"
planned_lesson_uuid_string = f"PlannedLesson_{timetable_uuid_string}_Class_{class_name}_Lesson_{lesson_number}_{date_safe}_{lesson_period_code}"
planned_lesson_node = PlannedLessonNode(
unique_id=planned_lesson_unique_id,
uuid_string=planned_lesson_uuid_string,
date=date,
start_time=class_lesson['start_time'].time(),
end_time=class_lesson['end_time'].time(),
@ -174,7 +174,7 @@ def init_worker_timetable(timetable_df: pd.DataFrame, school_worker_node: Teache
learning_statements=None,
learning_resource_codes=None,
learning_resources=None,
path="Not set"
node_storage_path="Not set"
)
# Create the PlannedLessonNode
neon.create_or_merge_neontology_node(planned_lesson_node, database=worker_db_name, operation='merge')
@ -186,7 +186,7 @@ def init_worker_timetable(timetable_df: pd.DataFrame, school_worker_node: Teache
TimetableLessonHasPlannedLesson(source=timetable_lesson_node, target=planned_lesson_node),
database=worker_db_name, operation='merge'
)
logging.info(f"Relationship created from {timetable_lesson_node.unique_id} to {planned_lesson_node.unique_id}")
logging.info(f"Relationship created from {timetable_lesson_node.uuid_string} to {planned_lesson_node.uuid_string}")
lesson_of_same_period += 1
lesson_number += 1
else:
@ -201,17 +201,17 @@ def init_worker_timetable(timetable_df: pd.DataFrame, school_worker_node: Teache
current_node = class_lesson_nodes[i]
i_safe = f"{i:02d}"
_, class_lesson_path = fs_handler.create_teacher_timetable_lesson_directory(class_path, f"{i_safe}_{current_node.date}_{current_node.period_code}")
current_node.path = class_lesson_path
current_node.node_storage_path = class_lesson_path
neon.create_or_merge_neontology_node(current_node, database=worker_db_name, operation='merge')
logging.info(f"TimetableLessonNode directory created and node merged into database: {current_node}")
# Create the tldraw file for the node
fs_handler.create_default_tldraw_file(current_node.path, current_node.to_dict())
fs_handler.create_default_tldraw_file(current_node.node_storage_path, current_node.to_dict())
if previous_node:
neon.create_or_merge_neontology_relationship(
TimetableLessonFollowsTimetableLesson(source=previous_node, target=current_node),
database=worker_db_name, operation='merge'
)
logging.info(f"Sequential relationship created between {previous_node.unique_id} and {current_node.unique_id}")
logging.info(f"Sequential relationship created between {previous_node.uuid_string} and {current_node.uuid_string}")
# Create sequential relationships for PlannedLessonNodes
for i in range(1, len(planned_lesson_nodes)):
@ -219,17 +219,17 @@ def init_worker_timetable(timetable_df: pd.DataFrame, school_worker_node: Teache
current_node = planned_lesson_nodes[i]
i_safe = f"{i:02d}"
_, planned_lesson_path = fs_handler.create_teacher_planned_lesson_directory(class_path, f"{i_safe}_{current_node.date}_{current_node.period_code}")
current_node.path = planned_lesson_path
current_node.node_storage_path = planned_lesson_path
neon.create_or_merge_neontology_node(current_node, database=worker_db_name, operation='merge')
logging.info(f"PlannedLessonNode directory created and node merged into database: {current_node}")
# Create the tldraw file for the node
fs_handler.create_default_tldraw_file(current_node.path, current_node.to_dict())
fs_handler.create_default_tldraw_file(current_node.node_storage_path, current_node.to_dict())
if previous_node:
neon.create_or_merge_neontology_relationship(
PlannedLessonFollowsPlannedLesson(source=previous_node, target=current_node),
database=worker_db_name, operation='merge'
)
logging.info(f"Sequential relationship created between {previous_node.unique_id} and {current_node.unique_id}")
logging.info(f"Sequential relationship created between {previous_node.uuid_string} and {current_node.uuid_string}")
logging.info(f"Successfully initialized worker timetable for worker {worker_node.teacher_code}")
return {"status": "success", "message": "Worker timetable initialized successfully"}

View File

@ -3,15 +3,15 @@ from modules.database.tools.neontology.basenode import BaseNode
class CCBaseNode(BaseNode):
__primarylabel__: ClassVar[str] = ''
__primaryproperty__: ClassVar[str] = 'unique_id'
unique_id: str
tldraw_snapshot: str
__primaryproperty__: ClassVar[str] = 'uuid_string'
uuid_string: str
node_storage_path: str
def to_dict(self):
return {
"__primarylabel__": self.__primarylabel__,
"unique_id": self.unique_id,
"tldraw_snapshot": self.tldraw_snapshot,
"uuid_string": self.uuid_string,
"node_storage_path": self.node_storage_path,
}
class UserBaseNode(CCBaseNode):
@ -25,8 +25,8 @@ class UserBaseNode(CCBaseNode):
def to_dict(self):
return {
"__primarylabel__": self.__primarylabel__,
"unique_id": self.unique_id,
"tldraw_snapshot": self.tldraw_snapshot,
"uuid_string": self.uuid_string,
"node_storage_path": self.node_storage_path,
"cc_username": self.cc_username,
"user_db_name": self.user_db_name,
"user_email": self.user_email,
@ -43,8 +43,8 @@ class WorkerBaseNode(CCBaseNode):
def to_dict(self):
return {
"__primarylabel__": self.__primarylabel__,
"unique_id": self.unique_id,
"tldraw_snapshot": self.tldraw_snapshot,
"uuid_string": self.uuid_string,
"node_storage_path": self.node_storage_path,
"worker_name": self.worker_name,
"worker_email": self.worker_email,
"worker_db_name": self.worker_db_name,

View File

@ -5,7 +5,7 @@ class SchoolNode(CCBaseNode):
__primarylabel__: ClassVar[str] = 'School'
# Core identification fields (required for all databases)
id: str # School's unique identifier within its type
uuid_string: str # School's unique identifier within its type
school_type: str # e.g., 'development', 'state', 'private', etc.
name: str
website: str = 'unknown'

View File

@ -2,6 +2,7 @@ import os
from typing import Dict, List, Optional
from supabase import create_client
from modules.logger_tool import initialise_logger
from modules.database.services.provisioning_service import ProvisioningService
from pydantic import BaseModel
@ -31,6 +32,7 @@ class AdminService:
"Authorization": f"Bearer {service_role_key}",
"Content-Type": "application/json",
}
self.provisioner = ProvisioningService()
def get_admin_profile(self, admin_id: str) -> Optional[Dict]:
"""Get admin profile by ID"""
@ -88,6 +90,10 @@ class AdminService:
result = (
self.supabase.table("admin_profiles").insert(profile_data).execute()
)
try:
self.provisioner.ensure_user(profile_data["id"])
except Exception as exc:
self.logger.warning(f"Provisioning admin user {profile_data['id']} failed: {exc}")
return result.data[0] if result else None
except Exception as e:
@ -186,6 +192,10 @@ class AdminService:
result = (
self.supabase.table("admin_profiles").insert(profile_data).execute()
)
try:
self.provisioner.ensure_user(profile_data["id"])
except Exception as exc:
self.logger.warning(f"Provisioning super admin {profile_data['id']} failed: {exc}")
return result.data[0] if result else None
except Exception as e:

View File

@ -1,67 +0,0 @@
import os
from typing import Dict, Any
from modules.logger_tool import initialise_logger
import modules.database.tools.neo4j_driver_tools as driver_tools
from modules.database.admin.neontology_provider import NeontologyProvider
from modules.database.admin.graph_provider import GraphNamingProvider
class GraphService:
def __init__(self):
self.logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
self.driver = driver_tools.get_driver()
self.neontology = NeontologyProvider()
self.graph_naming = GraphNamingProvider()
def check_schema_status(self, database_name: str = "neo4j") -> Dict[str, Any]:
"""Check the status of Neo4j schema including constraints, indexes, and labels"""
try:
with self.driver.session(database=database_name) as session:
# Check constraints
constraints_result = session.run("SHOW CONSTRAINTS")
constraints = list(constraints_result)
# Check indexes
indexes_result = session.run("SHOW INDEXES")
indexes = list(indexes_result)
# Check labels
labels_result = session.run("CALL db.labels()")
labels = list(labels_result)
return {
"constraints_count": len(constraints),
"indexes_count": len(indexes),
"labels_count": len(labels),
"constraints": [dict(record) for record in constraints],
"indexes": [dict(record) for record in indexes],
"labels": [dict(record) for record in labels]
}
except Exception as e:
self.logger.error(f"Error checking schema status: {str(e)}")
return {
"constraints_count": 0,
"indexes_count": 0,
"labels_count": 0,
"error": str(e)
}
def initialize_schema(self, database_name: str = "neo4j") -> Dict[str, Any]:
"""Initialize Neo4j schema with required constraints and indexes"""
try:
schema_queries = self.graph_naming.get_schema_creation_queries()
with self.driver.session(database=database_name) as session:
for query in schema_queries:
session.run(query)
return {
"status": "success",
"message": "Schema initialized successfully",
"details": self.check_schema_status(database_name)
}
except Exception as e:
self.logger.error(f"Error initializing schema: {str(e)}")
return {
"status": "error",
"message": str(e)
}

View File

@ -1,45 +0,0 @@
from datetime import datetime, timedelta
import jwt
from typing import Dict, List
class JWTService:
"""JWT Service for Neo4j authentication
TODO: Security Enhancements Needed
- Implement token refresh mechanism
- Add token revocation capability
- Add token validation checks
- Implement rate limiting
- Add audit logging for token generation/usage
- Consider reducing token expiry time and implementing refresh tokens
"""
def __init__(self, secret_key: str, algorithm: str = "HS256"):
self.secret_key = secret_key
self.algorithm = algorithm
def generate_neo4j_token(self, user_data: Dict) -> str:
"""Generate JWT token for Neo4j database access"""
payload = {
"sub": user_data["email"],
"roles": self._get_neo4j_roles(user_data["user_type"]),
"iss": "supabase",
"aud": "neo4j",
"iat": datetime.utcnow(),
"exp": datetime.utcnow() + timedelta(hours=24)
}
if "school_uuid" in user_data:
payload["worker_db_name"] = f"cc.institutes.{user_data['school_uuid']}"
return jwt.encode(payload, self.secret_key, algorithm=self.algorithm)
def _get_neo4j_roles(self, user_type: str) -> List[str]:
"""Map user types to Neo4j roles"""
role_mapping = {
"cc_admin": ["admin", "reader", "writer"],
"developer": ["developer", "reader", "writer"],
"email_teacher": ["teacher", "reader", "writer"],
"email_student": ["student", "reader"]
}
return role_mapping.get(user_type, ["reader"])

View File

@ -86,18 +86,18 @@ class Neo4jService:
with self.driver.session(database=database_name) as session:
# Create constraints
constraints = [
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:School) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Department) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Subject) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:YearGroup) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Class) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Teacher) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Student) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Calendar) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Term) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Week) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Day) REQUIRE n.unique_id IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Period) REQUIRE n.unique_id IS UNIQUE"
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:School) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Department) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Subject) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:YearGroup) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Class) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Teacher) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Student) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Calendar) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Term) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Week) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Day) REQUIRE n.uuid_string IS UNIQUE",
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Period) REQUIRE n.uuid_string IS UNIQUE"
]
# Create indexes

View File

@ -0,0 +1,306 @@
import json
import os
from datetime import datetime, timedelta
from typing import Dict, Optional, Tuple, List
from modules.logger_tool import initialise_logger
from modules.database.services.neo4j_service import Neo4jService
from modules.database.init import init_user
from modules.database.tools.supabase_storage_tools import SupabaseStorageTools
from modules.database.schemas.nodes.schools.schools import SchoolNode
import modules.database.tools.neontology_tools as neon
from modules.database.tools.neontology_tools import create_or_merge_neontology_node
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
_CC_USERS_DB = "cc.users"
_CC_SCHOOLS_DB = "cc.institutes"
_DEFAULT_INSTITUTE_NAME = os.getenv("DEFAULT_INSTITUTE_NAME", "KevlarAI")
_DEFAULT_INSTITUTE_ID = os.getenv("DEFAULT_INSTITUTE_ID")
class ProvisioningService:
"""Coordinates provisioning of Neo4j resources for schools and users."""
def __init__(self):
self.neo4j_service = Neo4jService()
self.supabase = SupabaseServiceRoleClient().supabase
# ------------------------------------------------------------------
# Naming helpers
# ------------------------------------------------------------------
@staticmethod
def _sanitize_component(value: str) -> str:
return "".join(ch for ch in value.lower() if ch.isalnum())
def _build_user_db_name(self, role: str, user_id: str) -> str:
return f"{_CC_USERS_DB}.{self._sanitize_component(role)}.{self._sanitize_component(user_id)}"
def _build_school_db_name(self, institute_id: str) -> str:
return f"{_CC_SCHOOLS_DB}.{self._sanitize_component(institute_id)}"
# ------------------------------------------------------------------
# Supabase helpers
# ------------------------------------------------------------------
def _get_profile(self, user_id: str) -> Dict:
response = (
self.supabase
.table("profiles")
.select("*")
.eq("id", user_id)
.single()
.execute()
)
if not response.data:
raise ValueError(f"Profile {user_id} not found")
return response.data
def _get_membership(self, profile_id: str) -> Optional[Dict]:
response = (
self.supabase
.table("institute_memberships")
.select("*")
.eq("profile_id", profile_id)
.limit(1)
.execute()
)
data = response.data or []
return data[0] if data else None
def _get_institute(self, institute_id: str) -> Optional[Dict]:
response = (
self.supabase
.table("institutes")
.select("*")
.eq("id", institute_id)
.single()
.execute()
)
return response.data if response and response.data else None
def _get_institute_by_name(self, name: str) -> Optional[Dict]:
response = (
self.supabase
.table("institutes")
.select("*")
.eq("name", name)
.limit(1)
.execute()
)
data = response.data or []
return data[0] if data else None
def _determine_membership_role(self, user_type: str) -> str:
if "teacher" in user_type:
return "teacher"
if "student" in user_type:
return "student"
return "staff"
def _ensure_membership(self, profile: Dict, user_type: str) -> Optional[Dict]:
membership = self._get_membership(profile["id"])
if membership:
return membership
institute_id = _DEFAULT_INSTITUTE_ID
institute = None
if institute_id:
institute = self._get_institute(institute_id)
if not institute:
logger.warning(f"Default institute {_DEFAULT_INSTITUTE_ID} not found; attempting lookup by name")
institute_id = None
if not institute_id:
institute = self._get_institute_by_name(_DEFAULT_INSTITUTE_NAME)
if not institute:
raise ValueError(f"Default institute '{_DEFAULT_INSTITUTE_NAME}' not found; cannot create membership")
institute_id = institute["id"]
role = self._determine_membership_role(user_type)
try:
response = (
self.supabase
.table("institute_memberships")
.insert({
"profile_id": profile["id"],
"institute_id": institute_id,
"role": role
})
.execute()
)
data = response.data or []
membership = data[0] if isinstance(data, list) and data else data
email = profile.get("email") or profile.get("user_email") or profile.get("id")
logger.info(f"Created institute membership for {email} -> {institute_id} as {role}")
return membership
except Exception as exc:
logger.warning(f"Failed to create institute membership for {profile['id']}: {exc}")
# Try to fetch again in case of race condition
return self._get_membership(profile["id"])
# ------------------------------------------------------------------
# Provisioning actions
# ------------------------------------------------------------------
def ensure_school(self, institute_id: str) -> Dict[str, str]:
"""Ensure the Neo4j databases and root nodes exist for a school."""
institute = self._get_institute(institute_id)
if not institute:
raise ValueError(f"Institute {institute_id} not found in Supabase")
school_db = self._build_school_db_name(institute_id)
curriculum_db = f"{school_db}.curriculum"
# Ensure root namespaces exist
self.neo4j_service.create_database(_CC_SCHOOLS_DB)
self.neo4j_service.create_database(school_db)
self.neo4j_service.create_database(curriculum_db)
metadata = institute.get("metadata") or {}
if isinstance(metadata, str):
try:
metadata = json.loads(metadata)
except json.JSONDecodeError:
metadata = {}
school_type = metadata.get("school_type") or institute.get("school_type") or "demo"
school_node = SchoolNode(
uuid_string=self._sanitize_component(institute_id),
node_storage_path=f"schools/{self._sanitize_component(institute_id)}/databases/{school_db}/{self._sanitize_component(institute_id)}",
school_type=self._sanitize_component(school_type) or "demo",
name=institute.get("name", "Unknown School"),
website=institute.get("website", "https://example.com"),
)
neon.init_neontology_connection()
try:
create_or_merge_neontology_node(school_node, database=_CC_SCHOOLS_DB, operation='merge')
create_or_merge_neontology_node(school_node, database=school_db, operation='merge')
finally:
neon.close_neontology_connection()
# Try to persist database references back to Supabase (best effort)
updates = {
"neo4j_private_db_name": school_db,
"neo4j_private_sync_status": "ready",
"neo4j_private_sync_at": datetime.utcnow().isoformat(),
}
try:
(
self.supabase
.table("institutes")
.update(updates)
.eq("id", institute_id)
.execute()
)
except Exception as exc: # pragma: no cover - defensive logging only
logger.warning(f"Failed to update institute {institute_id} with db info: {exc}")
return {
"db_name": school_db,
"curriculum_db_name": curriculum_db,
"school_node": school_node,
}
def ensure_user(self, user_id: str) -> Dict[str, Optional[str]]:
"""Provision Neo4j resources for a specific user profile."""
profile = self._get_profile(user_id)
user_type_raw = (profile.get("user_type") or "").lower()
user_type_map = {
"teacher": ("email_teacher", "teacher"),
"email_teacher": ("email_teacher", "teacher"),
"student": ("email_student", "student"),
"email_student": ("email_student", "student"),
"developer": ("developer", "developer"),
"cc_developer": ("developer", "developer"),
"admin": ("superadmin", "superadmin"),
"super_admin": ("superadmin", "superadmin"),
"superadmin": ("superadmin", "superadmin"),
}
neo_user_type, worker_type = user_type_map.get(user_type_raw, (user_type_raw or "standard", user_type_raw or "standard"))
user_db_name = profile.get("user_db_name")
if not user_db_name:
user_db_name = self._build_user_db_name(worker_type, user_id)
full_name = profile.get("full_name") or profile.get("display_name") or profile.get("username") or "User"
username = profile.get("username") or self._sanitize_component(profile.get("email", "user"))
user_email = profile.get("email") or profile.get("user_email") or ""
school_db_name = profile.get("school_db_name")
school_node = None
membership = None
if worker_type in ("teacher", "student"):
membership = self._ensure_membership(profile, user_type_raw)
if not membership:
raise ValueError("Unable to determine institute membership for school-based user")
if membership:
institute_id = membership.get("institute_id")
if institute_id:
ensure_school_result = self.ensure_school(institute_id)
school_db_name = ensure_school_result["db_name"]
school_meta = ensure_school_result.get("school_node")
if isinstance(school_meta, SchoolNode):
school_node = school_meta
else:
school_node = SchoolNode(
uuid_string=self._sanitize_component(institute_id),
node_storage_path="",
school_type=getattr(school_meta, "school_type", "demo") if school_meta else "demo",
name=(school_meta.get("name") if isinstance(school_meta, dict) else None) or "Unknown School",
website=(school_meta.get("website") if isinstance(school_meta, dict) else None) or "https://example.com",
)
# Ensure base namespaces exist before creating user-specific db
self.neo4j_service.create_database(_CC_USERS_DB)
self.neo4j_service.create_database(user_db_name)
calendar_start = datetime.utcnow().date()
calendar_end = (datetime.utcnow() + timedelta(days=365)).date()
# Initialize storage tools for user provisioning
storage_tools = SupabaseStorageTools(user_db_name, init_run_type="user")
init_user.create_user(
user_id=user_id,
user_type=neo_user_type,
username=username,
user_email=user_email,
user_name=full_name,
worker_name=full_name,
worker_type=worker_type,
worker_email=user_email,
cc_users_db_name=_CC_USERS_DB,
user_db_name=user_db_name,
worker_db_name=school_db_name,
calendar_start_date=calendar_start,
calendar_end_date=calendar_end,
school_node=school_node,
storage_tools=storage_tools,
)
profile_updates = {
"user_db_name": user_db_name,
"school_db_name": school_db_name,
"neo4j_sync_status": "ready",
"neo4j_synced_at": datetime.utcnow().isoformat(),
}
try:
(
self.supabase
.table("profiles")
.update(profile_updates)
.eq("id", user_id)
.execute()
)
except Exception as exc: # pragma: no cover - logging only
logger.warning(f"Failed to update profile {user_id} with provisioning info: {exc}")
return {
"user_db_name": user_db_name,
"worker_db_name": school_db_name,
"worker_type": worker_type,
}

View File

@ -1,412 +0,0 @@
import os
from typing import Dict, Any, BinaryIO
import json
import pandas as pd
import modules.database.tools.neo4j_driver_tools as driver_tools
import modules.database.tools.neo4j_session_tools as session_tools
import modules.database.schemas.nodes.schools.schools as school_nodes
import modules.database.schemas.nodes.schools.curriculum as curriculum_nodes
import modules.database.schemas.nodes.schools.pastoral as pastoral_nodes
import modules.database.schemas.nodes.structures.schools as school_structures
from modules.database.schemas.entities import entities
from modules.database.schemas.relationships import curriculum_relationships, entity_relationships, entity_curriculum_rels
from modules.database.admin.neontology_provider import NeontologyProvider
from modules.database.admin.graph_provider import GraphNamingProvider
from modules.database.supabase.utils.client import SupabaseAnonClient
from modules.database.supabase.utils.storage import StorageManager
from modules.database.services.neo4j_service import Neo4jService
from modules.logger_tool import initialise_logger
class SchoolAdminService:
def __init__(self):
self.logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
self.driver = driver_tools.get_driver()
self.neontology = NeontologyProvider()
self.graph_naming = GraphNamingProvider()
self.storage = StorageManager(SupabaseAnonClient)
self.neo4j_service = Neo4jService()
def check_database_exists(self, database_name: str) -> Dict[str, Any]:
"""Check if a Neo4j database exists"""
return self.neo4j_service.check_database_exists(database_name)
def create_database(self, db_name: str) -> Dict:
"""Creates a Neo4j database with the given name"""
return self.neo4j_service.create_database(db_name)
def create_school_node(self, school_data: Dict) -> Dict:
"""Creates a school node in cc.institutes database and stores TLDraw file in Supabase"""
try:
# Convert school data to SchoolNode
school_unique_id = self.graph_naming.get_school_unique_id(school_data['urn'])
school_path = self.graph_naming.get_school_path("cc.institutes", school_data['urn'])
school_node = entities.SchoolNode(
unique_id=school_unique_id,
path=school_path,
urn=school_data['urn'],
establishment_number=school_data['establishment_number'],
establishment_name=school_data['establishment_name'],
establishment_type=school_data['establishment_type'],
establishment_status=school_data['establishment_status'],
phase_of_education=school_data['phase_of_education'] if school_data['phase_of_education'] not in [None, ''] else None,
statutory_low_age=int(school_data['statutory_low_age']) if school_data.get('statutory_low_age') is not None else 0,
statutory_high_age=int(school_data['statutory_high_age']) if school_data.get('statutory_high_age') is not None else 0,
religious_character=school_data.get('religious_character') if school_data.get('religious_character') not in [None, ''] else None,
school_capacity=int(school_data['school_capacity']) if school_data.get('school_capacity') is not None else 0,
school_website=school_data.get('school_website', ''),
ofsted_rating=school_data.get('ofsted_rating') if school_data.get('ofsted_rating') not in [None, ''] else None
)
# Create default tldraw file data
tldraw_data = {
"document": {
"version": 1,
"id": school_data['urn'],
"name": school_data['establishment_name'],
"meta": {
"created_at": "",
"updated_at": "",
"creator_id": "",
"is_template": False,
"is_snapshot": False,
"is_draft": False,
"template_id": None,
"snapshot_id": None,
"draft_id": None
}
},
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 22
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"cc-school-node": 1
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"store": {
"document:document": {
"gridSize": 10,
"name": school_data['establishment_name'],
"meta": {},
"id": school_data['urn'],
"typeName": "document"
},
"page:page": {
"meta": {},
"id": "page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
"shape:school-node": {
"x": 0,
"y": 0,
"rotation": 0,
"type": "cc-school-node",
"id": school_unique_id,
"parentId": "page",
"index": "a1",
"props": school_node.to_dict(),
"typeName": "shape"
},
"instance:instance": {
"id": "instance",
"currentPageId": "page",
"typeName": "instance"
},
"camera:camera": {
"x": 0,
"y": 0,
"z": 1,
"id": "camera",
"typeName": "camera"
}
}
}
# Store tldraw file in Supabase storage
file_path = f"{school_data['urn']}/tldraw.json"
file_options = {
"content-type": "application/json",
"x-upsert": "true",
"metadata": {
"establishment_urn": school_data['urn'],
"establishment_name": school_data['establishment_name']
}
}
# Upload file
self.storage.upload_file(
bucket_id="cc.institutes",
file_path=file_path,
file_data=json.dumps(tldraw_data).encode(),
content_type="application/json",
upsert=True
)
# Create node in Neo4j
with self.neontology as neo:
self.logger.info(f"Creating school node in Neo4j: {school_node.to_dict()}")
neo.create_or_merge_node(school_node, database="cc.institutes", operation="merge")
return {"status": "success", "node": school_node}
except Exception as e:
self.logger.error(f"Error creating school node: {str(e)}")
return {"status": "error", "message": str(e)}
def create_private_database(self, school_data: Dict) -> Dict:
"""Creates a private database for a specific school"""
try:
private_db_name = f"cc.institutes.{school_data['urn']}"
with self.driver.session() as session:
session_tools.create_database(session, private_db_name)
self.logger.info(f"Created private database {private_db_name}")
return {
"status": "success",
"message": f"Database {private_db_name} created successfully"
}
except Exception as e:
self.logger.error(f"Error creating private database: {str(e)}")
return {"status": "error", "message": str(e)}
def create_basic_structure(self, school_node: school_nodes.SchoolNode, database_name: str) -> Dict:
"""Creates basic structural nodes in the specified database"""
try:
# Create Department Structure node
department_structure_node_unique_id = f"DepartmentStructure_{school_node.unique_id}"
department_structure_node = entities.DepartmentStructureNode(
unique_id=department_structure_node_unique_id,
tldraw_snapshot=""
)
# Create Curriculum Structure node
curriculum_node = curriculum_nodes.CurriculumStructureNode(
unique_id=f"CurriculumStructure_{school_node.unique_id}",
tldraw_snapshot=""
)
# Create Pastoral Structure node
pastoral_node = school_structures.PastoralStructureNode(
unique_id=f"PastoralStructure_{school_node.unique_id}",
tldraw_snapshot=""
)
with self.neontology as neo:
# Create nodes
neo.create_or_merge_node(department_structure_node, database=str(database_name), operation='merge')
neo.create_or_merge_node(curriculum_node, database=str(database_name), operation='merge')
neo.create_or_merge_node(pastoral_node, database=str(database_name), operation='merge')
# Create relationships
neo.create_or_merge_relationship(
entity_relationships.SchoolHasDepartmentStructure(source=school_node, target=department_structure_node),
database=database_name, operation='merge'
)
neo.create_or_merge_relationship(
entity_curriculum_rels.SchoolHasCurriculumStructure(source=school_node, target=curriculum_node),
database=database_name, operation='merge'
)
neo.create_or_merge_relationship(
entity_curriculum_rels.SchoolHasPastoralStructure(source=school_node, target=pastoral_node),
database=database_name, operation='merge'
)
return {
"status": "success",
"message": "Basic structure created successfully",
"nodes": {
"department_structure": department_structure_node,
"curriculum_structure": curriculum_node,
"pastoral_structure": pastoral_node
}
}
except Exception as e:
self.logger.error(f"Error creating basic structure: {str(e)}")
return {"status": "error", "message": str(e)}
def create_detailed_structure(self, school_node: school_nodes.SchoolNode, database_name: str, excel_file: BinaryIO) -> Dict:
"""Creates detailed structural nodes from Excel file"""
try:
# Store Excel file in Supabase
file_path = f"{school_node.urn}/structure.xlsx"
# Upload Excel file
self.storage.upload_file(
bucket_id="cc.institutes",
file_path=file_path,
file_data=excel_file.read(),
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
upsert=True
)
# Process Excel file
dataframes = pd.read_excel(excel_file, sheet_name=None)
# Get existing basic structure nodes
with self.neontology as neo:
result = neo.cypher_read("""
MATCH (s:School {unique_id: $school_id})
OPTIONAL MATCH (s)-[:HAS_DEPARTMENT_STRUCTURE]->(ds:DepartmentStructure)
OPTIONAL MATCH (s)-[:HAS_CURRICULUM_STRUCTURE]->(cs:CurriculumStructure)
OPTIONAL MATCH (s)-[:HAS_PASTORAL_STRUCTURE]->(ps:PastoralStructure)
RETURN ds, cs, ps
""", {"school_id": school_node.unique_id}, database=database_name)
if not result:
raise Exception("Basic structure not found")
department_structure = result['ds']
curriculum_structure = result['cs']
pastoral_structure = result['ps']
# Create departments and subjects
unique_departments = dataframes['keystagesyllabuses']['Department'].dropna().unique()
node_library = {}
with self.neontology as neo:
for department_name in unique_departments:
department_node = entities.DepartmentNode(
unique_id=f"Department_{school_node.unique_id}_{department_name.replace(' ', '_')}",
department_name=department_name,
tldraw_snapshot=""
)
neo.create_or_merge_node(department_node, database=database_name, operation='merge')
node_library[f'department_{department_name}'] = department_node
# Link to department structure
neo.create_or_merge_relationship(
entity_relationships.DepartmentStructureHasDepartment(
source=department_structure,
target=department_node
),
database=database_name,
operation='merge'
)
# Create year groups
year_groups = self.sort_year_groups(dataframes['yeargroupsyllabuses'])['YearGroup'].unique()
last_year_group_node = None
for year_group in year_groups:
numeric_year_group = pd.to_numeric(year_group, errors='coerce')
if pd.notna(numeric_year_group):
year_group_node = pastoral_nodes.YearGroupNode(
unique_id=f"YearGroup_{school_node.unique_id}_YGrp{int(numeric_year_group)}",
year_group=str(int(numeric_year_group)),
year_group_name=f"Year {int(numeric_year_group)}",
tldraw_snapshot=""
)
neo.create_or_merge_node(year_group_node, database=database_name, operation='merge')
node_library[f'year_group_{int(numeric_year_group)}'] = year_group_node
# Create sequential relationship
if last_year_group_node:
neo.create_or_merge_relationship(
curriculum_relationships.YearGroupFollowsYearGroup(
source=last_year_group_node,
target=year_group_node
),
database=database_name,
operation='merge'
)
last_year_group_node = year_group_node
# Link to pastoral structure
neo.create_or_merge_relationship(
curriculum_relationships.PastoralStructureIncludesYearGroup(
source=pastoral_structure,
target=year_group_node
),
database=database_name,
operation='merge'
)
# Create key stages
key_stages = dataframes['keystagesyllabuses']['KeyStage'].unique()
last_key_stage_node = None
for key_stage in sorted(key_stages):
key_stage_node = curriculum_nodes.KeyStageNode(
unique_id=f"KeyStage_{curriculum_structure.unique_id}_KStg{key_stage}",
key_stage_name=f"Key Stage {key_stage}",
key_stage=str(key_stage),
tldraw_snapshot=""
)
neo.create_or_merge_node(key_stage_node, database=database_name, operation='merge')
node_library[f'key_stage_{key_stage}'] = key_stage_node
# Create sequential relationship
if last_key_stage_node:
neo.create_or_merge_relationship(
curriculum_relationships.KeyStageFollowsKeyStage(
source=last_key_stage_node,
target=key_stage_node
),
database=database_name,
operation='merge'
)
last_key_stage_node = key_stage_node
# Link to curriculum structure
neo.create_or_merge_relationship(
curriculum_relationships.CurriculumStructureIncludesKeyStage(
source=curriculum_structure,
target=key_stage_node
),
database=database_name,
operation='merge'
)
return {
"status": "success",
"message": "Detailed structure created successfully",
"node_library": node_library
}
except Exception as e:
self.logger.error(f"Error creating detailed structure: {str(e)}")
return {"status": "error", "message": str(e)}
def sort_year_groups(self, df: pd.DataFrame) -> pd.DataFrame:
"""Helper function to sort year groups numerically"""
df = df.copy()
df['YearGroupNumeric'] = pd.to_numeric(df['YearGroup'], errors='coerce')
return df.sort_values(by='YearGroupNumeric')

View File

@ -1,472 +0,0 @@
import os
from typing import Dict, List, Optional, BinaryIO
import json
import pandas as pd
from backend.modules.database.schemas import entities
from modules.logger_tool import initialise_logger
from modules.database.tools.filesystem_tools import ClassroomCopilotFilesystem
import modules.database.tools.neo4j_driver_tools as driver_tools
import modules.database.tools.neo4j_session_tools as session_tools
from modules.database.admin.neontology_provider import NeontologyProvider
from modules.database.admin.graph_provider import GraphNamingProvider
from modules.database.schemas import curriculum_neo
from modules.database.schemas.relationships import curriculum_relationships, entity_relationships, entity_curriculum_rels
from modules.database.supabase.utils.storage import StorageManager
class SchoolService:
def __init__(self):
self.logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
self.driver = driver_tools.get_driver()
self.neontology = NeontologyProvider()
self.graph_naming = GraphNamingProvider()
self.storage = StorageManager()
def create_schools_database(self) -> Dict:
"""Creates the main cc.institutes database in Neo4j"""
try:
db_name = "cc.institutes"
with self.driver.session() as session:
session_tools.create_database(session, db_name)
self.logger.info(f"Created database {db_name}")
return {
"status": "success",
"message": f"Database {db_name} created successfully"
}
except Exception as e:
self.logger.error(f"Error creating schools database: {str(e)}")
return {"status": "error", "message": str(e)}
def create_school_node(self, school_data: Dict) -> Dict:
"""Creates a school node in cc.institutes database and stores TLDraw file in Supabase"""
try:
# Convert school data to SchoolNode
school_unique_id = self.graph_naming.get_school_unique_id(school_data['urn'])
school_path = self.graph_naming.get_school_path("cc.institutes", school_data['urn'])
school_node = entities.SchoolNode(
unique_id=school_unique_id,
path=school_path,
urn=school_data['urn'],
establishment_number=school_data['establishment_number'],
establishment_name=school_data['establishment_name'],
establishment_type=school_data['establishment_type'],
establishment_status=school_data['establishment_status'],
phase_of_education=school_data['phase_of_education'] if school_data['phase_of_education'] not in [None, ''] else None,
statutory_low_age=int(school_data['statutory_low_age']) if school_data.get('statutory_low_age') is not None else 0,
statutory_high_age=int(school_data['statutory_high_age']) if school_data.get('statutory_high_age') is not None else 0,
religious_character=school_data.get('religious_character') if school_data.get('religious_character') not in [None, ''] else None,
school_capacity=int(school_data['school_capacity']) if school_data.get('school_capacity') is not None else 0,
school_website=school_data.get('school_website', ''),
ofsted_rating=school_data.get('ofsted_rating') if school_data.get('ofsted_rating') not in [None, ''] else None
)
# Create default tldraw file data
tldraw_data = {
"document": {
"version": 1,
"id": school_data['urn'],
"name": school_data['establishment_name'],
"meta": {
"created_at": "",
"updated_at": "",
"creator_id": "",
"is_template": False,
"is_snapshot": False,
"is_draft": False,
"template_id": None,
"snapshot_id": None,
"draft_id": None
}
},
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": {}
},
"camera": {
"version": 1
},
"document": {
"version": 2
},
"instance": {
"version": 22
},
"instance_page_state": {
"version": 5
},
"page": {
"version": 1
},
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"cc-school-node": 1
}
},
"instance_presence": {
"version": 5
},
"pointer": {
"version": 1
}
}
},
"store": {
"document:document": {
"gridSize": 10,
"name": school_data['establishment_name'],
"meta": {},
"id": school_data['urn'],
"typeName": "document"
},
"page:page": {
"meta": {},
"id": "page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
"shape:school-node": {
"x": 0,
"y": 0,
"rotation": 0,
"type": "cc-school-node",
"id": school_unique_id,
"parentId": "page",
"index": "a1",
"props": school_node.to_dict(),
"typeName": "shape"
},
"instance:instance": {
"id": "instance",
"currentPageId": "page",
"typeName": "instance"
},
"camera:camera": {
"x": 0,
"y": 0,
"z": 1,
"id": "camera",
"typeName": "camera"
}
}
}
# Store tldraw file in Supabase storage
file_path = f"{school_data['urn']}/tldraw.json"
file_options = {
"content-type": "application/json",
"x-upsert": "true",
"metadata": {
"establishment_urn": school_data['urn'],
"establishment_name": school_data['establishment_name']
}
}
# Upload file
self.storage.upload_file(
bucket_id="cc.institutes",
file_path=file_path,
file_data=json.dumps(tldraw_data).encode(),
content_type="application/json",
upsert=True
)
# Create node in Neo4j
with self.neontology as neo:
self.logger.info(f"Creating school node in Neo4j: {school_node.to_dict()}")
neo.create_or_merge_node(school_node, database="cc.institutes", operation="merge")
return {"status": "success", "node": school_node}
except Exception as e:
self.logger.error(f"Error creating school node: {str(e)}")
return {"status": "error", "message": str(e)}
def create_private_database(self, school_data: Dict) -> Dict:
"""Creates a private database for a specific school"""
try:
private_db_name = f"cc.institutes.{school_data['urn']}"
with self.driver.session() as session:
session_tools.create_database(session, private_db_name)
self.logger.info(f"Created private database {private_db_name}")
return {
"status": "success",
"message": f"Database {private_db_name} created successfully"
}
except Exception as e:
self.logger.error(f"Error creating private database: {str(e)}")
return {"status": "error", "message": str(e)}
def create_basic_structure(self, school_node: entities.SchoolNode, database_name: str) -> Dict:
"""Creates basic structural nodes in the specified database"""
try:
# Create filesystem paths
fs_handler = ClassroomCopilotFilesystem(database_name, init_run_type="school")
# Create Department Structure node
department_structure_node_unique_id = f"DepartmentStructure_{school_node.unique_id}"
_, department_path = fs_handler.create_school_department_directory(school_node.path, "departments")
department_structure_node = entities.DepartmentStructureNode(
unique_id=department_structure_node_unique_id,
path=department_path
)
# Create Curriculum Structure node
_, curriculum_path = fs_handler.create_school_curriculum_directory(school_node.path)
curriculum_node = curriculum_neo.CurriculumStructureNode(
unique_id=f"CurriculumStructure_{school_node.unique_id}",
path=curriculum_path
)
# Create Pastoral Structure node
_, pastoral_path = fs_handler.create_school_pastoral_directory(school_node.path)
pastoral_node = curriculum_neo.PastoralStructureNode(
unique_id=f"PastoralStructure_{school_node.unique_id}",
path=pastoral_path
)
with self.neontology as neo:
# Create nodes
neo.create_or_merge_node(department_structure_node, database=str(database_name), operation='merge')
fs_handler.create_default_tldraw_file(department_structure_node.path, department_structure_node.to_dict())
neo.create_or_merge_node(curriculum_node, database=str(database_name), operation='merge')
fs_handler.create_default_tldraw_file(curriculum_node.path, curriculum_node.to_dict())
neo.create_or_merge_node(pastoral_node, database=database_name, operation='merge')
fs_handler.create_default_tldraw_file(pastoral_node.path, pastoral_node.to_dict())
# Create relationships
neo.create_or_merge_relationship(
entity_relationships.SchoolHasDepartmentStructure(source=school_node, target=department_structure_node),
database=database_name, operation='merge'
)
neo.create_or_merge_relationship(
entity_curriculum_rels.SchoolHasCurriculumStructure(source=school_node, target=curriculum_node),
database=database_name, operation='merge'
)
neo.create_or_merge_relationship(
entity_curriculum_rels.SchoolHasPastoralStructure(source=school_node, target=pastoral_node),
database=database_name, operation='merge'
)
return {
"status": "success",
"message": "Basic structure created successfully",
"nodes": {
"department_structure": department_structure_node,
"curriculum_structure": curriculum_node,
"pastoral_structure": pastoral_node
}
}
except Exception as e:
self.logger.error(f"Error creating basic structure: {str(e)}")
return {"status": "error", "message": str(e)}
def create_detailed_structure(self, school_node: entities.SchoolNode, database_name: str, excel_file: BinaryIO) -> Dict:
"""Creates detailed structural nodes from Excel file"""
try:
# Store Excel file in Supabase
file_path = f"{school_node.urn}/structure.xlsx"
# Upload Excel file
self.storage.upload_file(
bucket_id="cc.institutes",
file_path=file_path,
file_data=excel_file.read(),
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
upsert=True
)
# Process Excel file
dataframes = pd.read_excel(excel_file, sheet_name=None)
# Get existing basic structure nodes
with self.neontology as neo:
result = neo.cypher_read("""
MATCH (s:School {unique_id: $school_id})
OPTIONAL MATCH (s)-[:HAS_DEPARTMENT_STRUCTURE]->(ds:DepartmentStructure)
OPTIONAL MATCH (s)-[:HAS_CURRICULUM_STRUCTURE]->(cs:CurriculumStructure)
OPTIONAL MATCH (s)-[:HAS_PASTORAL_STRUCTURE]->(ps:PastoralStructure)
RETURN ds, cs, ps
""", {"school_id": school_node.unique_id}, database=database_name)
if not result:
raise Exception("Basic structure not found")
department_structure = result['ds']
curriculum_structure = result['cs']
pastoral_structure = result['ps']
# Create departments and subjects
unique_departments = dataframes['keystagesyllabuses']['Department'].dropna().unique()
fs_handler = ClassroomCopilotFilesystem(database_name, init_run_type="school")
node_library = {}
with self.neontology as neo:
for department_name in unique_departments:
_, department_path = fs_handler.create_school_department_directory(school_node.path, department_name)
department_node = entities.DepartmentNode(
unique_id=f"Department_{school_node.unique_id}_{department_name.replace(' ', '_')}",
department_name=department_name,
path=department_path
)
neo.create_or_merge_node(department_node, database=database_name, operation='merge')
fs_handler.create_default_tldraw_file(department_node.path, department_node.to_dict())
node_library[f'department_{department_name}'] = department_node
# Link to department structure
neo.create_or_merge_relationship(
entity_relationships.DepartmentStructureHasDepartment(
source=department_structure,
target=department_node
),
database=database_name,
operation='merge'
)
# Create year groups
year_groups = self.sort_year_groups(dataframes['yeargroupsyllabuses'])['YearGroup'].unique()
last_year_group_node = None
for year_group in year_groups:
numeric_year_group = pd.to_numeric(year_group, errors='coerce')
if pd.notna(numeric_year_group):
_, year_group_path = fs_handler.create_pastoral_year_group_directory(
pastoral_structure.path,
str(int(numeric_year_group))
)
year_group_node = curriculum_neo.YearGroupNode(
unique_id=f"YearGroup_{school_node.unique_id}_YGrp{int(numeric_year_group)}",
year_group=str(int(numeric_year_group)),
year_group_name=f"Year {int(numeric_year_group)}",
path=year_group_path
)
neo.create_or_merge_node(year_group_node, database=database_name, operation='merge')
fs_handler.create_default_tldraw_file(year_group_node.path, year_group_node.to_dict())
node_library[f'year_group_{int(numeric_year_group)}'] = year_group_node
# Create sequential relationship
if last_year_group_node:
neo.create_or_merge_relationship(
curriculum_relationships.YearGroupFollowsYearGroup(
source=last_year_group_node,
target=year_group_node
),
database=database_name,
operation='merge'
)
last_year_group_node = year_group_node
# Link to pastoral structure
neo.create_or_merge_relationship(
curriculum_relationships.PastoralStructureIncludesYearGroup(
source=pastoral_structure,
target=year_group_node
),
database=database_name,
operation='merge'
)
# Create key stages
key_stages = dataframes['keystagesyllabuses']['KeyStage'].unique()
last_key_stage_node = None
for key_stage in sorted(key_stages):
_, key_stage_path = fs_handler.create_curriculum_key_stage_directory(
curriculum_structure.path,
str(key_stage)
)
key_stage_node = curriculum_neo.KeyStageNode(
unique_id=f"KeyStage_{curriculum_structure.unique_id}_KStg{key_stage}",
key_stage_name=f"Key Stage {key_stage}",
key_stage=str(key_stage),
path=key_stage_path
)
neo.create_or_merge_node(key_stage_node, database=database_name, operation='merge')
fs_handler.create_default_tldraw_file(key_stage_node.path, key_stage_node.to_dict())
node_library[f'key_stage_{key_stage}'] = key_stage_node
# Create sequential relationship
if last_key_stage_node:
neo.create_or_merge_relationship(
curriculum_relationships.KeyStageFollowsKeyStage(
source=last_key_stage_node,
target=key_stage_node
),
database=database_name,
operation='merge'
)
last_key_stage_node = key_stage_node
# Link to curriculum structure
neo.create_or_merge_relationship(
curriculum_relationships.CurriculumStructureIncludesKeyStage(
source=curriculum_structure,
target=key_stage_node
),
database=database_name,
operation='merge'
)
return {
"status": "success",
"message": "Detailed structure created successfully",
"node_library": node_library
}
except Exception as e:
self.logger.error(f"Error creating detailed structure: {str(e)}")
return {"status": "error", "message": str(e)}
def sort_year_groups(self, df: pd.DataFrame) -> pd.DataFrame:
"""Helper function to sort year groups numerically"""
df = df.copy()
df['YearGroupNumeric'] = pd.to_numeric(df['YearGroup'], errors='coerce')
return df.sort_values(by='YearGroupNumeric')
def check_schools_database(self) -> Dict:
"""Check if the schools database exists and has been initialized"""
try:
db_name = "cc.institutes"
with self.driver.session() as session:
# Check if database exists
databases = session_tools.list_databases(session)
if db_name not in databases:
return {
"status": "error",
"message": f"Database {db_name} does not exist"
}
# Check if database has any nodes (indicating it's been initialized)
session.run("USE " + db_name)
result = session.run("MATCH (n) RETURN count(n) as count").single()
node_count = result["count"] if result else 0
if node_count == 0:
return {
"status": "error",
"message": f"Database {db_name} exists but has no nodes"
}
return {
"status": "success",
"message": f"Database {db_name} exists and has {node_count} nodes"
}
except Exception as e:
self.logger.error(f"Error checking schools database: {str(e)}")
return {"status": "error", "message": str(e)}

View File

@ -14,14 +14,13 @@ class CreateBucketOptions(TypedDict, total=False):
allowed_mime_types: List[str]
name: str
def _create_base_client(url: str, key: str, options: Optional[Dict[str, Any]] = None, access_token: Optional[str] = None) -> Client:
def _create_base_client(url: str, key: str, options: Optional[Dict[str, Any]] = None) -> Client:
"""Create a base Supabase client with given configuration."""
client_options = SyncClientOptions(
schema="public",
storage=SyncMemoryStorage(),
headers={
"apikey": key,
"Authorization": f"Bearer {access_token if access_token else key}"
"Authorization": f"Bearer {key}"
}
)
return create_client(url, key, options=client_options)
@ -29,16 +28,16 @@ def _create_base_client(url: str, key: str, options: Optional[Dict[str, Any]] =
class SupabaseServiceRoleClient:
"""Supabase client for making authenticated requests using the service role key"""
def __init__(self, url: Optional[str] = None, service_role_key: Optional[str] = None, access_token: Optional[str] = None):
def __init__(self, url: Optional[str] = None, service_role_key: Optional[str] = None):
"""Initialize the Supabase client with URL and service role key"""
self.url = url or os.environ.get("SUPABASE_URL", "http://kong:8000")
self.url = url or os.environ.get("SUPABASE_URL", "http://localhost:8000")
self.service_role_key = service_role_key or os.environ.get("SERVICE_ROLE_KEY")
if not self.url or not self.service_role_key:
raise ValueError("SUPABASE_URL and SERVICE_ROLE_KEY must be provided")
# Initialize Supabase client with service role key and optional access token
self.supabase = _create_base_client(self.url, self.service_role_key, access_token=access_token)
self.supabase = _create_base_client(self.url, self.service_role_key)
def create_bucket(self, id: str, options: Optional[CreateBucketOptions] = None) -> Dict[str, Any]:
"""Create a storage bucket with the given ID and options"""
@ -48,17 +47,12 @@ class SupabaseServiceRoleClient:
options['name'] = id # Use ID as default name if not provided
return self.supabase.storage.create_bucket(id, options=options)
@classmethod
def for_admin(cls, access_token: str) -> 'SupabaseServiceRoleClient':
"""Create a client instance for the super admin using their access token"""
return cls(access_token=access_token)
class SupabaseAnonClient:
"""Supabase client for making authenticated requests using the anon key"""
def __init__(self, url: Optional[str] = None, anon_key: Optional[str] = None, access_token: Optional[str] = None):
"""Initialize the Supabase client with URL and anon key"""
self.url = url or os.environ.get("SUPABASE_URL", "http://kong:8000")
self.url = url or os.environ.get("SUPABASE_URL", "http://localhost:8000")
self.anon_key = anon_key or os.environ.get("ANON_KEY")
if not self.url or not self.anon_key:

View File

@ -18,7 +18,6 @@ import re
class ClassroomCopilotFilesystem:
def __init__(self, db_name: str, init_run_type: str = None):
logging.info(f"Initializing ClassroomCopilotFilesystem with db_name: {db_name} and init_run_type: {init_run_type}")
self.db_name = db_name
@ -27,19 +26,21 @@ class ClassroomCopilotFilesystem:
if not self.base_path:
raise ValueError("NODE_FILESYSTEM_PATH environment variable not set")
logging.info(f"Initializing ClassroomCopilotFilesystem with db_name: {db_name} and init_run_type: {init_run_type} with base path: {self.base_path}")
# Set root path based on init type
if init_run_type == "school":
self.root_path = os.path.join(self.base_path, "schools", self.db_name)
self.root_path = os.path.join(self.base_path, "schools")
logging.debug(f"School root path: {self.root_path}")
elif init_run_type == "user":
self.root_path = os.path.join(self.base_path, "users", self.db_name)
self.root_path = os.path.join(self.base_path, "users")
logging.debug(f"User root path: {self.root_path}")
elif init_run_type == "multiplayer":
self.root_path = os.path.join(self.base_path, "multiplayer")
logging.debug(f"Multiplayer root path: {self.root_path}")
else:
self.root_path = os.path.join(self.base_path, self.db_name)
logging.debug(f"Default root path: {self.root_path}")
self.root_path = self.base_path
logging.debug(f"Database root path: {self.root_path}")
# Ensure root directory exists
os.makedirs(self.root_path, exist_ok=True)
@ -63,45 +64,33 @@ class ClassroomCopilotFilesystem:
return True
return False
def sanitize_username(self, username):
return re.sub(r'[^\w\-_\.]', '_', username)
def create_user_directory(self, username, user_type=None, school_path=None):
def create_private_user_directory(self, user_id):
"""Create a directory for a specific user."""
sanitized_username = self.sanitize_username(username)
if school_path:
# For school database: /schools/[school_db]/users/[user_type]/[username]
user_path = os.path.join(self.root_path, "users", user_type, sanitized_username)
else:
# For user database: /users/[user_db]/[username]
user_path = os.path.join(self.root_path, sanitized_username)
# For user database: /users/[user_db]/[username]
user_path = os.path.join(self.root_path, user_id)
logging.info(f"Creating user directory at {user_path}")
return self.create_directory(user_path), user_path
def create_user_worker_directory(self, user_path, worker_code):
def create_user_worker_directory(self, user_path, worker_id, worker_type):
"""Create a worker directory under the user directory."""
# Create worker directory: [user_path]/[worker_code]
worker_path = os.path.join(user_path, worker_code)
worker_path = os.path.join(user_path, worker_type, worker_id)
logging.info(f"Creating worker directory at {worker_path}")
return self.create_directory(worker_path), worker_path
def create_school_worker_directory(self, school_path, worker_type):
def create_school_worker_directory(self, school_path, worker_type, worker_id):
"""Create a worker directory under the school directory."""
worker_path = os.path.join(school_path, "workers", worker_type)
logging.info(f"Creating school worker directory at {worker_path}")
worker_path = os.path.join(school_path, "workers", worker_type, worker_id)
logging.info(f"Creating school {worker_type} worker directory at {worker_path}")
return self.create_directory(worker_path), worker_path
def create_school_directory(self, school_uuid=None):
def create_school_directory(self, school_uuid_string):
"""Create a directory for a specific school."""
logging.info(f"Creating school directory with school_uuid: {school_uuid}")
if school_uuid is None:
logging.debug(f"School UUID is None, creating school directory at {self.root_path}")
school_path = self.root_path
else:
logging.debug(f"School UUID is not None, creating school directory at {os.path.join(self.root_path, school_uuid)}")
school_path = os.path.join(self.root_path, school_uuid)
logging.info(f"Creating school directory with uuid_string: {school_uuid_string}")
logging.debug(f"School UUID is not None, creating school directory at {os.path.join(self.root_path, school_uuid_string)}")
school_path = os.path.join(self.root_path, school_uuid_string)
return self.create_directory(school_path), school_path
def create_year_directory(self, year, calendar_path=None):
@ -248,7 +237,12 @@ class ClassroomCopilotFilesystem:
"""Create a directory for a specific topic under a year group syllabus."""
topic_path = os.path.join(year_group_syllabus_path, "topics", f"{topic_id}")
return self.create_directory(topic_path), topic_path
def create_curriculum_keystage_topic_directory(self, keystage_syllabus_path, topic_id):
"""Create a directory for a specific key stage topic under a key stage group syllabus."""
topic_path = os.path.join(keystage_syllabus_path, "core_topics", f"{topic_id}")
return self.create_directory(topic_path), topic_path
def create_curriculum_lesson_directory(self, topic_path, lesson_id):
"""Create a directory for a specific lesson under a topic."""
lesson_path = os.path.join(topic_path, "lessons", f"{lesson_id}")
@ -276,285 +270,4 @@ class ClassroomCopilotFilesystem:
def create_teacher_planned_lesson_directory(self, class_path, lesson_id):
planned_lesson_path = os.path.join(class_path, "planned_lessons", lesson_id)
return self.create_directory(planned_lesson_path), planned_lesson_path
# TLDraw File Creation
def create_default_tldraw_file(self, node_path, node_data):
"""Create a tldraw file for a node."""
logging.info(f"Creating tldraw file for node at {node_path}")
# Ensure the directory exists
os.makedirs(node_path, exist_ok=True)
tldraw_path = os.path.join(node_path, 'tldraw_file.json')
# Create default tldraw content
tldraw_content = {
"document": {
"store": {
"document:document": {
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
"page:page": {
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
}
},
"schema":
{"schemaVersion":2,
"sequences": {
"com.tldraw.store":4,
"com.tldraw.asset":1,
"com.tldraw.camera":1,
"com.tldraw.document":2,
"com.tldraw.instance":25,
"com.tldraw.instance_page_state":5,
"com.tldraw.page":1,
"com.tldraw.instance_presence":5,
"com.tldraw.pointer":1,
"com.tldraw.shape":4,
"com.tldraw.asset.bookmark":2,
"com.tldraw.asset.image":5,
"com.tldraw.asset.video":5,
"com.tldraw.shape.arrow":5,
"com.tldraw.shape.bookmark":2,
"com.tldraw.shape.draw":2,
"com.tldraw.shape.embed":4,
"com.tldraw.shape.frame":0,
"com.tldraw.shape.geo":9,
"com.tldraw.shape.group":0,
"com.tldraw.shape.highlight":1,
"com.tldraw.shape.image":4,
"com.tldraw.shape.line":5,
"com.tldraw.shape.note":8,
"com.tldraw.shape.text":2,
"com.tldraw.shape.video":2,
"com.tldraw.shape.youtube-embed":0,
"com.tldraw.shape.calendar":0,
"com.tldraw.shape.microphone":1,
"com.tldraw.shape.transcriptionText":0,
"com.tldraw.shape.slide":0,"com.tldraw.shape.slideshow":0,
"com.tldraw.shape.user_node":1,
"com.tldraw.shape.developer_node":1,
"com.tldraw.shape.student_node":1,
"com.tldraw.shape.teacher_node":1,
"com.tldraw.shape.calendar_node":1,
"com.tldraw.shape.calendar_year_node":1,
"com.tldraw.shape.calendar_month_node":1,
"com.tldraw.shape.calendar_week_node":1,
"com.tldraw.shape.calendar_day_node":1,
"com.tldraw.shape.calendar_time_chunk_node":1,
"com.tldraw.shape.teacher_timetable_node":1,
"com.tldraw.shape.timetable_lesson_node":1,
"com.tldraw.shape.planned_lesson_node":1,
"com.tldraw.shape.pastoral_structure_node":1,
"com.tldraw.shape.year_group_node":1,
"com.tldraw.shape.curriculum_structure_node":1,
"com.tldraw.shape.key_stage_node":1,
"com.tldraw.shape.key_stage_syllabus_node":1,
"com.tldraw.shape.year_group_syllabus_node":1,
"com.tldraw.shape.subject_node":1,
"com.tldraw.shape.topic_node":1,
"com.tldraw.shape.topic_lesson_node":1,
"com.tldraw.shape.learning_statement_node":1,
"com.tldraw.shape.science_lab_node":1,
"com.tldraw.shape.school_timetable_node":1,
"com.tldraw.shape.academic_year_node":1,
"com.tldraw.shape.academic_term_node":1,
"com.tldraw.shape.academic_week_node":1,
"com.tldraw.shape.academic_day_node":1,
"com.tldraw.shape.academic_period_node":1,
"com.tldraw.shape.registration_period_node":1,
"com.tldraw.shape.school_node":1,
"com.tldraw.shape.department_node":1,
"com.tldraw.shape.room_node":1,
"com.tldraw.shape.subject_class_node":1,
"com.tldraw.shape.general_relationship":1,
"com.tldraw.binding.arrow":0,
"com.tldraw.binding.slide-layout":0
}
},
"recordVersions": {
"asset": { "version": 1, "subTypeKey": "type", "subTypeVersions": {} },
"camera": { "version": 1 },
"document": { "version": 2 },
"instance": { "version": 21 },
"instance_page_state": { "version": 5 },
"page": { "version": 1 },
"shape": { "version": 3, "subTypeKey": "type", "subTypeVersions": {} },
"instance_presence": { "version": 5 },
"pointer": { "version": 1 }
},
"rootShapeIds":[],
"bindings":[],
"assets":[]
},
"session": {
"version": 0,
"currentPageId": "page:page",
"pageStates": [{
"pageId": "page:page",
"camera": {"x": 0, "y": 0, "z": 1},
"selectedShapeIds": []
}]
},
"node_data": node_data
}
with open(tldraw_path, 'w') as f:
json.dump(tldraw_content, f, indent=4)
logging.info(f"tldraw file created at {tldraw_path}")
return tldraw_path
def create_default_tldraw_file_in_storage(self, admin_supabase, bucket_id, file_path, node_data):
"""Create a tldraw file in Supabase storage."""
logging.info(f"Creating tldraw file in storage at {file_path}")
# Create default tldraw content
tldraw_content = {
"document": {
"store": {
"document:document": {
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
"page:page": {
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
}
},
"schema":
{"schemaVersion":2,
"sequences": {
"com.tldraw.store":4,
"com.tldraw.asset":1,
"com.tldraw.camera":1,
"com.tldraw.document":2,
"com.tldraw.instance":25,
"com.tldraw.instance_page_state":5,
"com.tldraw.page":1,
"com.tldraw.instance_presence":5,
"com.tldraw.pointer":1,
"com.tldraw.shape":4,
"com.tldraw.asset.bookmark":2,
"com.tldraw.asset.image":5,
"com.tldraw.asset.video":5,
"com.tldraw.shape.arrow":5,
"com.tldraw.shape.bookmark":2,
"com.tldraw.shape.draw":2,
"com.tldraw.shape.embed":4,
"com.tldraw.shape.frame":0,
"com.tldraw.shape.geo":9,
"com.tldraw.shape.group":0,
"com.tldraw.shape.highlight":1,
"com.tldraw.shape.image":4,
"com.tldraw.shape.line":5,
"com.tldraw.shape.note":8,
"com.tldraw.shape.text":2,
"com.tldraw.shape.video":2,
"com.tldraw.shape.youtube-embed":0,
"com.tldraw.shape.calendar":0,
"com.tldraw.shape.microphone":1,
"com.tldraw.shape.transcriptionText":0,
"com.tldraw.shape.slide":0,"com.tldraw.shape.slideshow":0,
"com.tldraw.shape.user_node":1,
"com.tldraw.shape.developer_node":1,
"com.tldraw.shape.student_node":1,
"com.tldraw.shape.teacher_node":1,
"com.tldraw.shape.calendar_node":1,
"com.tldraw.shape.calendar_year_node":1,
"com.tldraw.shape.calendar_month_node":1,
"com.tldraw.shape.calendar_week_node":1,
"com.tldraw.shape.calendar_day_node":1,
"com.tldraw.shape.calendar_time_chunk_node":1,
"com.tldraw.shape.teacher_timetable_node":1,
"com.tldraw.shape.timetable_lesson_node":1,
"com.tldraw.shape.planned_lesson_node":1,
"com.tldraw.shape.pastoral_structure_node":1,
"com.tldraw.shape.year_group_node":1,
"com.tldraw.shape.curriculum_structure_node":1,
"com.tldraw.shape.key_stage_node":1,
"com.tldraw.shape.key_stage_syllabus_node":1,
"com.tldraw.shape.year_group_syllabus_node":1,
"com.tldraw.shape.subject_node":1,
"com.tldraw.shape.topic_node":1,
"com.tldraw.shape.topic_lesson_node":1,
"com.tldraw.shape.learning_statement_node":1,
"com.tldraw.shape.science_lab_node":1,
"com.tldraw.shape.school_timetable_node":1,
"com.tldraw.shape.academic_year_node":1,
"com.tldraw.shape.academic_term_node":1,
"com.tldraw.shape.academic_week_node":1,
"com.tldraw.shape.academic_day_node":1,
"com.tldraw.shape.academic_period_node":1,
"com.tldraw.shape.registration_period_node":1,
"com.tldraw.shape.school_node":1,
"com.tldraw.shape.department_node":1,
"com.tldraw.shape.room_node":1,
"com.tldraw.shape.subject_class_node":1,
"com.tldraw.shape.general_relationship":1,
"com.tldraw.binding.arrow":0,
"com.tldraw.binding.slide-layout":0
}
},
"recordVersions": {
"asset": { "version": 1, "subTypeKey": "type", "subTypeVersions": {} },
"camera": { "version": 1 },
"document": { "version": 2 },
"instance": { "version": 21 },
"instance_page_state": { "version": 5 },
"page": { "version": 1 },
"shape": { "version": 3, "subTypeKey": "type", "subTypeVersions": {} },
"instance_presence": { "version": 5 },
"pointer": { "version": 1 }
},
"rootShapeIds":[],
"bindings":[],
"assets":[]
},
"session": {
"version": 0,
"currentPageId": "page:page",
"pageStates": [{
"pageId": "page:page",
"camera": {"x": 0, "y": 0, "z": 1},
"selectedShapeIds": []
}]
},
"node_data": node_data
}
# Convert the content to JSON string
tldraw_json = json.dumps(tldraw_content, indent=4)
try:
# Upload the file to Supabase storage
result = admin_supabase.storage.from_(bucket_id).upload(
path=file_path,
file=tldraw_json,
file_options={"content-type": "application/json"}
)
if result.get('error'):
logging.error(f"Error creating tldraw file in storage: {result['error']}")
raise Exception(f"Failed to create tldraw file: {result['error']}")
logging.info(f"tldraw file created in storage at {file_path}")
return True
except Exception as e:
logging.error(f"Error creating tldraw file in storage: {str(e)}")
raise e
return self.create_directory(planned_lesson_path), planned_lesson_path

View File

@ -13,8 +13,8 @@ def get_static_nodes(context: str, db_name: str) -> List[Dict[str, Any]]:
query = """
MATCH (t:Teacher)
RETURN DISTINCT {
id: t.unique_id,
path: t.path,
id: t.uuid_string,
path: t.node_storage_path,
label: t.teacher_name_formal,
type: 'Teacher',
isStatic: true,
@ -24,8 +24,8 @@ def get_static_nodes(context: str, db_name: str) -> List[Dict[str, Any]]:
UNION ALL
MATCH (t:UserTeacherTimetable)
RETURN DISTINCT {
id: t.unique_id,
path: t.path,
id: t.uuid_string,
path: t.node_storage_path,
label: t.name,
type: 'UserTeacherTimetable',
isStatic: true,
@ -35,8 +35,8 @@ def get_static_nodes(context: str, db_name: str) -> List[Dict[str, Any]]:
UNION ALL
MATCH (t:UserTeacherTimetable)-[:HAS_CLASS]->(c:Class)
RETURN DISTINCT {
id: c.unique_id,
path: c.path,
id: c.uuid_string,
path: c.node_storage_path,
label: c.name,
type: 'Class',
isStatic: true,
@ -49,8 +49,8 @@ def get_static_nodes(context: str, db_name: str) -> List[Dict[str, Any]]:
query = """
MATCH (u:User)
RETURN DISTINCT {
id: u.unique_id,
path: u.path,
id: u.uuid_string,
path: u.node_storage_path,
label: u.user_name,
type: 'User',
isStatic: true,
@ -70,8 +70,8 @@ def get_static_nodes(context: str, db_name: str) -> List[Dict[str, Any]]:
ELSE 1
END as nodeOrder
RETURN DISTINCT {
id: n.unique_id,
path: n.path,
id: n.uuid_string,
path: n.node_storage_path,
label: n.name,
type: 'Calendar',
isStatic: true,
@ -98,7 +98,7 @@ def get_today_calendar_node(db_name: str) -> Optional[Dict[str, Any]]:
query = """
MATCH (n:Calendar)
WHERE date($today) >= date(n.start_date) AND date($today) <= date(n.end_date)
RETURN n.unique_id as id, n.path as path, n.name as label,
RETURN n.uuid_string as id, n.path as path, n.name as label,
'Calendar' as type
LIMIT 1
"""
@ -117,7 +117,7 @@ def get_relative_calendar_node(day_offset: int, db_name: str) -> Optional[Dict[s
query = """
MATCH (n:Calendar)
WHERE date($target_date) >= date(n.start_date) AND date($target_date) <= date(n.end_date)
RETURN n.unique_id as id, n.path as path, n.name as label,
RETURN n.uuid_string as id, n.node_storage_path as path, n.name as label,
'Calendar' as type
LIMIT 1
"""
@ -136,7 +136,7 @@ def get_next_month_node(db_name: str) -> Optional[Dict[str, Any]]:
query = """
MATCH (n:Calendar)
WHERE date($next_month_start) >= date(n.start_date) AND date($next_month_start) <= date(n.end_date)
RETURN n.unique_id as id, n.path as path, n.name as label,
RETURN n.uuid_string as id, n.node_storage_path as path, n.name as label,
'Calendar' as type
LIMIT 1
"""
@ -155,7 +155,7 @@ def get_previous_month_node(db_name: str) -> Optional[Dict[str, Any]]:
query = """
MATCH (n:Calendar)
WHERE date($prev_month_start) >= date(n.start_date) AND date($prev_month_start) <= date(n.end_date)
RETURN n.unique_id as id, n.path as path, n.name as label,
RETURN n.uuid_string as id, n.node_storage_path as path, n.name as label,
'Calendar' as type
LIMIT 1
"""
@ -172,7 +172,7 @@ def get_user_timetables(db_name: str) -> List[Dict[str, Any]]:
"""Get user's timetables."""
query = """
MATCH (t:UserTeacherTimetable)
RETURN t.unique_id as id, t.path as path, t.name as label,
RETURN t.uuid_string as id, t.node_storage_path as path, t.name as label,
'UserTeacherTimetable' as type
"""
try:
@ -186,8 +186,8 @@ def get_user_timetables(db_name: str) -> List[Dict[str, Any]]:
def get_timetable_classes(timetable_id: str, db_name: str) -> List[Dict[str, Any]]:
"""Get classes for a timetable."""
query = """
MATCH (t:UserTeacherTimetable {unique_id: $timetable_id})-[:HAS_CLASS]->(c:Class)
RETURN c.unique_id as id, c.path as path, c.name as label,
MATCH (t:UserTeacherTimetable {uuid_string: $timetable_id})-[:HAS_CLASS]->(c:Class)
RETURN c.uuid_string as id, c.node_storage_path as path, c.name as label,
'Class' as type
"""
try:
@ -202,9 +202,9 @@ def get_next_lesson(class_id: str, db_name: str) -> Optional[Dict[str, Any]]:
"""Get next lesson for a class."""
now = datetime.now().strftime("%Y-%m-%d %H:%M")
query = """
MATCH (c:Class {unique_id: $class_id})-[:HAS_LESSON]->(l:Lesson)
MATCH (c:Class {uuid_string: $class_id})-[:HAS_LESSON]->(l:Lesson)
WHERE l.start_time > $now
RETURN l.unique_id as id, l.path as path, l.name as label,
RETURN l.uuid_string as id, l.node_storage_path as path, l.name as label,
'Lesson' as type
ORDER BY l.start_time ASC
LIMIT 1
@ -222,9 +222,9 @@ def get_previous_lesson(class_id: str, db_name: str) -> Optional[Dict[str, Any]]
"""Get previous lesson for a class."""
now = datetime.now().strftime("%Y-%m-%d %H:%M")
query = """
MATCH (c:Class {unique_id: $class_id})-[:HAS_LESSON]->(l:Lesson)
MATCH (c:Class {uuid_string: $class_id})-[:HAS_LESSON]->(l:Lesson)
WHERE l.start_time < $now
RETURN l.unique_id as id, l.path as path, l.name as label,
RETURN l.uuid_string as id, l.path as path, l.name as label,
'Lesson' as type
ORDER BY l.start_time DESC
LIMIT 1
@ -251,20 +251,20 @@ def save_shared_snapshot(path: str, room_id: str, snapshot: Dict[str, Any]) -> b
def get_connected_nodes_for_workers(node_id: str, db_name: str) -> List[Dict[str, Any]]:
"""Get connected nodes specific to the workers context."""
query = """
MATCH (n {unique_id: $node_id})
MATCH (n {uuid_string: $node_id})
WITH n
CALL {
WITH n
MATCH (n:UserTeacherTimetable)-[:HAS_CLASS]->(c:Class)
RETURN c.unique_id as id, c.path as path, c.name as label,
RETURN c.uuid_string as id, c.node_storage_path as path, c.name as label,
'Class' as type
UNION
MATCH (n:Class)<-[:HAS_CLASS]-(t:UserTeacherTimetable)
RETURN t.unique_id as id, t.path as path, t.name as label,
RETURN t.uuid_string as id, t.node_storage_path as path, t.name as label,
'UserTeacherTimetable' as type
UNION
MATCH (n:Class)-[:HAS_LESSON]->(l:Lesson)
RETURN l.unique_id as id, l.path as path, l.name as label,
RETURN l.uuid_string as id, l.node_storage_path as path, l.name as label,
'Lesson' as type
}
RETURN DISTINCT id, path, label, type
@ -284,8 +284,8 @@ def get_connected_nodes(node_id: str, db_name: str, context: str = None) -> List
# Default query for other contexts
query = """
MATCH (n {unique_id: $node_id})-[r]-(connected)
RETURN DISTINCT connected.unique_id as id, connected.path as path,
MATCH (n {uuid_string: $node_id})-[r]-(connected)
RETURN DISTINCT connected.uuid_string as id, connected.path as path,
connected.name as label, labels(connected)[0] as type
"""
try:
@ -314,37 +314,37 @@ def get_worker_structure(db_name: str) -> Dict[str, Any]:
// Collect all nodes
RETURN {
schools: collect(DISTINCT {
id: s.unique_id,
path: s.path,
id: s.uuid_string,
path: s.node_storage_path,
name: s.school_name,
__primarylabel__: 'School'
}),
departments: collect(DISTINCT {
id: d.unique_id,
path: d.path,
id: d.uuid_string,
path: d.node_storage_path,
code: d.department_code,
school_id: s.unique_id,
school_id: s.uuid_string,
__primarylabel__: 'Department'
}),
timetables: collect(DISTINCT {
id: t.unique_id,
path: t.path,
id: t.uuid_string,
path: t.node_storage_path,
name: t.name,
department_id: d.unique_id,
department_id: d.uuid_string,
__primarylabel__: 'UserTeacherTimetable'
}),
classes: collect(DISTINCT {
id: c.unique_id,
path: c.path,
id: c.uuid_string,
path: c.node_storage_path,
code: c.class_code,
timetable_id: t.unique_id,
timetable_id: t.uuid_string,
__primarylabel__: 'Class'
}),
lessons: collect(DISTINCT {
id: l.unique_id,
path: l.path,
id: l.uuid_string,
path: l.node_storage_path,
start_time: l.start_time,
class_id: c.unique_id,
class_id: c.uuid_string,
__primarylabel__: 'TimetableLesson'
})
} as structure
@ -369,10 +369,10 @@ def get_worker_structure(db_name: str) -> Dict[str, Any]:
def get_school_node(school_id: str, db_name: str) -> Optional[Dict[str, Any]]:
"""Get a specific school node."""
query = """
MATCH (s:School {unique_id: $school_id})
MATCH (s:School {uuid_string: $school_id})
RETURN {
id: s.unique_id,
path: s.path,
id: s.uuid_string,
path: s.node_storage_path,
name: s.school_name,
__primarylabel__: 'School'
} as node
@ -389,10 +389,10 @@ def get_school_node(school_id: str, db_name: str) -> Optional[Dict[str, Any]]:
def get_department_node(dept_id: str, db_name: str) -> Optional[Dict[str, Any]]:
"""Get a specific department node."""
query = """
MATCH (d:Department {unique_id: $dept_id})
MATCH (d:Department {uuid_string: $dept_id})
RETURN {
id: d.unique_id,
path: d.path,
id: d.uuid_string,
path: d.node_storage_path,
code: d.department_code,
__primarylabel__: 'Department'
} as node
@ -409,10 +409,10 @@ def get_department_node(dept_id: str, db_name: str) -> Optional[Dict[str, Any]]:
def get_timetable_node(timetable_id: str, db_name: str) -> Optional[Dict[str, Any]]:
"""Get a specific timetable node."""
query = """
MATCH (t:UserTeacherTimetable {unique_id: $timetable_id})
MATCH (t:UserTeacherTimetable {uuid_string: $timetable_id})
RETURN {
id: t.unique_id,
path: t.path,
id: t.uuid_string,
path: t.node_storage_path,
name: t.name,
__primarylabel__: 'UserTeacherTimetable'
} as node
@ -429,10 +429,10 @@ def get_timetable_node(timetable_id: str, db_name: str) -> Optional[Dict[str, An
def get_class_node(class_id: str, db_name: str) -> Optional[Dict[str, Any]]:
"""Get a specific class node."""
query = """
MATCH (c:Class {unique_id: $class_id})
MATCH (c:Class {uuid_string: $class_id})
RETURN {
id: c.unique_id,
path: c.path,
id: c.uuid_string,
path: c.node_storage_path,
code: c.class_code,
__primarylabel__: 'Class'
} as node
@ -449,10 +449,10 @@ def get_class_node(class_id: str, db_name: str) -> Optional[Dict[str, Any]]:
def get_lesson_node(lesson_id: str, db_name: str) -> Optional[Dict[str, Any]]:
"""Get a specific lesson node."""
query = """
MATCH (l:TimetableLesson {unique_id: $lesson_id})
MATCH (l:TimetableLesson {uuid_string: $lesson_id})
RETURN {
id: l.unique_id,
path: l.path,
id: l.uuid_string,
path: l.node_storage_path,
start_time: l.start_time,
__primarylabel__: 'TimetableLesson'
} as node
@ -473,8 +473,8 @@ def get_current_lesson(db_name: str) -> Optional[Dict[str, Any]]:
MATCH (l:TimetableLesson)
WHERE l.start_time >= $now
RETURN {
id: l.unique_id,
path: l.path,
id: l.uuid_string,
path: l.node_storage_path,
start_time: l.start_time,
__primarylabel__: 'TimetableLesson'
} as node

View File

@ -15,8 +15,6 @@ logging = logger.get_logger(
import requests
import base64
dev_mode = os.getenv('DEV_MODE', 'false')
def send_query(query, encoded_credentials=None, params=None, method='POST', database="system", endpoint="/tx/commit"):
if encoded_credentials is None:
logging.debug(f"Sending query to Neo4j: {query}")

View File

@ -15,16 +15,16 @@ logging = logger.get_logger(
import modules.database.tools.queries as query
from contextlib import suppress
def get_node_by_unique_id_and_adjacent_nodes(session, unique_id):
return session.read_transaction(_get_node_by_unique_id_and_adjacent_nodes, unique_id)
def get_node_by_uuid_string_and_adjacent_nodes(session, uuid_string):
return session.read_transaction(_get_node_by_uuid_string_and_adjacent_nodes, uuid_string)
def _get_node_by_unique_id_and_adjacent_nodes(tx, unique_id):
def _get_node_by_uuid_string_and_adjacent_nodes(tx, uuid_string):
query = """
MATCH (n {unique_id: $unique_id})
MATCH (n {uuid_string: $uuid_string})
OPTIONAL MATCH (n)-[r]-(adjacent)
RETURN n AS node, COLLECT(DISTINCT {node: adjacent, relationship: r}) AS connected_nodes
"""
result = tx.run(query, unique_id=unique_id)
result = tx.run(query, uuid_string=uuid_string)
record = result.single()
if record:
node = record["node"]
@ -242,20 +242,20 @@ def _find_nodes_by_label(tx, label):
result = tx.run(query)
return [record["n"] for record in result]
def get_node_by_unique_id(session, unique_id):
return session.read_transaction(_get_node_by_unique_id, unique_id)
def get_node_by_uuid_string(session, uuid_string):
return session.read_transaction(_get_node_by_uuid_string, uuid_string)
def _get_node_by_unique_id(tx, unique_id):
def _get_node_by_uuid_string(tx, uuid_string):
query = f"""
MATCH (n)
WHERE n.unique_id = $unique_id
WHERE n.uuid_string = $uuid_string
RETURN n
"""
logging.debug(f"Executing query with unique_id: {unique_id}")
result = tx.run(query, unique_id=unique_id)
logging.debug(f"Executing query with uuid_string: {uuid_string}")
result = tx.run(query, uuid_string=uuid_string)
record = result.single()
if record is None:
logging.warning(f"No node found with unique_id: {unique_id}")
logging.warning(f"No node found with uuid_string: {uuid_string}")
return None
return record[0]

View File

@ -70,11 +70,10 @@ class BaseNode(CommonModel): # pyre-ignore[13]
def merge(self, database: str = 'neo4j') -> None:
"""Merge this node into the graph."""
params = self._get_merge_parameters()
all_labels = [self.__primarylabel__] + self.__secondarylabels__
cypher = f"""
MERGE (n:{":".join(all_labels)} {{ {self.__primaryproperty__}: $pp }})
ON MATCH SET n += $set_on_match
@ -82,10 +81,15 @@ class BaseNode(CommonModel): # pyre-ignore[13]
SET n += $always_set
RETURN n
"""
print(f"DEBUG: Executing merge query: {cypher}")
print(f"DEBUG: With params: {params}")
print(f"DEBUG: Database: {database}")
graph = GraphConnection()
with graph.driver.session(database=database) as session:
result = session.run(cypher, params).single()
print(f"DEBUG: Merge result: {result}")
if result:
return self.__class__(**dict(result["n"]))
return None

View File

@ -60,14 +60,20 @@ def create_or_merge_neontology_node(node: BaseNode, database: str = 'neo4j', ope
operation (str): The operation to perform ('create' or 'merge'). Defaults to 'merge'.
"""
try:
logging.debug(f"Creating/merging node: {node.__class__.__name__} with label '{node.__primarylabel__}' in database '{database}'")
logging.debug(f"Node data: {node.to_dict()}")
if operation == "create":
node.create(database=database)
result = node.create(database=database)
logging.debug(f"Create result: {result}")
elif operation == "merge":
node.merge(database=database)
result = node.merge(database=database)
logging.debug(f"Merge result: {result}")
else:
logging.error(f"Invalid operation: {operation}")
except Exception as e:
logging.error(f"Error in processing node: {e}")
raise # Re-raise to see the actual error
# Create or merge a Neontology node in the Neo4j database. If a ValidationError occurs
# due to a NaN value, replace it with a default value and retry.

View File

@ -0,0 +1,451 @@
"""
Supabase Storage Tools for ClassroomCopilot
Replaces local filesystem paths with Supabase Storage bucket paths
"""
import os
from modules.logger_tool import initialise_logger
from typing import Tuple, Optional
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
class SupabaseStorageTools:
"""
Generates Supabase Storage paths for TLDraw snapshots and other files.
Path format: bucket/nodetype/node_unique_id
Example: cc.snapshots/User/fda8dca7-4d18-43c9-bb74-260777043447
"""
def __init__(self, db_name: str, init_run_type: str = None):
self.db_name = db_name
self.init_run_type = init_run_type
# Define bucket mappings based on node types
self.bucket_mappings = {
'User': 'cc.public.snapshots',
'Teacher': 'cc.public.snapshots',
'Student': 'cc.public.snapshots',
'School': 'cc.public.snapshots',
'Department': 'cc.public.snapshots',
'Subject': 'cc.public.snapshots',
'CalendarYear': 'cc.public.snapshots',
'CalendarMonth': 'cc.public.snapshots',
'CalendarWeek': 'cc.public.snapshots',
'CalendarDay': 'cc.public.snapshots',
'CalendarTimeChunk': 'cc.public.snapshots',
'KeyStage': 'cc.public.snapshots',
'YearGroup': 'cc.public.snapshots',
'KeyStageSyllabus': 'cc.public.snapshots',
'YearGroupSyllabus': 'cc.public.snapshots',
'Topic': 'cc.public.snapshots',
'TopicLesson': 'cc.public.snapshots',
'LearningStatement': 'cc.public.snapshots',
'UserTeacherTimetable': 'cc.public.snapshots',
'Class': 'cc.public.snapshots',
'TimetableLesson': 'cc.public.snapshots',
'SuperAdmin': 'cc.public.snapshots',
'Developer': 'cc.public.snapshots',
'CurriculumStructure': 'cc.public.snapshots',
'PastoralStructure': 'cc.public.snapshots',
'DepartmentStructure': 'cc.public.snapshots',
}
logger.info(f"Initializing SupabaseStorageTools with db_name: {db_name} and init_run_type: {init_run_type}")
def get_storage_path(self, node_type: str, node_id: str) -> str:
"""
Generate Supabase Storage path for a node.
Args:
node_type: The type of node (e.g., 'User', 'Teacher', 'School')
node_id: The unique identifier for the node
Returns:
str: Storage path in format bucket/nodetype/node_id
"""
bucket = self.bucket_mappings.get(node_type, 'cc.public.snapshots')
path = f"{bucket}/{node_type}/{node_id}"
logger.debug(f"Generated storage path for {node_type} {node_id}: {path}")
return path
def create_user_storage_path(self, user_id: str) -> Tuple[bool, str]:
"""
Create storage path for a user node.
Args:
user_id: The user's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('User', user_id)
logger.info(f"Created user storage path: {path}")
return True, path
def create_teacher_storage_path(self, teacher_id: str) -> Tuple[bool, str]:
"""
Create storage path for a teacher node.
Args:
teacher_id: The teacher's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('Teacher', teacher_id)
logger.info(f"Created teacher storage path: {path}")
return True, path
def create_student_storage_path(self, student_id: str) -> Tuple[bool, str]:
"""
Create storage path for a student node.
Args:
student_id: The student's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('Student', student_id)
logger.info(f"Created student storage path: {path}")
return True, path
def create_school_storage_path(self, school_id: str) -> Tuple[bool, str]:
"""
Create storage path for a school node.
Args:
school_id: The school's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('School', school_id)
logger.info(f"Created school storage path: {path}")
return True, path
def create_calendar_year_storage_path(self, year: int) -> Tuple[bool, str]:
"""
Create storage path for a calendar year node.
Args:
year: The year
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('CalendarYear', str(year))
logger.info(f"Created calendar year storage path: {path}")
return True, path
def create_calendar_month_storage_path(self, year: int, month: int) -> Tuple[bool, str]:
"""
Create storage path for a calendar month node.
Args:
year: The year
month: The month
Returns:
Tuple[bool, str]: (success, storage_path)
"""
month_id = f"{year}_{month:02d}"
path = self.get_storage_path('CalendarMonth', month_id)
logger.info(f"Created calendar month storage path: {path}")
return True, path
def create_calendar_week_storage_path(self, year: int, week: int) -> Tuple[bool, str]:
"""
Create storage path for a calendar week node.
Args:
year: The ISO year
week: The ISO week number
Returns:
Tuple[bool, str]: (success, storage_path)
"""
week_id = f"{year}_{week:02d}"
path = self.get_storage_path('CalendarWeek', week_id)
logger.info(f"Created calendar week storage path: {path}")
return True, path
def create_calendar_day_storage_path(self, year: int, month: int, day: int) -> Tuple[bool, str]:
"""
Create storage path for a calendar day node.
Args:
year: The year
month: The month
day: The day
Returns:
Tuple[bool, str]: (success, storage_path)
"""
day_id = f"{year}_{month:02d}_{day:02d}"
path = self.get_storage_path('CalendarDay', day_id)
logger.info(f"Created calendar day storage path: {path}")
return True, path
def create_calendar_time_chunk_storage_path(self, day_id: str, chunk_index: int) -> Tuple[bool, str]:
"""
Create storage path for a calendar time chunk node.
Args:
day_id: The day identifier (e.g., "2025_01_15")
chunk_index: The time chunk index within the day
Returns:
Tuple[bool, str]: (success, storage_path)
"""
chunk_id = f"{day_id}_{chunk_index:02d}"
path = self.get_storage_path('CalendarTimeChunk', chunk_id)
logger.info(f"Created calendar time chunk storage path: {path}")
return True, path
def create_department_storage_path(self, department_id: str) -> Tuple[bool, str]:
"""
Create storage path for a department node.
Args:
department_id: The department's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('Department', department_id)
logger.info(f"Created department storage path: {path}")
return True, path
def create_subject_storage_path(self, subject_id: str) -> Tuple[bool, str]:
"""
Create storage path for a subject node.
Args:
subject_id: The subject's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('Subject', subject_id)
logger.info(f"Created subject storage path: {path}")
return True, path
def create_key_stage_storage_path(self, key_stage_id: str) -> Tuple[bool, str]:
"""
Create storage path for a key stage node.
Args:
key_stage_id: The key stage's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('KeyStage', key_stage_id)
logger.info(f"Created key stage storage path: {path}")
return True, path
def create_year_group_storage_path(self, year_group_id: str) -> Tuple[bool, str]:
"""
Create storage path for a year group node.
Args:
year_group_id: The year group's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('YearGroup', year_group_id)
logger.info(f"Created year group storage path: {path}")
return True, path
def create_key_stage_syllabus_storage_path(self, syllabus_id: str) -> Tuple[bool, str]:
"""
Create storage path for a key stage syllabus node.
Args:
syllabus_id: The syllabus's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('KeyStageSyllabus', syllabus_id)
logger.info(f"Created key stage syllabus storage path: {path}")
return True, path
def create_year_group_syllabus_storage_path(self, syllabus_id: str) -> Tuple[bool, str]:
"""
Create storage path for a year group syllabus node.
Args:
syllabus_id: The syllabus's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('YearGroupSyllabus', syllabus_id)
logger.info(f"Created year group syllabus storage path: {path}")
return True, path
def create_topic_storage_path(self, topic_id: str) -> Tuple[bool, str]:
"""
Create storage path for a topic node.
Args:
topic_id: The topic's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('Topic', topic_id)
logger.info(f"Created topic storage path: {path}")
return True, path
def create_topic_lesson_storage_path(self, lesson_id: str) -> Tuple[bool, str]:
"""
Create storage path for a topic lesson node.
Args:
lesson_id: The lesson's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('TopicLesson', lesson_id)
logger.info(f"Created topic lesson storage path: {path}")
return True, path
def create_learning_statement_storage_path(self, statement_id: str) -> Tuple[bool, str]:
"""
Create storage path for a learning statement node.
Args:
statement_id: The statement's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('LearningStatement', statement_id)
logger.info(f"Created learning statement storage path: {path}")
return True, path
def create_timetable_storage_path(self, timetable_id: str) -> Tuple[bool, str]:
"""
Create storage path for a timetable node.
Args:
timetable_id: The timetable's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('UserTeacherTimetable', timetable_id)
logger.info(f"Created timetable storage path: {path}")
return True, path
def create_class_storage_path(self, class_id: str) -> Tuple[bool, str]:
"""
Create storage path for a class node.
Args:
class_id: The class's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('Class', class_id)
logger.info(f"Created class storage path: {path}")
return True, path
def create_timetable_lesson_storage_path(self, lesson_id: str) -> Tuple[bool, str]:
"""
Create storage path for a timetable lesson node.
Args:
lesson_id: The lesson's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('TimetableLesson', lesson_id)
logger.info(f"Created timetable lesson storage path: {path}")
return True, path
def create_super_admin_storage_path(self, admin_id: str) -> Tuple[bool, str]:
"""
Create storage path for a super admin node.
Args:
admin_id: The admin's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('SuperAdmin', admin_id)
logger.info(f"Created super admin storage path: {path}")
return True, path
def create_curriculum_storage_path(self, curriculum_id: str) -> Tuple[bool, str]:
"""
Create storage path for a curriculum structure node.
Args:
curriculum_id: The curriculum's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('CurriculumStructure', curriculum_id)
logger.info(f"Created curriculum structure storage path: {path}")
return True, path
def create_pastoral_storage_path(self, pastoral_id: str) -> Tuple[bool, str]:
"""
Create storage path for a pastoral structure node.
Args:
pastoral_id: The pastoral's unique identifier
Returns:
Tuple[bool, str]: (success, storage_path)
"""
path = self.get_storage_path('PastoralStructure', pastoral_id)
logger.info(f"Created pastoral structure storage path: {path}")
return True, path
# Legacy compatibility methods that return the same interface as filesystem tools
def create_private_user_directory(self, user_id: str) -> Tuple[bool, str]:
"""Legacy compatibility method."""
return self.create_user_storage_path(user_id)
def create_user_worker_directory(self, user_path: str, worker_id: str, worker_type: str) -> Tuple[bool, str]:
"""Legacy compatibility method."""
if worker_type in ['teacher', 'email_teacher', 'ms_teacher']:
return self.create_teacher_storage_path(worker_id)
elif worker_type in ['student', 'email_student', 'ms_student']:
return self.create_student_storage_path(worker_id)
elif worker_type == 'superadmin':
return self.create_super_admin_storage_path(worker_id)
elif worker_type == 'developer':
return self.create_developer_storage_path(worker_id)
else:
# Default to generic storage path
path = self.get_storage_path(worker_type.title(), worker_id)
return True, path
def create_school_directory(self, school_uuid_string: str) -> Tuple[bool, str]:
"""Legacy compatibility method."""
return self.create_school_storage_path(school_uuid_string)
def create_school_curriculum_directory(self, school_path: Optional[str] = None) -> Tuple[bool, str]:
"""Legacy compatibility method - returns empty path since curriculum is handled by individual nodes."""
return True, ""
def create_school_pastoral_directory(self, school_path: Optional[str] = None) -> Tuple[bool, str]:
"""Legacy compatibility method - returns empty path since pastoral is handled by individual nodes."""
return True, ""
def create_directory(self, path: str) -> bool:
"""Legacy compatibility method - always returns True since we don't create physical directories."""
return True

View File

@ -0,0 +1,544 @@
"""
Enhanced Document Analysis Module
This module provides comprehensive document structure analysis beyond basic split maps,
including multi-level hierarchies, numbering system detection, and content type analysis.
"""
import re
import json
import uuid
import datetime
from typing import Dict, List, Any, Optional, Tuple
from dataclasses import dataclass, asdict
from pathlib import Path
import fitz # PyMuPDF
from modules.logger_tool import initialise_logger
import os
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
@dataclass
class DocumentSection:
"""Represents a document section at any hierarchy level"""
id: str
title: str
level: int
start_page: int
end_page: int
numbering: Optional[str] = None
parent_id: Optional[str] = None
children: List[str] = None
content_types: Dict[str, int] = None
confidence: float = 0.8
def __post_init__(self):
if self.children is None:
self.children = []
if self.content_types is None:
self.content_types = {}
@dataclass
class NumberingSystem:
"""Represents a detected numbering or coding system"""
system_id: str
pattern: str
description: str
examples: List[str]
applies_to_levels: List[int]
confidence: float
@dataclass
class ContentBlock:
"""Represents a content block with type information"""
block_id: str
page: int
bbox: Tuple[float, float, float, float] # x0, y0, x1, y1
content_type: str # 'text', 'image', 'table', 'formula', 'diagram'
text_content: Optional[str] = None
metadata: Dict[str, Any] = None
class DocumentAnalyzer:
"""Enhanced document analyzer for comprehensive structure detection"""
def __init__(self):
self.numbering_patterns = [
# Roman numerals
(r'^([IVX]+)\.?\s+(.+)', 'roman_numerals', 'Roman numeral chapters (I, II, III, ...)'),
# Decimal numbering
(r'^(\d+(?:\.\d+)*)\.?\s+(.+)', 'decimal_numbering', 'Decimal numbering (1.1, 1.2.1, ...)'),
# Letter numbering
(r'^([A-Z])\.?\s+(.+)', 'letter_chapters', 'Letter chapters (A, B, C, ...)'),
(r'^([a-z])\.?\s+(.+)', 'letter_sections', 'Letter sections (a, b, c, ...)'),
# Bracketed numbering
(r'^\((\d+)\)\s+(.+)', 'bracketed_numbers', 'Bracketed numbers ((1), (2), ...)'),
# Legal numbering
(r'\s*(\d+(?:\.\d+)*)\s+(.+)', 'legal_sections', 'Legal sections (§1, §1.1, ...)'),
# Article numbering
(r'^(?:Article|Art\.?)\s+(\d+(?:\.\d+)*)\s+(.+)', 'articles', 'Article numbering'),
]
def analyze_document_structure(self, pdf_bytes: bytes, tika_json: Dict = None,
docling_json: Dict = None) -> Dict[str, Any]:
"""
Fast, header-only structure analysis.
- Prefer PDF outline/bookmarks
- Otherwise, use Docling heading roles from existing artefact JSON
- No full-text scans; no per-page content analysis
"""
logger.info("Starting FAST document structure analysis (headings only)")
doc = fitz.open(stream=pdf_bytes, filetype="pdf")
page_count = len(doc)
# Try PDF outline first
sections: List[DocumentSection] = self._extract_from_pdf_outline(doc)
# Fallback to Docling headings if outline inadequate
if (not sections) and docling_json:
sections = self._extract_from_docling(docling_json)
# Final fallback: coarse windows
if not sections:
sections = []
step = max(10, min(30, page_count // 5 or 1))
i = 1
idx = 1
while i <= page_count:
end = min(page_count, i + step - 1)
sections.append(DocumentSection(
id=f"sec{idx:02d}",
title=f"Pages {i}-{end}",
level=1,
start_page=i,
end_page=end,
confidence=0.2
))
i = end + 1
idx += 1
# Build hierarchy relationships and adjust parent end-pages using sibling boundaries
sections = self._build_section_hierarchy(sections)
# Normalize and finalize sections (clamp, front matter, last-page coverage)
sections = self._normalize_and_cover(sections, page_count)
doc.close()
return {
"version": 2,
"analysis_timestamp": datetime.datetime.utcnow().isoformat() + "Z",
"page_count": page_count,
"sections": [asdict(section) for section in sections],
"metadata": {
"analyzer_version": "2.1-fast",
"analysis_methods": ["pdf_outline", "docling_headings"],
}
}
def _extract_hierarchical_structure(self, doc: fitz.Document, tika_json: Dict = None,
docling_json: Dict = None) -> List[DocumentSection]:
# Kept for backward compat; delegate to outline + docling only
sections = self._extract_from_pdf_outline(doc)
if (not sections) and docling_json:
sections = self._extract_from_docling(docling_json)
return sections
def _extract_from_pdf_outline(self, doc: fitz.Document) -> List[DocumentSection]:
"""Extract sections from PDF outline/bookmarks"""
sections = []
toc = doc.get_toc(simple=False)
for i, (level, title, page, dest) in enumerate(toc):
if page < 1:
continue
section_id = f"outline_{i:03d}"
# Calculate end page (next section's start - 1, or last page)
end_page = page
for j in range(i + 1, len(toc)):
if toc[j][2] > 0: # Valid page number
end_page = toc[j][2] - 1
break
else:
end_page = len(doc)
section = DocumentSection(
id=section_id,
title=title.strip(),
level=level,
start_page=page,
end_page=end_page,
confidence=0.95
)
sections.append(section)
return sections
def _extract_from_docling(self, docling_json: Dict) -> List[DocumentSection]:
"""Extract sections from Docling analysis"""
sections: List[DocumentSection] = []
blocks = docling_json.get("blocks", []) or docling_json.get("elements", [])
# 1) Collect headings with page and level, preserving order
heading_items: List[Tuple[int, str, int, str]] = [] # (page, level, order_index, title)
order_index = 0
for block in blocks:
role_raw = (block.get("role") or block.get("type") or "").lower()
if not ("heading" in role_raw or role_raw in ("h1", "h2", "h3", "h4", "h5", "h6", "title")):
continue
text = (block.get("text") or block.get("content") or "").strip()
if not text:
continue
page_val = block.get("page", None)
if page_val is None:
page_val = block.get("page_no", None)
if page_val is None:
page_val = block.get("pageIndex", None)
try:
page_int = int(page_val) if page_val is not None else 1
except Exception:
page_int = 1
# Normalize to 1-based
page_int = page_int + 1 if page_int == 0 else page_int
# Determine heading level
level = 1
if "1" in role_raw or role_raw == "title":
level = 1
elif "2" in role_raw:
level = 2
elif "3" in role_raw:
level = 3
elif "4" in role_raw:
level = 4
elif "5" in role_raw:
level = 5
elif "6" in role_raw:
level = 6
heading_items.append((page_int, level, order_index, text))
order_index += 1
if not heading_items:
return sections
# 2) Sort by page then order_index to preserve within-page order
heading_items.sort(key=lambda h: (h[0], h[2]))
# 3) Build sections with hierarchical end-page computation
stack: List[DocumentSection] = []
idx_counter = 0
def close_until(level_threshold: int, next_page: int):
nonlocal sections, stack
while stack and stack[-1].level >= level_threshold:
cur = stack.pop()
# If next heading on same page, close at same page; else previous page
if next_page <= cur.start_page:
cur.end_page = cur.start_page
else:
cur.end_page = next_page - 1
if cur.end_page < cur.start_page:
cur.end_page = cur.start_page
sections.append(cur)
for page_int, level, _, text in heading_items:
# Close siblings and deeper levels
close_until(level, page_int)
# Open new heading
section_id = f"docling_{idx_counter:03d}"
idx_counter += 1
new_sec = DocumentSection(
id=section_id,
title=text,
level=level,
start_page=page_int,
end_page=page_int, # temporary; will finalize when closing
confidence=0.8
)
stack.append(new_sec)
# Close any remaining open sections at document end later in normalization
while stack:
cur = stack.pop()
sections.append(cur)
return sections
def _normalize_and_cover(self, sections: List[DocumentSection], page_count: int) -> List[DocumentSection]:
"""Harden outline sections while preserving hierarchy:
- clamp each section to [1, page_count]
- fix inverted ranges (but DO NOT remove hierarchical overlaps)
- ensure coverage from page 1 with synthetic front-matter if needed
- ensure last top-level section extends to page_count
- compute numbering hint if missing
"""
if not sections:
return sections
# Clamp values per section; do not modify overlap relationships
for s in sections:
s.start_page = max(1, min(s.start_page or 1, page_count))
s.end_page = max(1, min(s.end_page or s.start_page, page_count))
if s.end_page < s.start_page:
s.end_page = s.start_page
# Maintain original order (as produced by extractor and hierarchy builder)
# Insert synthetic front matter if needed
if sections and sections[0].start_page > 1:
# Generate a unique synthetic id that won't collide with existing ids
existing_ids = {s.id for s in sections}
base_id = "outline_front_matter"
syn_id = base_id
idx = 1
while syn_id in existing_ids:
syn_id = f"{base_id}_{idx}"
idx += 1
front = DocumentSection(
id=syn_id,
title="Front matter",
level=1,
start_page=1,
end_page=sections[0].start_page - 1,
confidence=0.6
)
sections.insert(0, front)
# Ensure last top-level section covers to page_count
top_levels = [s for s in sections if s.parent_id is None]
if top_levels:
last_top = top_levels[-1]
if last_top.end_page < page_count:
last_top.end_page = page_count
# Light numbering extraction based on heading text prefix
for s in sections:
m = re.match(r"^\s*([A-Za-z]+|[IVXLCM]+|\d+(?:\.\d+)*)\.?\s+", s.title)
if m:
s.numbering = s.numbering or m.group(1)
return sections
def _extract_from_text_patterns(self, doc: fitz.Document) -> List[DocumentSection]:
# Disabled in fast mode
return []
def _estimate_section_level(self, numbering: str, system_type: str) -> int:
"""Estimate section level based on numbering pattern"""
if system_type == 'roman_numerals':
return 1 # Typically chapter level
elif system_type == 'decimal_numbering':
dots = numbering.count('.')
return min(dots + 1, 6) # 1.1.1 = level 3
elif system_type == 'letter_chapters':
return 1
elif system_type == 'letter_sections':
return 2
else:
return 2 # Default
def _detect_numbering_systems(self, sections: List[DocumentSection]) -> List[NumberingSystem]:
"""Detect numbering systems used in the document"""
systems = []
# Group sections by their numbering patterns
pattern_groups = {}
for section in sections:
if section.numbering:
for pattern, system_type, description in self.numbering_patterns:
if re.match(pattern.replace(r'^(.+)', section.numbering), section.numbering):
if system_type not in pattern_groups:
pattern_groups[system_type] = {
'pattern': pattern,
'description': description,
'examples': [],
'levels': set(),
'count': 0
}
pattern_groups[system_type]['examples'].append(section.numbering)
pattern_groups[system_type]['levels'].add(section.level)
pattern_groups[system_type]['count'] += 1
break
# Create NumberingSystem objects
for system_type, data in pattern_groups.items():
if data['count'] >= 2: # At least 2 examples to be confident
system = NumberingSystem(
system_id=system_type,
pattern=data['pattern'],
description=data['description'],
examples=data['examples'][:5], # First 5 examples
applies_to_levels=list(data['levels']),
confidence=min(0.9, 0.5 + (data['count'] * 0.1))
)
systems.append(system)
return systems
def _analyze_content_types(self, doc: fitz.Document, sections: List[DocumentSection]) -> Dict[str, Any]:
# Disabled in fast mode
return {"total_blocks": 0, "content_types": {}, "sections": {}}
def _detect_tables_in_page(self, page) -> int:
return 0
def _has_complex_formatting(self, page) -> bool:
return False
def _merge_and_deduplicate_sections(self, sections: List[DocumentSection]) -> List[DocumentSection]:
"""Merge overlapping sections and remove duplicates"""
if not sections:
return []
# Sort by start page, then by level
sections.sort(key=lambda s: (s.start_page, s.level))
merged = []
for section in sections:
# Check if this section overlaps significantly with existing ones
is_duplicate = False
for existing in merged:
if (existing.start_page == section.start_page and
abs(existing.level - section.level) <= 1 and
self._text_similarity(existing.title, section.title) > 0.8):
# This is likely a duplicate, merge information
if section.confidence > existing.confidence:
existing.title = section.title
existing.numbering = section.numbering or existing.numbering
existing.confidence = section.confidence
is_duplicate = True
break
if not is_duplicate:
merged.append(section)
return merged
def _text_similarity(self, text1: str, text2: str) -> float:
"""Calculate text similarity (simple implementation)"""
if not text1 or not text2:
return 0.0
# Simple word-based similarity
words1 = set(text1.lower().split())
words2 = set(text2.lower().split())
if not words1 and not words2:
return 1.0
intersection = words1.intersection(words2)
union = words1.union(words2)
return len(intersection) / len(union) if union else 0.0
def _build_section_hierarchy(self, sections: List[DocumentSection]) -> List[DocumentSection]:
"""Build parent-child relationships between sections"""
if not sections:
return []
# Sort by start page and level
sections.sort(key=lambda s: (s.start_page, s.level))
# Build hierarchy
for i, section in enumerate(sections):
# Find parent (previous section with lower level)
for j in range(i - 1, -1, -1):
potential_parent = sections[j]
if (potential_parent.level < section.level and
potential_parent.start_page <= section.start_page and
potential_parent.end_page >= section.start_page):
section.parent_id = potential_parent.id
potential_parent.children.append(section.id)
break
# Update end pages based on children
for j in range(i + 1, len(sections)):
next_section = sections[j]
if (next_section.level <= section.level and
next_section.start_page > section.start_page):
section.end_page = min(section.end_page, next_section.start_page - 1)
break
return sections
def _generate_processing_recommendations(self, sections: List[DocumentSection],
content_analysis: Dict) -> Dict[str, Any]:
"""Generate intelligent processing recommendations"""
recommendations = {
"document_length_category": "short", # short, medium, long
"suggested_processing_approach": "full_document", # full_document, section_by_section
"high_priority_sections": [],
"ocr_recommended_sections": [],
"image_analysis_sections": [],
"table_extraction_sections": [],
"estimated_total_time": 0
}
total_pages = max(s.end_page for s in sections) if sections else 0
# Categorize document length
if total_pages <= 10:
recommendations["document_length_category"] = "short"
recommendations["suggested_processing_approach"] = "full_document"
elif total_pages <= 50:
recommendations["document_length_category"] = "medium"
recommendations["suggested_processing_approach"] = "section_by_section"
else:
recommendations["document_length_category"] = "long"
recommendations["suggested_processing_approach"] = "section_by_section"
# Analyze each section for recommendations
total_estimated_time = 0
for section in sections:
section_data = content_analysis["sections"].get(section.id, {})
# High priority sections (first few sections, or sections with important titles)
if (section.start_page <= 5 or
any(keyword in section.title.lower() for keyword in
['abstract', 'summary', 'introduction', 'conclusion', 'executive'])):
recommendations["high_priority_sections"].append(section.id)
# OCR recommendations
if section_data.get("images", 0) > 0 or section_data.get("has_complex_formatting", False):
recommendations["ocr_recommended_sections"].append(section.id)
# Image analysis recommendations
if section_data.get("images", 0) > 2: # Sections with multiple images
recommendations["image_analysis_sections"].append(section.id)
# Table extraction recommendations
if section_data.get("tables", 0) > 0:
recommendations["table_extraction_sections"].append(section.id)
total_estimated_time += section_data.get("estimated_processing_time", 0)
recommendations["estimated_total_time"] = total_estimated_time
return recommendations
def create_document_outline_hierarchy_artefact(file_id: str, pdf_bytes: bytes,
tika_json: Dict = None,
docling_json: Dict = None) -> Dict[str, Any]:
"""
Create a comprehensive document outline hierarchy artefact
Args:
file_id: File ID
pdf_bytes: PDF file content
tika_json: Optional Tika analysis results
docling_json: Optional Docling analysis results
Returns:
Document outline hierarchy artefact
"""
analyzer = DocumentAnalyzer()
analysis = analyzer.analyze_document_structure(pdf_bytes, tika_json, docling_json)
# Add file metadata
analysis["file_id"] = file_id
analysis["artefact_id"] = str(uuid.uuid4())
analysis["artefact_type"] = "document_outline_hierarchy"
return analysis

View File

@ -39,28 +39,41 @@ class DocumentProcessor:
# Use LibreOffice for conversion
with tempfile.TemporaryDirectory() as temp_dir:
output_file = Path(temp_dir) / f"{input_file.stem}.pdf"
# Convert using LibreOffice
cmd = [
'libreoffice',
'--headless',
'--convert-to', 'pdf',
'--outdir', str(temp_dir),
str(input_file)
]
try:
subprocess.run(cmd, check=True, capture_output=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Conversion failed: {e.stderr.decode()}")
with tempfile.TemporaryDirectory() as profile_dir:
output_file = Path(temp_dir) / f"{input_file.stem}.pdf"
# Convert using LibreOffice with explicit profile directory
cmd = [
'/Applications/LibreOffice.app/Contents/MacOS/soffice',
'--headless',
'--invisible',
'--nodefault',
'--nolockcheck',
'--nologo',
'--norestore',
f'-env:UserInstallation=file://{profile_dir}',
'--convert-to', 'pdf',
'--outdir', str(temp_dir),
str(input_file)
]
try:
result = subprocess.run(cmd, check=True, capture_output=True, timeout=120)
except subprocess.CalledProcessError as e:
stderr_msg = e.stderr.decode() if e.stderr else "No stderr output"
stdout_msg = e.stdout.decode() if e.stdout else "No stdout output"
raise RuntimeError(f"Conversion failed: {stderr_msg}. Stdout: {stdout_msg}")
except subprocess.TimeoutExpired:
raise RuntimeError("Conversion failed: Process timed out after 120 seconds")
if not output_file.exists():
raise RuntimeError("Conversion failed: Output file not created")
if not output_file.exists():
# List all files in temp_dir for debugging
files_in_dir = list(Path(temp_dir).glob('*'))
raise RuntimeError(f"Conversion failed: Output file not created. Files in output dir: {files_in_dir}")
# Read and return the PDF content
with open(output_file, 'rb') as f:
return f.read()
# Read and return the PDF content
with open(output_file, 'rb') as f:
return f.read()
def batch_convert_directory(self, directory: str) -> List[Dict]:
"""

View File

@ -0,0 +1,411 @@
"""
Memory-Aware Queue Management System
====================================
Provides intelligent queue management based on memory usage and file sizes
rather than simple task count limits. Supports multiple users with fair
queuing and capacity management.
Features:
- Memory-based queue limits (not just task count)
- Fair queuing across multiple users
- Upload capacity checking with user feedback
- Graceful degradation under load
- Service-specific memory tracking
"""
import os
import time
import json
import uuid
import logging
from typing import Dict, List, Optional, Any, Tuple
from dataclasses import dataclass, asdict
from enum import Enum
import redis
from .redis_manager import get_redis_manager
import psutil
logger = logging.getLogger(__name__)
class QueueStatus(Enum):
ACCEPTING = "accepting" # Normal operation
BUSY = "busy" # High load, warn users
OVERLOADED = "overloaded" # Reject new uploads
MAINTENANCE = "maintenance" # Manual override
@dataclass
class MemoryConfig:
"""Memory configuration for queue management."""
max_total_memory_mb: int = 2048 # 2GB total queue memory
max_user_memory_mb: int = 512 # 512MB per user
max_file_size_mb: int = 100 # 100MB max file size
memory_warning_threshold: float = 0.8 # Warn at 80%
memory_reject_threshold: float = 0.95 # Reject at 95%
@dataclass
class QueuedFile:
"""Represents a file waiting in the queue."""
file_id: str
user_id: str
filename: str
size_bytes: int
mime_type: str
cabinet_id: str
priority: int = 1
queued_at: float = 0
estimated_processing_time: int = 300 # seconds
memory_estimate_mb: float = 0
def __post_init__(self):
if self.queued_at == 0:
self.queued_at = time.time()
# Estimate memory usage (rough heuristic)
self.memory_estimate_mb = self._estimate_memory_usage()
def _estimate_memory_usage(self) -> float:
"""Estimate memory usage for this file during processing."""
base_mb = self.size_bytes / (1024 * 1024)
# Processing multipliers based on operations
if self.mime_type == 'application/pdf':
# PDF: original + extracted text + images + thumbnails
return base_mb * 3.5
elif self.mime_type.startswith('image/'):
# Images: original + resized variants + OCR text
return base_mb * 2.5
else:
# Other docs: original + PDF conversion + processing
return base_mb * 4.0
class MemoryAwareQueue:
"""Memory-aware queue management system."""
def __init__(self, environment: str = "dev"):
self.redis_manager = get_redis_manager(environment)
self.redis_client = self.redis_manager.client
self.config = self._load_config()
# Redis keys
self.upload_queue_key = "upload_queue"
self.processing_memory_key = "processing_memory"
self.user_quota_key = "user_quotas"
self.system_status_key = "system_status"
logger.info(f"🧠 Memory-aware queue initialized (max: {self.config.max_total_memory_mb}MB)")
def _load_config(self) -> MemoryConfig:
"""Load memory configuration from environment."""
return MemoryConfig(
max_total_memory_mb=int(os.getenv('QUEUE_MAX_MEMORY_MB', '2048')),
max_user_memory_mb=int(os.getenv('QUEUE_MAX_USER_MEMORY_MB', '512')),
max_file_size_mb=int(os.getenv('MAX_FILE_SIZE_MB', '100')),
memory_warning_threshold=float(os.getenv('MEMORY_WARNING_THRESHOLD', '0.8')),
memory_reject_threshold=float(os.getenv('MEMORY_REJECT_THRESHOLD', '0.95'))
)
def check_upload_capacity(self, user_id: str, file_size_bytes: int,
mime_type: str) -> Tuple[bool, str, Dict[str, Any]]:
"""
Check if system can accept a new upload.
Returns:
(can_accept, message, queue_info)
"""
# Create temporary QueuedFile to estimate memory
temp_file = QueuedFile(
file_id="temp",
user_id=user_id,
filename="temp",
size_bytes=file_size_bytes,
mime_type=mime_type,
cabinet_id="temp"
)
file_memory_mb = temp_file.memory_estimate_mb
# Check file size limit
if file_size_bytes > (self.config.max_file_size_mb * 1024 * 1024):
return False, f"File too large (max: {self.config.max_file_size_mb}MB)", {}
# Get current memory usage
current_memory = self._get_current_memory_usage()
user_memory = self._get_user_memory_usage(user_id)
# Check user quota
if user_memory + file_memory_mb > self.config.max_user_memory_mb:
return False, f"User quota exceeded (limit: {self.config.max_user_memory_mb}MB)", {
'user_current': user_memory,
'user_limit': self.config.max_user_memory_mb
}
# Check system capacity
total_after = current_memory + file_memory_mb
max_memory = self.config.max_total_memory_mb
if total_after > (max_memory * self.config.memory_reject_threshold):
queue_info = self._get_queue_info()
return False, "System overloaded. Please try again later.", {
'current_memory': current_memory,
'max_memory': max_memory,
'utilization': current_memory / max_memory,
'queue_position': queue_info['total_queued'] + 1
}
# Calculate wait time estimate
wait_estimate = self._estimate_wait_time(user_id)
status = "ready"
message = "Upload accepted"
if total_after > (max_memory * self.config.memory_warning_threshold):
status = "busy"
message = f"System busy. Estimated wait: {wait_estimate // 60}m {wait_estimate % 60}s"
return True, message, {
'status': status,
'estimated_wait_seconds': wait_estimate,
'memory_usage': {
'current': current_memory,
'after_upload': total_after,
'limit': max_memory,
'utilization': total_after / max_memory
},
'user_quota': {
'used': user_memory,
'after_upload': user_memory + file_memory_mb,
'limit': self.config.max_user_memory_mb
}
}
def enqueue_file(self, file_id: str, user_id: str, filename: str,
size_bytes: int, mime_type: str, cabinet_id: str,
priority: int = 1) -> Dict[str, Any]:
"""
Add file to upload queue.
Returns:
Queue information including position and estimated wait time
"""
queued_file = QueuedFile(
file_id=file_id,
user_id=user_id,
filename=filename,
size_bytes=size_bytes,
mime_type=mime_type,
cabinet_id=cabinet_id,
priority=priority
)
# Serialize and add to Redis queue (priority queue: higher priority = lower score)
score = time.time() - (priority * 1000000) # Priority affects score significantly
self.redis_client.zadd(
self.upload_queue_key,
{json.dumps(asdict(queued_file)): score}
)
# Update user quota tracking
self._update_user_quota(user_id, queued_file.memory_estimate_mb, increment=True)
# Get queue position and wait estimate
position = self._get_queue_position(file_id)
wait_estimate = self._estimate_wait_time(user_id)
logger.info(f"📋 Queued file {file_id} for user {user_id} (pos: {position}, wait: {wait_estimate}s)")
return {
'queued': True,
'file_id': file_id,
'queue_position': position,
'estimated_wait_seconds': wait_estimate,
'memory_estimate_mb': queued_file.memory_estimate_mb
}
def dequeue_next_file(self, service_name: str) -> Optional[QueuedFile]:
"""
Get next file from queue for processing.
Args:
service_name: The service requesting work (for capacity management)
"""
# Check if service has capacity
service_memory = self._get_service_memory_usage(service_name)
service_limit = self._get_service_memory_limit(service_name)
if service_memory >= service_limit:
logger.debug(f"Service {service_name} at capacity ({service_memory}/{service_limit}MB)")
return None
# Get next item from priority queue (lowest score first)
items = self.redis_client.zrange(self.upload_queue_key, 0, 0, withscores=True)
if not items:
return None
file_data_json, score = items[0]
file_data = json.loads(file_data_json)
queued_file = QueuedFile(**file_data)
# Check if this file would exceed service memory limit
if service_memory + queued_file.memory_estimate_mb > service_limit:
# Skip this file for now, try smaller ones later
logger.debug(f"File {queued_file.file_id} too large for {service_name} capacity")
return None
# Remove from queue
self.redis_client.zrem(self.upload_queue_key, file_data_json)
# Update tracking
self._update_user_quota(queued_file.user_id, queued_file.memory_estimate_mb, increment=False)
self._update_service_memory(service_name, queued_file.memory_estimate_mb, increment=True)
logger.info(f"🎯 Dequeued file {queued_file.file_id} for {service_name} processing")
return queued_file
def complete_processing(self, service_name: str, file_id: str, memory_used_mb: float):
"""Mark file processing as complete and free memory."""
self._update_service_memory(service_name, memory_used_mb, increment=False)
logger.info(f"✅ Completed processing {file_id} in {service_name} (freed {memory_used_mb}MB)")
def _get_current_memory_usage(self) -> float:
"""Get current total memory usage across all services."""
services = ['docling', 'tika', 'llm', 'document_analysis']
total = 0
for service in services:
service_key = f"{self.processing_memory_key}:{service}"
memory = float(self.redis_client.get(service_key) or 0)
total += memory
return total
def _get_user_memory_usage(self, user_id: str) -> float:
"""Get current memory usage for a specific user."""
user_key = f"{self.user_quota_key}:{user_id}"
return float(self.redis_client.get(user_key) or 0)
def _get_service_memory_usage(self, service_name: str) -> float:
"""Get current memory usage for a service."""
service_key = f"{self.processing_memory_key}:{service_name}"
return float(self.redis_client.get(service_key) or 0)
def _get_service_memory_limit(self, service_name: str) -> float:
"""Get memory limit for a service."""
# Service-specific memory limits as percentage of total
limits = {
'docling': 0.4, # 40% for Docling (memory-intensive)
'tika': 0.2, # 20% for Tika
'llm': 0.3, # 30% for LLM processing
'document_analysis': 0.1 # 10% for document analysis
}
percentage = limits.get(service_name, 0.1)
return self.config.max_total_memory_mb * percentage
def _update_user_quota(self, user_id: str, memory_mb: float, increment: bool):
"""Update user memory quota tracking."""
user_key = f"{self.user_quota_key}:{user_id}"
if increment:
self.redis_client.incrbyfloat(user_key, memory_mb)
else:
current = float(self.redis_client.get(user_key) or 0)
new_value = max(0, current - memory_mb)
self.redis_client.set(user_key, new_value)
# Set expiration for cleanup
self.redis_client.expire(user_key, 86400) # 24 hours
def _update_service_memory(self, service_name: str, memory_mb: float, increment: bool):
"""Update service memory usage tracking."""
service_key = f"{self.processing_memory_key}:{service_name}"
if increment:
self.redis_client.incrbyfloat(service_key, memory_mb)
else:
current = float(self.redis_client.get(service_key) or 0)
new_value = max(0, current - memory_mb)
self.redis_client.set(service_key, new_value)
# Set expiration for cleanup
self.redis_client.expire(service_key, 3600) # 1 hour
def _get_queue_position(self, file_id: str) -> int:
"""Get position of file in queue."""
items = self.redis_client.zrange(self.upload_queue_key, 0, -1)
for i, item in enumerate(items):
file_data = json.loads(item)
if file_data['file_id'] == file_id:
return i + 1
return 0
def _estimate_wait_time(self, user_id: str) -> int:
"""Estimate wait time for user's next file."""
# Simple estimation based on queue position and average processing time
queue_size = self.redis_client.zcard(self.upload_queue_key)
avg_processing_time = 300 # 5 minutes average
return int(queue_size * avg_processing_time * 0.5) # Assume parallel processing
def _get_queue_info(self) -> Dict[str, Any]:
"""Get comprehensive queue information."""
total_queued = self.redis_client.zcard(self.upload_queue_key)
current_memory = self._get_current_memory_usage()
max_memory = self.config.max_total_memory_mb
return {
'total_queued': total_queued,
'memory_usage': {
'current_mb': current_memory,
'max_mb': max_memory,
'utilization': current_memory / max_memory if max_memory > 0 else 0
},
'status': self._determine_system_status(current_memory, max_memory)
}
def _determine_system_status(self, current_memory: float, max_memory: float) -> str:
"""Determine current system status based on memory usage."""
utilization = current_memory / max_memory if max_memory > 0 else 0
if utilization >= self.config.memory_reject_threshold:
return "overloaded"
elif utilization >= self.config.memory_warning_threshold:
return "busy"
else:
return "ready"
def get_system_status(self) -> Dict[str, Any]:
"""Get comprehensive system status for monitoring."""
queue_info = self._get_queue_info()
# Service-specific info
services = {}
for service_name in ['docling', 'tika', 'llm', 'document_analysis']:
services[service_name] = {
'memory_used_mb': self._get_service_memory_usage(service_name),
'memory_limit_mb': self._get_service_memory_limit(service_name),
'utilization': self._get_service_memory_usage(service_name) / self._get_service_memory_limit(service_name)
}
return {
'status': queue_info['status'],
'queue': queue_info,
'services': services,
'config': asdict(self.config)
}
# Convenience functions
def get_memory_queue(environment: str = "dev") -> MemoryAwareQueue:
"""Get memory-aware queue instance."""
return MemoryAwareQueue(environment)
def check_upload_capacity(user_id: str, file_size: int, mime_type: str, environment: str = "dev") -> Tuple[bool, str, Dict]:
"""Quick capacity check for upload."""
queue = get_memory_queue(environment)
return queue.check_upload_capacity(user_id, file_size, mime_type)

View File

@ -0,0 +1,223 @@
"""
Page Image Generation Module
This module generates full-resolution page images and thumbnails from PDF documents
for use in the document viewer UI.
"""
import io
import uuid
from typing import Dict, List, Any, Tuple
from pathlib import Path
import fitz # PyMuPDF
from PIL import Image
from modules.logger_tool import initialise_logger
import os
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
class PageImageGenerator:
"""Generates page images and thumbnails from PDF documents"""
def __init__(self):
# Image generation settings
self.full_image_dpi = 200 # High quality for full images
self.thumbnail_dpi = 100 # Lower quality for thumbnails
self.thumbnail_max_width = 300
self.thumbnail_max_height = 400
self.image_format = "PNG"
self.thumbnail_format = "WEBP" # More efficient for thumbnails
def generate_page_images(self, file_id: str, cabinet_id: str, pdf_bytes: bytes) -> Dict[str, Any]:
"""
Generate full page images and thumbnails for a PDF document
Args:
file_id: File ID
cabinet_id: Cabinet ID for storage path
pdf_bytes: PDF file content
Returns:
Page images artefact data
"""
logger.info(f"Starting page image generation for file_id={file_id}")
doc = fitz.open(stream=pdf_bytes, filetype="pdf")
page_count = len(doc)
artefact_id = str(uuid.uuid4())
page_images = []
for page_num in range(page_count):
page = doc[page_num]
page_number = page_num + 1
logger.debug(f"Processing page {page_number}/{page_count} for file_id={file_id}")
# Generate full resolution image
full_image_data, full_dimensions = self._generate_full_image(page, page_number)
full_image_path = f"{cabinet_id}/{file_id}/{artefact_id}/page_{page_number:03d}_full.png"
# Generate thumbnail
thumbnail_data, thumbnail_dimensions = self._generate_thumbnail(page, page_number)
thumbnail_path = f"{cabinet_id}/{file_id}/{artefact_id}/page_{page_number:03d}_thumb.webp"
page_info = {
"page": page_number,
"full_image_path": full_image_path,
"full_image_data": full_image_data, # Will be uploaded separately
"full_dimensions": full_dimensions,
"thumbnail_path": thumbnail_path,
"thumbnail_data": thumbnail_data, # Will be uploaded separately
"thumbnail_dimensions": thumbnail_dimensions,
"rotation": page.rotation,
"has_text": bool(page.get_text().strip()),
"has_images": len(page.get_images()) > 0,
"has_drawings": len(page.get_drawings()) > 0
}
page_images.append(page_info)
doc.close()
artefact_data = {
"version": 1,
"file_id": file_id,
"artefact_id": artefact_id,
"artefact_type": "page_images",
"generation_timestamp": self._get_timestamp(),
"page_count": page_count,
"page_images": page_images,
"generation_settings": {
"full_image_dpi": self.full_image_dpi,
"thumbnail_dpi": self.thumbnail_dpi,
"thumbnail_max_width": self.thumbnail_max_width,
"thumbnail_max_height": self.thumbnail_max_height,
"image_format": self.image_format,
"thumbnail_format": self.thumbnail_format
},
"storage_info": {
"total_full_images": page_count,
"total_thumbnails": page_count,
"estimated_storage_mb": self._estimate_storage_size(page_images)
}
}
logger.info(f"Generated {page_count} page images for file_id={file_id}")
return artefact_data
def _generate_full_image(self, page: fitz.Page, page_number: int) -> Tuple[bytes, Dict[str, int]]:
"""Generate full resolution page image"""
# Create transformation matrix for high DPI
mat = fitz.Matrix(self.full_image_dpi / 72, self.full_image_dpi / 72)
# Render page to pixmap
pix = page.get_pixmap(matrix=mat, alpha=False)
# Convert to PNG bytes
img_data = pix.tobytes("png")
dimensions = {
"width": pix.width,
"height": pix.height
}
pix = None # Free memory
return img_data, dimensions
def _generate_thumbnail(self, page: fitz.Page, page_number: int) -> Tuple[bytes, Dict[str, int]]:
"""Generate thumbnail image"""
# Create transformation matrix for lower DPI
mat = fitz.Matrix(self.thumbnail_dpi / 72, self.thumbnail_dpi / 72)
# Render page to pixmap
pix = page.get_pixmap(matrix=mat, alpha=False)
# Convert to PIL Image for resizing
img_data = pix.tobytes("png")
pil_image = Image.open(io.BytesIO(img_data))
# Resize to thumbnail dimensions while maintaining aspect ratio
pil_image.thumbnail((self.thumbnail_max_width, self.thumbnail_max_height), Image.Resampling.LANCZOS)
# Convert to WebP for better compression
thumbnail_buffer = io.BytesIO()
pil_image.save(thumbnail_buffer, format="WEBP", quality=85, optimize=True)
thumbnail_data = thumbnail_buffer.getvalue()
dimensions = {
"width": pil_image.width,
"height": pil_image.height
}
pix = None # Free memory
pil_image.close()
return thumbnail_data, dimensions
def _estimate_storage_size(self, page_images: List[Dict]) -> float:
"""Estimate total storage size in MB"""
total_bytes = 0
for page_info in page_images:
# Estimate full image size (PNG is roughly 3-4 bytes per pixel)
full_dims = page_info["full_dimensions"]
full_size = full_dims["width"] * full_dims["height"] * 3.5
# Estimate thumbnail size (WebP is much more efficient)
thumb_dims = page_info["thumbnail_dimensions"]
thumb_size = thumb_dims["width"] * thumb_dims["height"] * 0.5
total_bytes += full_size + thumb_size
return round(total_bytes / (1024 * 1024), 2) # Convert to MB
def _get_timestamp(self) -> str:
"""Get current timestamp in ISO format"""
import datetime
return datetime.datetime.utcnow().isoformat() + "Z"
def generate_single_page_image(self, pdf_bytes: bytes, page_number: int,
image_type: str = "full") -> Tuple[bytes, Dict[str, int]]:
"""
Generate a single page image (for on-demand generation)
Args:
pdf_bytes: PDF file content
page_number: Page number (1-based)
image_type: "full" or "thumbnail"
Returns:
Tuple of (image_bytes, dimensions)
"""
doc = fitz.open(stream=pdf_bytes, filetype="pdf")
if page_number < 1 or page_number > len(doc):
doc.close()
raise ValueError(f"Page number {page_number} is out of range (1-{len(doc)})")
page = doc[page_number - 1] # Convert to 0-based index
if image_type == "thumbnail":
image_data, dimensions = self._generate_thumbnail(page, page_number)
else:
image_data, dimensions = self._generate_full_image(page, page_number)
doc.close()
return image_data, dimensions
def create_page_images_artefact(file_id: str, cabinet_id: str, pdf_bytes: bytes) -> Dict[str, Any]:
"""
Create page images artefact for a PDF document
Args:
file_id: File ID
cabinet_id: Cabinet ID
pdf_bytes: PDF file content
Returns:
Page images artefact data
"""
generator = PageImageGenerator()
return generator.generate_page_images(file_id, cabinet_id, pdf_bytes)

File diff suppressed because it is too large Load Diff

679
modules/queue_system.py Normal file
View File

@ -0,0 +1,679 @@
"""
Robust Document Processing Queue System
This module provides a Redis-based queuing system for document processing tasks
to prevent server overload and handle concurrent processing efficiently.
Features:
- Priority-based queuing (high, normal, low)
- Rate limiting per service (Tika, Docling, LLM)
- Concurrent processing limits
- Task retry mechanism with exponential backoff
- Dead letter queue for failed tasks
- Health monitoring and metrics
- Graceful shutdown handling
"""
import json
import time
import uuid
import asyncio
import threading
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Any, Callable, Union
from urllib.parse import urlparse
from dataclasses import dataclass, asdict
from enum import Enum
import redis
import os
from modules.logger_tool import initialise_logger
from .redis_manager import get_redis_manager, Environment
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
# Custom exceptions
class QueueConnectionError(Exception):
"""Raised when the queue system cannot connect to Redis"""
pass
class QueueFullError(Exception):
"""Raised when a service queue is at capacity"""
pass
class RateLimitError(Exception):
"""Raised when rate limits are exceeded"""
pass
class TaskPriority(Enum):
HIGH = "high" # Interactive uploads, user waiting
NORMAL = "normal" # Regular batch processing
LOW = "low" # Background/cleanup tasks
class TaskStatus(Enum):
PENDING = "pending"
PROCESSING = "processing"
COMPLETED = "completed"
FAILED = "failed"
RETRYING = "retrying"
DEAD = "dead"
class ServiceType(Enum):
TIKA = "tika"
DOCLING = "docling"
LLM = "llm"
SPLIT_MAP = "split_map"
DOCUMENT_ANALYSIS = "document_analysis"
PAGE_IMAGES = "page_images"
@dataclass
class QueueTask:
"""Represents a task in the processing queue."""
id: str
service: ServiceType
priority: TaskPriority
file_id: str
task_type: str # e.g., "tika_metadata", "docling_frontmatter", "llm_classify"
payload: Dict[str, Any]
created_at: float
scheduled_at: float = None # For delayed/retry tasks
attempts: int = 0
max_attempts: int = 3
timeout: int = 300 # seconds
callback_url: Optional[str] = None
user_id: Optional[str] = None
def __post_init__(self):
if self.scheduled_at is None:
self.scheduled_at = time.time()
class DocumentProcessingQueue:
"""Redis-based document processing queue with rate limiting and priorities."""
def __init__(self, environment: str = None, redis_url: str = None):
"""Initialize queue with Redis connection using new Redis manager.
Args:
environment: 'dev', 'prod', or 'test' (auto-detected if not provided)
redis_url: Legacy parameter for backward compatibility
"""
# Auto-detect environment from startup mode if not provided
if not environment:
environment = 'dev' if os.getenv('BACKEND_DEV_MODE', 'true').lower() == 'true' else 'prod'
# Initialize Redis manager for this environment
self.redis_manager = get_redis_manager(environment)
# Initialize Redis environment (ensures service running and connects)
if not self.redis_manager.initialize_environment():
raise ConnectionError(f"Failed to initialize Redis for {environment} environment")
# Use the managed Redis client
self.redis_client = self.redis_manager.client
self.environment = environment
logger.info(f"🎯 Queue initialized for {environment} environment (db={self.redis_manager.config.db})")
# Queue configuration
self.service_limits = {
ServiceType.TIKA: int(os.getenv('QUEUE_TIKA_LIMIT', '3')),
ServiceType.DOCLING: int(os.getenv('QUEUE_DOCLING_LIMIT', '2')),
ServiceType.LLM: int(os.getenv('QUEUE_LLM_LIMIT', '5')),
ServiceType.SPLIT_MAP: int(os.getenv('QUEUE_SPLIT_MAP_LIMIT', '10')),
ServiceType.DOCUMENT_ANALYSIS: int(os.getenv('QUEUE_DOCUMENT_ANALYSIS_LIMIT', '5')),
ServiceType.PAGE_IMAGES: int(os.getenv('QUEUE_PAGE_IMAGES_LIMIT', '3'))
}
# Rate limiting (requests per minute)
self.rate_limits = {
ServiceType.TIKA: int(os.getenv('QUEUE_TIKA_RATE', '60')),
ServiceType.DOCLING: int(os.getenv('QUEUE_DOCLING_RATE', '30')),
ServiceType.LLM: int(os.getenv('QUEUE_LLM_RATE', '120')),
ServiceType.SPLIT_MAP: int(os.getenv('QUEUE_SPLIT_MAP_RATE', '100'))
}
# Queue names
self.queue_keys = {
priority: f"queue:{priority.value}" for priority in TaskPriority
}
self.processing_key = "processing"
self.dead_letter_key = "dead_letter"
self.metrics_key = "metrics"
# Worker control
self.workers_running = {}
self.shutdown_event = threading.Event()
logger.info(f"⚙️ Queue service limits: {dict(self.service_limits)}")
def _get_task_key(self, task_id: str) -> str:
"""Get Redis key for task data."""
return f"task:{task_id}"
def _get_service_processing_key(self, service: ServiceType) -> str:
"""Get Redis key for service processing counter."""
return f"processing:{service.value}"
def _get_rate_limit_key(self, service: ServiceType) -> str:
"""Get Redis key for rate limiting."""
return f"rate_limit:{service.value}:{int(time.time() // 60)}"
def enqueue_task(self,
service: ServiceType,
task_type: str,
file_id: str,
payload: Dict[str, Any],
priority: TaskPriority = TaskPriority.NORMAL,
user_id: str = None,
timeout: int = 300,
max_attempts: int = 3) -> str:
"""
Enqueue a new processing task.
Returns:
str: Task ID
"""
task_id = str(uuid.uuid4())
task = QueueTask(
id=task_id,
service=service,
priority=priority,
file_id=file_id,
task_type=task_type,
payload=payload,
created_at=time.time(),
timeout=timeout,
max_attempts=max_attempts,
user_id=user_id
)
try:
# Store task data (convert enums to strings for Redis)
task_dict = asdict(task)
task_dict['service'] = task_dict['service'].value
task_dict['priority'] = task_dict['priority'].value
task_dict['payload'] = json.dumps(task_dict['payload'])
# Convert None values to empty strings for Redis
for key, value in task_dict.items():
if value is None:
task_dict[key] = ''
self.redis_client.hset(
self._get_task_key(task_id),
mapping=task_dict
)
self.redis_client.expire(self._get_task_key(task_id), 86400) # 24 hours TTL
# Add to priority queue
queue_key = self.queue_keys[priority]
self.redis_client.lpush(queue_key, task_id)
except redis.ConnectionError as e:
logger.error(f"Redis connection failed when enqueueing task: {e}")
logger.error("Please ensure Redis is running. Start the API server with './start.sh dev' to auto-start Redis.")
raise QueueConnectionError(f"Queue system unavailable: Redis connection failed")
except Exception as e:
logger.error(f"Failed to enqueue task {task_id}: {e}")
raise
# Update metrics
self._update_metrics("enqueued", service.value, priority.value)
logger.info(f"Enqueued task {task_id}: {service.value}/{task_type} for file {file_id}")
return task_id
def dequeue_task(self, timeout: int = 10) -> Optional[QueueTask]:
"""
Dequeue next available task respecting service limits and rate limits.
Args:
timeout: Blocking timeout in seconds
Returns:
QueueTask or None if no task available
"""
# Check all priority queues in order
for priority in [TaskPriority.HIGH, TaskPriority.NORMAL, TaskPriority.LOW]:
queue_key = self.queue_keys[priority]
# Non-blocking pop to check availability
task_id = self.redis_client.rpop(queue_key)
if not task_id:
continue
# Get task data
task_data = self.redis_client.hgetall(self._get_task_key(task_id))
if not task_data:
logger.warning(f"Task {task_id} data not found, skipping")
continue
# Reconstruct task object (ignore non-dataclass keys like 'status', 'result', timestamps)
task_data['service'] = ServiceType(task_data['service'])
task_data['priority'] = TaskPriority(task_data['priority'])
task_data['created_at'] = float(task_data['created_at'])
task_data['scheduled_at'] = float(task_data['scheduled_at'])
task_data['attempts'] = int(task_data['attempts'])
task_data['max_attempts'] = int(task_data['max_attempts'])
task_data['timeout'] = int(task_data['timeout'])
task_data['payload'] = json.loads(task_data['payload'])
# Drop extraneous keys that may be present in Redis
for k in ['status', 'result', 'completed_at', 'failed_at', 'last_error', 'final_error']:
task_data.pop(k, None)
task = QueueTask(**task_data)
# Check if task is ready (for delayed/retry tasks)
if task.scheduled_at > time.time():
# Put back in queue for later
self.redis_client.lpush(queue_key, task_id)
continue
# Enforce simple dependency ordering using optional depends_on array in payload
try:
depends_on = []
if isinstance(task.payload, dict):
depends_on = task.payload.get('depends_on') or []
if isinstance(depends_on, list) and len(depends_on) > 0:
logger.info(f"Checking {len(depends_on)} dependencies for task {task_id}")
unmet = []
for dep_id in depends_on:
if not dep_id:
continue
dep_key = self._get_task_key(dep_id)
dep_status = self.redis_client.hget(dep_key, 'status') or TaskStatus.PENDING.value
if dep_status != TaskStatus.COMPLETED.value:
unmet.append((dep_id, dep_status))
if len(unmet) > 0:
# Reschedule this task a bit later to avoid tight loops
next_time = time.time() + 10
self.redis_client.hset(
self._get_task_key(task_id),
mapping={'scheduled_at': next_time}
)
# Put back for later processing
self.redis_client.lpush(queue_key, task_id)
logger.info(f"Deferring task {task_id} due to unmet dependencies: {unmet}")
continue
else:
logger.info(f"All {len(depends_on)} dependencies satisfied for task {task_id}")
except Exception as dep_e:
logger.warning(f"Dependency check failed for task {task_id}: {dep_e}")
# Check service limits
service_processing_key = self._get_service_processing_key(task.service)
current_processing = int(self.redis_client.get(service_processing_key) or 0)
if current_processing >= self.service_limits[task.service]:
# Put back in queue with delay to prevent infinite loops
logger.warning(f"🚨 SERVICE LIMIT: Task {task_id} re-queued due to service limit exceeded: {current_processing}/{self.service_limits[task.service]} for {task.service.value}")
# Add delay before re-queueing to prevent tight loops
next_time = time.time() + 5 # Wait 5 seconds before retrying
self.redis_client.hset(
self._get_task_key(task_id),
mapping={'scheduled_at': next_time}
)
self.redis_client.lpush(queue_key, task_id)
continue
# Check rate limits
rate_key = self._get_rate_limit_key(task.service)
current_rate = int(self.redis_client.get(rate_key) or 0)
if current_rate >= self.rate_limits[task.service]:
# Put back in queue with delay to prevent infinite loops
logger.warning(f"🚨 RATE LIMIT: Task {task_id} re-queued due to rate limit exceeded: {current_rate}/{self.rate_limits[task.service]} for {task.service.value}")
# Add delay before re-queueing to prevent tight loops
next_time = time.time() + 60 # Wait 60 seconds for rate limit reset
self.redis_client.hset(
self._get_task_key(task_id),
mapping={'scheduled_at': next_time}
)
self.redis_client.lpush(queue_key, task_id)
continue
# Task can be processed
# Increment processing counter
self.redis_client.incr(service_processing_key)
self.redis_client.expire(service_processing_key, 3600) # 1 hour
# Increment rate limit counter
self.redis_client.incr(rate_key)
self.redis_client.expire(rate_key, 60) # 1 minute
# Add to processing set
self.redis_client.hset(
self.processing_key,
task_id,
json.dumps({
'service': task.service.value,
'started_at': time.time(),
'worker_id': threading.current_thread().ident
})
)
# Update metrics
self._update_metrics("dequeued", task.service.value, task.priority.value)
logger.debug(f"Dequeued task {task_id}: {task.service.value}/{task.task_type}")
return task
return None
def complete_task(self, task: QueueTask, result: Dict[str, Any] = None):
"""Mark task as completed and clean up."""
# Remove from processing
self.redis_client.hdel(self.processing_key, task.id)
# Decrement processing counter
service_processing_key = self._get_service_processing_key(task.service)
self.redis_client.decr(service_processing_key)
# Update task status
self.redis_client.hset(
self._get_task_key(task.id),
mapping={
'status': TaskStatus.COMPLETED.value,
'completed_at': time.time(),
'result': json.dumps(result or {})
}
)
# Update metrics
self._update_metrics("completed", task.service.value, task.priority.value)
logger.info(f"Completed task {task.id}: {task.service.value}/{task.task_type}")
def fail_task(self, task: QueueTask, error: str, retry: bool = True):
"""Handle task failure with retry logic."""
# Remove from processing
self.redis_client.hdel(self.processing_key, task.id)
# Decrement processing counter
service_processing_key = self._get_service_processing_key(task.service)
self.redis_client.decr(service_processing_key)
task.attempts += 1
if retry and task.attempts < task.max_attempts:
# Enhanced retry logic with progress-aware delays for comparison tasks
if task.task_type == 'docling_comparison_analysis':
# Special handling for comparison analysis tasks
payload = getattr(task, 'payload', {})
# Check if this is a progress-aware retry
if hasattr(error, 'is_progress_retry') and error.is_progress_retry:
# Active progress - shorter delay (30s to 2 minutes)
delay = min(120, 30 + task.attempts * 15)
logger.info(f"Comparison task {task.id}: Active progress detected, shorter retry delay: {delay}s")
elif hasattr(error, 'is_alignment_retry') and error.is_alignment_retry:
# Alignment issues - medium delay (1-3 minutes)
delay = min(180, 60 + task.attempts * 20)
logger.info(f"Comparison task {task.id}: Alignment retry, medium delay: {delay}s")
elif hasattr(error, 'is_stalled_retry') and error.is_stalled_retry:
# Stalled processing - longer delay (2-10 minutes)
delay = min(600, 120 + task.attempts * 30)
logger.info(f"Comparison task {task.id}: Stalled retry, longer delay: {delay}s")
else:
# Default comparison delay - extended for large PDFs (5-20 minutes)
delay = min(1200, 300 + task.attempts * 60)
logger.info(f"Comparison task {task.id}: Standard retry, extended delay: {delay}s")
# Update progress tracking in payload for next attempt
if hasattr(error, 'current_progress'):
payload['previous_progress'] = error.current_progress
# Update the task payload in Redis
import json
self.redis_client.hset(
self._get_task_key(task.id),
'payload', json.dumps(payload)
)
else:
# Standard retry with exponential backoff for other tasks
delay = min(300, 2 ** task.attempts * 10) # Max 5 minutes
task.scheduled_at = time.time() + delay
task.status = TaskStatus.RETRYING
# Update task data
self.redis_client.hset(
self._get_task_key(task.id),
mapping={
'attempts': task.attempts,
'scheduled_at': task.scheduled_at,
'status': TaskStatus.RETRYING.value,
'last_error': error
}
)
# Re-queue for retry
queue_key = self.queue_keys[task.priority]
self.redis_client.lpush(queue_key, task.id)
# Update metrics
self._update_metrics("retried", task.service.value, task.priority.value)
logger.warning(f"Retrying task {task.id} in {delay}s (attempt {task.attempts}/{task.max_attempts}): {error}")
else:
# Move to dead letter queue
task.status = TaskStatus.DEAD
self.redis_client.hset(
self._get_task_key(task.id),
mapping={
'attempts': task.attempts,
'status': TaskStatus.DEAD.value,
'failed_at': time.time(),
'final_error': error
}
)
self.redis_client.lpush(self.dead_letter_key, task.id)
# Update metrics
self._update_metrics("failed", task.service.value, task.priority.value)
logger.error(f"Task {task.id} moved to dead letter queue after {task.attempts} attempts: {error}")
def get_queue_stats(self) -> Dict[str, Any]:
"""Get comprehensive queue statistics."""
stats = {
'queues': {},
'processing': {},
'service_limits': dict(self.service_limits),
'rate_limits': dict(self.rate_limits),
'dead_letter_count': self.redis_client.llen(self.dead_letter_key)
}
# Queue lengths
for priority in TaskPriority:
queue_key = self.queue_keys[priority]
stats['queues'][priority.value] = self.redis_client.llen(queue_key)
# Processing counts
for service in ServiceType:
service_key = self._get_service_processing_key(service)
stats['processing'][service.value] = int(self.redis_client.get(service_key) or 0)
# Total processing
stats['total_processing'] = self.redis_client.hlen(self.processing_key)
return stats
def _update_metrics(self, action: str, service: str, priority: str):
"""Update queue metrics."""
timestamp = int(time.time())
metric_key = f"{self.metrics_key}:{action}:{service}:{priority}:{timestamp // 60}"
self.redis_client.incr(metric_key)
self.redis_client.expire(metric_key, 3600) # 1 hour
def start_worker(self, worker_id: str = None, services: List[ServiceType] = None):
"""Start a queue worker thread."""
if worker_id is None:
worker_id = f"worker-{uuid.uuid4().hex[:8]}"
if services is None:
services = list(ServiceType)
def worker_loop():
logger.info(f"Starting worker {worker_id} for services: {[s.value for s in services]}")
while not self.shutdown_event.is_set():
try:
task = self.dequeue_task(timeout=5)
if task is None:
continue
# DEBUG: Log task details immediately after dequeue
logger.info(f"🔍 WORKER DEBUG: Dequeued task {task.id}, service={task.service.value}, task_type={task.task_type}")
logger.info(f"🔍 WORKER DEBUG: Worker {worker_id} handles services: {[s.value for s in services]}")
if task.service not in services:
# Put back in queue if worker doesn't handle this service
# But first clean up the processing state to avoid infinite loops
logger.warning(f"🚨 WORKER DEBUG: Task {task.id} service {task.service.value} NOT in worker services {[s.value for s in services]}")
self.redis_client.hdel(self.processing_key, task.id)
# NOTE: Do NOT decrement service_processing_key here - task will be re-processed by correct worker
# service_processing_key = self._get_service_processing_key(task.service)
# self.redis_client.decr(service_processing_key) # REMOVED: Caused negative counters
queue_key = self.queue_keys[task.priority]
self.redis_client.lpush(queue_key, task.id)
logger.warning(f"🚨 WORKER DEBUG: Task {task.id} re-queued due to service mismatch")
continue
# DEBUG: Confirm we're about to process
logger.info(f"✅ WORKER DEBUG: About to process task {task.id}")
# Process the task
self._process_task(task)
# DEBUG: Confirm processing completed
logger.info(f"✅ WORKER DEBUG: Finished processing task {task.id}")
except Exception as e:
logger.error(f"Worker {worker_id} error: {e}")
time.sleep(1)
logger.info(f"Worker {worker_id} shutting down")
thread = threading.Thread(target=worker_loop, name=f"QueueWorker-{worker_id}")
thread.daemon = True
thread.start()
self.workers_running[worker_id] = thread
return worker_id
def _process_task(self, task: QueueTask):
"""Process a single task (to be overridden by specific implementations)."""
logger.warning(f"No processor implemented for task {task.id}: {task.service.value}/{task.task_type}")
self.fail_task(task, "No processor implemented", retry=False)
def shutdown(self, timeout: int = 30):
"""Gracefully shutdown all workers."""
logger.info("Shutting down queue workers...")
self.shutdown_event.set()
# Wait for workers to finish
for worker_id, thread in self.workers_running.items():
thread.join(timeout=timeout)
if thread.is_alive():
logger.warning(f"Worker {worker_id} did not shut down gracefully")
self.workers_running.clear()
logger.info("Queue shutdown complete")
# Global queue instance
_queue_instance = None
def get_queue() -> DocumentProcessingQueue:
"""Get the global queue instance."""
global _queue_instance
if _queue_instance is None:
_queue_instance = DocumentProcessingQueue()
return _queue_instance
# Convenience functions for common operations
def enqueue_tika_task(file_id: str, payload: Dict[str, Any], priority: TaskPriority = TaskPriority.NORMAL) -> str:
"""Enqueue a Tika processing task."""
return get_queue().enqueue_task(
service=ServiceType.TIKA,
task_type="metadata_extraction",
file_id=file_id,
payload=payload,
priority=priority,
timeout=int(os.getenv('TIKA_TIMEOUT', '300'))
)
def enqueue_docling_task(file_id: str, task_type: str, payload: Dict[str, Any],
priority: TaskPriority = TaskPriority.NORMAL, timeout: int = 1800,
max_attempts: int = None) -> str:
"""Enqueue a Docling processing task with intelligent retry limits."""
# Auto-configure max_attempts based on task type and payload
if max_attempts is None:
if task_type == 'docling_comparison_analysis':
# Use the max_retry_attempts from payload, or default to high limit for comparisons
max_attempts = payload.get('max_retry_attempts', 50)
else:
# Standard retry limit for other docling tasks
max_attempts = 3
return get_queue().enqueue_task(
service=ServiceType.DOCLING,
task_type=task_type,
file_id=file_id,
payload=payload,
priority=priority,
timeout=timeout,
max_attempts=max_attempts
)
def enqueue_llm_task(file_id: str, task_type: str, payload: Dict[str, Any],
priority: TaskPriority = TaskPriority.NORMAL) -> str:
"""Enqueue an LLM processing task."""
return get_queue().enqueue_task(
service=ServiceType.LLM,
task_type=task_type,
file_id=file_id,
payload=payload,
priority=priority,
timeout=int(os.getenv('LLM_TIMEOUT', '180'))
)
def enqueue_split_map_task(file_id: str, payload: Dict[str, Any],
priority: TaskPriority = TaskPriority.NORMAL) -> str:
"""Enqueue a split map generation task."""
return get_queue().enqueue_task(
service=ServiceType.SPLIT_MAP,
task_type="generate_split_map",
file_id=file_id,
payload=payload,
priority=priority,
timeout=120
)
def enqueue_document_analysis_task(file_id: str, payload: Dict[str, Any],
priority: TaskPriority = TaskPriority.NORMAL) -> str:
"""Enqueue a document structure analysis task."""
return get_queue().enqueue_task(
service=ServiceType.DOCUMENT_ANALYSIS,
task_type="document_structure_analysis",
file_id=file_id,
payload=payload,
priority=priority,
timeout=int(os.getenv('DOCUMENT_ANALYSIS_TIMEOUT', '300'))
)
def enqueue_page_images_task(file_id: str, payload: Dict[str, Any],
priority: TaskPriority = TaskPriority.NORMAL) -> str:
"""Enqueue a page images generation task."""
return get_queue().enqueue_task(
service=ServiceType.PAGE_IMAGES,
task_type="generate_page_images",
file_id=file_id,
payload=payload,
priority=priority,
timeout=int(os.getenv('PAGE_IMAGES_TIMEOUT', '600'))
)

523
modules/redis_manager.py Normal file
View File

@ -0,0 +1,523 @@
"""
Comprehensive Redis Management System
=====================================
Handles environment-specific Redis configuration, service management,
task recovery, and health monitoring for ClassroomCopilot.
Features:
- Environment isolation (dev/prod/test databases)
- Automatic service management and health checks
- Task recovery and persistence strategies
- Graceful degradation and error handling
"""
import os
import redis
import subprocess
import time
import signal
import json
import logging
from typing import Dict, List, Optional, Any, Tuple
from dataclasses import dataclass
from enum import Enum
logger = logging.getLogger(__name__)
class Environment(Enum):
DEV = "dev"
PROD = "prod"
TEST = "test"
@dataclass
class RedisConfig:
host: str
port: int
db: int
password: Optional[str]
ssl: bool
persist: bool
task_ttl: int
url: str
class RedisManager:
"""Comprehensive Redis management with environment isolation and recovery."""
def __init__(self, environment: Environment = Environment.DEV):
self.environment = environment
self.config = self._load_config()
self.client: Optional[redis.Redis] = None
self._subprocess: Optional[subprocess.Popen] = None
self._health_check_enabled = True
logger.info(f"🔧 Redis Manager initialized for {environment.value} environment")
logger.info(f"📡 Target: {self.config.host}:{self.config.port}/db{self.config.db}")
def _load_config(self) -> RedisConfig:
"""Load environment-specific Redis configuration."""
# Base configuration
host = os.getenv('REDIS_HOST', 'localhost')
port = int(os.getenv('REDIS_PORT', '6379'))
password = os.getenv('REDIS_PASSWORD') or None
ssl = os.getenv('REDIS_SSL', 'false').lower() == 'true'
# Environment-specific settings
if self.environment == Environment.DEV:
db = int(os.getenv('REDIS_DB_DEV', '0'))
persist = os.getenv('REDIS_PERSIST_DEV', 'false').lower() == 'true'
task_ttl = int(os.getenv('REDIS_TASK_TTL_DEV', '3600'))
elif self.environment == Environment.PROD:
db = int(os.getenv('REDIS_DB_PROD', '1'))
persist = os.getenv('REDIS_PERSIST_PROD', 'true').lower() == 'true'
task_ttl = int(os.getenv('REDIS_TASK_TTL_PROD', '86400'))
else: # TEST
db = int(os.getenv('REDIS_DB_TEST', '2'))
persist = False
task_ttl = int(os.getenv('REDIS_TASK_TTL_TEST', '1800'))
# Construct URL
auth_part = f":{password}@" if password else ""
url = f"redis://{auth_part}{host}:{port}/{db}"
return RedisConfig(
host=host,
port=port,
db=db,
password=password,
ssl=ssl,
persist=persist,
task_ttl=task_ttl,
url=url
)
def ensure_service_running(self) -> bool:
"""Ensure Redis service is running, start if needed."""
# Check if Redis is already running
if self._is_redis_running():
logger.info("✅ Redis service already running")
return True
# Try to start Redis service
logger.info("🚀 Starting Redis service...")
# Try systemctl first (Linux production)
if self._try_systemctl_start():
return True
# Try brew services (macOS)
if self._try_brew_start():
return True
# Try direct Redis server start
if self._try_direct_start():
return True
# Try Docker fallback
if self._try_docker_start():
return True
logger.error("❌ Failed to start Redis service with all methods")
return False
def _is_redis_running(self) -> bool:
"""Check if Redis is accessible."""
try:
test_client = redis.Redis(
host=self.config.host,
port=self.config.port,
socket_connect_timeout=2,
socket_timeout=2
)
test_client.ping()
test_client.close()
return True
except Exception:
return False
def _try_systemctl_start(self) -> bool:
"""Try starting Redis with systemctl."""
try:
if not os.path.exists('/usr/bin/systemctl'):
return False
subprocess.run(['sudo', 'systemctl', 'start', 'redis'],
check=True, capture_output=True, timeout=10)
time.sleep(2)
return self._is_redis_running()
except Exception:
return False
def _try_brew_start(self) -> bool:
"""Try starting Redis with brew services."""
try:
if not os.path.exists('/opt/homebrew/bin/brew'):
return False
subprocess.run(['/opt/homebrew/bin/brew', 'services', 'start', 'redis'],
check=True, capture_output=True, timeout=10)
time.sleep(2)
return self._is_redis_running()
except Exception:
return False
def _try_direct_start(self) -> bool:
"""Try starting Redis server directly."""
try:
# Find redis-server binary
redis_cmd = None
for path in ['/opt/homebrew/bin/redis-server', '/usr/local/bin/redis-server', 'redis-server']:
try:
subprocess.run([path, '--version'], capture_output=True, check=True, timeout=5)
redis_cmd = path
break
except Exception:
continue
if not redis_cmd:
return False
# Start Redis with appropriate config
config_args = [
redis_cmd,
'--port', str(self.config.port),
'--bind', self.config.host,
'--protected-mode', 'no',
'--loglevel', 'notice',
'--daemonize', 'yes' # Run as daemon
]
# Add persistence settings
if not self.config.persist:
config_args.extend(['--save', '', '--appendonly', 'no'])
else:
config_args.extend(['--save', '60 1000', '--appendonly', 'yes'])
subprocess.run(config_args, check=True, capture_output=True, timeout=10)
time.sleep(3)
return self._is_redis_running()
except Exception as e:
logger.debug(f"Direct Redis start failed: {e}")
return False
def _try_docker_start(self) -> bool:
"""Try starting Redis with Docker."""
try:
subprocess.run(['docker', '--version'], capture_output=True, check=True, timeout=5)
# Check if Redis container already exists
result = subprocess.run(
['docker', 'ps', '-a', '--filter', 'name=classroomcopilot-redis', '--format', '{{.Names}}'],
capture_output=True, text=True, timeout=10
)
if 'classroomcopilot-redis' in result.stdout:
# Start existing container
subprocess.run(['docker', 'start', 'classroomcopilot-redis'],
check=True, capture_output=True, timeout=10)
else:
# Create new container
docker_cmd = [
'docker', 'run', '-d',
'--name', 'classroomcopilot-redis',
'-p', f'{self.config.port}:6379',
'redis:alpine'
]
if not self.config.persist:
docker_cmd.extend(['redis-server', '--save', '', '--appendonly', 'no'])
subprocess.run(docker_cmd, check=True, capture_output=True, timeout=30)
time.sleep(3)
return self._is_redis_running()
except Exception as e:
logger.debug(f"Docker Redis start failed: {e}")
return False
def connect(self) -> bool:
"""Establish Redis connection with retry logic."""
max_attempts = int(os.getenv('REDIS_MAX_RETRY_ATTEMPTS', '3'))
for attempt in range(1, max_attempts + 1):
try:
logger.info(f"🔌 Connecting to Redis... (attempt {attempt}/{max_attempts})")
self.client = redis.Redis(
host=self.config.host,
port=self.config.port,
db=self.config.db,
password=self.config.password,
decode_responses=True,
socket_connect_timeout=5,
socket_timeout=5,
retry_on_timeout=True
)
# Test connection
self.client.ping()
logger.info(f"✅ Connected to Redis {self.config.host}:{self.config.port}/db{self.config.db}")
return True
except Exception as e:
logger.warning(f"❌ Connection attempt {attempt} failed: {e}")
if attempt < max_attempts:
logger.info("⏳ Retrying in 2 seconds...")
time.sleep(2)
else:
logger.error("💥 All connection attempts failed")
return False
return False
def initialize_environment(self) -> bool:
"""Initialize Redis environment based on mode."""
if not self.ensure_service_running():
logger.error("Cannot initialize - Redis service not available")
return False
if not self.connect():
logger.error("Cannot initialize - Connection failed")
return False
if self.environment == Environment.DEV:
return self._initialize_dev_environment()
elif self.environment == Environment.PROD:
return self._initialize_prod_environment()
else:
return self._initialize_test_environment()
def _initialize_dev_environment(self) -> bool:
"""Initialize development environment - clean slate."""
try:
logger.info("🧹 DEV MODE: Clearing all data for clean startup...")
# Get all keys in this database
all_keys = self.client.keys('*')
if all_keys:
# Nuclear option - clear everything in this DB
self.client.flushdb()
logger.info(f"💥 DEV MODE: Nuked {len(all_keys)} keys for clean startup")
else:
logger.info("✅ DEV MODE: Database already clean")
# Set up development-specific config
try:
self.client.config_set('save', '') # Disable RDB snapshots
self.client.config_set('appendonly', 'no') # Disable AOF
except Exception as e:
logger.debug(f"Could not set Redis config (may not have permissions): {e}")
logger.info("🎯 DEV MODE: Environment initialized for fast iteration")
return True
except Exception as e:
logger.error(f"Failed to initialize dev environment: {e}")
return False
def _initialize_prod_environment(self) -> bool:
"""Initialize production environment - preserve data."""
try:
logger.info("🏭 PROD MODE: Initializing with data preservation...")
# Check for existing tasks and report
task_keys = self.client.keys('task:*')
queue_keys = self.client.keys('queue:*')
processing_keys = self.client.keys('processing:*')
logger.info(f"📊 PROD MODE: Found {len(task_keys)} tasks, {len(queue_keys)} queues, {len(processing_keys)} processing counters")
# Enable persistence
if self.config.persist:
try:
self.client.config_set('save', '60 1000') # Save every 60s if ≥1000 changes
self.client.config_set('appendonly', 'yes') # Enable AOF
logger.info("💾 PROD MODE: Persistence enabled")
except Exception as e:
logger.debug(f"Could not set Redis config (may not have permissions): {e}")
# Recover any stuck tasks
self._recover_stuck_tasks()
logger.info("✅ PROD MODE: Environment initialized with data recovery")
return True
except Exception as e:
logger.error(f"Failed to initialize prod environment: {e}")
return False
def _initialize_test_environment(self) -> bool:
"""Initialize test environment - isolated and clean."""
try:
logger.info("🧪 TEST MODE: Setting up isolated test environment...")
# Clear test database
self.client.flushdb()
# Disable persistence for speed
try:
self.client.config_set('save', '')
self.client.config_set('appendonly', 'no')
except Exception as e:
logger.debug(f"Could not set Redis config (may not have permissions): {e}")
logger.info("✅ TEST MODE: Clean, isolated environment ready")
return True
except Exception as e:
logger.error(f"Failed to initialize test environment: {e}")
return False
def _recover_stuck_tasks(self):
"""Recover tasks that were processing when system shut down."""
try:
logger.info("🔄 Recovering stuck tasks from previous session...")
# Get all processing tasks
processing_data = self.client.hgetall('processing')
if not processing_data:
logger.info("✅ No stuck tasks to recover")
return
recovered_count = 0
for task_id, task_info in processing_data.items():
try:
# Parse task info
info = json.loads(task_info)
# Check if task still exists
task_key = f"task:{task_id}"
if not self.client.exists(task_key):
logger.warning(f"⚠️ Task {task_id} data missing, removing from processing")
self.client.hdel('processing', task_id)
continue
# Reset task to pending and re-queue
self.client.hset(task_key, 'status', 'pending')
self.client.hdel(task_key, 'started_at')
# Add back to appropriate queue
priority = info.get('priority', 'normal')
queue_key = f"queue:{priority}"
self.client.lpush(queue_key, task_id)
# Remove from processing
self.client.hdel('processing', task_id)
# Reset service counters
service = info.get('service')
if service:
service_key = f"processing:{service}"
current_count = int(self.client.get(service_key) or 0)
if current_count > 0:
self.client.decr(service_key)
recovered_count += 1
logger.info(f"🔄 Recovered stuck task {task_id} ({service}/{priority})")
except Exception as e:
logger.error(f"Failed to recover task {task_id}: {e}")
# Remove problematic entry
self.client.hdel('processing', task_id)
logger.info(f"✅ Recovered {recovered_count} stuck tasks")
except Exception as e:
logger.error(f"Task recovery failed: {e}")
def health_check(self) -> Dict[str, Any]:
"""Comprehensive health check."""
health = {
'status': 'healthy',
'environment': self.environment.value,
'database': self.config.db,
'connection': False,
'memory_usage': None,
'queue_stats': {},
'error': None
}
try:
if not self.client:
raise Exception("No Redis connection")
# Test connection
self.client.ping()
health['connection'] = True
# Get memory usage
info = self.client.info('memory')
health['memory_usage'] = {
'used_memory_human': info.get('used_memory_human', 'unknown'),
'used_memory_peak_human': info.get('used_memory_peak_human', 'unknown')
}
# Get queue statistics
health['queue_stats'] = {
'total_keys': len(self.client.keys('*')),
'tasks': len(self.client.keys('task:*')),
'queues': {
'high': self.client.llen('queue:high'),
'normal': self.client.llen('queue:normal'),
'low': self.client.llen('queue:low')
},
'processing': self.client.hlen('processing'),
'dead_letter': self.client.llen('dead_letter')
}
except Exception as e:
health['status'] = 'unhealthy'
health['error'] = str(e)
return health
def shutdown(self, force: bool = False):
"""Graceful shutdown with optional data preservation."""
if self.environment == Environment.DEV and not force:
logger.info("🧹 DEV MODE: Clearing data on shutdown...")
try:
if self.client:
self.client.flushdb()
logger.info("✅ Dev data cleared")
except Exception as e:
logger.warning(f"Failed to clear dev data: {e}")
# Close connection
if self.client:
try:
self.client.close()
logger.info("🔌 Redis connection closed")
except Exception as e:
logger.warning(f"Error closing Redis connection: {e}")
# Stop subprocess if we started it
if self._subprocess:
try:
self._subprocess.terminate()
self._subprocess.wait(timeout=5)
logger.info("🛑 Redis subprocess stopped")
except Exception as e:
logger.warning(f"Error stopping Redis subprocess: {e}")
logger.info(f"✅ Redis manager shutdown complete ({self.environment.value})")
# Convenience functions for backward compatibility
def get_redis_manager(environment: str = "dev") -> RedisManager:
"""Get a Redis manager instance for the specified environment."""
env = Environment(environment.lower())
return RedisManager(env)
def ensure_redis_running(environment: str = "dev") -> bool:
"""Ensure Redis is running for the specified environment."""
manager = get_redis_manager(environment)
return manager.ensure_service_running()

2531
modules/task_processors.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -77,4 +77,5 @@ python-docx
pdfminer.six
Pillow
psutil
PyPDF2
PyPDF2
PyMuPDF

File diff suppressed because it is too large Load Diff

View File

@ -1,113 +0,0 @@
from fastapi import APIRouter, Request, Depends, HTTPException
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
import os
from modules.logger_tool import initialise_logger
from modules.database.services.school_admin_service import SchoolAdminService
from modules.database.supabase.utils.storage import StorageManager
from .auth import verify_admin
from typing import Dict
router = APIRouter()
templates = Jinja2Templates(directory="templates")
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
# Initialize services
school_service = SchoolAdminService()
storage_manager = StorageManager()
@router.get("/schools/manage", response_class=HTMLResponse)
async def manage_schools(request: Request, admin: Dict = Depends(verify_admin)):
"""Manage schools page"""
return templates.TemplateResponse(
"admin/schools/manage.html",
{"request": request, "admin": admin}
)
@router.get("/storage/manage", response_class=HTMLResponse)
async def manage_storage(request: Request, admin: Dict = Depends(verify_admin)):
"""Storage management page"""
try:
# Get list of storage buckets with correct IDs
buckets = [
{
"id": "cc.institutes",
"name": "School Files",
"public": False,
"file_size_limit": 50 * 1024 * 1024, # 50MB
"allowed_mime_types": [
"image/*",
"video/*",
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-powerpoint",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"text/plain",
"text/csv",
"application/json"
]
},
{
"id": "cc.users",
"name": "User Files",
"public": False,
"file_size_limit": 50 * 1024 * 1024, # 50MB
"allowed_mime_types": [
"image/*",
"video/*",
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-powerpoint",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"text/plain",
"text/csv",
"application/json"
]
}
]
return templates.TemplateResponse(
"admin/storage/manage.html",
{"request": request, "admin": admin, "buckets": buckets}
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/schema", response_class=HTMLResponse)
async def manage_schema(request: Request, admin: Dict = Depends(verify_admin)):
"""Schema management page"""
return templates.TemplateResponse(
"admin/schema/manage.html",
{"request": request, "admin": admin}
)
@router.get("/storage/{bucket_id}/contents")
async def list_bucket_contents(
request: Request,
bucket_id: str,
path: str = "",
admin: Dict = Depends(verify_admin)
):
"""List contents of a storage bucket"""
try:
contents = storage_manager.list_bucket_contents(bucket_id, path)
bucket = {"id": bucket_id, "name": bucket_id.replace("_", " ").title()}
return templates.TemplateResponse(
"admin/storage/contents.html",
{
"request": request,
"admin": admin,
"bucket": bucket,
"contents": contents,
"current_path": path
}
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))

View File

@ -1,498 +0,0 @@
from fastapi import APIRouter, Request, Depends, HTTPException, File, UploadFile, Form
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.templating import Jinja2Templates
from typing import Dict
import os
from modules.logger_tool import initialise_logger
from modules.database.services.admin_service import AdminService, AdminProfileBase
from modules.database.services.school_admin_service import SchoolAdminService
from modules.database.supabase.utils.client import SupabaseAnonClient
from modules.database.supabase.utils.storage import StorageManager
from .auth import verify_admin
import csv
import io
router = APIRouter()
templates = Jinja2Templates(directory="templates")
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
# Initialize services
admin_service = AdminService()
school_service = SchoolAdminService()
storage_manager = StorageManager(SupabaseAnonClient)
@router.get("/", response_class=HTMLResponse)
async def admin_dashboard(request: Request, admin: Dict = Depends(verify_admin)):
"""Render admin dashboard"""
return templates.TemplateResponse(
"admin/dashboard/index.html",
{
"request": request,
"admin": admin,
"app_version": os.getenv("APP_VERSION", "Unknown")
}
)
@router.get("/users")
async def list_users(request: Request, admin: Dict = Depends(verify_admin)):
"""List all users"""
return templates.TemplateResponse(
"admin/users/list.html",
{"request": request, "admin": admin}
)
@router.get("/users/{user_id}")
async def get_user(request: Request, user_id: str, admin: Dict = Depends(verify_admin)):
"""Get user details"""
return templates.TemplateResponse(
"admin/users/detail.html",
{"request": request, "admin": admin, "user_id": user_id}
)
@router.get("/admins")
async def list_admins(request: Request, admin: Dict = Depends(verify_admin)):
"""List all admins"""
if not admin.get("is_super_admin"):
raise HTTPException(status_code=403, detail="Only super admins can view admin list")
admins = admin_service.list_admins()
return templates.TemplateResponse(
"admin/users/admins.html",
{"request": request, "admin": admin, "admins": admins}
)
@router.post("/admins")
async def create_admin(admin_data: AdminProfileBase, current_admin: Dict = Depends(verify_admin)):
"""Create a new admin"""
try:
result = admin_service.create_admin(admin_data, current_admin)
return JSONResponse(content={"status": "success", "admin": result})
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@router.get("/schools/manage", response_class=HTMLResponse)
async def manage_schools(request: Request, admin: Dict = Depends(verify_admin)):
"""Manage schools page"""
try:
# Fetch schools from Supabase
result = admin_service.supabase.table("schools").select("*").execute()
schools = result.data if result else []
# Sort schools by establishment_name
schools.sort(key=lambda x: x.get("establishment_name", ""))
return templates.TemplateResponse(
"admin/schools/manage.html",
{
"request": request,
"admin": admin,
"schools": schools,
"schools_count": len(schools)
}
)
except Exception as e:
logger.error(f"Error fetching schools: {str(e)}")
return templates.TemplateResponse(
"admin/schools/manage.html",
{
"request": request,
"admin": admin,
"schools": [],
"schools_count": 0,
"error": str(e)
}
)
@router.post("/schools/import")
async def import_schools(
file: UploadFile = File(...),
admin: Dict = Depends(verify_admin)
):
"""Import schools from CSV file"""
if not file.filename.endswith('.csv'):
raise HTTPException(status_code=400, detail="Please upload a CSV file")
try:
# Process the CSV file
content = await file.read()
csv_text = content.decode('utf-8-sig') # Handle BOM if present
csv_reader = csv.DictReader(io.StringIO(csv_text))
# Prepare data for batch insert
schools_data = []
for row in csv_reader:
school_data = {
"urn": row.get("URN"),
"la_code": row.get("LA (code)"),
"la_name": row.get("LA (name)"),
"establishment_number": row.get("EstablishmentNumber"),
"establishment_name": row.get("EstablishmentName"),
"establishment_type": row.get("TypeOfEstablishment (name)"),
"establishment_type_group": row.get("EstablishmentTypeGroup (name)"),
"establishment_status": row.get("EstablishmentStatus (name)"),
"reason_establishment_opened": row.get("ReasonEstablishmentOpened (name)"),
"open_date": row.get("OpenDate"),
"reason_establishment_closed": row.get("ReasonEstablishmentClosed (name)"),
"close_date": row.get("CloseDate"),
"phase_of_education": row.get("PhaseOfEducation (name)"),
"statutory_low_age": row.get("StatutoryLowAge"),
"statutory_high_age": row.get("StatutoryHighAge"),
"boarders": row.get("Boarders (name)"),
"nursery_provision": row.get("NurseryProvision (name)"),
"official_sixth_form": row.get("OfficialSixthForm (name)"),
"gender": row.get("Gender (name)"),
"religious_character": row.get("ReligiousCharacter (name)"),
"religious_ethos": row.get("ReligiousEthos (name)"),
"diocese": row.get("Diocese (name)"),
"admissions_policy": row.get("AdmissionsPolicy (name)"),
"school_capacity": row.get("SchoolCapacity"),
"special_classes": row.get("SpecialClasses (name)"),
"census_date": row.get("CensusDate"),
"number_of_pupils": row.get("NumberOfPupils"),
"number_of_boys": row.get("NumberOfBoys"),
"number_of_girls": row.get("NumberOfGirls"),
"percentage_fsm": row.get("PercentageFSM"),
"trust_school_flag": row.get("TrustSchoolFlag (name)"),
"trusts_name": row.get("Trusts (name)"),
"school_sponsor_flag": row.get("SchoolSponsorFlag (name)"),
"school_sponsors_name": row.get("SchoolSponsors (name)"),
"federation_flag": row.get("FederationFlag (name)"),
"federations_name": row.get("Federations (name)"),
"ukprn": row.get("UKPRN"),
"fehe_identifier": row.get("FEHEIdentifier"),
"further_education_type": row.get("FurtherEducationType (name)"),
"ofsted_last_inspection": row.get("OfstedLastInsp"),
"last_changed_date": row.get("LastChangedDate"),
"street": row.get("Street"),
"locality": row.get("Locality"),
"address3": row.get("Address3"),
"town": row.get("Town"),
"county": row.get("County (name)"),
"postcode": row.get("Postcode"),
"school_website": row.get("SchoolWebsite"),
"telephone_num": row.get("TelephoneNum"),
"head_title": row.get("HeadTitle (name)"),
"head_first_name": row.get("HeadFirstName"),
"head_last_name": row.get("HeadLastName"),
"head_preferred_job_title": row.get("HeadPreferredJobTitle"),
"gssla_code": row.get("GSSLACode (name)"),
"parliamentary_constituency": row.get("ParliamentaryConstituency (name)"),
"urban_rural": row.get("UrbanRural (name)"),
"rsc_region": row.get("RSCRegion (name)"),
"country": row.get("Country (name)"),
"uprn": row.get("UPRN"),
"sen_stat": row.get("SENStat") == "true",
"sen_no_stat": row.get("SENNoStat") == "true",
"sen_unit_on_roll": row.get("SenUnitOnRoll"),
"sen_unit_capacity": row.get("SenUnitCapacity"),
"resourced_provision_on_roll": row.get("ResourcedProvisionOnRoll"),
"resourced_provision_capacity": row.get("ResourcedProvisionCapacity"),
}
# Clean up empty strings and convert types
for key, value in school_data.items():
if value == "":
school_data[key] = None
elif key in ["statutory_low_age", "statutory_high_age", "school_capacity",
"number_of_pupils", "number_of_boys", "number_of_girls",
"sen_unit_on_roll", "sen_unit_capacity",
"resourced_provision_on_roll", "resourced_provision_capacity"]:
if value:
try:
float_val = float(value)
int_val = int(float_val)
school_data[key] = int_val
except (ValueError, TypeError):
school_data[key] = None
elif key == "percentage_fsm":
if value:
try:
school_data[key] = float(value)
except (ValueError, TypeError):
school_data[key] = None
elif key in ["open_date", "close_date", "census_date",
"ofsted_last_inspection", "last_changed_date"]:
if value:
try:
# Convert date from DD-MM-YYYY to YYYY-MM-DD
parts = value.split("-")
if len(parts) == 3:
school_data[key] = f"{parts[2]}-{parts[1]}-{parts[0]}"
else:
school_data[key] = None
except:
school_data[key] = None
schools_data.append(school_data)
# Batch insert schools using admin service's Supabase client
if schools_data:
result = admin_service.supabase.table("schools").upsert(
schools_data,
on_conflict="urn" # Update if URN already exists
).execute()
logger.info(f"Imported {len(schools_data)} schools")
return {"status": "success", "imported_count": len(schools_data)}
else:
raise HTTPException(status_code=400, detail="No valid school data found in CSV")
except Exception as e:
logger.error(f"Error importing schools: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@router.post("/initialize-schools-database")
async def initialize_schools_database(admin: Dict = Depends(verify_admin)):
"""Initialize schools database"""
if not admin.get("is_super_admin"):
raise HTTPException(status_code=403, detail="Only super admins can initialize database")
result = school_service.create_schools_database()
if result["status"] == "error":
raise HTTPException(status_code=500, detail=result["message"])
return result
@router.get("/check-schools-database")
async def check_schools_database(admin: Dict = Depends(verify_admin)):
"""Check schools database status"""
try:
# Use SchoolService to check if database exists and has required nodes/relationships
result = school_service.check_schools_database()
return {"exists": result["status"] == "success"}
except Exception as e:
logger.error(f"Error checking schools database: {str(e)}")
return {"exists": False, "error": str(e)}
@router.get("/storage", response_class=HTMLResponse)
async def storage_management(request: Request, admin: Dict = Depends(verify_admin)):
"""Storage management page"""
try:
# Get list of storage buckets with correct IDs
buckets = [
{
"id": "cc.institutes",
"name": "School Files",
"public": False,
"file_size_limit": 50 * 1024 * 1024, # 50MB
"allowed_mime_types": [
"image/*",
"video/*",
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-powerpoint",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"text/plain",
"text/csv",
"application/json"
]
},
{
"id": "cc.users",
"name": "User Files",
"public": False,
"file_size_limit": 50 * 1024 * 1024, # 50MB
"allowed_mime_types": [
"image/*",
"video/*",
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-powerpoint",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"text/plain",
"text/csv",
"application/json"
]
}
]
return templates.TemplateResponse(
"admin/storage/manage.html",
{"request": request, "admin": admin, "buckets": buckets}
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/storage/{bucket_id}/contents")
async def list_bucket_contents(
request: Request,
bucket_id: str,
path: str = "",
admin: Dict = Depends(verify_admin)
):
"""List contents of a storage bucket"""
try:
contents = storage_manager.list_bucket_contents(bucket_id, path)
bucket = {"id": bucket_id, "name": bucket_id.replace("_", " ").title()}
return templates.TemplateResponse(
"admin/storage/contents.html",
{
"request": request,
"admin": admin,
"bucket": bucket,
"contents": contents,
"current_path": path
}
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/storage/{bucket_id}/download/{file_path:path}")
async def download_file(
bucket_id: str,
file_path: str,
admin: Dict = Depends(verify_admin)
):
"""Get download URL for a file"""
try:
url = storage_manager.create_signed_url(bucket_id, file_path)
return {"url": url}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.delete("/storage/{bucket_id}/objects/{object_path:path}")
async def delete_object(
bucket_id: str,
object_path: str,
admin: Dict = Depends(verify_admin)
):
"""Delete an object from storage"""
try:
storage_manager.delete_file(bucket_id, object_path)
return {"status": "success"}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/check-storage")
async def check_storage(admin: Dict = Depends(verify_admin)):
"""Check storage buckets status"""
try:
# Use the same bucket IDs as defined in initialize_storage
buckets = [
{"id": "cc.users", "name": "User Files"},
{"id": "cc.institutes", "name": "School Files"}
]
results = []
for bucket in buckets:
exists = storage_manager.check_bucket_exists(bucket["id"])
results.append({
"id": bucket["id"],
"name": bucket["name"],
"exists": exists
})
return {"buckets": results}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/initialize-storage")
async def initialize_storage(admin: Dict = Depends(verify_admin)):
"""Initialize storage buckets and policies for schools"""
try:
# Verify super admin status
if not admin.get('is_super_admin'):
raise HTTPException(status_code=403, detail="Only super admins can initialize storage")
# Use the storage manager to initialize storage
storage_manager = StorageManager(SupabaseAnonClient)
return storage_manager.initialize_storage()
except Exception as e:
logger.error(f"Error initializing storage: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/check-schema")
async def check_schema(admin: Dict = Depends(verify_admin)):
"""Check Neo4j schema status"""
try:
from modules.database.services.graph_service import GraphService
graph_service = GraphService()
# Get actual schema status
schema_status = graph_service.check_schema_status()
# Return status with proper validation
return {
"constraints_valid": schema_status["constraints_count"] > 0,
"constraints_count": schema_status["constraints_count"],
"indexes_valid": schema_status["indexes_count"] > 0,
"indexes_count": schema_status["indexes_count"],
"labels_valid": schema_status["labels_count"] > 0,
"labels_count": schema_status["labels_count"]
}
except Exception as e:
logger.error(f"Error checking schema: {str(e)}")
return {
"constraints_valid": False,
"constraints_count": 0,
"indexes_valid": False,
"indexes_count": 0,
"labels_valid": False,
"labels_count": 0,
"error": str(e)
}
@router.post("/initialize-schema")
async def initialize_schema(admin: Dict = Depends(verify_admin)):
"""Initialize Neo4j schema (constraints and indexes)"""
if not admin.get("is_super_admin"):
raise HTTPException(status_code=403, detail="Only super admins can initialize schema")
try:
from modules.database.services.graph_service import GraphService
graph_service = GraphService()
# Initialize schema
result = graph_service.initialize_schema()
if result["status"] == "error":
raise HTTPException(status_code=500, detail=result["message"])
return result
except Exception as e:
logger.error(f"Error initializing schema: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/schools/{school_id}")
async def view_school(request: Request, school_id: str, admin: Dict = Depends(verify_admin)):
"""View school details"""
try:
# Fetch school details from Supabase
result = admin_service.supabase.table("schools").select("*").eq("id", school_id).single().execute()
school = result.data if result else None
if not school:
raise HTTPException(status_code=404, detail="School not found")
return templates.TemplateResponse(
"admin/schools/detail.html",
{"request": request, "admin": admin, "school": school}
)
except Exception as e:
logger.error(f"Error fetching school details: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@router.delete("/schools/{school_id}")
async def delete_school(school_id: str, admin: Dict = Depends(verify_admin)):
"""Delete a school"""
try:
# Verify super admin status
if not admin.get("is_super_admin"):
raise HTTPException(status_code=403, detail="Only super admins can delete schools")
# Delete the school from Supabase
result = admin_service.supabase.table("schools").delete().eq("id", school_id).execute()
if not result.data:
raise HTTPException(status_code=404, detail="School not found")
return {"status": "success", "message": "School deleted successfully"}
except Exception as e:
logger.error(f"Error deleting school: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))

View File

@ -0,0 +1,7 @@
from fastapi import APIRouter
router = APIRouter()
@router.get("/ping")
def ping():
return {"status": "ok"}

View File

@ -45,7 +45,7 @@ async def login_page(
# If no super admin and init flag is true, show initialization form
if not has_super_admin:
expected_email = os.getenv("VITE_SUPER_ADMIN_EMAIL")
expected_email = os.getenv("ADMIN_EMAIL")
return templates.TemplateResponse(
"admin/login.html",
{

View File

@ -0,0 +1,3 @@
from . import cabinets, files

View File

@ -0,0 +1,75 @@
import os
from fastapi import APIRouter, Depends, HTTPException
from typing import Any, Dict
from modules.auth.supabase_bearer import SupabaseBearer
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
router = APIRouter()
auth = SupabaseBearer()
@router.get("/cabinets")
def list_cabinets(payload: Dict[str, Any] = Depends(auth)):
user_id = payload.get('sub') or payload.get('user_id')
if not user_id:
raise HTTPException(status_code=401, detail="Invalid token payload")
client = SupabaseServiceRoleClient()
# Owned + shared via membership
owned = client.supabase.table('file_cabinets').select('*').eq('user_id', user_id).execute().data
shared = client.supabase.table('cabinet_memberships').select('cabinet_id').eq('profile_id', user_id).execute().data
shared_ids = [m['cabinet_id'] for m in (shared or [])]
shared_rows = client.supabase.table('file_cabinets').select('*').in_('id', shared_ids).execute().data if shared_ids else []
return {"owned": owned or [], "shared": shared_rows or []}
@router.post("/cabinets")
def create_cabinet(body: Dict[str, Any], payload: Dict[str, Any] = Depends(auth)):
user_id = payload.get('sub') or payload.get('user_id')
name = (body or {}).get('name')
if not user_id or not name:
raise HTTPException(status_code=400, detail="name is required")
client = SupabaseServiceRoleClient()
res = client.supabase.table('file_cabinets').insert({
'user_id': user_id,
'name': name
}).execute()
return res.data
@router.patch("/cabinets/{cabinet_id}")
def rename_cabinet(cabinet_id: str, body: Dict[str, Any], payload: Dict[str, Any] = Depends(auth)):
name = (body or {}).get('name')
if not name:
raise HTTPException(status_code=400, detail="name is required")
client = SupabaseServiceRoleClient()
res = client.supabase.table('file_cabinets').update({'name': name}).eq('id', cabinet_id).execute()
return res.data
@router.delete("/cabinets/{cabinet_id}")
def delete_cabinet(cabinet_id: str, payload: Dict[str, Any] = Depends(auth)):
client = SupabaseServiceRoleClient()
res = client.supabase.table('file_cabinets').delete().eq('id', cabinet_id).execute()
return res.data
@router.post("/cabinets/{cabinet_id}/members")
def add_member(cabinet_id: str, body: Dict[str, Any], payload: Dict[str, Any] = Depends(auth)):
target_profile_id = (body or {}).get('profile_id')
role = (body or {}).get('role', 'viewer')
if not target_profile_id:
raise HTTPException(status_code=400, detail="profile_id required")
client = SupabaseServiceRoleClient()
# Insert membership (RLS will ensure only owner can do it)
res = client.supabase.table('cabinet_memberships').upsert({
'cabinet_id': cabinet_id,
'profile_id': target_profile_id,
'role': role
}).execute()
return res.data
@router.delete("/cabinets/{cabinet_id}/members/{profile_id}")
def remove_member(cabinet_id: str, profile_id: str, payload: Dict[str, Any] = Depends(auth)):
client = SupabaseServiceRoleClient()
res = client.supabase.table('cabinet_memberships').delete().match({
'cabinet_id': cabinet_id,
'profile_id': profile_id
}).execute()
return res.data

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,256 @@
"""
Simplified Files Router
======================
Simplified version of the files router with auto-processing removed.
Keeps only essential functionality for file management and manual processing triggers.
This replaces the complex auto-processing system with simple file storage.
"""
import os
import uuid
import logging
from typing import Dict, List, Optional, Any
from pathlib import Path
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, BackgroundTasks
from fastapi.responses import JSONResponse
from modules.auth.supabase_bearer import SupabaseBearer
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
from modules.database.supabase.utils.storage import StorageAdmin
from modules.logger_tool import initialise_logger
router = APIRouter()
auth = SupabaseBearer()
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
def _choose_bucket(scope: str, user_id: str, school_id: Optional[str]) -> str:
"""Choose appropriate bucket based on scope - matches old system logic."""
scope = (scope or 'teacher').lower()
if scope == 'school' and school_id:
return f"cc.institutes.{school_id}.private"
# teacher / student fall back to users bucket for now
return 'cc.users'
@router.post("/files/upload")
async def upload_file(
cabinet_id: str = Form(...),
path: str = Form(...),
scope: str = Form(...),
file: UploadFile = File(...),
payload: Dict[str, Any] = Depends(auth)
):
"""
SIMPLIFIED file upload - no automatic processing.
Just stores the file and creates a database record.
This is the legacy endpoint maintained for backward compatibility.
"""
try:
user_id = payload.get('sub') or payload.get('user_id')
if not user_id:
raise HTTPException(status_code=401, detail="User ID required")
# Read file content
file_bytes = await file.read()
file_size = len(file_bytes)
mime_type = file.content_type or 'application/octet-stream'
filename = file.filename or path
logger.info(f"📤 Simplified upload: {filename} ({file_size} bytes) for user {user_id}")
# Initialize services
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
# Generate file ID and storage path
file_id = str(uuid.uuid4())
# Use same bucket logic as old system for consistency
bucket = _choose_bucket('teacher', user_id, None)
storage_path = f"{cabinet_id}/{file_id}/{filename}"
# Store file in Supabase storage
try:
storage.upload_file(bucket, storage_path, file_bytes, mime_type, upsert=True)
except Exception as e:
logger.error(f"Storage upload failed for {file_id}: {e}")
raise HTTPException(status_code=500, detail=f"Storage upload failed: {str(e)}")
# Create database record
try:
insert_res = client.supabase.table('files').insert({
'id': file_id,
'name': filename,
'cabinet_id': cabinet_id,
'bucket': bucket,
'path': storage_path,
'mime_type': mime_type,
'uploaded_by': user_id,
'size_bytes': file_size,
'source': 'classroomcopilot-web',
'is_directory': False,
'processing_status': 'uploaded', # No auto-processing
'relative_path': filename
}).execute()
if not insert_res.data:
# Clean up storage on DB failure
try:
storage.delete_file(bucket, storage_path)
except:
pass
raise HTTPException(status_code=500, detail="Failed to create file record")
file_record = insert_res.data[0]
except Exception as e:
logger.error(f"Database insert failed for {file_id}: {e}")
# Clean up storage
try:
storage.delete_file(bucket, storage_path)
except:
pass
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
logger.info(f"✅ Simplified upload completed: {file_id}")
return {
'status': 'success',
'message': 'File uploaded successfully (no auto-processing)',
'file': file_record,
'auto_processing_disabled': True,
'next_steps': 'Use manual processing endpoints if needed'
}
except HTTPException:
raise
except Exception as e:
logger.error(f"Upload error: {e}")
raise HTTPException(status_code=500, detail=f"Upload failed: {str(e)}")
@router.get("/files")
def list_files(cabinet_id: str, payload: Dict[str, Any] = Depends(auth)):
"""List files in a cabinet."""
client = SupabaseServiceRoleClient()
res = client.supabase.table('files').select('*').eq('cabinet_id', cabinet_id).execute()
return res.data
@router.get("/files/{file_id}")
def get_file(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Get file details."""
client = SupabaseServiceRoleClient()
res = client.supabase.table('files').select('*').eq('id', file_id).single().execute()
if not res.data:
raise HTTPException(status_code=404, detail="File not found")
return res.data
@router.delete("/files/{file_id}")
def delete_file(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Delete a file."""
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
# Get file info first
res = client.supabase.table('files').select('*').eq('id', file_id).single().execute()
if not res.data:
raise HTTPException(status_code=404, detail="File not found")
file_data = res.data
# Delete from storage
try:
storage.delete_file(file_data['bucket'], file_data['path'])
except Exception as e:
logger.warning(f"Failed to delete file from storage: {e}")
# Delete from database
delete_res = client.supabase.table('files').delete().eq('id', file_id).execute()
logger.info(f"🗑️ Deleted file: {file_id}")
return {
'status': 'success',
'message': 'File deleted successfully'
}
@router.post("/files/{file_id}/process-manual")
async def trigger_manual_processing(
file_id: str,
processing_type: str = Form('basic'), # basic, advanced, custom
payload: Dict[str, Any] = Depends(auth)
):
"""
Trigger manual processing for a file.
This is where users can manually start processing when they want it.
"""
# TODO: Implement manual processing triggers
# This would call the archived processing logic when the user explicitly requests it
logger.info(f"🔧 Manual processing requested for file {file_id} (type: {processing_type})")
return {
'status': 'accepted',
'message': f'Manual processing queued for file {file_id}',
'processing_type': processing_type,
'note': 'Manual processing not yet implemented - will use archived auto-processing logic'
}
@router.get("/files/{file_id}/status")
def get_processing_status(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Get processing status for a file."""
client = SupabaseServiceRoleClient()
res = client.supabase.table('files').select('processing_status, error_message, extra').eq('id', file_id).single().execute()
if not res.data:
raise HTTPException(status_code=404, detail="File not found")
return {
'file_id': file_id,
'status': res.data.get('processing_status', 'unknown'),
'error': res.data.get('error_message'),
'details': res.data.get('extra', {})
}
# Keep existing artefacts endpoints for backward compatibility
@router.get("/files/{file_id}/artefacts")
def list_file_artefacts(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""List artefacts for a file."""
client = SupabaseServiceRoleClient()
res = client.supabase.table('document_artefacts').select('*').eq('file_id', file_id).execute()
return res.data or []
@router.get("/files/{file_id}/viewer-artefacts")
def list_viewer_artefacts(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""List artefacts organized for the viewer."""
client = SupabaseServiceRoleClient()
# Get all artefacts
res = client.supabase.table('document_artefacts').select('*').eq('file_id', file_id).execute()
artefacts = res.data or []
# Simple organization - no complex bundle logic
organized = {
'document_analysis': [],
'processing_bundles': [],
'raw_data': []
}
for artefact in artefacts:
artefact_type = artefact.get('type', '')
if 'analysis' in artefact_type.lower():
organized['document_analysis'].append(artefact)
elif any(bundle_type in artefact_type for bundle_type in ['docling', 'bundle']):
organized['processing_bundles'].append(artefact)
else:
organized['raw_data'].append(artefact)
return organized

View File

@ -0,0 +1,588 @@
# api/routers/database/files/split_map.py
"""
Automatic split_map.json generator for uploaded documents.
This module creates chapter/section boundaries for documents using existing artefacts
(Tika JSON, Docling frontmatter OCR) and optional PDF outline extraction.
Strategy (waterfall, stop at confidence 0.7):
1. PDF Outline/Bookmarks (best): confidence 0.95
2. Headings from Docling JSON: confidence 0.8
3. TOC from Tika text: confidence 0.7-0.8
4. Fixed windows: confidence 0.2
Hard constraints:
- For any fallback Docling "no-OCR" call: limit page_range to [1, min(30, page_count)]
- Never process more than 30 pages in one Docling request
- Use existing artefacts whenever possible
"""
import re
import json
import uuid
import datetime
import os
import requests
from typing import List, Dict, Any, Optional, Tuple
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
from modules.database.supabase.utils.storage import StorageAdmin
from modules.logger_tool import initialise_logger
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
# ---------- Utilities
def _now_iso():
"""Return current UTC timestamp in ISO format."""
return datetime.datetime.utcnow().replace(microsecond=0).isoformat() + "Z"
def _load_artefact_json(storage: StorageAdmin, bucket: str, rel_path: str) -> Optional[Dict[str, Any]]:
"""Load JSON artefact from storage."""
try:
raw = storage.download_file(bucket, rel_path)
return json.loads(raw.decode("utf-8"))
except Exception as e:
logger.debug(f"Failed to load artefact {rel_path}: {e}")
return None
def _page_count_from_tika(tika_json: Dict[str, Any]) -> Optional[int]:
"""Extract page count from Tika JSON metadata."""
for k in ("xmpTPg:NPages", "Page-Count", "pdf:PageCount", "pdf:pagecount"):
v = tika_json.get(k) or tika_json.get(k.lower())
try:
if v is not None:
return int(v)
except Exception:
pass
return None
# ---------- A) Outline via PyMuPDF (optional but recommended)
def _try_outline(pdf_bytes: bytes) -> Optional[List[Tuple[str, int]]]:
"""
Extract PDF outline/bookmarks using PyMuPDF.
Returns [(title, start_page)] for level-1 bookmarks only.
"""
try:
import fitz # PyMuPDF
doc = fitz.open(stream=pdf_bytes, filetype="pdf")
toc = doc.get_toc(simple=True) # list of [level, title, page]
doc.close()
# Keep level-1 only, ensure valid pages
out = []
for level, title, page in toc:
if level == 1 and page >= 1:
clean_title = title.strip()
if clean_title and len(clean_title) > 1:
out.append((clean_title, page))
return out if len(out) >= 2 else None # Need at least 2 chapters
except ImportError:
logger.debug("PyMuPDF not available, skipping outline extraction")
return None
except Exception as e:
logger.debug(f"Outline extraction failed: {e}")
return None
# ---------- B) Headings from Docling JSON
def _try_headings(docling_json: Dict[str, Any]) -> Optional[List[Tuple[str, int, int]]]:
"""
Extract headings from Docling JSON.
Returns [(title, start_page, level)] we only return starts; end pages are computed later.
"""
if not docling_json:
return None
# Handle different Docling JSON structures
blocks = (docling_json.get("blocks") or
docling_json.get("elements") or
docling_json.get("body", {}).get("blocks") or [])
candidates: List[Tuple[str, int, int]] = []
for b in blocks:
# Check if this is a heading block
role = (b.get("role") or b.get("type") or "").lower()
if not ("heading" in role or role in ("h1", "h2", "title", "section-header")):
continue
# Extract text content
text = (b.get("text") or b.get("content") or "").strip()
if not text or len(text) < 3:
continue
# Extract page number with robust handling of 0-based pageIndex
p = None
if b.get("pageIndex") is not None:
try:
p = int(b.get("pageIndex")) + 1
except Exception:
p = None
if p is None:
for key in ("page", "page_no", "page_number"):
if b.get(key) is not None:
try:
p = int(b.get(key))
except Exception:
p = None
break
if p is None or p < 1:
continue
# Determine heading level
level = 1 # default
if "1" in role or "h1" in role:
level = 1
elif "2" in role or "h2" in role:
level = 2
# Chapter regex boosts to level 1
if re.match(r"^\s*(chapter|ch\.?|section|part)\s+\d+", text, re.I):
level = 1
candidates.append((text, p, level))
if not candidates:
return None
# Prefer level 1; if none, promote level 2 to level 1
l1 = [(t, p, l) for (t, p, l) in candidates if l == 1]
if not l1:
l1 = [(t, p, 1) for (t, p, _) in candidates]
# Sort by page and keep strictly increasing pages only
l1_sorted = []
seen = set()
for (t, p, l) in sorted(l1, key=lambda x: x[1]):
if p not in seen and p >= 1:
l1_sorted.append((t, p, l))
seen.add(p)
return l1_sorted if len(l1_sorted) >= 2 else None
def _try_headings_fallback(file_id: str, cabinet_id: str, bucket: str,
processing_bytes: bytes, processing_mime: str,
page_count: int) -> Optional[List[Tuple[str, int, int]]]:
"""
Make a limited Docling no-OCR call (max 30 pages) to extract headings.
This is used only when existing artefacts don't have sufficient heading data.
"""
try:
docling_url = os.getenv('DOCLING_URL') or os.getenv('NEOFS_DOCLING_URL')
if not docling_url:
logger.debug("No Docling URL configured for headings fallback")
return None
# Strictly limit to first 30 pages
max_pages = min(30, page_count)
logger.info(f"Headings fallback: limited Docling call for file_id={file_id}, pages=1-{max_pages}")
# Build Docling request (no-OCR, limited pages)
docling_api_key = os.getenv('DOCLING_API_KEY')
headers = {'Accept': 'application/json'}
if docling_api_key:
headers['X-Api-Key'] = docling_api_key
form_data = [
('target_type', 'inbody'),
('to_formats', 'json'),
('do_ocr', 'false'),
('force_ocr', 'false'),
('image_export_mode', 'embedded'),
('pdf_backend', 'dlparse_v4'),
('table_mode', 'fast'),
('page_range', '1'),
('page_range', str(max_pages))
]
files = [('files', ('file', processing_bytes, processing_mime))]
# Make the request with timeout
timeout = int(os.getenv('DOCLING_HEADINGS_TIMEOUT', '1800')) # 30 minutes default
resp = requests.post(
f"{docling_url.rstrip('/')}/v1/convert/file",
files=files,
data=form_data,
headers=headers,
timeout=timeout
)
resp.raise_for_status()
docling_json = resp.json()
logger.debug(f"Headings fallback: received Docling response for file_id={file_id}")
return _try_headings(docling_json)
except Exception as e:
logger.error(f"Headings fallback failed for file_id={file_id}: {e}")
return None
# ---------- C) TOC from Tika text (dot leaders & page num)
TOC_LINE = re.compile(r"^\s*(.+?)\s?(\.{2,}|\s{3,})\s*(\d{1,4})\s*$")
def _try_toc_text(tika_text: str) -> Optional[List[Tuple[str, int]]]:
"""
Parse TOC from Tika text using dot leaders and page numbers.
Returns [(title, start_page)] if successful.
"""
if not tika_text:
return None
# Heuristic: only scan first ~1500 lines (roughly first 15 pages)
head = "\n".join(tika_text.splitlines()[:1500])
pairs = []
for line in head.splitlines():
m = TOC_LINE.match(line)
if not m:
continue
title = m.group(1).strip()
try:
page = int(m.group(3))
except Exception:
continue
# Reject obvious junk
if len(title) < 3 or page < 1 or page > 9999:
continue
# Skip common false positives
if any(skip in title.lower() for skip in ['copyright', 'isbn', 'published', 'printed']):
continue
pairs.append((title, page))
# Require at least 5 entries and monotonic pages
if len(pairs) >= 5:
pages = [p for _, p in pairs]
if pages == sorted(pages):
logger.debug(f"TOC extraction found {len(pairs)} entries")
return pairs
return None
# ---------- Build entries with ends, apply smoothing
def _entries_from_starts(starts: List[Tuple[str, int, int]], page_count: int, source: str = "headings") -> List[Dict[str, Any]]:
"""
Build entries from start points with computed end pages.
starts: [(title, page, level)]
"""
entries = []
base_confidence = 0.8 if source == "headings" else 0.75
for i, (title, start, level) in enumerate(starts):
end = (starts[i + 1][1] - 1) if i + 1 < len(starts) else page_count
entries.append({
"id": f"sec{i + 1:02d}",
"title": title,
"level": level,
"start_page": int(start),
"end_page": int(end),
"source": source,
"confidence": base_confidence
})
# Merge tiny sections (< 3 pages) into previous
merged = []
for e in entries:
section_size = e["end_page"] - e["start_page"] + 1
if merged and section_size < 3:
# Merge into previous section
merged[-1]["end_page"] = e["end_page"]
merged[-1]["title"] += " / " + e["title"]
merged[-1]["confidence"] *= 0.95 # Slight confidence penalty for merging
else:
merged.append(e)
return merged
def _entries_from_pairs(pairs: List[Tuple[str, int]], page_count: int, source: str = "outline") -> List[Dict[str, Any]]:
"""
Build entries from (title, start_page) pairs.
"""
entries = []
base_confidence = 0.95 if source == "outline" else (0.8 if source == "toc" else 0.75)
for i, (title, start) in enumerate(pairs):
end = (pairs[i + 1][1] - 1) if i + 1 < len(pairs) else page_count
entries.append({
"id": f"sec{i + 1:02d}",
"title": title,
"level": 1,
"start_page": int(start),
"end_page": int(end),
"source": source,
"confidence": base_confidence
})
# Apply same merging logic for tiny sections
merged = []
for e in entries:
section_size = e["end_page"] - e["start_page"] + 1
if merged and section_size < 3:
merged[-1]["end_page"] = e["end_page"]
merged[-1]["title"] += " / " + e["title"]
merged[-1]["confidence"] *= 0.95
else:
merged.append(e)
return merged
# ---------- Post-processing normalization
def _normalize_entries(entries: List[Dict[str, Any]], page_count: int) -> List[Dict[str, Any]]:
"""Normalize entries to ensure:
- coverage from page 1
- 1 <= start_page <= end_page <= page_count
- strictly increasing, non-overlapping ranges
- fill initial gap with a synthetic front matter section if needed
"""
if not entries:
return entries
# Sanitize and sort by start_page
safe: List[Dict[str, Any]] = []
for e in entries:
try:
s = int(e.get("start_page", 1))
t = int(e.get("end_page", s))
except Exception:
continue
s = max(1, min(s, page_count))
t = max(1, min(t, page_count))
if t < s:
t = s
ne = dict(e)
ne["start_page"], ne["end_page"] = s, t
safe.append(ne)
safe.sort(key=lambda x: (x["start_page"], x.get("level", 1)))
# De-overlap by adjusting starts; ensure monotonic ranges
normalized: List[Dict[str, Any]] = []
for e in safe:
if not normalized:
normalized.append(e)
continue
prev = normalized[-1]
if e["start_page"] <= prev["end_page"]:
e["start_page"] = prev["end_page"] + 1
if e["start_page"] > page_count:
continue
if e["end_page"] < e["start_page"]:
e["end_page"] = e["start_page"]
e["end_page"] = min(e["end_page"], page_count)
normalized.append(e)
# Insert synthetic front matter if first start > 1
if normalized and normalized[0]["start_page"] > 1:
front = {
"id": "sec00",
"title": "Front matter",
"level": 1,
"start_page": 1,
"end_page": normalized[0]["start_page"] - 1,
"source": "synthetic",
"confidence": 0.6,
}
normalized.insert(0, front)
# Ensure last section ends at page_count
if normalized and normalized[-1]["end_page"] < page_count:
normalized[-1]["end_page"] = page_count
# Renumber ids sequentially
out: List[Dict[str, Any]] = []
for idx, e in enumerate(normalized, start=1):
ne = dict(e)
ne["id"] = f"sec{idx:02d}"
out.append(ne)
return out
# ---------- Main entry point
def create_split_map_for_file(file_id: str) -> Dict[str, Any]:
"""
Create split_map.json for a file using waterfall strategy:
1. PDF outline (best)
2. Docling headings (from existing or limited fallback)
3. Tika TOC parsing
4. Fixed windows (fallback)
"""
logger.info(f"Creating split_map for file_id={file_id}")
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
# 1) Lookup file row & bucket
fr = client.supabase.table('files').select('id,bucket,cabinet_id,name,path,mime_type').eq('id', file_id).single().execute()
file_row = fr.data or {}
bucket = file_row.get('bucket')
cabinet_id = file_row.get('cabinet_id')
# 2) Find artefacts
arts = client.supabase.table('document_artefacts') \
.select('*').eq('file_id', file_id).order('created_at', desc=True).execute().data or []
def find_art(t):
for a in arts:
if a.get('type') == t:
return a
return None
a_pdf = find_art('document_pdf') # if converted to PDF
a_tika = find_art('tika_json')
a_noocr = find_art('docling_noocr_json')
a_fm = find_art('docling_frontmatter_json')
# 3) Load JSON/text
tika_json = _load_artefact_json(storage, bucket, a_tika['rel_path']) if a_tika else None
docling_noocr = _load_artefact_json(storage, bucket, a_noocr['rel_path']) if a_noocr else None
docling_fm = _load_artefact_json(storage, bucket, a_fm['rel_path']) if a_fm else None
# Get page count
page_count = _page_count_from_tika(tika_json or {}) or 100 # reasonable default
# Get PDF bytes for outline extraction
pdf_bytes = None
processing_bytes = None
processing_mime = None
if a_pdf:
# Use converted PDF
pdf_bytes = storage.download_file(bucket, a_pdf['rel_path'])
processing_bytes = pdf_bytes
processing_mime = 'application/pdf'
else:
# Check if original file is PDF
if file_row.get('mime_type') == 'application/pdf':
pdf_bytes = storage.download_file(bucket, file_row['path'])
processing_bytes = pdf_bytes
processing_mime = 'application/pdf'
# 4) Try methods in waterfall order
method = "fixed"
confidence = 0.2
entries: List[Dict[str, Any]] = []
# A) PDF Outline/Bookmarks (best)
if pdf_bytes and not entries:
logger.debug(f"Trying outline extraction for file_id={file_id}")
pairs = _try_outline(pdf_bytes)
if pairs:
entries = _entries_from_pairs(pairs, page_count, source="outline")
method, confidence = "outline", 0.95
logger.info(f"Split map: outline method found {len(entries)} sections")
# B) Headings from existing Docling JSON
if not entries:
logger.debug(f"Trying headings from existing Docling JSON for file_id={file_id}")
# Try no-OCR first, then frontmatter
for docling_json, source_name in [(docling_noocr, "noocr"), (docling_fm, "frontmatter")]:
if docling_json:
starts = _try_headings(docling_json)
if starts:
entries = _entries_from_starts(starts, page_count, source="headings")
method, confidence = "headings", 0.8
logger.info(f"Split map: headings method ({source_name}) found {len(entries)} sections")
break
# B2) Headings fallback with limited Docling call (if we have processing bytes)
if not entries and processing_bytes and processing_mime:
logger.debug(f"Trying headings fallback with limited Docling call for file_id={file_id}")
starts = _try_headings_fallback(file_id, cabinet_id, bucket, processing_bytes, processing_mime, page_count)
if starts:
entries = _entries_from_starts(starts, page_count, source="headings")
method, confidence = "headings", 0.75 # Slightly lower confidence for fallback
logger.info(f"Split map: headings fallback found {len(entries)} sections")
# C) TOC from Tika text
if not entries and tika_json:
logger.debug(f"Trying TOC extraction from Tika text for file_id={file_id}")
# Try common Tika text keys
text = tika_json.get("X-TIKA:content") or tika_json.get("content") or ""
pairs = _try_toc_text(text)
if pairs:
entries = _entries_from_pairs(pairs, page_count, source="toc")
method, confidence = "toc", 0.75
logger.info(f"Split map: TOC method found {len(entries)} sections")
# D) Fixed windows (fallback)
if not entries:
logger.info(f"Using fixed window fallback for file_id={file_id}")
step = max(10, min(20, page_count // 10)) # Adaptive step size
pairs = []
for i in range(1, page_count + 1, step):
end_page = min(i + step - 1, page_count)
title = f"Pages {i}-{end_page}" if i != end_page else f"Page {i}"
pairs.append((title, i))
entries = _entries_from_pairs(pairs, page_count, source="fixed")
method, confidence = "fixed", 0.2
logger.info(f"Split map: fixed method created {len(entries)} sections")
# 5) Normalize entries and build split_map.json
entries = _normalize_entries(entries, page_count)
split_map = {
"version": 1,
"file_id": file_id,
"source_pdf_artefact_id": a_pdf['id'] if a_pdf else None,
"sources": {
"docling_noocr_json": a_noocr['id'] if a_noocr else None,
"docling_frontmatter_json": a_fm['id'] if a_fm else None,
"tika_json": a_tika['id'] if a_tika else None
},
"method": method,
"confidence": confidence,
"page_count": page_count,
"entries": entries,
"created_at": _now_iso(),
"notes": f"auto-generated using {method} method; user can edit in Split Marker UI"
}
# 6) Store as artefact
artefact_id = str(uuid.uuid4())
rel_path = f"{cabinet_id}/{file_id}/{artefact_id}/split_map.json"
storage.upload_file(
bucket,
rel_path,
json.dumps(split_map, ensure_ascii=False, indent=2).encode("utf-8"),
"application/json",
upsert=True
)
# Enhanced metadata for UI display
enhanced_extra = {
"method": method,
"confidence": confidence,
"entries_count": len(entries),
"display_name": "Document Structure Map",
"bundle_label": "Split Map",
"section_title": "Document Structure Map",
"page_count": page_count,
"bundle_type": "split_map_json",
"processing_mode": "document_analysis",
"pipeline": "structure_analysis",
"is_structure_map": True,
"ui_category": "document_analysis",
"ui_order": 2,
"description": f"Document section boundaries identified using {method} method with {confidence:.1%} confidence ({len(entries)} sections)",
"viewer_type": "json"
}
client.supabase.table('document_artefacts').insert({
"id": artefact_id,
"file_id": file_id,
"type": "split_map_json",
"rel_path": rel_path,
"extra": enhanced_extra,
"status": "completed"
}).execute()
logger.info(f"Split map stored: file_id={file_id}, method={method}, confidence={confidence:.2f}, entries={len(entries)}")
return split_map

View File

@ -31,20 +31,19 @@ async def upload_curriculum(file: UploadFile = File(...), db_name: str = Form(..
async def upload_school_curriculum(
file: UploadFile = File(...),
db_name: str = Form(...),
school_uuid: str = Form(...),
school_uuid_string: str = Form(...),
school_name: str = Form(...),
school_website: str = Form(...),
school_path: str = Form(...)
school_node_storage_path: str = Form(...)
):
if file.content_type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
return {"status": "Error", "message": "Invalid file format"}
logging.info(f"Uploading curriculum for school {school_name} in {db_name}")
dataframes = xl.create_dataframes_from_fastapiuploadfile(file)
school_node = SchoolNode(
unique_id=f'School_{school_uuid}',
school_uuid=school_uuid,
school_name=school_name,
school_website=school_website,
path=school_path
uuid_string=school_uuid_string,
name=school_name,
website=school_website,
node_storage_path=school_node_storage_path
)
return init_school_curriculum.create_curriculum(db_name, dataframes, school_node)

View File

@ -23,9 +23,9 @@ def initialise_schools_from_config():
"""Initialize a school with the configuration provided from env variables
"""
default_config = {
"school_uuid": "kevlarai",
"school_name": "KevlarAI School",
"school_website": "https://kevlarai.com",
"uuid_string": "kevlarai-dev",
"name": "KevlarAI School",
"website": "https://kevlarai.com",
"timetable_file": "kevlarai_data/kevlarai_timetable.xlsx",
"curriculum_file": "kevlarai_data/kevlarai_curriculum.xlsx"
}
@ -33,10 +33,10 @@ def initialise_schools_from_config():
# school_config_str = os.getenv("SCHOOL_CONFIG") # TODO: Implement this
school_config = default_config
db_name = f"cc.institutes.{school_config['school_uuid']}"
db_name = f"cc.institutes.{school_config['uuid_string']}"
curriculum_db_name = f"{db_name}.curriculum"
logger.info(f"Creating database for {school_config['school_name']} using db_name: {db_name}")
logger.info(f"Creating database for {school_config['name']} using db_name: {db_name}")
driver = driver_tools.get_driver()
if driver is None:
logger.error("Failed to connect to Neo4j")
@ -54,7 +54,7 @@ def initialise_schools_from_config():
# Add filesystem path debugging
base_path = os.getenv("NODE_FILESYSTEM_PATH")
schools_path = os.path.join(base_path, "schools")
school_path = os.path.join(schools_path, f"cc.institutes.{school_config['school_uuid']}")
school_path = os.path.join(schools_path, f"cc.institutes.{school_config['uuid_string']}")
logger.debug("Filesystem paths:", {
"base_path": base_path,
@ -70,29 +70,34 @@ def initialise_schools_from_config():
})
# Create database entry for school without timetable or curriculum
logger.info(f"Creating school entry for {school_config['school_name']} in database {db_name} without timetable or curriculum")
logger.info(f"Creating school entry for {school_config['name']} in database {db_name} without timetable or curriculum")
school_uuid_string=school_config["uuid_strig"]
school_name=school_config["name"]
school_website=school_config["website"]
result = init_school.create_school(
db_name=db_name,
school_uuid=school_config["school_uuid"],
school_name=school_config["school_name"],
school_website=school_config["school_website"]
school_type="development",
uuid_string=school_uuid_string,
name=school_name,
website=school_website
)
logger.success(f"{school_config['school_name']} school entry created successfully")
logger.success(f"{school_config['name']} school entry created successfully")
# Create school node from result
school_node = result['school_node']
refreshed_school_node = SchoolNode(
unique_id=school_node.unique_id,
school_uuid=school_node.school_uuid,
school_name=school_node.school_name,
school_website=school_node.school_website,
path=school_node.path
school_type="development",
uuid_string=school_node.uuid_string,
name=school_node.name,
website=school_node.website
)
# Create timetable entries for school from Excel file
timetable_file = os.path.join(os.getenv("BACKEND_INIT_PATH"), school_config["timetable_file"])
logger.info(f"Creating timetable entries for {school_config['school_name']} using timetable file: {timetable_file}.")
logger.info(f"Creating timetable entries for {school_config['name']} using timetable file: {timetable_file}.")
school_timetable_dataframes = xl.create_dataframes(timetable_file)
@ -107,7 +112,7 @@ def initialise_schools_from_config():
curriculum_file = os.path.join(os.getenv("BACKEND_INIT_PATH"), school_config["curriculum_file"])
school_curriculum_dataframes = xl.create_dataframes(curriculum_file)
logger.info(f"Creating curriculum entries for {school_config['school_name']} using curriculum file: {curriculum_file}.")
logger.info(f"Creating curriculum entries for {school_config['name']} using curriculum file: {curriculum_file}.")
init_school_curriculum.create_curriculum(
dataframes=school_curriculum_dataframes,
db_name=db_name,
@ -123,18 +128,18 @@ async def create_user(
user_type: str = Form(...),
user_name: str = Form(...),
user_email: str = Form(...),
school_uuid: str = Form(None),
school_uuid_string: str = Form(None),
school_name: str = Form(None),
school_website: str = Form(None),
school_path: str = Form(None),
school_node_storage_path: str = Form(None),
worker_data: str = Form(None)
):
logger.info(f"Creating user with user_id: {user_id}, user_type: {user_type}, user_name: {user_name}, user_email: {user_email}")
if school_uuid:
logger.info(f"School UUID provided: {school_uuid}")
if school_uuid_string:
logger.info(f"School UUID string provided: {school_uuid_string}")
else:
logger.info(f"No school UUID provided")
logger.info(f"No school UUID string provided")
if school_name:
logger.info(f"School name provided: {school_name}")
@ -146,8 +151,8 @@ async def create_user(
else:
logger.info(f"No school website provided")
if school_path:
logger.info(f"School path provided: {school_path}")
if school_node_storage_path:
logger.info(f"School path provided: {school_node_storage_path}")
else:
logger.info(f"No school path provided")
@ -169,13 +174,12 @@ async def create_user(
# Create school node if school data provided
school_node = None
if all([school_uuid, school_name, school_website, school_path]):
if all([school_uuid_string, school_name, school_website, school_node_storage_path]):
school_node = SchoolNode(
unique_id=f'School_{school_uuid}',
school_uuid=school_uuid,
school_name=school_name,
school_website=school_website,
path=school_path
uuid_string=school_uuid_string,
name=school_name,
website=school_website,
node_storage_path=school_node_storage_path
)
# Create user with single database reference
@ -219,23 +223,23 @@ async def create_schools():
@router.post("/create-department")
async def create_department(
db_name: str = Form(...),
unique_id: str = Form(...),
uuid_string: str = Form(...),
department_name: str = Form(...),
department_code: str = Form(...),
path: str = Form(...)
department_node_storage_path: str = Form(...)
):
if db_name is None or unique_id is None or department_name is None or department_code is None or path is None:
logging.error(f"Invalid department data: {db_name}, {unique_id}, {department_name}, {department_code}, {path}")
if db_name is None or uuid_string is None or department_name is None or department_code is None or department_node_storage_path is None:
logging.error(f"Invalid department data: {db_name}, {uuid_string}, {department_name}, {department_code}, {department_node_storage_path}")
raise HTTPException(status_code=400, detail="Invalid department data")
department = DepartmentNode(
unique_id=unique_id,
uuid_string=uuid_string,
department_name=department_name,
department_code=department_code,
path=path
node_storage_path=department_node_storage_path
)
logger.info(f"Creating department {department_name} with unique_id {unique_id}")
logger.info(f"Creating department {department_name} with uuid_string {uuid_string}")
try:
result = init_school.create_department(db_name, department)
return JSONResponse(content={"status": "success", "data": result})
@ -246,20 +250,20 @@ async def create_department(
@router.post("/create-class")
async def create_class(
db_name: str = Form(...),
unique_id: str = Form(...),
uuid_string: str = Form(...),
subject_class_code: str = Form(...),
year_group: str = Form(...),
subject: str = Form(...),
subject_code: str = Form(...),
path: str = Form(...)
subject_node_storage_path: str = Form(...)
):
subject_class_node = SubjectClassNode(
unique_id=unique_id,
uuid_string=uuid_string,
subject_class_code=subject_class_code,
year_group=year_group,
subject=subject,
subject_code=subject_code,
path=path
node_storage_path=subject_node_storage_path
)
# Implementation for creating a class
pass
@ -267,14 +271,14 @@ async def create_class(
@router.post("/create-room")
async def create_room(
db_name: str = Form(...),
room_unique_id: str = Form(...),
room_uuid_string: str = Form(...),
room_code: str = Form(...),
path: str = Form(...)
room_node_storage_path: str = Form(...)
):
room = RoomNode(
room_unique_id=room_unique_id,
room_uuid_string=room_uuid_string,
room_code=room_code,
path=path
node_storage_path=room_node_storage_path
)
# Implementation for creating a room
pass

View File

@ -15,7 +15,7 @@ logging = logger.get_logger(
from fastapi import APIRouter, File, UploadFile, Form, HTTPException, BackgroundTasks
import pandas as pd
import modules.database.tools.neo4j_driver_tools as driver
from modules.database.tools.neo4j_session_tools import get_node_by_unique_id
from modules.database.tools.neo4j_session_tools import get_node_by_uuid_string
import modules.database.init.init_school_timetable as init_school_timetable
import modules.database.init.init_worker_timetable as init_worker_timetable
from modules.database.schemas.nodes.schools.schools import SchoolNode
@ -28,18 +28,16 @@ router = APIRouter()
async def upload_school_timetable(
file: UploadFile = File(...),
db_name: str = Form(...),
unique_id: str = Form(...),
school_uuid: str = Form(...),
school_uuid_string: str = Form(...),
school_name: str = Form(...),
school_website: str = Form(...),
path: str = Form(...)
school_node_storage_path: str = Form(...)
):
school_node = SchoolNode(
unique_id=unique_id,
school_uuid=school_uuid,
school_name=school_name,
school_website=school_website,
path=path
uuid_string=school_uuid_string,
name=school_name,
website=school_website,
node_storage_path=school_node_storage_path
)
if file.content_type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
return {"status": "Error", "message": "Invalid file format"}
@ -91,13 +89,13 @@ async def process_worker_timetable(file_content, worker_node_data):
timetable_df = pd.read_excel(BytesIO(file_content))
# Get the school version of the worker node
logging.info(f"Getting school worker node for {worker_node_data['unique_id']} from {worker_node_data['worker_db_name']}")
logging.info(f"Getting school worker node for {worker_node_data['uuid_string']} from {worker_node_data['worker_db_name']}")
with neo_driver.session(database=worker_node_data['worker_db_name']) as neo_session:
school_worker_node = get_node_by_unique_id(session=neo_session, unique_id=worker_node_data['unique_id'])
school_worker_node = get_node_by_uuid_string(session=neo_session, uuid_string=worker_node_data['uuid_string'])
if school_worker_node is None:
error_msg = f"School worker node not found for unique_id: {worker_node_data['unique_id']}"
error_msg = f"School worker node not found for uuid_string: {worker_node_data['uuid_string']}"
logging.error(error_msg)
raise Exception(error_msg)

View File

@ -15,7 +15,7 @@ logging = logger.get_logger(
from fastapi import APIRouter, File, UploadFile, Form, HTTPException, BackgroundTasks
import pandas as pd
import modules.database.tools.neo4j_driver_tools as driver
from modules.database.tools.neo4j_session_tools import get_node_by_unique_id
from modules.database.tools.neo4j_session_tools import get_node_by_uuid_string
import modules.database.init.init_school_timetable as init_school_timetable
import modules.database.init.init_worker_timetable as init_worker_timetable
from modules.database.schemas.nodes.users import UserNode
@ -31,18 +31,16 @@ router = APIRouter()
async def upload_school_timetable(
file: UploadFile = File(...),
db_name: str = Form(...),
unique_id: str = Form(...),
school_uuid: str = Form(...),
school_uuid_string: str = Form(...),
school_name: str = Form(...),
school_website: str = Form(...),
path: str = Form(...)
school_node_storage_path: str = Form(...)
):
school_node = SchoolNode(
unique_id=unique_id,
school_uuid=school_uuid,
school_name=school_name,
school_website=school_website,
path=path
uuid_string=school_uuid_string,
name=school_name,
website=school_website,
node_storage_path=school_node_storage_path
)
if file.content_type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
return {"status": "Error", "message": "Invalid file format"}
@ -101,13 +99,13 @@ async def process_worker_timetable(file_content, user_node_data, worker_node_dat
timetable_df = pd.read_excel(BytesIO(file_content))
# Get the school version of the worker node
logging.info(f"Getting school worker node for {worker_node_data['unique_id']} from {worker_node_data['worker_db_name']}")
logging.info(f"Getting school worker node for {worker_node_data['uuid_string']} from {worker_node_data['worker_db_name']}")
with neo_driver.session(database=worker_node_data['worker_db_name']) as neo_session:
school_worker_node = get_node_by_unique_id(session=neo_session, unique_id=worker_node_data['unique_id'])
school_worker_node = get_node_by_uuid_string(session=neo_session, uuid_string=worker_node_data['uuid_string'])
if school_worker_node is None:
error_msg = f"School worker node not found for unique_id: {worker_node_data['unique_id']}"
error_msg = f"School worker node not found for uuid_string: {worker_node_data['uuid_string']}"
logging.error(error_msg)
raise Exception(error_msg)
@ -127,23 +125,23 @@ async def process_worker_timetable(file_content, user_node_data, worker_node_dat
# Create TeacherNode from worker_node_data
user_worker_node = TeacherNode(
unique_id=worker_node_data['unique_id'],
uuid_string=worker_node_data['uuid_string'],
teacher_code=worker_node_data['teacher_code'],
teacher_name_formal=worker_node_data['teacher_name_formal'],
teacher_email=worker_node_data['teacher_email'],
path=worker_node_data['path'],
node_storage_path=worker_node_data['node_storage_path'],
worker_db_name=worker_node_data['worker_db_name'],
user_db_name=worker_node_data['user_db_name']
)
# Create user node
user_node = UserNode(
unique_id=user_node_data['unique_id'],
uuid_string=user_node_data['uuid_string'],
user_id=user_node_data['user_id'],
user_type=user_node_data['user_type'],
user_name=user_node_data['user_name'],
user_email=user_node_data['user_email'],
path=user_node_data['path'],
node_storage_path=user_node_data['node_storage_path'],
worker_node_data=user_node_data['worker_node_data']
)

View File

@ -27,29 +27,29 @@ async def get_calendar_structure(db_name: str) -> Dict[str, Any]:
// Collect all nodes with dates converted to strings
RETURN {
years: collect(DISTINCT {
id: y.unique_id,
path: y.path,
id: y.uuid_string,
path: y.node_storage_path,
date: toString(y.date),
__primarylabel__: 'CalendarYear'
}),
months: collect(DISTINCT {
id: m.unique_id,
path: m.path,
id: m.uuid_string,
path: m.node_storage_path,
date: toString(m.date),
__primarylabel__: 'CalendarMonth'
}),
weeks: collect(DISTINCT {
id: w.unique_id,
path: w.path,
id: w.uuid_string,
path: w.node_storage_path,
date: toString(w.date),
__primarylabel__: 'CalendarWeek'
}),
days: collect(DISTINCT {
id: d.unique_id,
path: d.path,
id: d.uuid_string,
path: d.node_storage_path,
date: toString(d.date),
week_id: w.unique_id,
month_id: m.unique_id,
week_id: w.uuid_string,
month_id: m.uuid_string,
__primarylabel__: 'CalendarDay'
})
} as structure
@ -98,11 +98,11 @@ async def get_calendar_days(db_name: str, start_date: str, end_date: str) -> Dic
OPTIONAL MATCH (w:CalendarWeek)-[:WEEK_INCLUDES_DAY]->(d)
OPTIONAL MATCH (m:CalendarMonth)-[:MONTH_INCLUDES_DAY]->(d)
RETURN {
id: d.unique_id,
path: d.path,
id: d.uuid_string,
path: d.node_storage_path,
date: d.date,
week_id: w.unique_id,
month_id: m.unique_id,
week_id: w.uuid_string,
month_id: m.uuid_string,
__primarylabel__: 'CalendarDay'
} as day
ORDER BY d.date
@ -132,10 +132,10 @@ async def get_calendar_weeks(db_name: str, start_date: str, end_date: str) -> Di
WHERE date(w.date) >= date($start_date) AND date(w.date) <= date($end_date)
WITH w, collect(d) as days
RETURN {
id: w.unique_id,
path: w.path,
id: w.uuid_string,
path: w.node_storage_path,
date: w.date,
day_ids: [day in days | day.unique_id],
day_ids: [day in days | day.uuid_string],
__primarylabel__: 'CalendarWeek'
} as week
ORDER BY w.date
@ -165,10 +165,10 @@ async def get_calendar_months(db_name: str, start_date: str, end_date: str) -> D
WHERE date(m.date) >= date($start_date) AND date(m.date) <= date($end_date)
WITH m, collect(d) as days
RETURN {
id: m.unique_id,
path: m.path,
id: m.uuid_string,
path: m.node_storage_path,
date: m.date,
day_ids: [day in days | day.unique_id],
day_ids: [day in days | day.uuid_string],
__primarylabel__: 'CalendarMonth'
} as month
ORDER BY m.date
@ -197,10 +197,10 @@ async def get_calendar_years(db_name: str) -> Dict[str, Any]:
MATCH (y:CalendarYear)-[:YEAR_INCLUDES_MONTH]->(m:CalendarMonth)
WITH y, collect(m) as months
RETURN {
id: y.unique_id,
path: y.path,
id: y.uuid_string,
path: y.node_storage_path,
date: y.date,
month_ids: [month in months | month.unique_id],
month_ids: [month in months | month.uuid_string],
__primarylabel__: 'CalendarYear'
} as year
ORDER BY y.date

View File

@ -47,7 +47,7 @@ def get_default_node_week(db_name: str) -> Dict[str, Any]:
return {
"status": "success",
"node": {
"id": node["unique_id"],
"id": node["uuid_string"],
"path": node["path"],
"type": "CalendarWeek",
"label": node.get("title", "Calendar Week"),
@ -81,7 +81,7 @@ def get_default_node_month(db_name: str) -> Dict[str, Any]:
return {
"status": "success",
"node": {
"id": node["unique_id"],
"id": node["uuid_string"],
"path": node["path"],
"type": "CalendarMonth",
"label": node.get("title", "Calendar Month"),
@ -89,6 +89,39 @@ def get_default_node_month(db_name: str) -> Dict[str, Any]:
}
}
@router.get("/debug-list-nodes")
async def debug_list_nodes(db_name: str) -> Dict[str, Any]:
"""Debug endpoint to list all nodes in a database."""
try:
with driver_tools.get_session(database=db_name) as session:
query = """
MATCH (n)
RETURN labels(n) as labels, n.uuid_string as uuid, n.user_name as name, n.cc_username as username
LIMIT 20
"""
result = session.run(query)
nodes = []
for record in result:
nodes.append({
"labels": list(record["labels"]),
"uuid": record["uuid"],
"name": record["name"],
"username": record["username"]
})
return {
"status": "success",
"db_name": db_name,
"node_count": len(nodes),
"nodes": nodes
}
except Exception as e:
return {
"status": "error",
"db_name": db_name,
"error": str(e)
}
@router.get("/get-default-node/{context}")
async def get_default_node(context: str, db_name: str, base_context: str | None = None) -> Dict[str, Any]:
"""Get the default node for a given context."""
@ -244,8 +277,9 @@ async def get_default_node(context: str, db_name: str, base_context: str | None
return {
"status": "success",
"node": {
"id": node["unique_id"],
"id": node["uuid_string"],
"path": node["path"],
"node_storage_path": node.get("node_storage_path", node["path"]),
"type": list(node.labels)[0],
"label": node.get("title", ""),
"data": converted_data

View File

@ -51,10 +51,10 @@ router = APIRouter()
@router.get("/get_teacher_timetable_events")
async def get_teacher_timetable_events(
unique_id: str,
uuid_string: str,
worker_db_name: str
):
logging.info(f"Getting timetable events for teacher {unique_id} from database {worker_db_name}")
logging.info(f"Getting timetable events for teacher {uuid_string} from database {worker_db_name}")
neo_driver = driver.get_driver(db_name=worker_db_name)
if neo_driver is None:
return {"status": "error", "message": "Failed to connect to the database"}
@ -62,9 +62,9 @@ async def get_teacher_timetable_events(
try:
with neo_driver.session(database=worker_db_name) as neo_session:
query = """
MATCH (t:Teacher {unique_id: $unique_id})-[:TEACHER_HAS_TIMETABLE]->(tt:TeacherTimetable)
MATCH (t:Teacher {uuid_string: $uuid_string})-[:TEACHER_HAS_TIMETABLE]->(tt:TeacherTimetable)
-[:TIMETABLE_HAS_CLASS]->(sc:SubjectClass)-[:CLASS_HAS_LESSON]->(tl:TimetableLesson)
RETURN tl.unique_id as id,
RETURN tl.uuid_string as id,
tl.period_code as period_code,
COALESCE(sc.subject_class_code, 'Untitled Class') as subject_class,
tl.date as date,
@ -72,7 +72,7 @@ async def get_teacher_timetable_events(
tl.end_time as end_time,
tl.path as path
"""
result = neo_session.run(query, unique_id=unique_id)
result = neo_session.run(query, uuid_string=uuid_string)
events = []
for record in result:
@ -92,7 +92,7 @@ async def get_teacher_timetable_events(
"path": record['path']
}
})
logging.info(f"Found {len(events)} events for teacher {unique_id}")
logging.info(f"Found {len(events)} events for teacher {uuid_string}")
return {"status": "success", "events": events}
except Exception as e:
logging.error(f"Error fetching events: {str(e)}")

View File

@ -25,18 +25,18 @@ from fastapi import APIRouter, HTTPException, Query
router = APIRouter()
@router.get("/get-node")
async def get_node(unique_id: str = Query(...), db_name: str = Query(...)):
logging.info(f"Getting node for {unique_id} from database {db_name}")
async def get_node(uuid_string: str = Query(...), db_name: str = Query(...)):
logging.info(f"Getting node for {uuid_string} from database {db_name}")
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
return {"status": "error", "message": "Failed to connect to the database"}
try:
with neo_driver.session(database=db_name) as neo_session:
query = """
MATCH (n {unique_id: $unique_id})
MATCH (n {uuid_string: $uuid_string})
RETURN n
"""
result = neo_session.run(query, unique_id=unique_id)
result = neo_session.run(query, uuid_string=uuid_string)
record = result.single()
if record:
@ -47,11 +47,23 @@ async def get_node(unique_id: str = Query(...), db_name: str = Query(...)):
try:
# Convert node based on its type
node_type = node_labels[0] if node_labels else "Unknown"
if node_type in globals():
node_class = globals()[f"{node_type}Node"]
logging.debug(f"Attempting to convert node of type: {node_type}")
logging.debug(f"Available node classes: {[name for name in globals() if name.endswith('Node')]}")
logging.debug(f"UserNode in globals: {'UserNode' in globals()}")
logging.debug(f"UserNode class: {UserNode}")
logging.debug(f"UserNode class name: {UserNode.__name__}")
# Try to find the node class
node_class_name = f"{node_type}Node"
if node_class_name in globals():
node_class = globals()[node_class_name]
logging.debug(f"Found node class: {node_class}")
node_object = node_class(**node_data)
node_dict = node_object.to_dict()
logging.debug(f"Successfully converted node to dict: {node_dict}")
else:
logging.warning(f"No node class found for type: {node_type} (looking for {node_class_name}), using raw data")
logging.debug(f"Available classes: {[name for name in globals() if 'Node' in name]}")
node_dict = node_data
return {
@ -101,8 +113,8 @@ async def get_user_node(user_id: str = Query(...)):
driver.close_driver(neo_driver)
@router.get("/get-connected-nodes")
async def get_connected_nodes(unique_id: str = Query(...), db_name: str = Query(...)):
logging.info(f"Getting connected nodes for {unique_id} from database {db_name}")
async def get_connected_nodes(uuid_string: str = Query(...), db_name: str = Query(...)):
logging.info(f"Getting connected nodes for {uuid_string} from database {db_name}")
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
return {"status": "error", "message": "Failed to connect to the database"}
@ -110,11 +122,11 @@ async def get_connected_nodes(unique_id: str = Query(...), db_name: str = Query(
try:
with neo_driver.session(database=db_name) as neo_session:
query = """
MATCH (n {unique_id: $unique_id})
MATCH (n {uuid_string: $uuid_string})
OPTIONAL MATCH (n)-[]-(connected)
RETURN n, collect(connected) as connected_nodes
"""
result = neo_session.run(query, unique_id=unique_id)
result = neo_session.run(query, uuid_string=uuid_string)
record = result.single()
if record:
main_node = record['n']
@ -171,15 +183,15 @@ async def get_connected_nodes(unique_id: str = Query(...), db_name: str = Query(
driver.close_driver(neo_driver)
@router.get("/get-user-connected-nodes")
async def get_user_connected_nodes(unique_id: str = Query(...)):
logging.info(f"Getting user adjacent nodes for node {unique_id}")
async def get_user_connected_nodes(uuid_string: str = Query(...)):
logging.info(f"Getting user adjacent nodes for node {uuid_string}")
db_name = os.getenv("NEO4J_DB_NAME", "cc.institutes.kevlarai") # TODO: This function needs to be able to take a db_name as a parameter
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
raise HTTPException(status_code=500, detail="Failed to connect to the database")
try:
with neo_driver.session(database=db_name) as neo_session:
user_node_and_connected_nodes = session.get_node_by_unique_id_and_adjacent_nodes(neo_session, unique_id)
user_node_and_connected_nodes = session.get_node_by_uuid_string_and_adjacent_nodes(neo_session, uuid_string)
user_node = user_node_and_connected_nodes['node']
connected_nodes = user_node_and_connected_nodes['connected_nodes']
try:
@ -251,15 +263,15 @@ async def get_user_connected_nodes(unique_id: str = Query(...)):
driver.close_driver(neo_driver)
@router.get("/get-worker-connected-nodes")
async def get_worker_connected_nodes(unique_id: str = Query(...)):
logging.info(f"Getting worker adjacent nodes for node {unique_id}")
async def get_worker_connected_nodes(uuid_string: str = Query(...)):
logging.info(f"Getting worker adjacent nodes for node {uuid_string}")
db_name = os.getenv("NEO4J_DB_NAME", "cc.institutes.kevlarai") # TODO: This function needs to be able to take a db_name as a parameter
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
raise HTTPException(status_code=500, detail="Failed to connect to the database")
try:
with neo_driver.session(database=db_name) as neo_session:
node_and_connected_nodes = session.get_node_by_unique_id_and_adjacent_nodes(neo_session, unique_id)
node_and_connected_nodes = session.get_node_by_uuid_string_and_adjacent_nodes(neo_session, uuid_string)
worker_node = node_and_connected_nodes['node']
connected_nodes = node_and_connected_nodes['connected_nodes']
try:
@ -319,9 +331,9 @@ async def get_worker_connected_nodes(unique_id: str = Query(...)):
driver.close_driver(neo_driver)
@router.get("/get-calendar-connected-nodes")
async def get_calendar_connected_nodes(unique_id: str = Query(...)):
async def get_calendar_connected_nodes(uuid_string: str = Query(...)):
db_name = os.getenv("NEO4J_DB_NAME", "cc.institutes.kevlarai")
logging.info(f"Getting connected nodes for calendar {unique_id} from database {db_name}")
logging.info(f"Getting connected nodes for calendar {uuid_string} from database {db_name}")
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
return {"status": "error", "message": "Failed to connect to the database"}
@ -330,11 +342,11 @@ async def get_calendar_connected_nodes(unique_id: str = Query(...)):
with neo_driver.session(database=db_name) as neo_session:
query = """
MATCH (n)
WHERE n.unique_id = $unique_id AND (n:Calendar OR n:CalendarYear OR n:CalendarMonth OR n:CalendarWeek OR n:CalendarDay OR n:CalendarTimeChunk)
WHERE n.uuid_string = $uuid_string AND (n:Calendar OR n:CalendarYear OR n:CalendarMonth OR n:CalendarWeek OR n:CalendarDay OR n:CalendarTimeChunk)
OPTIONAL MATCH (n)-[]-(connected)
RETURN n, collect(connected) as connected_nodes
"""
result = neo_session.run(query, unique_id=unique_id)
result = neo_session.run(query, uuid_string=uuid_string)
record = result.single()
if record:
calendar_node = record['n']
@ -369,9 +381,9 @@ async def get_calendar_connected_nodes(unique_id: str = Query(...)):
driver.close_driver(neo_driver)
@router.get("/get-teacher-timetable-connected-nodes")
async def get_teacher_timetable_connected_nodes(unique_id: str = Query(...)):
async def get_teacher_timetable_connected_nodes(uuid_string: str = Query(...)):
db_name = os.getenv("NEO4J_DB_NAME", "cc.institutes.kevlarai")
logging.info(f"Getting connected nodes for teacher timetable {unique_id} from database {db_name}")
logging.info(f"Getting connected nodes for teacher timetable {uuid_string} from database {db_name}")
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
return {"status": "error", "message": "Failed to connect to the database"}
@ -379,11 +391,11 @@ async def get_teacher_timetable_connected_nodes(unique_id: str = Query(...)):
try:
with neo_driver.session(database=db_name) as neo_session:
query = """
MATCH (n:TeacherTimetable {unique_id: $unique_id})
MATCH (n:TeacherTimetable {uuid_string: $uuid_string})
OPTIONAL MATCH (n)-[]-(connected)
RETURN n, collect(connected) as connected_nodes
"""
result = neo_session.run(query, unique_id=unique_id)
result = neo_session.run(query, uuid_string=uuid_string)
record = result.single()
if record:
teacher_timetable_node = record['n']
@ -422,9 +434,9 @@ async def get_teacher_timetable_connected_nodes(unique_id: str = Query(...)):
driver.close_driver(neo_driver)
@router.get("/get-school-timetable-connected-nodes")
async def get_school_timetable_connected_nodes(unique_id: str = Query(...)):
async def get_school_timetable_connected_nodes(uuid_string: str = Query(...)):
db_name = os.getenv("NEO4J_DB_NAME", "cc.institutes.kevlarai")
logging.info(f"Getting connected nodes for school timetable {unique_id} from database {db_name}")
logging.info(f"Getting connected nodes for school timetable {uuid_string} from database {db_name}")
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
return {"status": "error", "message": "Failed to connect to the database"}
@ -432,11 +444,11 @@ async def get_school_timetable_connected_nodes(unique_id: str = Query(...)):
try:
with neo_driver.session(database=db_name) as neo_session:
query = """
MATCH (n:SchoolTimetable {unique_id: $unique_id})
MATCH (n:SchoolTimetable {uuid_string: $uuid_string})
OPTIONAL MATCH (n)-[]-(connected)
RETURN n, collect(connected) as connected_nodes
"""
result = neo_session.run(query, unique_id=unique_id)
result = neo_session.run(query, uuid_string=uuid_string)
record = result.single()
if record:
school_timetable_node = record['n']
@ -483,9 +495,9 @@ async def get_school_timetable_connected_nodes(unique_id: str = Query(...)):
driver.close_driver(neo_driver)
@router.get("/get-curriculum-connected-nodes")
async def get_curriculum_connected_nodes(unique_id: str = Query(...)):
async def get_curriculum_connected_nodes(uuid_string: str = Query(...)):
db_name = os.getenv("NEO4J_DB_NAME", "cc.institutes.kevlarai")
logging.info(f"Getting connected nodes for curriculum {unique_id} from database {db_name}")
logging.info(f"Getting connected nodes for curriculum {uuid_string} from database {db_name}")
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
return {"status": "error", "message": "Failed to connect to the database"}
@ -494,11 +506,11 @@ async def get_curriculum_connected_nodes(unique_id: str = Query(...)):
with neo_driver.session(database=db_name) as neo_session:
query = """
MATCH (n)
WHERE n.unique_id = $unique_id AND (n:PastoralStructure OR n:YearGroup OR n:CurriculumStructure OR n:KeyStage OR n:KeyStageSyllabus OR n:YearGroupSyllabus OR n:Subject OR n:Topic OR n:TopicLesson OR n:LearningStatement OR n:ScienceLab)
WHERE n.uuid_string = $uuid_string AND (n:PastoralStructure OR n:YearGroup OR n:CurriculumStructure OR n:KeyStage OR n:KeyStageSyllabus OR n:YearGroupSyllabus OR n:Subject OR n:Topic OR n:TopicLesson OR n:LearningStatement OR n:ScienceLab)
OPTIONAL MATCH (n)-[]-(connected)
RETURN n, collect(connected) as connected_nodes
"""
result = neo_session.run(query, unique_id=unique_id)
result = neo_session.run(query, uuid_string=uuid_string)
record = result.single()
if record:
curriculum_node = record['n']
@ -533,26 +545,18 @@ async def get_curriculum_connected_nodes(unique_id: str = Query(...)):
driver.close_driver(neo_driver)
@router.get("/get-school-node")
async def get_school_node(school_uuid: str = Query(...)):
logging.info(f"Getting school node for school {school_uuid}...")
db_name = f"cc.institutes.{school_uuid}"
async def get_school_node(school_uuid_string: str = Query(...)):
logging.info(f"Getting school node for school {school_uuid_string}...")
db_name = f"cc.institutes.{school_uuid_string}"
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
return {"status": "error", "message": "Failed to connect to the database"}
try:
with neo_driver.session(database=db_name) as neo_session:
nodes = session.find_nodes_by_label_and_properties(neo_session, "School", {"school_uuid": school_uuid})
nodes = session.find_nodes_by_label_and_properties(neo_session, "School", {"uuid_string": school_uuid_string})
if nodes:
school_node = nodes[0]
data = SchoolNode(
unique_id=school_node["unique_id"],
school_uuid=school_node["school_uuid"],
school_name=school_node["school_name"],
school_website=school_node["school_website"],
path=school_node["path"]
)
school_node_data = data.to_dict()
school_node_data = SchoolNode(**nodes[0]).to_dict()
return {"status": "success", "school_node": school_node_data, "school_node_raw": nodes}
else:
return {"status": "not_found", "message": "School node not found"}

View File

@ -89,8 +89,8 @@ async def get_all_nodes_and_edges():
@router.get("/get-connected-nodes-and-edges")
async def get_connected_nodes_and_edges(unique_id: str = Query(...), db_name: str = Query(...)):
logging.info(f"Getting connected nodes and edges for {unique_id} from database {db_name}")
async def get_connected_nodes_and_edges(uuid_string: str = Query(...), db_name: str = Query(...)):
logging.info(f"Getting connected nodes and edges for {uuid_string} from database {db_name}")
neo_driver = driver.get_driver(db_name=db_name)
if neo_driver is None:
return {"status": "error", "message": "Failed to connect to the database"}
@ -98,11 +98,11 @@ async def get_connected_nodes_and_edges(unique_id: str = Query(...), db_name: st
try:
with neo_driver.session(database=db_name) as neo_session:
query = """
MATCH (n {unique_id: $unique_id})
MATCH (n {uuid_string: $uuid_string})
OPTIONAL MATCH (n)-[r]-(connected)
RETURN n, collect(connected) as connected_nodes, collect(r) as relationships
"""
result = neo_session.run(query, unique_id=unique_id)
result = neo_session.run(query, uuid_string=uuid_string)
record = result.single()
if record:
main_node = record['n']

View File

@ -34,20 +34,24 @@ async def read_tldraw_user_node_file(user_node: UserNode):
logging.debug(f"Filesystem root path: {fs.root_path}")
# Handle path based on environment
if os.getenv("DEV_MODE") == "true":
# In dev mode, use the full system path from the node
if not user_node.path:
raise HTTPException(status_code=400, detail="Node path not found")
logging.debug(f"Using DEV_MODE path: {user_node.path}")
base_path = os.path.normpath(user_node.path)
# Use the path directly as provided - it represents the structure from root
if not user_node.node_storage_path:
raise HTTPException(status_code=400, detail="Node path not found")
# The path might already contain parts of the filesystem structure
# We need to construct the full path carefully
if user_node.node_storage_path.startswith("users/"):
# If path starts with users/, remove it since filesystem already has users/ structure
base_path = user_node.node_storage_path[6:] # Remove "users/" prefix
logging.debug(f"Removed 'users/' prefix, base_path is now: {base_path}")
else:
# In prod mode, construct path using formatted email
logging.warning(f"Using db_name as base path not ready in prod: {db_name}")
base_path = formatted_email
base_path = user_node.node_storage_path
logging.debug(f"No 'users/' prefix found, using path as-is: {base_path}")
base_path = os.path.normpath(base_path)
logging.debug(f"Using base path: {base_path}")
# Construct final path including tldraw file
logging.debug(f"Base path: {base_path}")
file_path = os.path.join(base_path, "tldraw_file.json")
logging.debug(f"File path: {file_path}")
file_location = os.path.normpath(os.path.join(fs.root_path, file_path))
@ -68,8 +72,30 @@ async def read_tldraw_user_node_file(user_node: UserNode):
logging.error(f"Error reading file: {e}")
raise HTTPException(status_code=500, detail="Error reading file")
else:
logging.debug(f"File does not exist: {file_location}")
raise HTTPException(status_code=404, detail="File not found")
# Check if directory exists
directory_location = os.path.dirname(file_location)
if os.path.exists(directory_location):
logging.debug(f"Directory exists but file doesn't, creating default tldraw file at: {file_location}")
try:
# Create default tldraw content
default_tldraw_content = create_default_tldraw_content()
# Ensure directory exists (should already exist, but just in case)
os.makedirs(directory_location, exist_ok=True)
# Write the default file
with open(file_location, "w") as file:
json.dump(default_tldraw_content, file, indent=4)
logging.info(f"Default tldraw file created at: {file_location}")
return default_tldraw_content
except Exception as e:
logging.error(f"Error creating default tldraw file: {e}")
raise HTTPException(status_code=500, detail="Error creating default tldraw file")
else:
logging.debug(f"Neither directory nor file exists: {directory_location}")
raise HTTPException(status_code=404, detail="Directory not found")
@router.post("/set_tldraw_user_node_file")
async def set_tldraw_user_node_file(user_node: UserNode, data: Dict):
@ -81,15 +107,22 @@ async def set_tldraw_user_node_file(user_node: UserNode, data: Dict):
fs = ClassroomCopilotFilesystem(db_name=db_name, init_run_type="user")
# Handle path based on environment
if os.getenv("ENVIRONMENT") == "dev":
# In dev mode, use the full system path from the node
if not user_node.path:
raise HTTPException(status_code=400, detail="Node path not found")
base_path = os.path.normpath(user_node.path)
# Use the path directly as provided - it represents the structure from root
if not user_node.node_storage_path:
raise HTTPException(status_code=400, detail="Node path not found")
# The path might already contain parts of the filesystem structure
# We need to construct the full path carefully
if user_node.node_storage_path.startswith("users/"):
# If path starts with users/, remove it since filesystem already has users/ structure
base_path = user_node.node_storage_path[6:] # Remove "users/" prefix
logging.debug(f"Removed 'users/' prefix, base_path is now: {base_path}")
else:
# In prod mode, construct path using formatted email
base_path = formatted_email
base_path = user_node.node_storage_path
logging.debug(f"No 'users/' prefix found, using path as-is: {base_path}")
base_path = os.path.normpath(base_path)
logging.debug(f"Using base path: {base_path}")
# Construct final path including tldraw file
file_path = os.path.join(base_path, "tldraw_file.json")
@ -99,11 +132,15 @@ async def set_tldraw_user_node_file(user_node: UserNode, data: Dict):
try:
# Ensure directory exists
os.makedirs(os.path.dirname(file_location), exist_ok=True)
directory_location = os.path.dirname(file_location)
os.makedirs(directory_location, exist_ok=True)
logging.debug(f"Ensured directory exists: {directory_location}")
# Write the file
with open(file_location, "w") as file:
json.dump(data, file)
json.dump(data, file, indent=4)
logging.info(f"tldraw file successfully written to: {file_location}")
return {"status": "success"}
except Exception as e:
logging.error(f"Error writing file: {e}")
@ -112,29 +149,38 @@ async def set_tldraw_user_node_file(user_node: UserNode, data: Dict):
@router.get("/get_tldraw_node_file")
async def read_tldraw_node_file(path: str, db_name: str):
logging.debug(f"Reading tldraw file for path: {path}")
logging.debug(f"Database name: {db_name}")
fs = ClassroomCopilotFilesystem(db_name=db_name, init_run_type="user")
logging.debug(f"Filesystem root path: {fs.root_path}")
# Handle path based on environment
if os.getenv("DEV_MODE") == "true":
# In dev mode, use the full system path from the node
if not path:
raise HTTPException(status_code=400, detail="Path not provided")
logging.debug(f"Using DEV_MODEpath: {path}")
base_path = os.path.normpath(path)
# Use the path directly as provided - it represents the structure from root
if not path:
raise HTTPException(status_code=400, detail="Path not provided")
# The path might already contain parts of the filesystem structure
# We need to construct the full path carefully
if path.startswith("users/"):
# If path starts with users/, remove it since filesystem already has users/ structure
base_path = path[6:] # Remove "users/" prefix
logging.debug(f"Removed 'users/' prefix, base_path is now: {base_path}")
else:
# In prod mode, construct path
logging.warning(f"Using db_name as base path not ready in prod: {db_name}")
base_path = db_name
base_path = path
logging.debug(f"No 'users/' prefix found, using path as-is: {base_path}")
base_path = os.path.normpath(base_path)
logging.debug(f"Using base path: {base_path}")
# Construct final path including tldraw file
logging.debug(f"Base path: {base_path}")
file_path = os.path.join(base_path, "tldraw_file.json")
logging.debug(f"File path: {file_path}")
file_location = os.path.normpath(os.path.join(fs.root_path, file_path))
logging.debug(f"File location: {file_location}")
logging.debug(f"Final file location: {file_location}")
# Debug: Check what directories exist
logging.debug(f"Checking if root path exists: {fs.root_path} - {os.path.exists(fs.root_path)}")
logging.debug(f"Checking if base path exists: {os.path.join(fs.root_path, base_path)} - {os.path.exists(os.path.join(fs.root_path, base_path))}")
logging.debug(f"Attempting to read file at: {file_location}")
@ -151,8 +197,44 @@ async def read_tldraw_node_file(path: str, db_name: str):
logging.error(f"Error reading file: {e}")
raise HTTPException(status_code=500, detail="Error reading file")
else:
logging.debug(f"File does not exist: {file_location}")
raise HTTPException(status_code=404, detail="File not found")
# Check if directory exists
directory_location = os.path.dirname(file_location)
logging.debug(f"Checking if directory exists: {directory_location} - {os.path.exists(directory_location)}")
if os.path.exists(directory_location):
logging.debug(f"Directory exists but file doesn't, creating default tldraw file at: {file_location}")
try:
# Create default tldraw content
default_tldraw_content = create_default_tldraw_content()
# Ensure directory exists (should already exist, but just in case)
os.makedirs(directory_location, exist_ok=True)
# Write the default file
with open(file_location, "w") as file:
json.dump(default_tldraw_content, file, indent=4)
logging.info(f"Default tldraw file created at: {file_location}")
return default_tldraw_content
except Exception as e:
logging.error(f"Error creating default tldraw file: {e}")
raise HTTPException(status_code=500, detail="Error creating default tldraw file")
else:
logging.debug(f"Neither directory nor file exists: {directory_location}")
# List contents of parent directories to help debug
parent_dir = os.path.dirname(directory_location)
if os.path.exists(parent_dir):
logging.debug(f"Parent directory exists: {parent_dir}")
try:
contents = os.listdir(parent_dir)
logging.debug(f"Parent directory contents: {contents}")
except Exception as e:
logging.debug(f"Could not list parent directory contents: {e}")
else:
logging.debug(f"Parent directory does not exist: {parent_dir}")
raise HTTPException(status_code=404, detail="Directory not found")
@router.post("/set_tldraw_node_file")
async def set_tldraw_node_file(path: str, db_name: str, data: Dict):
@ -162,22 +244,25 @@ async def set_tldraw_node_file(path: str, db_name: str, data: Dict):
logging.debug(f"Filesystem root path: {fs.root_path}")
# Handle path based on environment
if os.getenv("DEV_MODE") == "true":
# In dev mode, use the full system path from the node
if not path:
raise HTTPException(status_code=400, detail="Path not provided")
logging.debug(f"Using DEV_MODEpath: {path}")
base_path = os.path.normpath(path)
# Use the path directly as provided - it represents the structure from root
if not path:
raise HTTPException(status_code=400, detail="Path not provided")
# The path might already contain parts of the filesystem structure
# We need to construct the full path carefully
if path.startswith("users/"):
# If path starts with users/, remove it since filesystem already has users/ structure
base_path = path[6:] # Remove "users/" prefix
logging.debug(f"Removed 'users/' prefix, base_path is now: {base_path}")
else:
# In prod mode, construct path
logging.warning(f"Using db_name as base path not ready in prod: {db_name}")
base_path = db_name
base_path = path
logging.debug(f"No 'users/' prefix found, using path as-is: {base_path}")
base_path = os.path.normpath(base_path)
logging.debug(f"Using base path: {base_path}")
# Construct final path including tldraw file
logging.debug(f"Base path: {base_path}")
file_path = os.path.join(base_path, "tldraw_file.json")
logging.debug(f"File path: {file_path}")
file_location = os.path.normpath(os.path.join(fs.root_path, file_path))
logging.debug(f"File location: {file_location}")
@ -185,12 +270,94 @@ async def set_tldraw_node_file(path: str, db_name: str, data: Dict):
try:
# Ensure directory exists
os.makedirs(os.path.dirname(file_location), exist_ok=True)
directory_location = os.path.dirname(file_location)
os.makedirs(directory_location, exist_ok=True)
logging.debug(f"Ensured directory exists: {directory_location}")
# Write the file
with open(file_location, "w") as file:
json.dump(data, file)
json.dump(data, file, indent=4)
logging.info(f"tldraw file successfully written to: {file_location}")
return {"status": "success"}
except Exception as e:
logging.error(f"Error writing file: {e}")
raise HTTPException(status_code=500, detail="Error writing file")
def create_default_tldraw_content():
"""Create default tldraw content structure."""
return {
"document": {
"store": {
"document:document": {
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
"page:page": {
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
}
},
"schema": {
"schemaVersion": 2,
"sequences": {
"com.tldraw.store": 4,
"com.tldraw.asset": 1,
"com.tldraw.camera": 1,
"com.tldraw.document": 2,
"com.tldraw.instance": 25,
"com.tldraw.instance_page_state": 5,
"com.tldraw.page": 1,
"com.tldraw.instance_presence": 5,
"com.tldraw.pointer": 1,
"com.tldraw.shape": 4,
"com.tldraw.asset.bookmark": 2,
"com.tldraw.asset.image": 5,
"com.tldraw.asset.video": 5,
"com.tldraw.shape.arrow": 5,
"com.tldraw.shape.bookmark": 2,
"com.tldraw.shape.draw": 2,
"com.tldraw.shape.embed": 4,
"com.tldraw.shape.frame": 0,
"com.tldraw.shape.geo": 9,
"com.tldraw.shape.group": 0,
"com.tldraw.shape.highlight": 1,
"com.tldraw.shape.image": 4,
"com.tldraw.shape.line": 5,
"com.tldraw.shape.note": 8,
"com.tldraw.shape.text": 2,
"com.tldraw.shape.video": 2,
"com.tldraw.binding.arrow": 0
}
},
"recordVersions": {
"asset": {"version": 1, "subTypeKey": "type", "subTypeVersions": {}},
"camera": {"version": 1},
"document": {"version": 2},
"instance": {"version": 21},
"instance_page_state": {"version": 5},
"page": {"version": 1},
"shape": {"version": 3, "subTypeKey": "type", "subTypeVersions": {}},
"instance_presence": {"version": 5},
"pointer": {"version": 1}
},
"rootShapeIds": [],
"bindings": [],
"assets": []
},
"session": {
"version": 0,
"currentPageId": "page:page",
"pageStates": [{
"pageId": "page:page",
"camera": {"x": 0, "y": 0, "z": 1},
"selectedShapeIds": []
}]
}
}

View File

@ -0,0 +1,265 @@
"""
TLDraw Supabase Storage Router
=============================
Handles TLDraw snapshot operations using Supabase Storage instead of local filesystem.
This replaces the old filesystem-based tldraw_filesystem.py router.
"""
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
import os
import json
import logging
from fastapi import APIRouter, HTTPException, Query
from typing import Dict, Any
from modules.database.supabase.utils.storage import StorageAdmin
from modules.logger_tool import initialise_logger
router = APIRouter()
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
def create_default_tldraw_content():
"""Create default tldraw content structure."""
return {
"document": {
"store": {
"document:document": {
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
"page:page": {
"meta": {},
"id": "page:page",
"name": "Page 1",
"index": "a1",
"typeName": "page"
}
},
"schema": {
"schemaVersion": 2,
"sequences": {
"com.tldraw.store": 4,
"com.tldraw.asset": 1,
"com.tldraw.camera": 1,
"com.tldraw.document": 2,
"com.tldraw.instance": 25,
"com.tldraw.instance_page_state": 5,
"com.tldraw.page": 1,
"com.tldraw.instance_presence": 5,
"com.tldraw.pointer": 1,
"com.tldraw.shape": 4,
"com.tldraw.asset.bookmark": 2,
"com.tldraw.asset.image": 5,
"com.tldraw.asset.video": 5,
"com.tldraw.shape.arrow": 5,
"com.tldraw.shape.bookmark": 2,
"com.tldraw.shape.draw": 2,
"com.tldraw.shape.embed": 4,
"com.tldraw.shape.frame": 0,
"com.tldraw.shape.geo": 9,
"com.tldraw.shape.group": 0,
"com.tldraw.shape.highlight": 1,
"com.tldraw.shape.image": 4,
"com.tldraw.shape.line": 5,
"com.tldraw.shape.note": 8,
"com.tldraw.shape.text": 2,
"com.tldraw.shape.video": 2,
"com.tldraw.binding.arrow": 0
}
},
"recordVersions": {
"asset": {"version": 1, "subTypeKey": "type", "subTypeVersions": {}},
"camera": {"version": 1},
"document": {"version": 2},
"instance": {"version": 21},
"instance_page_state": {"version": 5},
"page": {"version": 1},
"shape": {"version": 3, "subTypeKey": "type", "subTypeVersions": {}},
"instance_presence": {"version": 5},
"pointer": {"version": 1}
},
"rootShapeIds": [],
"bindings": [],
"assets": []
},
"session": {
"version": 0,
"currentPageId": "page:page",
"pageStates": [{
"pageId": "page:page",
"camera": {"x": 0, "y": 0, "z": 1},
"selectedShapeIds": []
}]
}
}
@router.get("/get_tldraw_node_file")
async def read_tldraw_node_file_from_supabase(
path: str = Query(..., description="Supabase Storage path (e.g., 'cc.public.snapshots/User/user_id')"),
db_name: str = Query(..., description="Database name for context")
):
"""
Load TLDraw snapshot from Supabase Storage.
Args:
path: Supabase Storage path in format 'bucket/nodetype/node_id'
db_name: Database name for context (used for logging)
Returns:
TLDraw snapshot data
"""
logger.debug(f"Reading tldraw file from Supabase Storage for path: {path}")
logger.debug(f"Database name: {db_name}")
if not path:
raise HTTPException(status_code=400, detail="Path not provided")
try:
# Initialize Supabase Storage
storage = StorageAdmin()
# Parse the path to extract bucket and file path
# Expected format: "cc.public.snapshots/User/user_id" or "cc.public.snapshots/Teacher/teacher_id"
path_parts = path.split('/')
if len(path_parts) < 3:
raise HTTPException(status_code=400, detail="Invalid path format. Expected: bucket/nodetype/node_id")
bucket = path_parts[0] # e.g., "cc.public.snapshots"
node_type = path_parts[1] # e.g., "User", "Teacher"
node_id = path_parts[2] # e.g., "cbc309e5-4029-4c34-aab7-0aa33c563cd0"
# Construct the file path in Supabase Storage
# Format: nodetype/node_id/tldraw_file.json
file_path = f"{node_type}/{node_id}/tldraw_file.json"
logger.debug(f"Bucket: {bucket}")
logger.debug(f"File path: {file_path}")
try:
# Try to download the file from Supabase Storage
file_data = storage.download_file(bucket, file_path)
# Parse JSON data
try:
snapshot_data = json.loads(file_data.decode('utf-8'))
logger.info(f"Successfully loaded tldraw snapshot from Supabase Storage: {file_path}")
# Ensure the snapshot has the correct structure for TLDraw
if isinstance(snapshot_data, dict) and 'document' in snapshot_data and 'session' in snapshot_data:
# Check if it has the new format (schemaVersion in document.schema)
if 'document' in snapshot_data and isinstance(snapshot_data['document'], dict) and 'schema' in snapshot_data['document']:
return snapshot_data
# Check if it has the old format (schemaVersion at root level)
elif 'schemaVersion' in snapshot_data:
return snapshot_data
else:
# Use default structure if schema is missing
logger.warning(f"Snapshot data from {file_path_in_bucket} is missing schemaVersion. Using default structure.")
return create_default_tldraw_content()
else:
# Use default structure if basic structure is missing
logger.warning(f"Snapshot data from {file_path_in_bucket} is missing top-level TLDraw keys. Using default structure.")
return create_default_tldraw_content()
except json.JSONDecodeError as e:
logger.error(f"Failed to parse JSON from Supabase Storage file: {e}")
raise HTTPException(status_code=500, detail="Invalid JSON in file")
except Exception as e:
# File doesn't exist, create default content
logger.info(f"File not found in Supabase Storage, creating default tldraw content: {file_path}")
# Create default tldraw content
default_content = create_default_tldraw_content()
try:
# Upload default content to Supabase Storage
json_data = json.dumps(default_content, indent=2).encode('utf-8')
storage.upload_file(bucket, file_path, json_data, 'application/json', upsert=True)
logger.info(f"Default tldraw file created in Supabase Storage: {file_path}")
return default_content
except Exception as upload_error:
logger.error(f"Error creating default tldraw file in Supabase Storage: {upload_error}")
raise HTTPException(status_code=500, detail="Error creating default tldraw file")
except HTTPException:
# Re-raise HTTP exceptions
raise
except Exception as e:
logger.error(f"Unexpected error loading tldraw file from Supabase Storage: {e}")
raise HTTPException(status_code=500, detail=f"Error loading file: {str(e)}")
@router.post("/set_tldraw_node_file")
async def set_tldraw_node_file_in_supabase(
path: str = Query(..., description="Supabase Storage path (e.g., 'cc.public.snapshots/User/user_id')"),
db_name: str = Query(..., description="Database name for context"),
data: Dict[str, Any] = None
):
"""
Save TLDraw snapshot to Supabase Storage.
Args:
path: Supabase Storage path in format 'bucket/nodetype/node_id'
db_name: Database name for context (used for logging)
data: TLDraw snapshot data to save
Returns:
Success status
"""
logger.debug(f"Saving tldraw file to Supabase Storage for path: {path}")
logger.debug(f"Database name: {db_name}")
if not path:
raise HTTPException(status_code=400, detail="Path not provided")
if not data:
raise HTTPException(status_code=400, detail="Data not provided")
try:
# Initialize Supabase Storage
storage = StorageAdmin()
# Parse the path to extract bucket and file path
path_parts = path.split('/')
if len(path_parts) < 3:
raise HTTPException(status_code=400, detail="Invalid path format. Expected: bucket/nodetype/node_id")
bucket = path_parts[0] # e.g., "cc.public.snapshots"
node_type = path_parts[1] # e.g., "User", "Teacher"
node_id = path_parts[2] # e.g., "cbc309e5-4029-4c34-aab7-0aa33c563cd0"
# Construct the file path in Supabase Storage
file_path = f"{node_type}/{node_id}/tldraw_file.json"
logger.debug(f"Bucket: {bucket}")
logger.debug(f"File path: {file_path}")
# Convert data to JSON
try:
json_data = json.dumps(data, indent=2).encode('utf-8')
except (TypeError, ValueError) as e:
logger.error(f"Failed to serialize data to JSON: {e}")
raise HTTPException(status_code=400, detail="Invalid data format")
# Upload to Supabase Storage
try:
storage.upload_file(bucket, file_path, json_data, 'application/json', upsert=True)
logger.info(f"Successfully saved tldraw snapshot to Supabase Storage: {file_path}")
return {"status": "success", "message": "File saved successfully"}
except Exception as upload_error:
logger.error(f"Error uploading file to Supabase Storage: {upload_error}")
raise HTTPException(status_code=500, detail="Error saving file")
except HTTPException:
# Re-raise HTTP exceptions
raise
except Exception as e:
logger.error(f"Unexpected error saving tldraw file to Supabase Storage: {e}")
raise HTTPException(status_code=500, detail=f"Error saving file: {str(e)}")

View File

@ -29,34 +29,34 @@ async def get_worker_structure(db_name: str) -> Dict[str, Any]:
// Collect all nodes
RETURN {
timetables: collect(DISTINCT {
id: tt.unique_id,
path: tt.path,
id: tt.uuid_string,
path: tt.node_storage_path,
title: tt.title,
type: tt.__primarylabel__,
startTime: toString(tt.start_date),
endTime: toString(tt.end_date)
}),
classes: collect(DISTINCT {
id: c.unique_id,
path: c.path,
id: c.uuid_string,
path: c.node_storage_path,
title: c.title,
type: c.__primarylabel__
}),
lessons: collect(DISTINCT {
id: l.unique_id,
path: l.path,
id: l.uuid_string,
path: l.node_storage_path,
title: l.title,
type: l.__primarylabel__
}),
journals: collect(DISTINCT {
id: j.unique_id,
path: j.path,
id: j.uuid_string,
path: j.node_storage_path,
title: j.title,
type: j.__primarylabel__
}),
planners: collect(DISTINCT {
id: p.unique_id,
path: p.path,
id: p.uuid_string,
path: p.node_storage_path,
title: p.title,
type: p.__primarylabel__
})
@ -106,8 +106,8 @@ async def get_timetables(db_name: str, start_date: str, end_date: str) -> Dict[s
MATCH (tt:UserTeacherTimetable)
WHERE date(tt.start_date) >= date($start_date) AND date(tt.end_date) <= date($end_date)
RETURN {
id: tt.unique_id,
path: tt.path,
id: tt.uuid_string,
path: tt.node_storage_path,
title: tt.title,
type: tt.__primarylabel__,
startTime: toString(tt.start_date),
@ -138,8 +138,8 @@ async def get_journals(db_name: str) -> Dict[str, Any]:
query = """
MATCH (j:Journal)
RETURN {
id: j.unique_id,
path: j.path,
id: j.uuid_string,
path: j.node_storage_path,
title: j.title,
type: j.__primarylabel__
} as journal
@ -168,8 +168,8 @@ async def get_planners(db_name: str) -> Dict[str, Any]:
query = """
MATCH (p:Planner)
RETURN {
id: p.unique_id,
path: p.path,
id: p.uuid_string,
path: p.node_storage_path,
title: p.title,
type: p.__primarylabel__
} as planner

View File

@ -1,3 +1,4 @@
from weakref import ref
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
import os
@ -18,36 +19,21 @@ from langchain_community.graphs import Neo4jGraph
from langchain_community.chat_models import ChatOpenAI
from langchain.prompts.prompt import PromptTemplate
from routers.llm.private.ollama.ollama_wrapper import OllamaWrapper
from modules.database.tools.neontology.utils import get_node_types, get_rels_by_type
from modules.database.tools.neontology.basenode import BaseNode
from modules.database.tools.neontology.baserelationship import BaseRelationship
router = APIRouter()
# Define the schema for nodes and relationships
node_types = {
"KeyStage": ["merged", "key_stage_name", "unique_id", "created"],
"KeyStageSyllabus": ["ks_syllabus_name", "unique_id", "created", "merged", "ks_syllabus_key_stage", "ks_syllabus_subject"],
"YearGroup": ["created", "merged", "unique_id", "year_group_name"],
"YearGroupSyllabus": ["created", "merged", "yr_syllabus_name", "yr_syllabus_year_group", "yr_syllabus_id", "yr_syllabus_subject"],
"Topic": ["topic_type", "topic_assessment_type", "created", "merged", "unique_id", "topic_id", "total_number_of_lessons_for_topic", "topic_title"],
"Lesson": ["topic_lesson_id", "topic_lesson_type", "created", "merged", "topic_lesson_title", "topic_lesson_length", "topic_lesson_suggested_activities", "topic_lesson_weblinks", "topic_lesson_skills_learned"],
"LearningStatement": ["created", "merged", "lesson_learning_statement", "lesson_learning_statement_id", "lesson_learning_statement_type"]
}
relationship_types = {
"KEY_STAGE_INCLUDES_KEY_STAGE_SYLLABUS": ["created", "merged"],
"KEY_STAGE_SYLLABUS_INCLUDES_YEAR_GROUP_SYLLABUS": ["created", "merged"],
"YEAR_GROUP_FOLLOWS_YEAR_GROUP": ["created", "merged"],
"KEY_STAGE_FOLLOWS_KEY_STAGE": ["created", "merged"],
"YEAR_SYLLABUS_INCLUDES_TOPIC": ["created", "merged"],
"TOPIC_INCLUDES_LESSON": ["created", "merged"],
"LESSON_INCLUDES_LEARNING_STATEMENT": ["created", "merged"],
"LESSON_FOLLOWS_LESSON": ["created", "merged"]
}
node_types = get_node_types(BaseNode)
relationship_types = get_rels_by_type(BaseRelationship)
@router.get("/prompt")
async def query_graph(
database: str, prompt: str, top_k: int = 30, model: str = "gpt-4o", temperature: float = 0,
database: str, prompt: str, top_k: int = 30, model: str = "qwen2.5-coder:3b", temperature: float = 0,
verbose: bool = False, return_intermediate_steps: bool = False, exclude_types: list = None, include_types: list = None,
return_direct: bool = False, validate_cypher: bool = False, model_type: str = "openai"
return_direct: bool = False, validate_cypher: bool = False, model_type: str = "ollama"
):
logging.info(f"Received request with prompt: {prompt}")
if exclude_types is None:
@ -70,7 +56,9 @@ async def query_graph(
url=os.environ['APP_BOLT_URL'],
username=os.environ['USER_NEO4J'],
password=os.environ['PASSWORD_NEO4J'],
database=database
database=database,
enhanced_schema=True,
sanitize=True,
)
logging.info("Refreshing schema...")
@ -79,14 +67,18 @@ async def query_graph(
schema = graph.schema
logging.info(f"Schema: {schema}")
CYPHER_GENERATION_TEMPLATE = """Task: Generate a Cypher statement to query a graph database for timetable information.
CYPHER_GENERATION_TEMPLATE = """Task: Generate a Cypher statement to query a graph database.
Role:
You are an assistant in a school for teachers, specializing in querying graph databases to find answers to questions.
The teacher will ask you questions about their timetable.
You are an assistant specializing in querying graph databases to find answers to questions about establishments, schools, and related data.
The user will ask you questions about the graph database
Instructions:
1. Use only the provided relationship types and properties in the schema.
2. Do not use any other relationship types or properties that are not provided.
3. When querying for geographic entities like counties, towns, or countries, use the 'name' property, not 'code'.
4. To find relationship types, use: MATCH (n:NodeType)-[r]->(m) RETURN DISTINCT type(r)
5. Relationship labels are in uppercase, e.g. LOCATED_IN_COUNTRY
6. For broad queries use OPTIONAL MATCH to allow for null results, e.g. OPTIONAL MATCH (n:NodeType) RETURN n.name
Schema:
{schema}
@ -95,6 +87,7 @@ async def query_graph(
1. Do not include any explanations or apologies in your responses.
2. Do not respond to any questions that might ask anything else than for you to construct a Cypher statement.
3. Do not include any text except the generated Cypher statement.
4. Do not include line break characters n other formatting keys.
The question is:
{question}"""
@ -105,11 +98,11 @@ async def query_graph(
)
if model_type == "ollama":
ollama_host = os.getenv("OLLAMA_URL")
ollama_port = os.getenv("OLLAMA_PORT")
ollama_host = os.getenv("HOST_OLLAMA")
ollama_port = os.getenv("PORT_OLLAMA")
if not ollama_host or not ollama_port:
raise HTTPException(status_code=500, detail="Ollama host or port not set")
client = OllamaWrapper(host=f'http://{ollama_host}:{ollama_port}')
client = OllamaWrapper(host=f'{ollama_host}:{ollama_port}', model=model)
cypher_llm = client
qa_llm = client
else:
@ -127,7 +120,8 @@ async def query_graph(
exclude_types=exclude_types,
include_types=include_types,
return_direct=return_direct,
validate_cypher=validate_cypher
validate_cypher=validate_cypher,
allow_dangerous_requests=True
)
formatted_prompt = CYPHER_GENERATION_PROMPT.format(schema=schema, question=prompt)
@ -150,4 +144,6 @@ async def query_graph(
logging.info(f"Cypher chain: \n{chain}\n")
logging.info("==================================================")
return chain(prompt)
return chain(prompt)

View File

@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [
{
@ -47,7 +47,7 @@
"import json\n",
"\n",
"# Define the URL of your FastAPI server\n",
"BASE_URL = \"http://localhost:8000\" # Adjust this if your server is running on a different port or host\n",
"BASE_URL = \"http://localhost:8001\" # Adjust this if your server is running on a different port or host\n",
"\n",
"# Define the endpoint\n",
"ENDPOINT = f\"{BASE_URL}/api/langchain/interactive_langgraph_query/query\"\n",
@ -81,7 +81,7 @@
"\n",
"def test_followup_queries(model=\"openai\"):\n",
" queries = [\n",
" \"What is the latest local news from a particular town?\"\n",
" \"Tell me everything you can about schools in Medway\"\n",
" ]\n",
" \n",
" print(f\"Testing queries requiring follow-up using {model} model:\")\n",
@ -117,7 +117,7 @@
"#test_simple_queries(\"ollama\")\n",
"\n",
"print(\"\\nRunning simple query tests with OpenAI:\\n\")\n",
"test_simple_queries(\"openai\")\n",
"test_simple_queries(\"ollama\")\n",
"\n",
"#print(\"\\nRunning follow-up query tests with Ollama:\\n\")\n",
"#test_followup_queries(\"ollama\")\n",

View File

@ -4,14 +4,16 @@ from langchain_core.runnables.base import Runnable
from langchain.prompts.base import StringPromptValue
class OllamaWrapper(Runnable):
def __init__(self, host: str):
def __init__(self, host: str, model: str = "llama3.2:latest"):
self.client = Client(host=host)
self.model = model
def invoke(self, prompt: Any, config: Dict[str, Any] = None, **kwargs: Any) -> str:
if isinstance(prompt, StringPromptValue):
prompt = prompt.to_string()
model_name = kwargs.get("model", "llama3")
# Use the model from constructor, but allow override via kwargs
model_name = kwargs.get("model", self.model)
options = {
"temperature": kwargs.get("temperature"),
"top_p": kwargs.get("top_p"),

View File

@ -0,0 +1,168 @@
import os
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel
import redis
from modules.logger_tool import initialise_logger
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
router = APIRouter()
def _redis_client() -> redis.Redis:
host = os.getenv('REDIS_HOST', '127.0.0.1')
port = int(os.getenv('REDIS_PORT', '6379'))
return redis.Redis(host=host, port=port, decode_responses=True)
@router.get("/ping")
def ping() -> Dict[str, Any]:
try:
r = _redis_client()
pong = r.ping()
return {"ok": True, "pong": pong}
except Exception as e:
logger.error(f"Redis ping failed: {e}")
raise HTTPException(status_code=500, detail=f"Redis ping failed: {e}")
@router.get("/info")
def info(section: Optional[str] = Query(None, description="Optional INFO section, e.g. memory, server, clients, keyspace")) -> Dict[str, Any]:
try:
r = _redis_client()
data = r.info(section) if section else r.info()
return {"ok": True, "info": data}
except Exception as e:
logger.error(f"Redis info failed: {e}")
raise HTTPException(status_code=500, detail=f"Redis info failed: {e}")
@router.get("/scan")
def scan(cursor: int = 0, pattern: Optional[str] = None, count: int = Query(100, ge=1, le=10000)) -> Dict[str, Any]:
try:
r = _redis_client()
next_cursor, keys = r.scan(cursor=cursor, match=pattern, count=count)
return {"ok": True, "cursor": next_cursor, "keys": keys, "count": len(keys)}
except Exception as e:
logger.error(f"Redis scan failed: {e}")
raise HTTPException(status_code=500, detail=f"Redis scan failed: {e}")
@router.get("/keys")
def list_keys(pattern: str = Query("*", description="Glob-style pattern to match keys"), limit: int = Query(200, ge=1, le=5000)) -> Dict[str, Any]:
try:
r = _redis_client()
keys: List[str] = []
cursor = 0
while True and len(keys) < limit:
cursor, batch = r.scan(cursor=cursor, match=pattern, count=min(1000, limit - len(keys)))
keys.extend(batch)
if cursor == 0:
break
return {"ok": True, "keys": keys[:limit], "count": len(keys[:limit])}
except Exception as e:
logger.error(f"Redis keys failed: {e}")
raise HTTPException(status_code=500, detail=f"Redis keys failed: {e}")
@router.get("/key")
def get_key(key: str) -> Dict[str, Any]:
try:
r = _redis_client()
t = r.type(key)
value: Any = None
if t == 'string':
value = r.get(key)
elif t == 'hash':
value = r.hgetall(key)
elif t == 'list':
value = r.lrange(key, 0, 99)
elif t == 'set':
value = list(r.smembers(key))
elif t == 'zset':
value = r.zrange(key, 0, 99, withscores=True)
ttl = r.ttl(key)
return {"ok": True, "type": t, "ttl": ttl, "value": value}
except Exception as e:
logger.error(f"Redis get key failed: {e}")
raise HTTPException(status_code=500, detail=f"Redis get key failed: {e}")
class DeleteKeysBody(BaseModel):
keys: Optional[List[str]] = None
pattern: Optional[str] = None
@router.post("/delete")
def delete_keys(body: DeleteKeysBody) -> Dict[str, Any]:
if not body.keys and not body.pattern:
raise HTTPException(status_code=400, detail="Provide 'keys' or 'pattern'")
try:
r = _redis_client()
to_delete: List[str] = body.keys or []
if body.pattern:
# Resolve pattern to keys via SCAN to avoid blocking
keys: List[str] = []
cursor = 0
while True:
cursor, batch = r.scan(cursor=cursor, match=body.pattern, count=1000)
keys.extend(batch)
if cursor == 0:
break
to_delete.extend(keys)
deleted = 0
for k in set(to_delete):
try:
deleted += r.delete(k)
except Exception:
pass
return {"ok": True, "deleted": deleted}
except Exception as e:
logger.error(f"Redis delete failed: {e}")
raise HTTPException(status_code=500, detail=f"Redis delete failed: {e}")
@router.post("/flushdb")
def flush_db(confirm: bool = Query(False, description="Must be true to flush the current DB")) -> Dict[str, Any]:
if not confirm:
raise HTTPException(status_code=400, detail="Set confirm=true to flush the current Redis DB")
try:
r = _redis_client()
r.flushdb()
return {"ok": True, "message": "Flushed current Redis DB"}
except Exception as e:
logger.error(f"Redis FLUSHDB failed: {e}")
raise HTTPException(status_code=500, detail=f"Redis FLUSHDB failed: {e}")
@router.get("/queues")
def queue_stats() -> Dict[str, Any]:
"""Report queue sizes and basic counters used by DocumentProcessingQueue."""
try:
r = _redis_client()
keys = {
"high": "queue:high",
"normal": "queue:normal",
"low": "queue:low",
"processing": "processing",
"dead_letter": "dead_letter",
"metrics": "metrics",
}
data = {
"queues": {
"high": r.llen(keys["high"]),
"normal": r.llen(keys["normal"]),
"low": r.llen(keys["low"]),
},
"processing": r.hgetall(keys["processing"]),
"dead_letter": r.llen(keys["dead_letter"]),
"metrics": r.hgetall(keys["metrics"]),
}
return {"ok": True, **data}
except Exception as e:
logger.error(f"Queue stats failed: {e}")
raise HTTPException(status_code=500, detail=f"Queue stats failed: {e}")

53
routers/provisioning.py Normal file
View File

@ -0,0 +1,53 @@
from datetime import date
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from modules.auth.supabase_bearer import SupabaseBearer
from modules.database.services.provisioning_service import ProvisioningService
router = APIRouter(prefix="/provisioning", tags=["Provisioning"])
auth = SupabaseBearer()
class ProvisionUserRequest(BaseModel):
user_id: str
class ProvisionUserResponse(BaseModel):
user_db_name: str
worker_db_name: Optional[str]
worker_type: Optional[str]
class ProvisionSchoolRequest(BaseModel):
institute_id: str
class ProvisionSchoolResponse(BaseModel):
db_name: str
curriculum_db_name: str
@router.post("/users", response_model=ProvisionUserResponse)
def provision_user(payload: ProvisionUserRequest, token=Depends(auth)):
"""Ensure a user's Neo4j resources exist."""
# Basic authorization: require matching subject or service role token
if token.get('role') not in ('service_role', 'admin') and token.get('sub') != payload.user_id:
raise HTTPException(status_code=403, detail="Forbidden")
service = ProvisioningService()
result = service.ensure_user(payload.user_id)
return ProvisionUserResponse(**result)
@router.post("/schools", response_model=ProvisionSchoolResponse)
def provision_school(payload: ProvisionSchoolRequest, token=Depends(auth)):
"""Ensure a school's Neo4j resources exist."""
if token.get('role') not in ('service_role', 'admin'):
raise HTTPException(status_code=403, detail="Forbidden")
service = ProvisioningService()
result = service.ensure_school(payload.institute_id)
return ProvisionSchoolResponse(db_name=result['db_name'], curriculum_db_name=result['curriculum_db_name'])

313
routers/queue_management.py Normal file
View File

@ -0,0 +1,313 @@
"""
Queue Management API
Provides endpoints for monitoring and managing the document processing queue.
"""
from fastapi import APIRouter, HTTPException, Depends
from typing import Dict, Any, List, Optional
from modules.queue_system import get_queue, TaskPriority, ServiceType
from modules.task_processors import get_processor
from modules.auth.supabase_bearer import SupabaseBearer
import os
router = APIRouter()
auth = SupabaseBearer()
@router.get("/queue/stats")
def get_queue_stats(payload: Dict[str, Any] = Depends(auth)):
"""Get comprehensive queue statistics."""
queue = get_queue()
stats = queue.get_queue_stats()
return stats
@router.get("/queue/health")
def queue_health():
"""Check queue health status."""
try:
queue = get_queue()
stats = queue.get_queue_stats()
# Basic health checks
total_processing = stats['total_processing']
total_queued = sum(stats['queues'].values())
dead_letter_count = stats['dead_letter_count']
status = "healthy"
issues = []
if dead_letter_count > 10:
issues.append(f"High dead letter count: {dead_letter_count}")
status = "degraded"
if total_processing == 0 and total_queued > 0:
issues.append("Tasks queued but no workers processing")
status = "degraded"
# Check Redis connectivity
queue.redis_client.ping()
return {
"status": status,
"total_processing": total_processing,
"total_queued": total_queued,
"dead_letter_count": dead_letter_count,
"issues": issues,
"timestamp": queue.redis_client.time()[0]
}
except Exception as e:
return {
"status": "unhealthy",
"error": str(e),
"timestamp": None
}
@router.post("/queue/workers/start")
def start_workers(
worker_count: int = 1,
services: Optional[List[str]] = None,
payload: Dict[str, Any] = Depends(auth)
):
"""Start queue workers."""
if not payload.get('role') == 'service_role': # Admin only
raise HTTPException(status_code=403, detail="Admin access required")
processor = get_processor()
# Convert service names to enums
service_enums = []
if services:
for service_name in services:
try:
service_enums.append(ServiceType(service_name))
except ValueError:
raise HTTPException(status_code=400, detail=f"Invalid service: {service_name}")
else:
service_enums = list(ServiceType)
worker_ids = []
for i in range(worker_count):
worker_id = processor.start_worker(services=service_enums)
worker_ids.append(worker_id)
return {
"message": f"Started {worker_count} workers",
"worker_ids": worker_ids,
"services": [s.value for s in service_enums]
}
@router.post("/queue/workers/stop")
def stop_workers(timeout: int = 30, payload: Dict[str, Any] = Depends(auth)):
"""Stop all queue workers."""
if not payload.get('role') == 'service_role': # Admin only
raise HTTPException(status_code=403, detail="Admin access required")
processor = get_processor()
processor.shutdown(timeout=timeout)
return {"message": "Workers shutdown initiated"}
@router.get("/queue/tasks/{task_id}")
def get_task_status(task_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Get status of a specific task."""
queue = get_queue()
# Get task data from Redis
task_key = queue._get_task_key(task_id)
task_data = queue.redis_client.hgetall(task_key)
if not task_data:
raise HTTPException(status_code=404, detail="Task not found")
return task_data
@router.get("/queue/tasks/by-file/{file_id}")
def list_tasks_by_file(file_id: str, limit: int = 200, payload: Dict[str, Any] = Depends(auth)):
"""List recent queue tasks for a given file_id (best-effort scan)."""
queue = get_queue()
results: List[Dict[str, Any]] = []
count = 0
import json
try:
for key in queue.redis_client.scan_iter(match="task:*"):
task_data = queue.redis_client.hgetall(key)
if not task_data:
continue
if task_data.get('file_id') != file_id:
continue
# Build a brief
try:
payload_raw = task_data.get('payload') or '{}'
payload_obj = json.loads(payload_raw)
except Exception:
payload_obj = {}
results.append({
'id': task_data.get('id') or key.split(':', 1)[-1],
'service': task_data.get('service'),
'task_type': task_data.get('task_type'),
'status': task_data.get('status', 'pending'),
'priority': task_data.get('priority'),
'created_at': float(task_data.get('created_at') or 0),
'scheduled_at': float(task_data.get('scheduled_at') or 0),
'depends_on': payload_obj.get('depends_on') or []
})
count += 1
if count >= max(1, int(limit)):
break
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed scanning tasks: {e}")
# Sort by created_at desc
results.sort(key=lambda x: x.get('created_at', 0), reverse=True)
return {
'file_id': file_id,
'count': len(results),
'tasks': results
}
@router.get("/queue/tasks/{task_id}/dependencies")
def get_task_dependencies(task_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Inspect a task's dependency state (direct depends_on only)."""
queue = get_queue()
task_key = queue._get_task_key(task_id)
task_data = queue.redis_client.hgetall(task_key)
if not task_data:
raise HTTPException(status_code=404, detail="Task not found")
# Parse payload JSON stored in Redis
import json
try:
payload_raw = task_data.get('payload') or '{}'
payload_obj = json.loads(payload_raw)
except Exception:
payload_obj = {}
depends_on = payload_obj.get('depends_on') or []
if not isinstance(depends_on, list):
depends_on = []
details: List[Dict[str, Any]] = []
missing: List[str] = []
all_completed = True
for dep_id in depends_on:
if not dep_id:
continue
dep_key = queue._get_task_key(dep_id)
dep_data = queue.redis_client.hgetall(dep_key)
if not dep_data:
missing.append(dep_id)
all_completed = False
details.append({
'task_id': dep_id,
'status': 'missing'
})
continue
status = dep_data.get('status', 'pending')
if status != 'completed':
all_completed = False
details.append({
'task_id': dep_id,
'status': status,
'service': dep_data.get('service'),
'task_type': dep_data.get('task_type'),
'created_at': dep_data.get('created_at'),
'scheduled_at': dep_data.get('scheduled_at')
})
return {
'task_id': task_id,
'depends_on': depends_on,
'all_completed': all_completed,
'missing': missing,
'details': details
}
@router.delete("/queue/dead-letter/{task_id}")
def remove_dead_task(task_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Remove a task from the dead letter queue."""
if not payload.get('role') == 'service_role': # Admin only
raise HTTPException(status_code=403, detail="Admin access required")
queue = get_queue()
# Remove from dead letter queue
removed = queue.redis_client.lrem(queue.dead_letter_key, 1, task_id)
if removed == 0:
raise HTTPException(status_code=404, detail="Task not found in dead letter queue")
# Clean up task data
queue.redis_client.delete(queue._get_task_key(task_id))
return {"message": f"Removed task {task_id} from dead letter queue"}
@router.post("/queue/dead-letter/{task_id}/retry")
def retry_dead_task(task_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Retry a task from the dead letter queue."""
if not payload.get('role') == 'service_role': # Admin only
raise HTTPException(status_code=403, detail="Admin access required")
queue = get_queue()
# Get task data
task_key = queue._get_task_key(task_id)
task_data = queue.redis_client.hgetall(task_key)
if not task_data:
raise HTTPException(status_code=404, detail="Task not found")
# Remove from dead letter queue
removed = queue.redis_client.lrem(queue.dead_letter_key, 1, task_id)
if removed == 0:
raise HTTPException(status_code=404, detail="Task not found in dead letter queue")
# Reset task for retry
queue.redis_client.hset(
task_key,
mapping={
'attempts': 0,
'status': 'pending',
'scheduled_at': queue.redis_client.time()[0]
}
)
# Re-queue task
priority = TaskPriority(task_data['priority'])
queue_key = queue.queue_keys[priority]
queue.redis_client.lpush(queue_key, task_id)
return {"message": f"Task {task_id} requeued for retry"}
@router.get("/queue/metrics")
def get_queue_metrics(hours: int = 1, payload: Dict[str, Any] = Depends(auth)):
"""Get queue processing metrics over time."""
queue = get_queue()
# This is a simplified version - in production you'd want more sophisticated metrics
current_time = queue.redis_client.time()[0]
start_time = current_time - (hours * 3600)
# Scan for metric keys in the time range
metrics = {}
pattern = f"{queue.metrics_key}:*"
for key in queue.redis_client.scan_iter(match=pattern):
# Parse key format: metrics:action:service:priority:timestamp_minute
parts = key.split(':')
if len(parts) >= 5:
action = parts[1]
service = parts[2]
priority = parts[3]
timestamp_minute = int(parts[4])
if timestamp_minute >= (start_time // 60):
count = int(queue.redis_client.get(key) or 0)
metric_key = f"{action}_{service}_{priority}"
if metric_key not in metrics:
metrics[metric_key] = 0
metrics[metric_key] += count
return {
"time_range_hours": hours,
"metrics": metrics
}

174
routers/queue_monitor.py Normal file
View File

@ -0,0 +1,174 @@
"""
Queue Monitoring Router
Provides endpoints to monitor queue status, service limits, and processing counts
to help debug issues like Docling server overload.
"""
from fastapi import APIRouter, Depends
from typing import Dict, Any, List
from modules.auth.supabase_bearer import SupabaseBearer
from modules.queue_system import get_queue
from modules.redis_manager import get_redis_manager
from modules.logger_tool import initialise_logger
import os
router = APIRouter()
auth = SupabaseBearer()
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
@router.get("/queue/status")
def get_queue_status(payload: Dict[str, Any] = Depends(auth)):
"""Get comprehensive queue status including service limits and current processing counts."""
try:
queue = get_queue()
stats = queue.get_queue_stats()
# Add environment configuration
config = {
'QUEUE_DOCLING_LIMIT': int(os.getenv('QUEUE_DOCLING_LIMIT', '2')),
'QUEUE_TIKA_LIMIT': int(os.getenv('QUEUE_TIKA_LIMIT', '3')),
'QUEUE_LLM_LIMIT': int(os.getenv('QUEUE_LLM_LIMIT', '5')),
'BUNDLE_ARCHITECTURE_ENABLED': True,
'AUTO_DOCLING_OCR': os.getenv('AUTO_DOCLING_OCR', 'true'),
'AUTO_DOCLING_NO_OCR': os.getenv('AUTO_DOCLING_NO_OCR', 'true'),
'AUTO_DOCLING_VLM': os.getenv('AUTO_DOCLING_VLM', 'false')
}
return {
'queue_statistics': stats,
'configuration': config,
'redis_host': queue.redis_host,
'redis_port': queue.redis_port,
'service_limits': dict(queue.service_limits),
'rate_limits': dict(queue.rate_limits)
}
except Exception as e:
logger.error(f"Failed to get queue status: {e}")
return {
'error': str(e),
'queue_available': False
}
@router.get("/queue/tasks/by-file/{file_id}")
def get_file_queue_tasks(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Get all queue tasks for a specific file (for debugging)."""
try:
# This would require extending the queue system to track tasks by file_id
# For now, return a placeholder that indicates this feature needs implementation
return {
'message': 'File-specific task tracking not yet implemented',
'file_id': file_id,
'suggestion': 'Check Redis directly or extend queue system with file_id indexing'
}
except Exception as e:
logger.error(f"Failed to get tasks for file {file_id}: {e}")
return {
'error': str(e),
'file_id': file_id
}
@router.get("/queue/health")
def get_comprehensive_queue_health(payload: Dict[str, Any] = Depends(auth)):
"""Get comprehensive queue and Redis health information with environment details."""
try:
# Determine environment
environment = 'dev' if os.getenv('BACKEND_DEV_MODE', 'true').lower() == 'true' else 'prod'
# Get Redis manager health
redis_manager = get_redis_manager(environment)
redis_health = redis_manager.health_check()
# Get queue stats
queue_stats = {}
queue_available = False
try:
queue = get_queue()
queue_stats = queue.get_queue_stats()
queue_available = True
except Exception as e:
queue_stats = {'error': str(e)}
# Environment configuration
env_config = {
'current_environment': environment,
'redis_database': redis_health.get('database', 'unknown'),
'persistence_enabled': os.getenv(f'REDIS_PERSIST_{environment.upper()}', 'unknown'),
'task_ttl': os.getenv(f'REDIS_TASK_TTL_{environment.upper()}', 'unknown'),
'service_limits': {
'docling': int(os.getenv('QUEUE_DOCLING_LIMIT', '2')),
'tika': int(os.getenv('QUEUE_TIKA_LIMIT', '3')),
'llm': int(os.getenv('QUEUE_LLM_LIMIT', '5')),
'split_map': int(os.getenv('QUEUE_SPLIT_MAP_LIMIT', '10')),
'document_analysis': int(os.getenv('QUEUE_DOCUMENT_ANALYSIS_LIMIT', '5')),
'page_images': int(os.getenv('QUEUE_PAGE_IMAGES_LIMIT', '3'))
},
'workers': int(os.getenv('QUEUE_WORKERS', '1'))
}
# Overall health status
overall_status = 'healthy'
issues = []
if redis_health['status'] != 'healthy':
overall_status = 'unhealthy'
issues.append(f"Redis: {redis_health.get('error', 'Unknown issue')}")
if not queue_available:
overall_status = 'degraded'
issues.append(f"Queue system: {queue_stats.get('error', 'Not accessible')}")
# Check for concerning queue states
if queue_available and queue_stats.get('dead_letter_count', 0) > 0:
overall_status = 'warning'
issues.append(f"Dead letter queue has {queue_stats['dead_letter_count']} failed tasks")
return {
'status': overall_status,
'issues': issues,
'timestamp': redis_health.get('timestamp'),
'environment': env_config,
'redis': redis_health,
'queue': queue_stats,
'recommendations': _get_health_recommendations(redis_health, queue_stats, environment)
}
except Exception as e:
logger.error(f"Failed to get comprehensive queue health: {e}")
return {
'status': 'error',
'error': str(e),
'timestamp': None
}
def _get_health_recommendations(redis_health: Dict, queue_stats: Dict, environment: str) -> List[str]:
"""Generate health recommendations based on current state."""
recommendations = []
# Redis recommendations
if redis_health.get('status') != 'healthy':
recommendations.append("Check Redis service status and connectivity")
# Queue recommendations
if queue_stats.get('dead_letter_count', 0) > 5:
recommendations.append("High number of failed tasks - check task processing logic")
# Processing recommendations
processing_counts = queue_stats.get('processing', {})
for service, count in processing_counts.items():
if count < 0:
recommendations.append(f"Negative processing counter for {service} - restart server to reset")
# Environment-specific recommendations
if environment == 'dev':
recommendations.append("Development mode: Database will be cleared on restart")
else:
recommendations.append("Production mode: Tasks will be recovered on restart")
if not recommendations:
recommendations.append("System appears healthy - no specific recommendations")
return recommendations

543
routers/simple_upload.py Normal file
View File

@ -0,0 +1,543 @@
"""
Simple Upload Router
===================
Handles file and directory uploads without automatic processing.
Just stores files in Supabase storage and creates database records.
Features:
- Single file upload
- Directory/folder upload with manifest
- No automatic processing
- Immediate response to users
- Directory structure preservation
"""
import os
import uuid
import json
import tempfile
import logging
from typing import Dict, List, Optional, Any
from pathlib import Path
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, BackgroundTasks
from fastapi.responses import JSONResponse
from modules.auth.supabase_bearer import SupabaseBearer
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
from modules.database.supabase.utils.storage import StorageAdmin
from modules.logger_tool import initialise_logger
router = APIRouter()
auth = SupabaseBearer()
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
def _choose_bucket(scope: str, user_id: str, school_id: Optional[str]) -> str:
"""Choose appropriate bucket based on scope - matches old system logic."""
scope = (scope or 'teacher').lower()
if scope == 'school' and school_id:
return f"cc.institutes.{school_id}.private"
# teacher / student fall back to users bucket for now
return 'cc.users'
@router.post("/files/upload")
async def upload_single_file(
cabinet_id: str = Form(...),
path: str = Form(...),
scope: str = Form(...),
file: UploadFile = File(...),
payload: Dict[str, Any] = Depends(auth)
):
"""
Simple single file upload - no automatic processing.
Just stores the file and creates a database record.
"""
try:
user_id = payload.get('sub') or payload.get('user_id')
if not user_id:
raise HTTPException(status_code=401, detail="User ID required")
# Read file content
file_bytes = await file.read()
file_size = len(file_bytes)
mime_type = file.content_type or 'application/octet-stream'
filename = file.filename or path
logger.info(f"📤 Simple upload: {filename} ({file_size} bytes) for user {user_id}")
# Initialize services
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
# Generate file ID and storage path
file_id = str(uuid.uuid4())
# Use same bucket logic as old system for consistency
bucket = _choose_bucket('teacher', user_id, None) # Default to teacher scope
storage_path = f"{cabinet_id}/{file_id}/{filename}"
# Store file in Supabase storage
try:
storage.upload_file(bucket, storage_path, file_bytes, mime_type, upsert=True)
except Exception as e:
logger.error(f"Storage upload failed for {file_id}: {e}")
raise HTTPException(status_code=500, detail=f"Storage upload failed: {str(e)}")
# Create database record
try:
insert_res = client.supabase.table('files').insert({
'id': file_id,
'name': filename,
'cabinet_id': cabinet_id,
'bucket': bucket,
'path': storage_path,
'mime_type': mime_type,
'uploaded_by': user_id,
'size_bytes': file_size,
'source': 'classroomcopilot-web',
'is_directory': False,
'processing_status': 'uploaded',
'relative_path': filename # For single files, relative path is just the filename
}).execute()
if not insert_res.data:
# Clean up storage on DB failure
try:
storage.delete_file(bucket, storage_path)
except:
pass
raise HTTPException(status_code=500, detail="Failed to create file record")
file_record = insert_res.data[0]
except Exception as e:
logger.error(f"Database insert failed for {file_id}: {e}")
# Clean up storage
try:
storage.delete_file(bucket, storage_path)
except:
pass
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
logger.info(f"✅ Simple upload completed: {file_id}")
return {
'status': 'success',
'message': 'File uploaded successfully',
'file': file_record,
'processing_required': False, # No automatic processing
'next_steps': 'File is ready for manual processing if needed'
}
except HTTPException:
raise
except Exception as e:
logger.error(f"Upload error: {e}")
raise HTTPException(status_code=500, detail=f"Upload failed: {str(e)}")
@router.post("/files/upload-directory")
async def upload_directory(
cabinet_id: str = Form(...),
scope: str = Form(...),
directory_name: str = Form(...),
files: List[UploadFile] = File(...),
file_paths: str = Form(...), # JSON string of relative paths
payload: Dict[str, Any] = Depends(auth)
):
"""
Upload a complete directory/folder with all files.
Preserves directory structure and creates a manifest.
"""
try:
user_id = payload.get('sub') or payload.get('user_id')
if not user_id:
raise HTTPException(status_code=401, detail="User ID required")
# Parse file paths
try:
relative_paths = json.loads(file_paths)
except json.JSONDecodeError:
raise HTTPException(status_code=400, detail="Invalid file_paths JSON")
if len(files) != len(relative_paths):
raise HTTPException(status_code=400, detail="Files and paths count mismatch")
logger.info(f"📁 Directory upload: {directory_name} ({len(files)} files) for user {user_id}")
# Initialize services
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
# Generate session ID for this directory upload
upload_session_id = str(uuid.uuid4())
directory_id = str(uuid.uuid4())
# Use same bucket logic as old system for consistency
bucket = _choose_bucket('teacher', user_id, None)
# Calculate total size and build manifest
total_size = 0
directory_structure = {}
uploaded_files = []
directory_records = {} # Track created directories: {relative_path: directory_id}
# First, analyze all paths to determine directory structure
all_directories = set()
for relative_path in relative_paths:
# Get all parent directories for this file
path_parts = relative_path.split('/')
for i in range(len(path_parts) - 1): # Exclude the filename
dir_path = '/'.join(path_parts[:i+1])
all_directories.add(dir_path)
logger.info(f"📁 Creating directory structure with {len(all_directories)} directories: {sorted(all_directories)}")
try:
# Create directory records for all directories (sorted to create parents first)
sorted_directories = sorted(all_directories, key=lambda x: (len(x.split('/')), x))
for dir_path in sorted_directories:
dir_id = str(uuid.uuid4())
path_parts = dir_path.split('/')
dir_name = path_parts[-1] # Last part is the directory name
# Determine parent directory
parent_id = None
if len(path_parts) > 1:
parent_path = '/'.join(path_parts[:-1])
parent_id = directory_records.get(parent_path)
directory_record = {
'id': dir_id,
'name': dir_name,
'cabinet_id': cabinet_id,
'bucket': bucket,
'path': f"{cabinet_id}/{dir_id}/",
'mime_type': 'inode/directory',
'uploaded_by': user_id,
'size_bytes': 0,
'source': 'classroomcopilot-web',
'is_directory': True,
'parent_directory_id': parent_id,
'upload_session_id': upload_session_id,
'processing_status': 'uploaded',
'relative_path': dir_path
}
directory_records[dir_path] = dir_id
# Insert directory record
result = client.supabase.table('files').insert(directory_record).execute()
logger.info(f"📁 Created directory: {dir_path} (ID: {dir_id}, Parent: {parent_id})")
# Process each file
for i, (file, relative_path) in enumerate(zip(files, relative_paths)):
try:
# Read file content
file_bytes = await file.read()
file_size = len(file_bytes)
mime_type = file.content_type or 'application/octet-stream'
filename = file.filename or f"file_{i}"
total_size += file_size
# Generate file ID and determine parent directory
file_id = str(uuid.uuid4())
# Find the correct parent directory for this file
path_parts = relative_path.split('/')
if len(path_parts) > 1:
parent_dir_path = '/'.join(path_parts[:-1])
parent_directory_id = directory_records.get(parent_dir_path)
else:
parent_directory_id = None # File is in root cabinet
# Use parent directory ID for storage path if exists, otherwise use a generated path
if parent_directory_id:
storage_path = f"{cabinet_id}/{parent_directory_id}/{path_parts[-1]}"
else:
storage_path = f"{cabinet_id}/{file_id}"
# Store file in Supabase storage
storage.upload_file(bucket, storage_path, file_bytes, mime_type, upsert=True)
# Create file record
file_record = {
'id': file_id,
'name': filename,
'cabinet_id': cabinet_id,
'bucket': bucket,
'path': storage_path,
'mime_type': mime_type,
'uploaded_by': user_id,
'size_bytes': file_size,
'source': 'classroomcopilot-web',
'is_directory': False,
'parent_directory_id': parent_directory_id,
'relative_path': relative_path,
'upload_session_id': upload_session_id,
'processing_status': 'uploaded'
}
uploaded_files.append(file_record)
# Build directory structure for manifest
_add_to_directory_structure(directory_structure, relative_path, {
'size': file_size,
'mime_type': mime_type,
'file_id': file_id
})
logger.info(f"📄 Uploaded file {i+1}/{len(files)}: {relative_path}")
except Exception as e:
logger.error(f"Failed to upload file {relative_path}: {e}")
# Continue with other files, don't fail entire upload
continue
# Create directory manifest
directory_manifest = {
'total_files': len(uploaded_files),
'total_size_bytes': total_size,
'directory_structure': directory_structure,
'upload_timestamp': '2024-09-23T12:00:00Z', # TODO: Use actual timestamp
'upload_method': 'directory_picker',
'upload_session_id': upload_session_id
}
# Update root directory with manifest and total size (if root directory exists)
root_directory_id = directory_records.get(sorted_directories[0]) if sorted_directories else None
if root_directory_id:
update_res = client.supabase.table('files').update({
'size_bytes': total_size,
'directory_manifest': directory_manifest
}).eq('id', root_directory_id).execute()
if not update_res.data:
logger.warning("Failed to update root directory with manifest")
# Insert all file records in batch
if uploaded_files:
files_insert_res = client.supabase.table('files').insert(uploaded_files).execute()
if not files_insert_res.data:
logger.warning("Some file records failed to insert")
logger.info(f"✅ Directory upload completed: {root_directory_id} ({len(uploaded_files)} files, {len(sorted_directories)} directories)")
return {
'status': 'success',
'message': f'Directory uploaded successfully with {len(uploaded_files)} files in {len(sorted_directories)} directories',
'directories_created': len(sorted_directories),
'files_count': len(uploaded_files),
'total_size_bytes': total_size,
'root_directory_id': root_directory_id,
'upload_session_id': upload_session_id,
'processing_required': False, # No automatic processing
'next_steps': 'Files are ready for manual processing if needed'
}
except Exception as e:
logger.error(f"Directory upload failed: {e}")
# TODO: Implement cleanup of partially uploaded files
raise HTTPException(status_code=500, detail=f"Directory upload failed: {str(e)}")
except HTTPException:
raise
except Exception as e:
logger.error(f"Directory upload error: {e}")
raise HTTPException(status_code=500, detail=f"Upload failed: {str(e)}")
def _add_to_directory_structure(structure: Dict, relative_path: str, file_info: Dict):
"""Add a file to the directory structure manifest."""
path_parts = relative_path.split('/')
current_level = structure
# Navigate/create directory structure
for i, part in enumerate(path_parts):
if i == len(path_parts) - 1:
# This is the file itself
current_level[part] = file_info
else:
# This is a directory
if part not in current_level:
current_level[part] = {}
current_level = current_level[part]
@router.get("/files")
def list_files(
cabinet_id: str,
include_directories: bool = True,
parent_directory_id: Optional[str] = None,
page: int = 1,
per_page: int = 20,
search: Optional[str] = None,
sort_by: str = 'created_at',
sort_order: str = 'desc',
payload: Dict[str, Any] = Depends(auth)
):
"""
List files with pagination, search, and sorting support.
Args:
cabinet_id: Cabinet to list files from
include_directories: Whether to include directory entries
parent_directory_id: Filter by parent directory
page: Page number (1-based)
per_page: Items per page (max 100)
search: Search term for filename
sort_by: Field to sort by (name, size_bytes, created_at, processing_status)
sort_order: Sort order (asc, desc)
"""
try:
client = SupabaseServiceRoleClient()
# Validate pagination parameters
page = max(1, page)
per_page = min(max(1, per_page), 100) # Limit to 100 items per page
offset = (page - 1) * per_page
# Validate sort parameters
valid_sort_fields = ['name', 'size_bytes', 'created_at', 'processing_status', 'mime_type']
if sort_by not in valid_sort_fields:
sort_by = 'created_at'
if sort_order.lower() not in ['asc', 'desc']:
sort_order = 'desc'
# Build base query
query = client.supabase.table('files').select('*').eq('cabinet_id', cabinet_id)
count_query = client.supabase.table('files').select('id', count='exact').eq('cabinet_id', cabinet_id)
# Apply filters
if parent_directory_id:
query = query.eq('parent_directory_id', parent_directory_id)
count_query = count_query.eq('parent_directory_id', parent_directory_id)
elif not include_directories:
query = query.eq('is_directory', False)
count_query = count_query.eq('is_directory', False)
# Apply search filter
if search:
search_term = f"%{search}%"
query = query.ilike('name', search_term)
count_query = count_query.ilike('name', search_term)
# Get total count
count_res = count_query.execute()
total_count = count_res.count if hasattr(count_res, 'count') else len(count_res.data or [])
# Apply sorting and pagination
query = query.order(sort_by, desc=(sort_order.lower() == 'desc'))
query = query.range(offset, offset + per_page - 1)
res = query.execute()
files = res.data or []
# Calculate pagination metadata
total_pages = (total_count + per_page - 1) // per_page
has_next = page < total_pages
has_prev = page > 1
return {
'files': files,
'pagination': {
'page': page,
'per_page': per_page,
'total_count': total_count,
'total_pages': total_pages,
'has_next': has_next,
'has_prev': has_prev,
'offset': offset
},
'filters': {
'search': search,
'sort_by': sort_by,
'sort_order': sort_order,
'include_directories': include_directories,
'parent_directory_id': parent_directory_id
}
}
except Exception as e:
logger.error(f"List files error: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/files/{file_id}")
def get_file_details(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Get detailed information about a file or directory."""
try:
client = SupabaseServiceRoleClient()
res = client.supabase.table('files').select('*').eq('id', file_id).single().execute()
if not res.data:
raise HTTPException(status_code=404, detail="File not found")
file_data = res.data
# If it's a directory, also get its contents
if file_data.get('is_directory'):
contents_res = client.supabase.table('files').select('*').eq('parent_directory_id', file_id).execute()
file_data['contents'] = contents_res.data or []
return file_data
except HTTPException:
raise
except Exception as e:
logger.error(f"Get file details error: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.delete("/files/{file_id}")
def delete_file(file_id: str, payload: Dict[str, Any] = Depends(auth)):
"""Delete a file or directory and its contents."""
try:
client = SupabaseServiceRoleClient()
storage = StorageAdmin()
# Get file info
res = client.supabase.table('files').select('*').eq('id', file_id).single().execute()
if not res.data:
raise HTTPException(status_code=404, detail="File not found")
file_data = res.data
# If it's a directory, delete all contents first
if file_data.get('is_directory'):
contents_res = client.supabase.table('files').select('*').eq('parent_directory_id', file_id).execute()
# Delete each file in the directory
for content_file in contents_res.data or []:
try:
# Delete from storage
storage.delete_file(content_file['bucket'], content_file['path'])
except Exception as e:
logger.warning(f"Failed to delete file from storage: {content_file['path']}: {e}")
# Delete all directory contents from database
client.supabase.table('files').delete().eq('parent_directory_id', file_id).execute()
else:
# Delete single file from storage
try:
storage.delete_file(file_data['bucket'], file_data['path'])
except Exception as e:
logger.warning(f"Failed to delete file from storage: {file_data['path']}: {e}")
# Delete the main record
delete_res = client.supabase.table('files').delete().eq('id', file_id).execute()
logger.info(f"🗑️ Deleted {'directory' if file_data.get('is_directory') else 'file'}: {file_id}")
return {
'status': 'success',
'message': f"{'Directory' if file_data.get('is_directory') else 'File'} deleted successfully"
}
except HTTPException:
raise
except Exception as e:
logger.error(f"Delete file error: {e}")
raise HTTPException(status_code=500, detail=str(e))

Some files were not shown because too many files have changed in this diff Show More