Lisa Dunlap commited on
Commit
b369b7e
Β·
1 Parent(s): 6dd2290

fixed margins

Browse files
app.py CHANGED
@@ -1,39 +1,10 @@
1
  import os
2
- from pathlib import Path
3
 
4
  from lmmvibes.vis_gradio.app import launch_app
5
- from lmmvibes.utils.persistent_storage import (
6
- get_hf_home_dir,
7
- get_cache_dir,
8
- is_persistent_storage_available,
9
- get_storage_info
10
- )
11
 
12
  # Launch the app for Hugging Face Spaces
13
  if __name__ == "__main__":
14
- # Set up persistent storage for Hugging Face Spaces
15
- if is_persistent_storage_available():
16
- print("πŸš€ Persistent storage available - configuring for HF Spaces")
17
-
18
- # Set Hugging Face cache to persistent storage
19
- hf_home = get_hf_home_dir()
20
- os.environ.setdefault("HF_HOME", str(hf_home))
21
-
22
- # Set cache directory for other libraries
23
- cache_dir = get_cache_dir()
24
- os.environ.setdefault("TRANSFORMERS_CACHE", str(cache_dir / "transformers"))
25
- os.environ.setdefault("HF_DATASETS_CACHE", str(cache_dir / "datasets"))
26
-
27
- # Print storage info
28
- storage_info = get_storage_info()
29
- print(f"πŸ“ Data directory: {storage_info['data_dir']}")
30
- print(f"πŸ—„οΈ Cache directory: {storage_info['cache_dir']}")
31
- print(f"πŸ€— HF Home: {storage_info['hf_home']}")
32
-
33
- if storage_info['storage_paths']:
34
- print(f"πŸ’Ύ Storage: {storage_info['storage_paths']['free_gb']:.1f}GB free / {storage_info['storage_paths']['total_gb']:.1f}GB total")
35
- else:
36
- print("⚠️ Persistent storage not available - using local storage")
37
-
38
- # Launch the Gradio app
39
  launch_app(share=False, server_name="0.0.0.0", server_port=7860)
 
1
  import os
 
2
 
3
  from lmmvibes.vis_gradio.app import launch_app
 
 
 
 
 
 
4
 
5
  # Launch the app for Hugging Face Spaces
6
  if __name__ == "__main__":
7
+ # Optimize HF cache to persistent storage in Spaces
8
+ if os.path.isdir("/data"):
9
+ os.environ.setdefault("HF_HOME", "/data/.huggingface")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  launch_app(share=False, server_name="0.0.0.0", server_port=7860)
lmmvibes/utils/persistent_storage.py CHANGED
@@ -1,22 +1,14 @@
1
  """
2
  Utilities for persistent storage in Hugging Face Spaces.
3
-
4
- This module provides utilities for managing persistent storage in Hugging Face Spaces,
5
- including data directories, cache management, and file operations.
6
  """
7
  import os
8
- import shutil
9
  from pathlib import Path
10
- from typing import Optional, Union
11
- import tempfile
12
 
13
 
14
  def get_persistent_data_dir() -> Optional[Path]:
15
  """Get the persistent data directory if available.
16
 
17
- In Hugging Face Spaces, this will be `/data/app_data`.
18
- Returns None if persistent storage is not available.
19
-
20
  Returns:
21
  Path to persistent storage directory if available, None otherwise.
22
  """
@@ -30,9 +22,6 @@ def get_persistent_data_dir() -> Optional[Path]:
30
  def get_cache_dir() -> Path:
31
  """Get the appropriate cache directory (persistent if available, temp otherwise).
32
 
33
- In Hugging Face Spaces, this will be `/data/.cache`.
34
- Falls back to temp directory in local development.
35
-
36
  Returns:
37
  Path to cache directory.
38
  """
@@ -42,27 +31,10 @@ def get_cache_dir() -> Path:
42
  return cache_dir
43
  else:
44
  # Fallback to temp directory
 
45
  return Path(tempfile.gettempdir()) / "app_cache"
46
 
47
 
