Architecture
The User Workspaces Server follows a modular, plugin-based architecture that allows for flexible configuration and extensibility. This section describes the core architectural patterns and components.
System Architecture Overview
graph TB
subgraph "Client Layer"
Client[REST API Client]
WSClient[WebSocket Client]
end
subgraph "API Layer"
REST[REST API Endpoints]
WS[WebSocket Consumers]
Auth[Token Authentication]
end
subgraph "Application Layer"
Views[Views/ViewSets]
Serializers[Serializers]
Models[Django Models]
end
subgraph "Controller Layer"
JobTypes[Job Types]
Resources[Resources]
StorageMethods[Storage Methods]
AuthMethods[Authentication Methods]
end
subgraph "Background Processing"
DjangoQ[Django-Q Queue]
Redis[Redis Broker]
Tasks[Background Tasks]
end
subgraph "Data Layer"
FileSystem[(File System)]
PostgreSQL[(PostgreSQL Database)]
end
Client -->|HTTP/HTTPS| REST
WSClient -->|WebSocket| WS
REST --> Auth
WS --> Auth
Auth --> Views
Views --> Serializers
Serializers --> Models
Models --> PostgreSQL
Views --> JobTypes
Views --> Resources
Views --> StorageMethods
Views --> AuthMethods
Resources -->|depends on| StorageMethods
Resources -->|depends on| AuthMethods
Resources --> JobTypes
Resources --> Models
StorageMethods -->|depends on| AuthMethods
StorageMethods --> FileSystem
StorageMethods --> Models
AuthMethods --> Models
JobTypes --> Models
Views --> DjangoQ
DjangoQ --> Redis
Redis --> Tasks
Tasks --> Models
Tasks --> Resources
Tasks --> StorageMethods
style JobTypes fill:#e1f5ff
style Resources fill:#e1f5ff
style StorageMethods fill:#e1f5ff
style AuthMethods fill:#e1f5ff
Configuration-Driven Plugin System
The system uses dynamic configuration to load controllers at runtime:
Configuration Files:
config.jsonanddjango_config.jsonin thesrc/directoryDynamic Loading:
utils.generate_controller_object()instantiates controllers based on class namesController Registry:
apps.pyloads and registers all configured components during Django startup
Controllers are composed with dependencies injected during initialization based on the configuration. All controllers receive configuration dictionaries.
Background Tasks
Task Registration: All background tasks defined in
tasks.pyJob Status Monitoring: Continuous polling of job states via
update_job_status()Workspace Management: Directory synchronization and quota tracking
User Quota Updates: Real-time disk space and core hours calculation
Shared Workspace Creation: Asynchronous workspace copying and email notifications
Database Design
Core Models
Workspace: User workspace containers with status tracking and JSON metadata
Job: Execution units linking workspaces to compute resources
UserQuota: Resource limits and usage tracking
ExternalUserMapping: Links Django users to external authentication systems
SharedWorkspaceMapping: Workspace sharing relationships
API Structure
RESTful Endpoints
More information can be found at the SmartAPI docs.
WebSocket Integration
Real-time Updates: Job status changes broadcasted via Django Channels
Passthrough Support: WebSocket proxying for interactive sessions
Channel Groups: Per-job status update channels
Security Model
Custom Authentication
Token System:
UserWorkspacesTokenAuthenticationwith customUWS-AuthorizationheaderMulti-Provider Support: Pluggable authentication backends
External User Mapping: Links internal Django users with external identity providers
Permission Validation
Storage methods validate user ownership of workspaces
Resource methods enforce user authentication for job execution
Path traversal protection prevents directory escape attacks
Development Patterns
Background Task Development
All tasks must be idempotent and handle failures gracefully
Use
async_task()for queueing with optional hooks for task chainingTasks automatically retry on failure based on Django-Q configuration
WebSocket Development
Consumer classes in
ws_consumers.pyhandle WebSocket connectionsUse channel groups for broadcasting updates to multiple clients
Passthrough consumers proxy WebSocket connections to running jobs