| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- """Pydantic schemas for GitHub backup configuration."""
- import re
- from datetime import datetime
- from enum import StrEnum
- from pydantic import BaseModel, Field, field_validator
- class ScheduleType(StrEnum):
- """Backup schedule types."""
- HOURLY = "hourly"
- DAILY = "daily"
- WEEKLY = "weekly"
- class GitHubBackupConfigCreate(BaseModel):
- """Schema for creating/updating GitHub backup config."""
- repository_url: str = Field(..., min_length=1, max_length=500, description="GitHub repository URL")
- access_token: str = Field(..., min_length=1, description="Personal Access Token")
- branch: str = Field(default="main", max_length=100, description="Branch to push to")
- schedule_enabled: bool = Field(default=False, description="Enable scheduled backups")
- schedule_type: ScheduleType = Field(default=ScheduleType.DAILY, description="Schedule frequency")
- backup_kprofiles: bool = Field(default=True, description="Backup K-profiles")
- backup_cloud_profiles: bool = Field(default=True, description="Backup Bambu Cloud profiles")
- backup_settings: bool = Field(default=False, description="Backup app settings")
- enabled: bool = Field(default=True, description="Enable backup feature")
- @field_validator("repository_url")
- @classmethod
- def validate_repo_url(cls, v: str) -> str:
- """Validate GitHub repository URL format."""
- # Accept various GitHub URL formats
- patterns = [
- r"^https://github\.com/[\w.-]+/[\w.-]+(?:\.git)?$",
- r"^git@github\.com:[\w.-]+/[\w.-]+(?:\.git)?$",
- ]
- v = v.strip().rstrip("/")
- if not any(re.match(p, v) for p in patterns):
- raise ValueError("Invalid GitHub repository URL. Expected format: https://github.com/owner/repo")
- return v
- class GitHubBackupConfigUpdate(BaseModel):
- """Schema for updating GitHub backup config (all fields optional)."""
- repository_url: str | None = Field(default=None, max_length=500)
- access_token: str | None = Field(default=None)
- branch: str | None = Field(default=None, max_length=100)
- schedule_enabled: bool | None = None
- schedule_type: ScheduleType | None = None
- backup_kprofiles: bool | None = None
- backup_cloud_profiles: bool | None = None
- backup_settings: bool | None = None
- enabled: bool | None = None
- @field_validator("repository_url")
- @classmethod
- def validate_repo_url(cls, v: str | None) -> str | None:
- if v is None:
- return v
- patterns = [
- r"^https://github\.com/[\w.-]+/[\w.-]+(?:\.git)?$",
- r"^git@github\.com:[\w.-]+/[\w.-]+(?:\.git)?$",
- ]
- v = v.strip().rstrip("/")
- if not any(re.match(p, v) for p in patterns):
- raise ValueError("Invalid GitHub repository URL")
- return v
- class GitHubBackupConfigResponse(BaseModel):
- """Schema for GitHub backup config API response."""
- id: int
- repository_url: str
- has_token: bool = Field(description="Whether an access token is configured")
- branch: str
- schedule_enabled: bool
- schedule_type: str
- backup_kprofiles: bool
- backup_cloud_profiles: bool
- backup_settings: bool
- enabled: bool
- last_backup_at: datetime | None
- last_backup_status: str | None
- last_backup_message: str | None
- last_backup_commit_sha: str | None
- next_scheduled_run: datetime | None
- created_at: datetime
- updated_at: datetime
- class Config:
- from_attributes = True
- class GitHubBackupLogResponse(BaseModel):
- """Schema for backup log API response."""
- id: int
- config_id: int
- started_at: datetime
- completed_at: datetime | None
- status: str
- trigger: str
- commit_sha: str | None
- files_changed: int
- error_message: str | None
- class Config:
- from_attributes = True
- class GitHubBackupStatus(BaseModel):
- """Schema for current backup status."""
- configured: bool = Field(description="Whether backup is configured")
- enabled: bool = Field(description="Whether backup is enabled")
- is_running: bool = Field(description="Whether a backup is currently running")
- progress: str | None = Field(default=None, description="Current backup progress message")
- last_backup_at: datetime | None
- last_backup_status: str | None
- next_scheduled_run: datetime | None
- class GitHubTestConnectionResponse(BaseModel):
- """Schema for test connection response."""
- success: bool
- message: str
- repo_name: str | None = None
- permissions: dict | None = None
- class GitHubBackupTriggerResponse(BaseModel):
- """Schema for manual backup trigger response."""
- success: bool
- message: str
- log_id: int | None = None
- commit_sha: str | None = None
- files_changed: int = 0
|