48
- def get_hf_home_dir() -> Path:
49
- """Get the Hugging Face home directory for model caching.
50
-
51
- In Hugging Face Spaces, this will be `/data/.huggingface`.
52
- Falls back to default ~/.cache/huggingface in local development.
53
-
54
- Returns:
55
- Path to HF home directory.
56
- """
57
- if os.path.isdir("/data"):
58
- hf_home = Path("/data/.huggingface")
59
- hf_home.mkdir(exist_ok=True)
60
- return hf_home
61
- else:
62
- # Fallback to default location
63
- return Path.home() / ".cache" / "huggingface"
64
-
65
-
66
  def save_uploaded_file(uploaded_file, filename: str) -> Optional[Path]:
67
  """Save an uploaded file to persistent storage.
68
 
@@ -79,112 +51,12 @@ def save_uploaded_file(uploaded_file, filename: str) -> Optional[Path]:
79
  save_path.parent.mkdir(parents=True, exist_ok=True)
80
 
81
  # Copy the uploaded file to persistent storage
82
- if hasattr(uploaded_file, 'name'):
83
- # Gradio file object
84
- shutil.copy2(uploaded_file.name, save_path)
85
- else:
86
- # Direct file path
87
- shutil.copy2(uploaded_file, save_path)
88
- return save_path
89
- return None
90
-
91
-
92
- def save_data_to_persistent(data: bytes, filename: str, subdirectory: str = "") -> Optional[Path]:
93
- """Save binary data to persistent storage.
94
-
95
- Args:
96
- data: Binary data to save
97
- filename: Name to save the file as
98
- subdirectory: Optional subdirectory within persistent storage
99
-
100
- Returns:
101
- Path to saved file if successful, None otherwise.
102
- """
103
- persistent_dir = get_persistent_data_dir()
104
- if persistent_dir:
105
- if subdirectory:
106
- save_dir = persistent_dir / subdirectory
107
- save_dir.mkdir(exist_ok=True)
108
- else:
109
- save_dir = persistent_dir
110
-
111
- save_path = save_dir / filename
112
- save_path.parent.mkdir(parents=True, exist_ok=True)
113
-
114
- with open(save_path, 'wb') as f:
115
- f.write(data)
116
  return save_path
117
  return None
118
 
119
 
120
- def load_data_from_persistent(filename: str, subdirectory: str = "") -> Optional[bytes]:
121
- """Load binary data from persistent storage.
122
-
123
- Args:
124
- filename: Name of the file to load
125
- subdirectory: Optional subdirectory within persistent storage
126
-
127
- Returns:
128
- Binary data if successful, None otherwise.
129
- """
130
- persistent_dir = get_persistent_data_dir()
131
- if persistent_dir:
132
- if subdirectory:
133
- load_path = persistent_dir / subdirectory / filename
134
- else:
135
- load_path = persistent_dir / filename
136
-
137
- if load_path.exists():
138
- with open(load_path, 'rb') as f:
139
- return f.read()
140
- return None
141
-
142
-
143
- def list_persistent_files(subdirectory: str = "", pattern: str = "*") -> list[Path]:
144
- """List files in persistent storage.
145
-
146
- Args:
147
- subdirectory: Optional subdirectory within persistent storage
148
- pattern: Glob pattern to match files (e.g., "*.json", "data_*")
149
-
150
- Returns:
151
- List of Path objects for matching files.
152
- """
153
- persistent_dir = get_persistent_data_dir()
154
- if persistent_dir:
155
- if subdirectory:
156
- search_dir = persistent_dir / subdirectory
157
- else:
158
- search_dir = persistent_dir
159
-
160
- if search_dir.exists():
161
- return list(search_dir.glob(pattern))
162
- return []
163
-
164
-
165
- def delete_persistent_file(filename: str, subdirectory: str = "") -> bool:
166
- """Delete a file from persistent storage.
167
-
168
- Args:
169
- filename: Name of the file to delete
170
- subdirectory: Optional subdirectory within persistent storage
171
-
172
- Returns:
173
- True if successful, False otherwise.
174
- """
175
- persistent_dir = get_persistent_data_dir()
176
- if persistent_dir:
177
- if subdirectory:
178
- file_path = persistent_dir / subdirectory / filename
179
- else:
180
- file_path = persistent_dir / filename
181
-
182
- if file_path.exists():
183
- file_path.unlink()
184
- return True
185
- return False
186
-
187
-
188
  def is_persistent_storage_available() -> bool:
189
  """Check if persistent storage is available.
