feat: Add WebDAV upload command for cloud projects (#356) · basicmachines-co/basic-memory@5258f45 · GitHub
Skip to content

Commit 5258f45

Browse files
phernandezclaude
andauthored
feat: Add WebDAV upload command for cloud projects (#356)
Signed-off-by: phernandez <paul@basicmachines.co> Signed-off-by: Pablo Hernandez <pablo@basicmachines.co> Co-authored-by: Claude <noreply@anthropic.com>
1 parent e773c00 commit 5258f45

11 files changed

Lines changed: 1050 additions & 68 deletions

File tree

docs/cloud-cli.md

Lines changed: 73 additions & 0 deletions

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ dependencies = [
3434
"pyjwt>=2.10.1",
3535
"python-dotenv>=1.1.0",
3636
"pytest-aio>=1.9.0",
37-
"aiofiles>=24.1.0", # Async file I/O
37+
"aiofiles>=24.1.0", # Async file I/O
3838
]
3939

4040

src/basic_memory/cli/commands/cloud/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
# Import all commands to register them with typer
44
from basic_memory.cli.commands.cloud.core_commands import * # noqa: F401,F403
5-
from basic_memory.cli.commands.cloud.api_client import get_authenticated_headers # noqa: F401
5+
from basic_memory.cli.commands.cloud.api_client import get_authenticated_headers, get_cloud_config # noqa: F401
6+
from basic_memory.cli.commands.cloud.upload_command import * # noqa: F401,F403

src/basic_memory/cli/commands/cloud/bisync_commands.py

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
from rich.table import Table
1313

1414
from basic_memory.cli.commands.cloud.api_client import CloudAPIError, make_api_request
15+
from basic_memory.cli.commands.cloud.cloud_utils import (
16+
create_cloud_project,
17+
fetch_cloud_projects,
18+
)
1519
from basic_memory.cli.commands.cloud.rclone_config import (
1620
add_tenant_to_rclone_config,
1721
)
@@ -21,11 +25,7 @@
2125
from basic_memory.schemas.cloud import (
2226
TenantMountInfo,
2327
MountCredentials,
24-
CloudProjectList,
25-
CloudProjectCreateRequest,
26-
CloudProjectCreateResponse,
2728
)
28-
from basic_memory.utils import generate_permalink
2929

3030
console = Console()
3131

@@ -110,24 +110,6 @@ async def generate_mount_credentials(tenant_id: str) -> MountCredentials:
110110
raise BisyncError(f"Failed to generate credentials: {e}") from e
111111

112112

113-
async def fetch_cloud_projects() -> CloudProjectList:
114-
"""Fetch list of projects from cloud API.
115-
116-
Returns:
117-
CloudProjectList with projects from cloud
118-
"""
119-
try:
120-
config_manager = ConfigManager()
121-
config = config_manager.config
122-
host_url = config.cloud_host.rstrip("/")
123-
124-
response = await make_api_request(method="GET", url=f"{host_url}/proxy/projects/projects")
125-
126-
return CloudProjectList.model_validate(response.json())
127-
except Exception as e:
128-
raise BisyncError(f"Failed to fetch cloud projects: {e}") from e
129-
130-
131113
def scan_local_directories(sync_dir: Path) -> list[str]:
132114
"""Scan local sync directory for project folders.
133115
@@ -148,41 +130,6 @@ def scan_local_directories(sync_dir: Path) -> list[str]:
148130
return directories
149131

150132

151-
async def create_cloud_project(project_name: str) -> CloudProjectCreateResponse:
152-
"""Create a new project on cloud.
153-
154-
Args:
155-
project_name: Name of project to create
156-
157-
Returns:
158-
CloudProjectCreateResponse with project details from API
159-
"""
160-
try:
161-
config_manager = ConfigManager()
162-
config = config_manager.config
163-
host_url = config.cloud_host.rstrip("/")
164-
165-
# Use generate_permalink to ensure consistent naming
166-
project_path = generate_permalink(project_name)
167-
168-
project_data = CloudProjectCreateRequest(
169-
name=project_name,
170-
path=project_path,
171-
set_default=False,
172-
)
173-
174-
response = await make_api_request(
175-
method="POST",
176-
url=f"{host_url}/proxy/projects/projects",
177-
headers={"Content-Type": "application/json"},
178-
json_data=project_data.model_dump(),
179-
)
180-
181-
return CloudProjectCreateResponse.model_validate(response.json())
182-
except Exception as e:
183-
raise BisyncError(f"Failed to create cloud project '{project_name}': {e}") from e
184-
185-
186133
def get_bisync_state_path(tenant_id: str) -> Path:
187134
"""Get path to bisync state directory."""
188135
return Path.home() / ".basic-memory" / "bisync-state" / tenant_id
Lines changed: 100 additions & 0 deletions

0 commit comments

Comments
 (0)