@weirdfingers/baseboards 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weirdfingers/baseboards",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "One-command launcher for the Boards image generation application",
5
5
  "type": "module",
6
6
  "bin": {
@@ -3,7 +3,7 @@ Boards Backend SDK
3
3
  Open-source creative toolkit for AI-generated content
4
4
  """
5
5
 
6
- __version__ = "0.4.0"
6
+ __version__ = "0.4.1"
7
7
 
8
8
  from .config import settings
9
9
 
@@ -56,6 +56,10 @@ class Settings(BaseSettings):
56
56
  # Frontend Integration
57
57
  frontend_base_url: str | None = None
58
58
 
59
+ # Internal API URL (for Docker environments where worker needs to reach API)
60
+ # This allows workers to reach the API using Docker internal networking
61
+ internal_api_url: str | None = None
62
+
59
63
  # Job Queue Settings
60
64
  job_queue_name: str = "boards-jobs"
61
65
  job_timeout: int = 3600 # 1 hour default timeout
@@ -93,6 +97,17 @@ class Settings(BaseSettings):
93
97
  # Global settings instance
94
98
  settings = Settings()
95
99
 
100
+ # Debug: Log settings initialization (only in debug mode)
101
+ if settings.debug:
102
+ from .logging import get_logger
103
+
104
+ _logger = get_logger(__name__)
105
+ _logger.debug(
106
+ "Settings initialized",
107
+ internal_api_url=settings.internal_api_url,
108
+ environment=settings.environment,
109
+ )
110
+
96
111
 
97
112
  def initialize_generator_api_keys() -> None:
98
113
  """
@@ -24,6 +24,55 @@ from .artifacts import (
24
24
  logger = get_logger(__name__)
25
25
 
26
26
 
27
+ def _rewrite_storage_url(storage_url: str) -> str:
28
+ """
29
+ Rewrite storage URL for Docker internal networking.
30
+
31
+ Similar to the Next.js imageLoader, this rewrites public API URLs
32
+ to internal Docker network URLs when running in containers.
33
+
34
+ Args:
35
+ storage_url: The original storage URL
36
+
37
+ Returns:
38
+ str: Rewritten URL if internal_api_url is configured, otherwise original URL
39
+ """
40
+ from ..config import settings
41
+
42
+ logger.debug(
43
+ "Checking URL rewriting configuration",
44
+ internal_api_url=settings.internal_api_url,
45
+ storage_url=storage_url[:100] if storage_url else None,
46
+ )
47
+
48
+ if not settings.internal_api_url:
49
+ logger.debug("No internal_api_url configured, skipping URL rewrite")
50
+ return storage_url
51
+
52
+ # Common patterns to replace (localhost and 127.0.0.1 with various ports)
53
+ # In Docker, the public URL is typically http://localhost:8800 or http://localhost:8088
54
+ # We need to replace it with the internal URL (http://api:8800)
55
+ replacements = [
56
+ ("http://localhost:8800", settings.internal_api_url),
57
+ ("http://127.0.0.1:8800", settings.internal_api_url),
58
+ ("http://localhost:8088", settings.internal_api_url),
59
+ ("http://127.0.0.1:8088", settings.internal_api_url),
60
+ ]
61
+
62
+ rewritten_url = storage_url
63
+ for public_pattern, internal_url in replacements:
64
+ if public_pattern in storage_url:
65
+ rewritten_url = storage_url.replace(public_pattern, internal_url)
66
+ logger.info(
67
+ "Rewrote storage URL for internal Docker networking",
68
+ original_url=storage_url,
69
+ rewritten_url=rewritten_url,
70
+ )
71
+ break
72
+
73
+ return rewritten_url
74
+
75
+
27
76
  async def resolve_artifact(
28
77
  artifact: AudioArtifact | VideoArtifact | ImageArtifact | LoRArtifact,
29
78
  ) -> str:
@@ -97,9 +146,17 @@ async def download_artifact_to_temp(
97
146
  os.chmod(temp_path, 0o600)
98
147
 
99
148
  try:
149
+ # Rewrite URL for Docker internal networking
150
+ download_url = _rewrite_storage_url(artifact.storage_url)
151
+
100
152
  # Stream the download to avoid loading large files into memory
101
153
  async with httpx.AsyncClient(timeout=300.0) as client:
102
- async with client.stream("GET", artifact.storage_url) as response:
154
+ logger.info(
155
+ "Attempting to download artifact",
156
+ original_url=artifact.storage_url,
157
+ download_url=download_url,
158
+ )
159
+ async with client.stream("GET", download_url) as response:
103
160
  response.raise_for_status()
104
161
 
105
162
  # Close the file descriptor returned by mkstemp and use aiofiles
@@ -5,7 +5,6 @@ services:
5
5
  api:
6
6
  volumes:
7
7
  - ./api:/app
8
- - ./data/storage:/app/data/storage
9
8
  environment:
10
9
  - PYTHONUNBUFFERED=1
11
10
  command:
@@ -24,9 +23,9 @@ services:
24
23
  worker:
25
24
  volumes:
26
25
  - ./api:/app
27
- - ./data/storage:/app/data/storage
28
26
  environment:
29
27
  - PYTHONUNBUFFERED=1
28
+ - BOARDS_INTERNAL_API_URL=http://api:8800
30
29
 
31
30
  web:
32
31
  command: sh -c "pnpm install && pnpm dev"
@@ -34,6 +34,8 @@ services:
34
34
  env_file:
35
35
  - docker/.env
36
36
  - api/.env
37
+ volumes:
38
+ - ./data/storage:/app/data/storage
37
39
  depends_on:
38
40
  db:
39
41
  condition: service_healthy
@@ -67,6 +69,10 @@ services:
67
69
  env_file:
68
70
  - docker/.env
69
71
  - api/.env
72
+ volumes:
73
+ - ./data/storage:/app/data/storage
74
+ environment:
75
+ - BOARDS_INTERNAL_API_URL=http://api:8800
70
76
  depends_on:
71
77
  db:
72
78
  condition: service_healthy
@@ -14,7 +14,7 @@
14
14
  "@radix-ui/react-navigation-menu": "^1.2.14",
15
15
  "@radix-ui/react-slot": "^1.2.3",
16
16
  "@tailwindcss/postcss": "^4.1.13",
17
- "@weirdfingers/boards": "^0.4.0",
17
+ "@weirdfingers/boards": "^0.4.1",
18
18
  "class-variance-authority": "^0.7.1",
19
19
  "clsx": "^2.0.0",
20
20
  "graphql": "^16.11.0",