190
 
@@ -205,50 +77,4 @@ def get_persistent_results_dir() -> Optional[Path]:
205
  results_dir = persistent_dir / "results"
206
  results_dir.mkdir(exist_ok=True)
207
  return results_dir
208
- return None
209
-
210
-
211
- def get_persistent_logs_dir() -> Optional[Path]:
212
- """Get the persistent logs directory for storing application logs.
213
-
214
- Returns:
215
- Path to persistent logs directory if available, None otherwise.
216
- """
217
- persistent_dir = get_persistent_data_dir()
218
- if persistent_dir:
219
- logs_dir = persistent_dir / "logs"
220
- logs_dir.mkdir(exist_ok=True)
221
- return logs_dir
222
- return None
223
-
224
-
225
- def get_storage_info() -> dict:
226
- """Get information about available storage.
227
-
228
- Returns:
229
- Dictionary with storage information.
230
- """
231
- info = {
232
- "persistent_available": is_persistent_storage_available(),
233
- "data_dir": None,
234
- "cache_dir": str(get_cache_dir()),
235
- "hf_home": str(get_hf_home_dir()),
236
- "storage_paths": {}
237
- }
238
-
239
- if info["persistent_available"]:
240
- data_dir = get_persistent_data_dir()
241
- info["data_dir"] = str(data_dir)
242
-
243
- # Check available space
244
- try:
245
- total, used, free = shutil.disk_usage(data_dir)
246
- info["storage_paths"] = {
247
- "total_gb": round(total / (1024**3), 2),
248
- "used_gb": round(used / (1024**3), 2),
249
- "free_gb": round(free / (1024**3), 2)
250
- }
251
- except OSError:
252
- pass
253
-
254
- return info
 
1
  """
2
  Utilities for persistent storage in Hugging Face Spaces.
 
 
 
3
  """
4
  import os
 
5
  from pathlib import Path
6
+ from typing import Optional
 
7
 
8
 
9
  def get_persistent_data_dir() -> Optional[Path]:
10
  """Get the persistent data directory if available.
11
 
 
 
 
12
  Returns:
13
  Path to persistent storage directory if available, None otherwise.
14
  """
 
22
  def get_cache_dir() -> Path:
23
  """Get the appropriate cache directory (persistent if available, temp otherwise).
24
 
 
 
 
25
  Returns:
26
  Path to cache directory.
27
  """
 
31
  return cache_dir
32
  else:
33
  # Fallback to temp directory
34
+ import tempfile
35
  return Path(tempfile.gettempdir()) / "app_cache"
36
 
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  def save_uploaded_file(uploaded_file, filename: str) -> Optional[Path]:
39
  """Save an uploaded file to persistent storage.
40
 
 
51
  save_path.parent.mkdir(parents=True, exist_ok=True)
52
 
53
  # Copy the uploaded file to persistent storage
54
+ import shutil
55
+ shutil.copy2(uploaded_file, save_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  return save_path
57
  return None
58
 
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  def is_persistent_storage_available() -> bool:
61
  """Check if persistent storage is available.
62
 
 
77
  results_dir = persistent_dir / "results"
78
  results_dir.mkdir(exist_ok=True)
79
  return results_dir
