remdb 0.3.0__py3-none-any.whl

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.

Potentially problematic release.


This version of remdb might be problematic. Click here for more details.

Files changed (187) hide show
  1. rem/__init__.py +2 -0
  2. rem/agentic/README.md +650 -0
  3. rem/agentic/__init__.py +39 -0
  4. rem/agentic/agents/README.md +155 -0
  5. rem/agentic/agents/__init__.py +8 -0
  6. rem/agentic/context.py +148 -0
  7. rem/agentic/context_builder.py +329 -0
  8. rem/agentic/mcp/__init__.py +0 -0
  9. rem/agentic/mcp/tool_wrapper.py +107 -0
  10. rem/agentic/otel/__init__.py +5 -0
  11. rem/agentic/otel/setup.py +151 -0
  12. rem/agentic/providers/phoenix.py +674 -0
  13. rem/agentic/providers/pydantic_ai.py +572 -0
  14. rem/agentic/query.py +117 -0
  15. rem/agentic/query_helper.py +89 -0
  16. rem/agentic/schema.py +396 -0
  17. rem/agentic/serialization.py +245 -0
  18. rem/agentic/tools/__init__.py +5 -0
  19. rem/agentic/tools/rem_tools.py +231 -0
  20. rem/api/README.md +420 -0
  21. rem/api/main.py +324 -0
  22. rem/api/mcp_router/prompts.py +182 -0
  23. rem/api/mcp_router/resources.py +536 -0
  24. rem/api/mcp_router/server.py +213 -0
  25. rem/api/mcp_router/tools.py +584 -0
  26. rem/api/routers/auth.py +229 -0
  27. rem/api/routers/chat/__init__.py +5 -0
  28. rem/api/routers/chat/completions.py +281 -0
  29. rem/api/routers/chat/json_utils.py +76 -0
  30. rem/api/routers/chat/models.py +124 -0
  31. rem/api/routers/chat/streaming.py +185 -0
  32. rem/auth/README.md +258 -0
  33. rem/auth/__init__.py +26 -0
  34. rem/auth/middleware.py +100 -0
  35. rem/auth/providers/__init__.py +13 -0
  36. rem/auth/providers/base.py +376 -0
  37. rem/auth/providers/google.py +163 -0
  38. rem/auth/providers/microsoft.py +237 -0
  39. rem/cli/README.md +455 -0
  40. rem/cli/__init__.py +8 -0
  41. rem/cli/commands/README.md +126 -0
  42. rem/cli/commands/__init__.py +3 -0
  43. rem/cli/commands/ask.py +566 -0
  44. rem/cli/commands/configure.py +497 -0
  45. rem/cli/commands/db.py +493 -0
  46. rem/cli/commands/dreaming.py +324 -0
  47. rem/cli/commands/experiments.py +1302 -0
  48. rem/cli/commands/mcp.py +66 -0
  49. rem/cli/commands/process.py +245 -0
  50. rem/cli/commands/schema.py +183 -0
  51. rem/cli/commands/serve.py +106 -0
  52. rem/cli/dreaming.py +363 -0
  53. rem/cli/main.py +96 -0
  54. rem/config.py +237 -0
  55. rem/mcp_server.py +41 -0
  56. rem/models/core/__init__.py +49 -0
  57. rem/models/core/core_model.py +64 -0
  58. rem/models/core/engram.py +333 -0
  59. rem/models/core/experiment.py +628 -0
  60. rem/models/core/inline_edge.py +132 -0
  61. rem/models/core/rem_query.py +243 -0
  62. rem/models/entities/__init__.py +43 -0
  63. rem/models/entities/file.py +57 -0
  64. rem/models/entities/image_resource.py +88 -0
  65. rem/models/entities/message.py +35 -0
  66. rem/models/entities/moment.py +123 -0
  67. rem/models/entities/ontology.py +191 -0
  68. rem/models/entities/ontology_config.py +131 -0
  69. rem/models/entities/resource.py +95 -0
  70. rem/models/entities/schema.py +87 -0
  71. rem/models/entities/user.py +85 -0
  72. rem/py.typed +0 -0
  73. rem/schemas/README.md +507 -0
  74. rem/schemas/__init__.py +6 -0
  75. rem/schemas/agents/README.md +92 -0
  76. rem/schemas/agents/core/moment-builder.yaml +178 -0
  77. rem/schemas/agents/core/rem-query-agent.yaml +226 -0
  78. rem/schemas/agents/core/resource-affinity-assessor.yaml +99 -0
  79. rem/schemas/agents/core/simple-assistant.yaml +19 -0
  80. rem/schemas/agents/core/user-profile-builder.yaml +163 -0
  81. rem/schemas/agents/examples/contract-analyzer.yaml +317 -0
  82. rem/schemas/agents/examples/contract-extractor.yaml +134 -0
  83. rem/schemas/agents/examples/cv-parser.yaml +263 -0
  84. rem/schemas/agents/examples/hello-world.yaml +37 -0
  85. rem/schemas/agents/examples/query.yaml +54 -0
  86. rem/schemas/agents/examples/simple.yaml +21 -0
  87. rem/schemas/agents/examples/test.yaml +29 -0
  88. rem/schemas/agents/rem.yaml +128 -0
  89. rem/schemas/evaluators/hello-world/default.yaml +77 -0
  90. rem/schemas/evaluators/rem/faithfulness.yaml +219 -0
  91. rem/schemas/evaluators/rem/lookup-correctness.yaml +182 -0
  92. rem/schemas/evaluators/rem/retrieval-precision.yaml +199 -0
  93. rem/schemas/evaluators/rem/retrieval-recall.yaml +211 -0
  94. rem/schemas/evaluators/rem/search-correctness.yaml +192 -0
  95. rem/services/__init__.py +16 -0
  96. rem/services/audio/INTEGRATION.md +308 -0
  97. rem/services/audio/README.md +376 -0
  98. rem/services/audio/__init__.py +15 -0
  99. rem/services/audio/chunker.py +354 -0
  100. rem/services/audio/transcriber.py +259 -0
  101. rem/services/content/README.md +1269 -0
  102. rem/services/content/__init__.py +5 -0
  103. rem/services/content/providers.py +806 -0
  104. rem/services/content/service.py +676 -0
  105. rem/services/dreaming/README.md +230 -0
  106. rem/services/dreaming/__init__.py +53 -0
  107. rem/services/dreaming/affinity_service.py +336 -0
  108. rem/services/dreaming/moment_service.py +264 -0
  109. rem/services/dreaming/ontology_service.py +54 -0
  110. rem/services/dreaming/user_model_service.py +297 -0
  111. rem/services/dreaming/utils.py +39 -0
  112. rem/services/embeddings/__init__.py +11 -0
  113. rem/services/embeddings/api.py +120 -0
  114. rem/services/embeddings/worker.py +421 -0
  115. rem/services/fs/README.md +662 -0
  116. rem/services/fs/__init__.py +62 -0
  117. rem/services/fs/examples.py +206 -0
  118. rem/services/fs/examples_paths.py +204 -0
  119. rem/services/fs/git_provider.py +935 -0
  120. rem/services/fs/local_provider.py +760 -0
  121. rem/services/fs/parsing-hooks-examples.md +172 -0
  122. rem/services/fs/paths.py +276 -0
  123. rem/services/fs/provider.py +460 -0
  124. rem/services/fs/s3_provider.py +1042 -0
  125. rem/services/fs/service.py +186 -0
  126. rem/services/git/README.md +1075 -0
  127. rem/services/git/__init__.py +17 -0
  128. rem/services/git/service.py +469 -0
  129. rem/services/phoenix/EXPERIMENT_DESIGN.md +1146 -0
  130. rem/services/phoenix/README.md +453 -0
  131. rem/services/phoenix/__init__.py +46 -0
  132. rem/services/phoenix/client.py +686 -0
  133. rem/services/phoenix/config.py +88 -0
  134. rem/services/phoenix/prompt_labels.py +477 -0
  135. rem/services/postgres/README.md +575 -0
  136. rem/services/postgres/__init__.py +23 -0
  137. rem/services/postgres/migration_service.py +427 -0
  138. rem/services/postgres/pydantic_to_sqlalchemy.py +232 -0
  139. rem/services/postgres/register_type.py +352 -0
  140. rem/services/postgres/repository.py +337 -0
  141. rem/services/postgres/schema_generator.py +379 -0
  142. rem/services/postgres/service.py +802 -0
  143. rem/services/postgres/sql_builder.py +354 -0
  144. rem/services/rem/README.md +304 -0
  145. rem/services/rem/__init__.py +23 -0
  146. rem/services/rem/exceptions.py +71 -0
  147. rem/services/rem/executor.py +293 -0
  148. rem/services/rem/parser.py +145 -0
  149. rem/services/rem/queries.py +196 -0
  150. rem/services/rem/query.py +371 -0
  151. rem/services/rem/service.py +527 -0
  152. rem/services/session/README.md +374 -0
  153. rem/services/session/__init__.py +6 -0
  154. rem/services/session/compression.py +360 -0
  155. rem/services/session/reload.py +77 -0
  156. rem/settings.py +1235 -0
  157. rem/sql/002_install_models.sql +1068 -0
  158. rem/sql/background_indexes.sql +42 -0
  159. rem/sql/install_models.sql +1038 -0
  160. rem/sql/migrations/001_install.sql +503 -0
  161. rem/sql/migrations/002_install_models.sql +1202 -0
  162. rem/utils/AGENTIC_CHUNKING.md +597 -0
  163. rem/utils/README.md +583 -0
  164. rem/utils/__init__.py +43 -0
  165. rem/utils/agentic_chunking.py +622 -0
  166. rem/utils/batch_ops.py +343 -0
  167. rem/utils/chunking.py +108 -0
  168. rem/utils/clip_embeddings.py +276 -0
  169. rem/utils/dict_utils.py +98 -0
  170. rem/utils/embeddings.py +423 -0
  171. rem/utils/examples/embeddings_example.py +305 -0
  172. rem/utils/examples/sql_types_example.py +202 -0
  173. rem/utils/markdown.py +16 -0
  174. rem/utils/model_helpers.py +236 -0
  175. rem/utils/schema_loader.py +336 -0
  176. rem/utils/sql_types.py +348 -0
  177. rem/utils/user_id.py +81 -0
  178. rem/utils/vision.py +330 -0
  179. rem/workers/README.md +506 -0
  180. rem/workers/__init__.py +5 -0
  181. rem/workers/dreaming.py +502 -0
  182. rem/workers/engram_processor.py +312 -0
  183. rem/workers/sqs_file_processor.py +193 -0
  184. remdb-0.3.0.dist-info/METADATA +1455 -0
  185. remdb-0.3.0.dist-info/RECORD +187 -0
  186. remdb-0.3.0.dist-info/WHEEL +4 -0
  187. remdb-0.3.0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,62 @@