80
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lmmvibes/utils/persistent_storage_example.py DELETED
@@ -1,252 +0,0 @@
1
- """
2
- Example usage of persistent storage utilities for Hugging Face Spaces.
3
-
4
- This file demonstrates how to use the persistent storage utilities
5
- for saving and loading data in Hugging Face Spaces.
6
- """
7
-
8
- import json
9
- import pandas as pd
10
- from pathlib import Path
11
-
12
- from .persistent_storage import (
13
- get_persistent_data_dir,
14
- get_cache_dir,
15
- get_hf_home_dir,
16
- save_data_to_persistent,
17
- load_data_from_persistent,
18
- save_uploaded_file,
19
- list_persistent_files,
20
- delete_persistent_file,
21
- is_persistent_storage_available,
22
- get_storage_info
23
- )
24
-
25
-
26
- def example_save_results(results_data: dict, experiment_name: str):
27
- """Example: Save pipeline results to persistent storage.
28
-
29
- Args:
30
- results_data: Dictionary containing pipeline results
31
- experiment_name: Name of the experiment
32
- """
33
- if not is_persistent_storage_available():
34
- print("⚠️ Persistent storage not available - skipping save")
35
- return None
36
-
37
- # Save results as JSON
38
- results_json = json.dumps(results_data, indent=2)
39
- results_bytes = results_json.encode('utf-8')
40
-
41
- filename = f"{experiment_name}_results.json"
42
- saved_path = save_data_to_persistent(
43
- data=results_bytes,
44
- filename=filename,
45
- subdirectory="experiments"
46
- )
47
-
48
- if saved_path:
49
- print(f"βœ… Saved results to: {saved_path}")
50
- return saved_path
51
- else:
52
- print("❌ Failed to save results")
53
- return None
54
-
55
-
56
- def example_load_results(experiment_name: str):
57
- """Example: Load pipeline results from persistent storage.
58
-
59
- Args:
60
- experiment_name: Name of the experiment
61
-
62
- Returns:
63
- Dictionary containing the loaded results or None
64
- """
65
- filename = f"{experiment_name}_results.json"
66
- results_bytes = load_data_from_persistent(
67
- filename=filename,
68
- subdirectory="experiments"
69
- )
70
-
71
- if results_bytes:
72
- results_data = json.loads(results_bytes.decode('utf-8'))
73
- print(f"βœ… Loaded results from: {filename}")
74
- return results_data
75
- else:
76
- print(f"❌ No results found for: {filename}")
77
- return None
78
-
79
-
80
- def example_save_dataframe(df: pd.DataFrame, filename: str):
81
- """Example: Save a pandas DataFrame to persistent storage.
82
-
83
- Args:
84
- df: DataFrame to save
85
- filename: Name of the file (with .parquet extension)
86
- """
87
- if not is_persistent_storage_available():
88
- print("⚠️ Persistent storage not available - skipping save")
89
- return None
90
-
91
- # Convert DataFrame to parquet bytes
92
- try:
93
- parquet_bytes = df.to_parquet()
94
- saved_path = save_data_to_persistent(
95
- data=parquet_bytes,
96
- filename=filename,
97
- subdirectory="dataframes"
98
- )
99
-
100
- if saved_path:
101
- print(f"βœ… Saved DataFrame to: {saved_path}")
102
- return saved_path
103
- else:
104
- print("❌ Failed to save DataFrame")
105
- return None
106
- except Exception as e:
107
- print(f"❌ Error saving DataFrame: {e}")
108
- return None
109
-
110
-
111
- def example_list_saved_files():
112
- """Example: List all files saved in persistent storage."""
113
- if not is_persistent_storage_available():
114
- print("⚠️ Persistent storage not available")
115
- return []
116
-
117
- print("πŸ“ Files in persistent storage:")
118
-
119
- # List all files
120
- all_files = list_persistent_files()
121
- if all_files:
122
- for file in all_files:
123
- print(f" - {file.name}")
124
- else:
125
- print(" No files found")
126
-
127
- # List experiment files
128
- experiment_files = list_persistent_files(subdirectory="experiments", pattern="*.json")
129
- if experiment_files:
130
- print("\nπŸ”¬ Experiment files:")
131
- for file in experiment_files:
132
- print(f" - {file.name}")
133
-
134
- # List dataframe files
135
- dataframe_files = list_persistent_files(subdirectory="dataframes", pattern="*.parquet")
136
- if dataframe_files:
137
- print("\nπŸ“Š DataFrame files:")
138
- for file in dataframe_files:
139
- print(f" - {file.name}")
140
-
141
- return all_files
142
-
143
-
144
- def example_storage_cleanup(days_old: int = 30):
145
- """Example: Clean up old files from persistent storage.
146
-
147
- Args:
148
- days_old: Delete files older than this many days
149
- """
150
- if not is_persistent_storage_available():
151
- print("⚠️ Persistent storage not available")
152
- return
153
-
154
- import time
155
- from datetime import datetime, timedelta
156
-
157
- cutoff_time = time.time() - (days_old * 24 * 60 * 60)
158
-
159
- print(f"🧹 Cleaning up files older than {days_old} days...")
160
-
161
- # List all files and check their modification time
162
- all_files = list_persistent_files()
163
- deleted_count = 0
164
-
165
- for file in all_files:
166
- if file.stat().st_mtime < cutoff_time:
167
- if delete_persistent_file(file.name):
168
- print(f"πŸ—‘οΈ Deleted: {file.name}")
169
- deleted_count += 1
170
-
171
- print(f"βœ… Cleanup complete - deleted {deleted_count} files")
172
-
173
-
174
- def example_storage_info():
175
- """Example: Display information about persistent storage."""
176
- info = get_storage_info()
177
-
178
- print("πŸ“Š Persistent Storage Information:")
179
- print(f" Available: {info['persistent_available']}")
180
-
181
- if info['persistent_available']:
182
- print(f" Data directory: {info['data_dir']}")
183
- print(f" Cache directory: {info['cache_dir']}")
184
- print(f" HF Home: {info['hf_home']}")
185
-
186
- if info['storage_paths']:
187
- print(f" Total storage: {info['storage_paths']['total_gb']:.1f}GB")
188
- print(f" Used storage: {info['storage_paths']['used_gb']:.1f}GB")
189
- print(f" Free storage: {info['storage_paths']['free_gb']:.1f}GB")
190
-
191
- # Calculate usage percentage
192
- usage_pct = (info['storage_paths']['used_gb'] / info['storage_paths']['total_gb']) * 100
193
- print(f" Usage: {usage_pct:.1f}%")
194
-
195
-
196
- # Example usage in a Gradio app
197
- def example_gradio_integration():
198
- """Example: How to integrate persistent storage with Gradio."""
199
-
200
- def save_uploaded_data(uploaded_file):
201
- """Save a file uploaded through Gradio."""
202
- if uploaded_file:
203
- saved_path = save_uploaded_file(uploaded_file, "user_upload.txt")
204
- if saved_path:
205
- return f"βœ… File saved to persistent storage: {saved_path.name}"
206
- else:
207
- return "❌ Failed to save file - persistent storage not available"
208
- return "⚠️ No file uploaded"
209
-
210
- def load_user_data():
211
- """Load previously uploaded data."""
212
- data_bytes = load_data_from_persistent("user_upload.txt")
213
- if data_bytes:
214
- return data_bytes.decode('utf-8')
215
- return "No data found"
216
-
217
- # This would be used in a Gradio interface like:
218
- # import gradio as gr
219
- #
220
- # with gr.Blocks() as demo:
221
- # file_input = gr.File(label="Upload file")
222
- # upload_btn = gr.Button("Save to persistent storage")
223
- # download_btn = gr.Button("Load from persistent storage")
224
- #
225
- # upload_btn.click(save_uploaded_data, inputs=[file_input])
226
- # download_btn.click(load_user_data)
227
-
228
-
229
- if __name__ == "__main__":
230
- # Run examples
231
- print("πŸ” Persistent Storage Examples")
232
- print("=" * 40)
233
-
234
- example_storage_info()
235
- print()
236
-
237
- example_list_saved_files()
238
- print()
239
-
240
- # Example: Save some test data
241
- test_data = {"experiment": "test", "results": [1, 2, 3], "timestamp": "2024-01-01"}
242
- example_save_results(test_data, "test_experiment")
243
- print()
244
-
245
- # Example: Load the test data
246
- loaded_data = example_load_results("test_experiment")
247
- if loaded_data:
248
- print(f"πŸ“Š Loaded data: {loaded_data}")
249
- print()
250
-
251
- # Example: List files again
252
- example_list_saved_files()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lmmvibes/vis_gradio/app.py CHANGED
@@ -87,17 +87,22 @@ def update_top_n_slider_maximum():
87
  def create_app() -> gr.Blocks:
88
  """Create the main Gradio application."""
89
 
90
- # Custom CSS for reduced margins and better sidebar layout
91
  custom_css = """
 
 
 
 
 
92
  .main-container {
93
  max-width: 100% !important;
94
  margin: 0 !important;
95
- padding: 0 !important;
96
  }
97
  .gradio-container {
98
  max-width: 100% !important;
99
  margin: 0 !important;
100
- padding: 0 10px !important;
101
  }
102
  .tabs {
103
  margin: 0 !important;
@@ -109,15 +114,74 @@ def create_app() -> gr.Blocks:
109
  }
110
  .tab-content {
111
  margin: 0 !important;
112
- padding: 10px !important;
113
  }
114
  .sidebar {
115
  border-right: 1px solid #e0e0e0;
116
  background-color: #f8f9fa;
117
- padding: 15px !important;
118
  }
119
  .main-content {
120
- padding: 10px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  }
122
  """
123
 
 
87
  def create_app() -> gr.Blocks:
88
  """Create the main Gradio application."""
89
 
90
+ # Custom CSS for minimal margins and better sidebar layout
91
  custom_css = """
92
+ /* Universal reset for all elements */
93
+ * {
94
+ box-sizing: border-box !important;
95
+ }
96
+
97
  .main-container {
98
  max-width: 100% !important;
99
  margin: 0 !important;
100
+ padding: 5px 0 0 8px !important;
101
  }
102
  .gradio-container {
103
  max-width: 100% !important;
104
  margin: 0 !important;
105
+ padding: 5px 0 0 8px !important;
106
  }
107
  .tabs {
108
  margin: 0 !important;
 
114
  }
115
  .tab-content {
116
  margin: 0 !important;
117
+ padding: 5px 0 2px 8px !important;
118
  }
119
  .sidebar {
120
  border-right: 1px solid #e0e0e0;
121
  background-color: #f8f9fa;
122
+ padding: 8px !important;
123
  }
124
  .main-content {
125
+ padding: 5px 0 2px 8px !important;
126
+ }
127
+ /* Additional selectors to override Gradio's default margins */
128
+ .block {
129
+ margin: 0 !important;
130
+ padding: 2px 0 2px 8px !important;
131
+ }
132
+ .form {
133
+ margin: 0 !important;
134
+ padding: 0 !important;
135
+ }
136
+ body {
137
+ margin: 0 !important;
138
+ padding: 5px 0 0 8px !important;
139
+ }
140
+ .app {
141
+ margin: 0 !important;
142
+ padding: 5px 0 0 8px !important;
143
+ }
144
+ /* Target specific Gradio container classes */
145
+ .gradio-row {
146
+ margin: 0 !important;
147
+ padding: 0 !important;
148
+ }
149
+ .gradio-column {
150
+ margin: 0 !important;
151
+ padding: 0 0 0 8px !important;
152
+ }
153
+ /* Override any container padding */
154
+ .container {
155
+ padding: 5px 0 0 8px !important;
156
+ margin: 0 !important;
157
+ }
158
+ /* Target the root element */
159
+ #root {
160
+ padding: 5px 0 0 8px !important;
161
+ margin: 0 !important;
162
+ }
163
+ /* Make sure no right padding on wrapper elements */
164
+ .wrap {
165
+ padding: 0 !important;
166
+ margin: 0 !important;
167
+ }
168
+ /* Aggressive targeting of common Gradio elements */
169
+ div[class*="gradio"] {
170
+ padding-right: 0 !important;
171
+ margin-right: 0 !important;
172
+ }
173
+ /* Target any div that might have padding */
174
+ .gradio-blocks > div,
175
+ .gradio-blocks div[style*="padding"] {
176
+ padding-right: 0 !important;
177
+ margin-right: 0 !important;
178
+ }
179
+ /* Ensure content fills width */
180
+ .gradio-blocks {
181
+ width: 100% !important;
182
+ max-width: 100% !important;
183
+ padding: 5px 0 0 8px !important;
184
+ margin: 0 !important;
185
  }
186
  """
187