1
+ """
2
+ File system abstraction layer for REM.
3
+
4
+ Provides unified interface for:
5
+ - S3 operations (via S3Provider)
6
+ - Local file operations (via LocalProvider)
7
+ - Columnar data with Polars
8
+ - Multiple file formats (yaml, json, csv, text, pdf, images, etc.)
9
+ - Standardized path naming conventions
10
+
11
+ Usage:
12
+ from rem.services.fs import FS, generate_presigned_url, get_uploads_path
13
+
14
+ fs = FS()
15
+
16
+ # Read from S3 or local
17
+ data = fs.read("s3://bucket/file.csv")
18
+ data = fs.read("/local/path/file.parquet")
19
+
20
+ # Write to S3 or local
21
+ fs.write("s3://bucket/output.json", {"key": "value"})
22
+
23
+ # Generate presigned URLs for S3
24
+ url = generate_presigned_url("s3://bucket/file.pdf", expiry=3600)
25
+
26
+ # Use standardized paths
27
+ upload_dir = get_uploads_path(user_id="user-123")
28
+ fs.write(f"{upload_dir}/data.json", {"key": "value"})
29
+ """
30
+
31
+ from rem.services.fs.provider import FS
32
+ from rem.services.fs.service import FileSystemService
33
+ from rem.services.fs.s3_provider import S3Provider, generate_presigned_url
34
+ from rem.services.fs.local_provider import LocalProvider
35
+ from rem.services.fs.paths import (
36
+ get_rem_home,
37
+ get_base_uri,
38
+ get_uploads_path,
39
+ get_versioned_path,
40
+ get_user_path,
41
+ get_temp_path,
42
+ ensure_dir_exists,
43
+ join_path,
44
+ )
45
+
46
+ __all__ = [
47
+ # Core providers
48
+ "FS",
49
+ "FileSystemService",
50
+ "S3Provider",
51
+ "LocalProvider",
52
+ "generate_presigned_url",
53
+ # Path conventions
54
+ "get_rem_home",
55
+ "get_base_uri",
56
+ "get_uploads_path",
57
+ "get_versioned_path",
58
+ "get_user_path",
59
+ "get_temp_path",
60
+ "ensure_dir_exists",
61
+ "join_path",
62
+ ]
@@ -0,0 +1,206 @@
1
+ """
2
+ Example usage of the REM file system service.
3
+
4
+ Run these examples to test the fs service functionality.
5
+ """
6
+
7
+ from rem.services.fs import FS, generate_presigned_url
8
+
9
+
10
+ def example_basic_operations():
11
+ """Basic read/write operations."""
12
+ fs = FS()
13
+
14
+ # Write and read JSON
15
+ data = {"name": "rem", "version": "0.1.0", "features": ["s3", "local", "polars"]}
16
+ fs.write("/tmp/test.json", data)
17
+ loaded = fs.read("/tmp/test.json")
18
+ print(f"JSON: {loaded}")
19
+
20
+ # Write and read YAML
21
+ config = {"database": {"host": "localhost", "port": 5432}, "cache": {"enabled": True}}
22
+ fs.write("/tmp/config.yaml", config)
23
+ loaded_config = fs.read("/tmp/config.yaml")
24
+ print(f"YAML: {loaded_config}")
25
+
26
+ # Write and read text
27
+ fs.write("/tmp/readme.md", "# Hello REM\n\nFile system abstraction.")
28
+ text = fs.read("/tmp/readme.md")
29
+ print(f"Text: {text[:50]}...")
30
+
31
+
32
+ def example_columnar_data():
33
+ """Columnar data with Polars."""
34
+ try:
35
+ import polars as pl
36
+ except ImportError:
37
+ print("Polars not installed - skipping columnar examples")
38
+ print("Install with: uv add polars")
39
+ return
40
+
41
+ fs = FS()
42
+
43
+ # Create sample dataframe
44
+ df = pl.DataFrame({
45
+ "id": [1, 2, 3, 4, 5],
46
+ "name": ["Alice", "Bob", "Carol", "Dave", "Eve"],
47
+ "score": [95.5, 87.2, 92.8, 78.3, 88.9],
48
+ })
49
+
50
+ # Write to CSV
51
+ fs.write("/tmp/data.csv", df)
52
+ csv_df = fs.read("/tmp/data.csv", use_polars=True)
53
+ print(f"CSV DataFrame:\n{csv_df}")
54
+
55
+ # Write to Parquet
56
+ fs.write("/tmp/data.parquet", df)
57
+ parquet_df = fs.read("/tmp/data.parquet")
58
+ print(f"Parquet DataFrame:\n{parquet_df}")
59
+
60
+
61
+ def example_image_operations():
62
+ """Image read/write operations."""
63
+ try:
64
+ from PIL import Image
65
+ import numpy as np
66
+ except ImportError:
67
+ print("Pillow not installed - skipping image examples")
68
+ print("Install with: uv add pillow")
69
+ return
70
+
71
+ fs = FS()
72
+
73
+ # Create sample image
74
+ img_array = np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
75
+ img = Image.fromarray(img_array)
76
+
77
+ # Write image
78
+ fs.write("/tmp/test.png", img)
79
+
80
+ # Read image
81
+ loaded_img = fs.read_image("/tmp/test.png")
82
+ print(f"Image: {loaded_img.size} {loaded_img.mode}")
83
+
84
+
85
+ def example_file_operations():
86
+ """File listing, copying, deleting."""
87
+ fs = FS()
88
+
89
+ # Create test files
90
+ fs.write("/tmp/rem_test/file1.txt", "Content 1")
91
+ fs.write("/tmp/rem_test/file2.txt", "Content 2")
92
+ fs.write("/tmp/rem_test/subdir/file3.txt", "Content 3")
93
+
94
+ # List files
95
+ files = fs.ls("/tmp/rem_test/")
96
+ print(f"Files: {files}")
97
+
98
+ # List directories
99
+ dirs = fs.ls_dirs("/tmp/rem_test/")
100
+ print(f"Directories: {dirs}")
101
+
102
+ # Copy file
103
+ fs.copy("/tmp/rem_test/file1.txt", "/tmp/rem_test/file1_copy.txt")
104
+
105
+ # Check existence
106
+ exists = fs.exists("/tmp/rem_test/file1_copy.txt")
107
+ print(f"Copy exists: {exists}")
108
+
109
+ # Delete files (with safety limit)
110
+ deleted = fs.delete("/tmp/rem_test/", limit=10)
111
+ print(f"Deleted {len(deleted)} files")
112
+
113
+
114
+ def example_s3_operations():
115
+ """S3 operations (requires configured S3 bucket)."""
116
+ fs = FS()
117
+
118
+ # NOTE: Update bucket name to your test bucket
119
+ test_bucket = "s3://rem-test-bucket"
120
+
121
+ try:
122
+ # Write to S3
123
+ data = {"timestamp": "2025-01-01T00:00:00Z", "event": "test"}
124
+ fs.write(f"{test_bucket}/test.json", data)
125
+
126
+ # Read from S3
127
+ loaded = fs.read(f"{test_bucket}/test.json")
128
+ print(f"S3 JSON: {loaded}")
129
+
130
+ # Generate presigned URL
131
+ url = generate_presigned_url(f"{test_bucket}/test.json", expiry=3600)
132
+ print(f"Presigned URL: {url[:100]}...")
133
+
134
+ # Copy from S3 to local
135
+ fs.copy(f"{test_bucket}/test.json", "/tmp/downloaded.json")
136
+ print("Downloaded from S3 to /tmp/downloaded.json")
137
+
138
+ # Upload from local to S3
139
+ fs.write("/tmp/upload.txt", "Upload test")
140
+ fs.copy("/tmp/upload.txt", f"{test_bucket}/uploaded.txt")
141
+ print("Uploaded to S3")
142
+
143
+ # List S3 files
144
+ files = fs.ls(f"{test_bucket}/")
145
+ print(f"S3 files: {files[:5]}") # First 5
146
+
147
+ except Exception as e:
148
+ print(f"S3 operations failed (bucket may not exist): {e}")
149
+ print("Configure S3 settings in .env and create test bucket")
150
+
151
+
152
+ def example_presigned_urls():
153
+ """Generate presigned URLs for S3 access."""
154
+ # Download URL
155
+ download_url = generate_presigned_url(
156
+ "s3://rem-bucket/document.pdf",
157
+ expiry=3600 # 1 hour
158
+ )
159
+ print(f"Download URL: {download_url[:100]}...")
160
+
161
+ # Upload URL
162
+ upload_url = generate_presigned_url(
163
+ "s3://rem-bucket/upload.pdf",
164
+ expiry=300, # 5 minutes
165
+ for_upload=True
166
+ )
167
+ print(f"Upload URL (PUT): {upload_url[:100]}...")
168
+
169
+
170
+ def main():
171
+ """Run all examples."""
172
+ print("=" * 60)
173
+ print("REM File System Service Examples")
174
+ print("=" * 60)
175
+
176
+ print("\n1. Basic Operations")
177
+ print("-" * 60)
178
+ example_basic_operations()
179
+
180
+ print("\n2. Columnar Data (Polars)")
181
+ print("-" * 60)
182
+ example_columnar_data()
183
+
184
+ print("\n3. Image Operations")
185
+ print("-" * 60)
186
+ example_image_operations()
187
+
188
+ print("\n4. File Operations")
189
+ print("-" * 60)
190
+ example_file_operations()
191
+
192
+ print("\n5. S3 Operations")
193
+ print("-" * 60)
194
+ example_s3_operations()
195
+
196
+ print("\n6. Presigned URLs")
197
+ print("-" * 60)
198
+ example_presigned_urls()
199
+
200
+ print("\n" + "=" * 60)
201
+ print("Examples complete!")
202
+ print("=" * 60)
203
+
204
+
205
+ if __name__ == "__main__":
206
+ main()
@@ -0,0 +1,204 @@
1
+ """
2
+ Examples demonstrating REM filesystem path conventions.
3
+
4
+ Run with:
5
+ python -m rem.services.fs.examples_paths
6
+ """
7
+
8
+ from datetime import datetime, date
9
+ from rem.services.fs import (
10
+ FS,
11
+ get_rem_home,
12
+ get_base_uri,
13
+ get_uploads_path,
14
+ get_versioned_path,
15
+ get_user_path,
16
+ get_temp_path,
17
+ ensure_dir_exists,
18
+ join_path,
19
+ )
20
+
21
+
22
+ def example_basic_paths():
23
+ """Demonstrate basic path generation."""
24
+ print("=== Basic Paths ===\n")
25
+
26
+ # REM home directory
27
+ rem_home = get_rem_home()
28
+ print(f"REM_HOME: {rem_home}")
29
+
30
+ # Base URI (auto-detects local vs S3 based on environment)
31
+ base_local = get_base_uri(use_s3=False)
32
+ print(f"Base URI (local): {base_local}")
33
+
34
+ base_s3 = get_base_uri(use_s3=True)
35
+ print(f"Base URI (S3): {base_s3}")
36
+ print()
37
+
38
+
39
+ def example_uploads_paths():
40
+ """Demonstrate uploads path generation."""
41
+ print("=== Uploads Paths ===\n")
42
+
43
+ # System uploads (no user_id)
44
+ system_upload = get_uploads_path()
45
+ print(f"System upload (today): {system_upload}")
46
+
47
+ # User-specific uploads
48
+ user_upload = get_uploads_path(user_id="user-123")
49
+ print(f"User upload (user-123): {user_upload}")
50
+
51
+ # With specific date
52
+ specific_date = date(2025, 1, 15)
53
+ dated_upload = get_uploads_path(user_id="user-456", dt=specific_date)
54
+ print(f"Dated upload (2025-01-15): {dated_upload}")
55
+
56
+ # With time included
57
+ now = datetime.now()
58
+ timed_upload = get_uploads_path(user_id="user-789", dt=now, include_time=True)
59
+ print(f"Timed upload (with hour/min): {timed_upload}")
60
+
61
+ # S3 version
62
+ s3_upload = get_uploads_path(user_id="user-123", use_s3=True)
63
+ print(f"S3 upload: {s3_upload}")
64
+ print()
65
+
66
+
67
+ def example_versioned_paths():
68
+ """Demonstrate versioned resource paths."""
69
+ print("=== Versioned Paths ===\n")
70
+
71
+ # Schemas
72
+ schema_path = get_versioned_path("schemas", "user-schema")
73
+ print(f"Schema path: {schema_path}")
74
+
75
+ # Agents
76
+ agent_path = get_versioned_path("agents", "query-agent", version="v2")
77
+ print(f"Agent path (v2): {agent_path}")
78
+
79
+ # Tools
80
+ tool_path = get_versioned_path("tools", "web-scraper")
81
+ print(f"Tool path: {tool_path}")
82
+
83
+ # Datasets
84
+ dataset_path = get_versioned_path("datasets", "training-data")
85
+ print(f"Dataset path: {dataset_path}")
86
+ print()
87
+
88
+
89
+ def example_user_paths():
90
+ """Demonstrate user-scoped paths."""
91
+ print("=== User Paths ===\n")
92
+
93
+ # User root
94
+ user_root = get_user_path("user-123")
95
+ print(f"User root: {user_root}")
96
+
97
+ # User documents
98
+ user_docs = get_user_path("user-123", "documents")
99
+ print(f"User documents: {user_docs}")
100
+
101
+ # User images
102
+ user_images = get_user_path("user-456", "images")
103
+ print(f"User images: {user_images}")
104
+ print()
105
+
106
+
107
+ def example_temp_paths():
108
+ """Demonstrate temporary file paths."""
109
+ print("=== Temp Paths ===\n")
110
+
111
+ # Default temp
112
+ temp_default = get_temp_path()
113
+ print(f"Default temp: {temp_default}")
114
+
115
+ # Processing temp
116
+ temp_processing = get_temp_path("processing")
117
+ print(f"Processing temp: {temp_processing}")
118
+
119
+ # Conversion temp
120
+ temp_conversion = get_temp_path("conversion")
121
+ print(f"Conversion temp: {temp_conversion}")
122
+ print()
123
+
124
+
125
+ def example_practical_usage():
126
+ """Demonstrate practical usage with FS."""
127
+ print("=== Practical Usage ===\n")
128
+
129
+ fs = FS()
130
+
131
+ # Get upload path for today
132
+ upload_dir = get_uploads_path(user_id="user-123")
133
+ print(f"Upload directory: {upload_dir}")
134
+
135
+ # Ensure directory exists (local only)
136
+ ensure_dir_exists(upload_dir)
137
+
138
+ # Write file to upload directory
139
+ file_path = join_path(upload_dir, "test-data.json", is_s3=False)
140
+ print(f"Writing to: {file_path}")
141
+
142
+ data = {
143
+ "message": "Hello from REM",
144
+ "timestamp": datetime.now().isoformat(),
145
+ "user_id": "user-123",
146
+ }
147
+ fs.write(file_path, data)
148
+ print(f"✓ Written successfully")
149
+
150
+ # Read it back
151
+ read_data = fs.read(file_path)
152
+ print(f"✓ Read back: {read_data}")
153
+
154
+ # List files in directory
155
+ files = fs.ls(upload_dir)
156
+ print(f"✓ Files in directory: {files}")
157
+ print()
158
+
159
+
160
+ def example_path_components():
161
+ """Demonstrate path structure breakdown."""
162
+ print("=== Path Structure ===\n")
163
+
164
+ example_path = get_uploads_path(
165
+ user_id="user-123", dt=datetime(2025, 1, 19, 14, 30), include_time=True
166
+ )
167
+
168
+ print(f"Full path: {example_path}")
169
+ print("\nBreakdown:")
170
+ print(" base_uri/rem/v1/uploads/user-123/2025/01/19/14_30")
171
+ print(" │ │ │ │ │ │ │ │ │")
172
+ print(" │ │ │ │ │ │ │ │ └─ minute")
173
+ print(" │ │ │ │ │ │ │ └──── hour")
174
+ print(" │ │ │ │ │ │ └─────── day")
175
+ print(" │ │ │ │ │ └──────────── month")
176
+ print(" │ │ │ │ └───────────────────── year")
177
+ print(" │ │ │ └───────────────────────────── user_id (or 'system')")
178
+ print(" │ │ └──────────────────────────────── category")
179
+ print(" │ └─────────────────────────────────── version")
180
+ print(" └──────────────────────────────────────────── namespace")
181
+ print()
182
+
183
+
184
+ def main():
185
+ """Run all examples."""
186
+ print("\n" + "=" * 70)
187
+ print("REM Filesystem Path Conventions Examples")
188
+ print("=" * 70 + "\n")
189
+
190
+ example_basic_paths()
191
+ example_uploads_paths()
192
+ example_versioned_paths()
193
+ example_user_paths()
194
+ example_temp_paths()
195
+ example_path_components()
196
+ example_practical_usage()
197
+
198
+ print("=" * 70)
199
+ print("Done! Check $REM_HOME/fs/rem/v1/uploads/ for created files")
200
+ print("=" * 70 + "\n")
201
+
202
+
203
+ if __name__ == "__main__":
204
+ main()