memra 0.2.4__py3-none-any.whl → 0.2.5__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.
memra/models.py CHANGED
@@ -26,6 +26,7 @@ class Agent(BaseModel):
26
26
  allow_delegation: bool = False
27
27
  fallback_agents: Optional[Dict[str, str]] = None
28
28
  config: Optional[Dict[str, Any]] = None
29
+ custom_processing: Optional[Any] = None # Function to call after tool execution
29
30
 
30
31
  class ExecutionPolicy(BaseModel):
31
32
  retry_on_fail: bool = True
@@ -62,7 +62,7 @@ class ToolRegistryClient:
62
62
  }
63
63
 
64
64
  # Make API call
65
- with httpx.Client(timeout=120.0) as client: # Longer timeout for tool execution
65
+ with httpx.Client(timeout=60.0) as client: # Reduced timeout for faster response
66
66
  response = client.post(
67
67
  f"{self.api_base}/tools/execute",
68
68
  headers={
@@ -81,7 +81,7 @@ class ToolRegistryClient:
81
81
  logger.error(f"Tool {tool_name} execution timed out")
82
82
  return {
83
83
  "success": False,
84
- "error": f"Tool execution timed out after 120 seconds"
84
+ "error": f"Tool execution timed out after 60 seconds"
85
85
  }
86
86
  except httpx.HTTPStatusError as e:
87
87
  logger.error(f"API error for tool {tool_name}: {e.response.status_code}")
@@ -0,0 +1,319 @@
1
+ Metadata-Version: 2.4
2
+ Name: memra
3
+ Version: 0.2.5
4
+ Summary: Declarative framework for enterprise workflows with MCP integration - Client SDK
5
+ Home-page: https://github.com/memra/memra-sdk
6
+ Author: Memra
7
+ Author-email: Memra <support@memra.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://memra.co
10
+ Project-URL: Repository, https://github.com/memra-platform/memra-sdk
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Requires-Python: >=3.8
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: pydantic>=1.8.0
24
+ Requires-Dist: httpx>=0.24.0
25
+ Requires-Dist: typing-extensions>=4.0.0
26
+ Requires-Dist: aiohttp>=3.8.0
27
+ Requires-Dist: aiohttp-cors>=0.7.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=6.0; extra == "dev"
30
+ Requires-Dist: pytest-asyncio; extra == "dev"
31
+ Requires-Dist: black; extra == "dev"
32
+ Requires-Dist: flake8; extra == "dev"
33
+ Provides-Extra: mcp
34
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == "mcp"
35
+ Dynamic: author
36
+ Dynamic: home-page
37
+ Dynamic: license-file
38
+ Dynamic: requires-python
39
+
40
+ # Memra SDK
41
+
42
+ **The declarative framework for building enterprise-grade AI workflows with MCP integration.**
43
+
44
+ [![PyPI version](https://badge.fury.io/py/memra.svg)](https://badge.fury.io/py/memra)
45
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
46
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
47
+
48
+ ## 🎯 Why Memra?
49
+
50
+ Building AI-powered business workflows is hard. You need to:
51
+ - **Orchestrate multiple AI agents** with different roles and responsibilities
52
+ - **Integrate with external tools** (databases, APIs, file systems)
53
+ - **Handle complex business logic** with validation and error recovery
54
+ - **Scale from prototypes to production** without rewriting everything
55
+ - **Maintain consistency** across different workflows and teams
56
+
57
+ **Memra solves these challenges** by providing a declarative framework that lets you focus on *what* you want to accomplish, not *how* to wire everything together.
58
+
59
+ ## 🚀 Quick Start (5 minutes!)
60
+
61
+ **Want to see Memra in action immediately?** Check out our [Quick Start Guide](QUICK_START.md) to run the ETL demo in minutes!
62
+
63
+ ### Installation
64
+
65
+ ```bash
66
+ pip install memra
67
+ ```
68
+
69
+ **📖 New to Memra?** For a complete beginner-friendly setup with step-by-step instructions, see our [Detailed Installation Guide](INSTALLATION_GUIDE.md) or run our automated setup script:
70
+
71
+ ```bash
72
+ # Automated setup for new users
73
+ bash scripts/setup_newbie.sh
74
+ ```
75
+
76
+ **🔧 Repository Structure:** This repo uses git submodules with sparse checkout to provide minimal access to infrastructure and workflow templates while keeping private content secure.
77
+
78
+ ### Basic Example
79
+
80
+ ```python
81
+ from memra import Agent, Department, LLM, ExecutionEngine
82
+
83
+ # Define an agent
84
+ agent = Agent(
85
+ role="Data Analyst",
86
+ job="Analyze customer data",
87
+ llm=LLM(model="llama-3.2-11b-vision-preview"),
88
+ sops=["Load data", "Perform analysis", "Generate report"],
89
+ output_key="analysis_result"
90
+ )
91
+
92
+ # Create a department
93
+ department = Department(
94
+ name="Analytics",
95
+ mission="Provide data insights",
96
+ agents=[agent],
97
+ workflow_order=["Data Analyst"]
98
+ )
99
+
100
+ # Execute the workflow
101
+ engine = ExecutionEngine()
102
+ result = engine.execute_department(department, {"data": "customer_data.csv"})
103
+ ```
104
+
105
+ ## 🏗️ Core Architecture
106
+
107
+ ### Agent
108
+ An AI worker that performs specific tasks using LLMs and tools. Agents have:
109
+ - **Role**: What they do (e.g., "Data Analyst", "Invoice Processor")
110
+ - **Job**: Specific task description
111
+ - **LLM**: Language model configuration
112
+ - **Tools**: External tools they can use
113
+ - **SOPs**: Standard operating procedures
114
+
115
+ ### Department
116
+ A team of agents working together to accomplish a mission. Departments:
117
+ - **Coordinate multiple agents** in a workflow
118
+ - **Handle dependencies** between agents
119
+ - **Provide execution policies** (retries, timeouts, error handling)
120
+ - **Manage context** and data flow
121
+
122
+ ### ExecutionEngine
123
+ Orchestrates the execution of departments and their workflows with:
124
+ - **Automatic agent coordination**
125
+ - **Tool integration** via MCP (Model Context Protocol)
126
+ - **Error handling and retries**
127
+ - **Execution tracing and monitoring**
128
+
129
+ ### LLM
130
+ Configuration for language models used by agents, supporting:
131
+ - **Multiple model providers** (OpenAI, Anthropic, local models)
132
+ - **Custom parameters** (temperature, max tokens, etc.)
133
+ - **Model-specific configurations**
134
+
135
+ ## 🔥 Real-World Examples
136
+
137
+ ### ETL Invoice Processing Demo
138
+ **Complete end-to-end workflow** that processes PDF invoices using vision models and stores data in PostgreSQL:
139
+
140
+ ```bash
141
+ # Run the ETL demo
142
+ python demos/etl_invoice_processing/etl_invoice_demo.py
143
+ ```
144
+
145
+ This demo showcases:
146
+ - **Vision model integration** for PDF processing
147
+ - **Multi-agent workflow** (Extractor, Validator, Database Engineer)
148
+ - **MCP tool integration** (PostgreSQL, SQL execution)
149
+ - **Data validation and error handling**
150
+ - **Production-ready patterns**
151
+
152
+ ### Smart File Discovery
153
+ Automatically discover and process files with intelligent routing:
154
+
155
+ ```python
156
+ from memra import Agent
157
+
158
+ # Smart agent that discovers and processes files automatically
159
+ smart_parser = Agent(
160
+ role="Smart Invoice Parser",
161
+ job="Discover and process invoice files intelligently",
162
+ tools=[
163
+ {"name": "FileDiscovery", "hosted_by": "memra"},
164
+ {"name": "FileCopy", "hosted_by": "memra"},
165
+ {"name": "InvoiceExtractionWorkflow", "hosted_by": "memra"}
166
+ ]
167
+ )
168
+
169
+ # Three modes of operation:
170
+ # 1. Auto-discovery: Scan invoices/ directory
171
+ # 2. External file: Copy from Downloads to invoices/
172
+ # 3. Specific file: Process exact file path
173
+ ```
174
+
175
+ ### Accounts Payable Workflow
176
+ Complete accounts payable processing with validation and database integration:
177
+
178
+ ```python
179
+ # See examples/accounts_payable_smart.py for full implementation
180
+ from memra import Department, Agent
181
+
182
+ ap_department = Department(
183
+ name="Accounts Payable",
184
+ mission="Process and validate vendor invoices",
185
+ agents=[
186
+ Agent(role="Invoice Extractor", ...),
187
+ Agent(role="Data Validator", ...),
188
+ Agent(role="Database Engineer", ...)
189
+ ],
190
+ workflow_order=["Invoice Extractor", "Data Validator", "Database Engineer"]
191
+ )
192
+ ```
193
+
194
+ ## 🛠️ Key Features
195
+
196
+ ### 🔌 MCP Integration
197
+ Built-in support for Model Context Protocol (MCP) tools:
198
+ - **Database operations** (PostgreSQL, MySQL, etc.)
199
+ - **File system operations** (discovery, copying, processing)
200
+ - **API integrations** (REST, GraphQL, custom APIs)
201
+ - **Custom tool development** with simple Python functions
202
+
203
+ ### 🎯 Declarative Workflows
204
+ Define workflows in terms of **what** you want to accomplish:
205
+
206
+ ```python
207
+ # Instead of writing procedural code, declare your workflow
208
+ department = Department(
209
+ name="Invoice Processing",
210
+ mission="Extract, validate, and store invoice data",
211
+ agents=[
212
+ Agent(role="Extractor", job="Extract data from PDFs"),
213
+ Agent(role="Validator", job="Validate extracted data"),
214
+ Agent(role="Database Engineer", job="Store data in database")
215
+ ],
216
+ workflow_order=["Extractor", "Validator", "Database Engineer"]
217
+ )
218
+ ```
219
+
220
+ ### 🔄 Error Handling & Recovery
221
+ Built-in resilience with:
222
+ - **Automatic retries** with configurable policies
223
+ - **Fallback agents** for critical workflows
224
+ - **Validation at each step**
225
+ - **Comprehensive error reporting**
226
+
227
+ ### 📊 Monitoring & Observability
228
+ Track workflow execution with:
229
+ - **Execution traces** showing agent and tool usage
230
+ - **Performance metrics** (timing, costs)
231
+ - **Error logs** with context
232
+ - **Audit trails** for compliance
233
+
234
+ ### 🚀 Production Ready
235
+ Scale from prototype to production:
236
+ - **Async execution** for high throughput
237
+ - **Resource management** and connection pooling
238
+ - **Configuration management** for different environments
239
+ - **Security best practices** for API keys and credentials
240
+
241
+ ## 📚 Documentation
242
+
243
+ - **[Quick Start Guide](QUICK_START.md)** - Get up and running in 5 minutes
244
+ - **[Detailed Installation Guide](INSTALLATION_GUIDE.md)** - Complete beginner-friendly setup instructions
245
+ - **[System Architecture](memra_system_architecture.md)** - Deep dive into Memra's design
246
+ - **[Text-to-SQL Guide](TEXT_TO_SQL_USAGE_GUIDE.md)** - Building database query workflows
247
+ - **[Examples Directory](examples/)** - Complete working examples
248
+ - **[Demos Directory](demos/)** - Advanced workflow demonstrations
249
+
250
+ ## 🏢 Use Cases
251
+
252
+ ### Financial Services
253
+ - **Invoice processing** and accounts payable automation
254
+ - **Document classification** and routing
255
+ - **Compliance monitoring** and reporting
256
+ - **Risk assessment** and fraud detection
257
+
258
+ ### Healthcare
259
+ - **Medical record processing** and data extraction
260
+ - **Claims processing** and validation
261
+ - **Patient data analysis** and insights
262
+ - **Regulatory compliance** workflows
263
+
264
+ ### Manufacturing
265
+ - **Quality control** and inspection workflows
266
+ - **Supply chain** optimization and monitoring
267
+ - **Equipment maintenance** scheduling
268
+ - **Production planning** and optimization
269
+
270
+ ### Retail & E-commerce
271
+ - **Order processing** and fulfillment
272
+ - **Customer service** automation
273
+ - **Inventory management** and forecasting
274
+ - **Market analysis** and trend detection
275
+
276
+ ## 🤝 Contributing
277
+
278
+ We welcome contributions! Please see our [contributing guide](CONTRIBUTING.md) for details.
279
+
280
+ ### Development Setup
281
+
282
+ ```bash
283
+ # Clone the repository
284
+ git clone https://github.com/memra-platform/memra-sdk.git
285
+ cd memra-sdk
286
+
287
+ # Install in development mode
288
+ pip install -e .
289
+
290
+ # Run tests
291
+ pytest tests/
292
+ ```
293
+
294
+ ## 📄 License
295
+
296
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
297
+
298
+ ### MIT License Summary
299
+ - ✅ **Commercial use** - Use in proprietary software
300
+ - ✅ **Modification** - Modify and distribute
301
+ - ✅ **Distribution** - Distribute copies
302
+ - ✅ **Private use** - Use privately
303
+ - ❌ **Liability** - No warranty provided
304
+ - ❌ **Warranty** - No warranty provided
305
+
306
+ ## 🆘 Support
307
+
308
+ - **Issues**: [GitHub Issues](https://github.com/memra-platform/memra-sdk/issues)
309
+ - **Discussions**: [GitHub Discussions](https://github.com/memra-platform/memra-sdk/discussions)
310
+ - **Email**: hello@memra.com
311
+
312
+ ## 🔗 Related Projects
313
+
314
+ - **[memra-workflows](https://github.com/memra-platform/memra-workflows)** - Production workflow templates
315
+ - **[memra-ops](https://github.com/memra-platform/memra-ops)** - Operations and deployment tools
316
+
317
+ ---
318
+
319
+ **Built with ❤️ by the memra team**
@@ -1,16 +1,26 @@
1
- memra/__init__.py,sha256=zVO29fnEDclBI9x9SFVzF9uJYAKhPDTNrMFMWuw6JC8,787
1
+ memra/__init__.py,sha256=InrJf0J3lQruKLuQ4R_JtTll553Die_vDNMCUnTCY2I,1108
2
+ memra/cli.py,sha256=nx_pzbB0ecKzOzg4TDMePV-QFbjlJCyOCoj96zACld4,9289
2
3
  memra/discovery.py,sha256=yJIQnrDQu1nyzKykCIuzG_5SW5dIXHCEBLLKRWacIoY,480
3
4
  memra/discovery_client.py,sha256=AbnKn6qhyrf7vmOvknEeDzH4tiGHsqPHtDaein_qaW0,1271
4
- memra/execution.py,sha256=oA66YKds6-8YXQJ7ppCj39C09xuXG1z8GWfF9Tm8Ml0,23861
5
- memra/models.py,sha256=sXMPRnMB_mUVtJdBFyd0ElCf_uh1yqx7iLssIYNm0vI,3333
5
+ memra/execution.py,sha256=OXpBKxwBIjhACWL_qh8KHNndO8HUgB6gBF81AiQBBm0,34751
6
+ memra/models.py,sha256=3KvjPCaMFGIvI017AIHS23jGnEBZdKHspe1Fp8w0xa0,3418
6
7
  memra/tool_registry.py,sha256=PDuWtiX_LX-vhKnx4JeL_ndUwG-oJ6bdhGe6iQeCDBw,15361
7
- memra/tool_registry_client.py,sha256=uzMQ4COvRams9vuPLcqcdljUpDlAYU_tyFxrRhrA0Lc,4009
8
- memra-0.2.4.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- memra-ops/app.py,sha256=eyswUTeTvKdPSVy5RHMDW9ijUXdBfYB1qDtwCdkDGDM,26057
8
+ memra/tool_registry_client.py,sha256=dPIj6DMS5wdu99XmVm-NQYHKH_m6nsknCh4C_imTFig,4009
9
+ memra-0.2.5.dist-info/licenses/LICENSE,sha256=8OrnTd8DWwLWmUEj5srSLvT4PREfW1Qo1T5gEUIHPws,1062
10
+ memra-ops/app.py,sha256=S8B82gOAuT9x-NhmVLL9HM03Pde3Fa7QXm6TG1PEbbU,29439
10
11
  memra-ops/config.py,sha256=6mBbS_stoEIhJDBqdJOalryAnyWeHbDy81mU1j08ids,969
11
- memra-ops/server_tool_registry.py,sha256=LYiLUL08M72Poaqt_rWt11BGMFlZKSSWjbW9SnfynEI,8212
12
+ memra-ops/mcp_bridge_server.py,sha256=tDEigRstIEAEu16F1ctCor2ny9CBbEOMY046bHdzFpE,47607
13
+ memra-ops/server_tool_registry.py,sha256=rg5wz8dTfJNqo2QRe69iBKJKeoJemltt_XzZsdxyJa8,8367
12
14
  memra-ops/config/config.py,sha256=7dcT9W5b_nWrVAylbdeOaA60_NJlhv2YLyEILTcNKtI,600
15
+ memra-ops/logic/__init__.py,sha256=UFKwzAUU-5pWt-7gcajY1M9PLoJ1wiQ8L0HDTlkRv7E,43
16
+ memra-ops/logic/file_tools.py,sha256=iVe4xE7lNBhhoiL0Hi2zx4oF7koDeVvsOh1uMbn6HEo,1126
17
+ memra-ops/logic/invoice_tools.py,sha256=Jp3PEFfUXRTAAP1ZM4Juei_zzPKy8EFi8H2uP6T9c2A,27787
18
+ memra-ops/logic/invoice_tools_fix.py,sha256=sF4qADqbfWEgOyavslrNlCDEyIkaZo35TtnyHd7PClY,3020
19
+ memra-ops/scripts/check_database.py,sha256=sBPmIJ10WW3jHQfOjeDRJnQahRBwVAi60-98r4HG9rw,987
20
+ memra-ops/scripts/clear_database.py,sha256=yO4JUbMOcSQ1-S57n1oua-SheM360yg-oNiPyj8LW5o,1441
21
+ memra-ops/scripts/monitor_database.py,sha256=OmIgUmtVjtUfSziSEiTy5CheueMMZ5R5HciPpMishE0,2287
13
22
  memra-ops/scripts/release.py,sha256=riQ-jz7-vnd1cSfQdU1eUZmVDyuWym1nmZW65lGetiI,4218
23
+ memra-ops/scripts/reset_database.py,sha256=QJagPQIkMOr3s-o-g_Urz0CvSYNm0D2xbwo3JSrKIWY,2255
14
24
  memra-ops/scripts/start_memra.py,sha256=VR7WESQXgvPuzZEFMhtmABSR7IzYixsnpgtoPcECLK0,11987
15
25
  memra-ops/scripts/stop_memra.py,sha256=yyTu4jxjUbxTrvobQ-UhpNk-eWB8bCFjcBPGW1scIJg,4591
16
26
  memra-ops/tests/test_llm_text_to_sql.py,sha256=IDL7FEzlm2Dr9pRCcJQ6SGddF9VBDfHonwztrDpxBGU,4099
@@ -20,7 +30,7 @@ memra-ops/tests/test_schema_aware_sql.py,sha256=b_XPtv7eldR2ARBVlriTHMA1nwqYUcMg
20
30
  memra-ops/tests/test_schema_aware_sql_simple.py,sha256=8f8zijkTwvIqVHM3B5oVviRfFS-U6bfC43fk9hcWsoE,2309
21
31
  memra-ops/tests/test_text_to_sql_demo.py,sha256=5mmpSwXZ8r8sj3J9iCYkFx0SgwyXPe-7Prie1hL6cis,5092
22
32
  memra-ops/tools/mcp_bridge_server.py,sha256=IKUNusZovPdR0_6Bv_XejmAk27lnHrM1uOE8xPVnM8s,35051
23
- memra-sdk/setup.py,sha256=ZeDcO25CHXm1rHoDZbWI2BE6B7s7LUa9XvFmUu_YEtk,1513
33
+ memra-sdk/setup.py,sha256=j95Pq2ha28B3owPv0J1isq5pgUwa9p02nbBXqxa4Lwo,1513
24
34
  memra-sdk/examples/accounts_payable.py,sha256=PfpXKrGOUu6NpkNcHy6cN6TtsXfnsJZhUv-KGlOvDqY,7990
25
35
  memra-sdk/examples/accounts_payable_client.py,sha256=tLHHCydEpasLHTHd4YULhSxFy6zs81X5PZHav0dlQ2I,7816
26
36
  memra-sdk/examples/accounts_payable_mcp.py,sha256=lOgwDfMVKxifQi70GmeXQnpZiIFrZnNj5_JSZ9qsdBw,7344
@@ -28,7 +38,7 @@ memra-sdk/examples/ask_questions.py,sha256=jek7EVXXZ_vODlMy_hQGQCkN9vYBfaW7SOWsI
28
38
  memra-sdk/examples/invoice_processing.py,sha256=STe3ri65WH_Ss84qiRWuGZTpDZke5GoJf8LEqOAc5ys,3980
29
39
  memra-sdk/examples/propane_delivery.py,sha256=ryvIxDjM9GJY9T6fFIqJgHOcX2PEMkfF_t_3E5CyZW4,2539
30
40
  memra-sdk/examples/simple_text_to_sql.py,sha256=NnpKo9nFpmPQ089zcSx4wwG6_tSHTmGJSS7LPs55NA0,5314
31
- memra-sdk/memra/__init__.py,sha256=zVO29fnEDclBI9x9SFVzF9uJYAKhPDTNrMFMWuw6JC8,787
41
+ memra-sdk/memra/__init__.py,sha256=CTiSeBBZ40-pNd2-wBIdZduqNLrA5OnWmmwk1y1f894,787
32
42
  memra-sdk/memra/discovery.py,sha256=yJIQnrDQu1nyzKykCIuzG_5SW5dIXHCEBLLKRWacIoY,480
33
43
  memra-sdk/memra/discovery_client.py,sha256=AbnKn6qhyrf7vmOvknEeDzH4tiGHsqPHtDaein_qaW0,1271
34
44
  memra-sdk/memra/execution.py,sha256=P7tAur0SEMtX6uLlfxTfCZBgMLIRj6Wl3dsv2EA9fHc,23443
@@ -51,8 +61,8 @@ memra-workflows/propane_delivery/propane_delivery.py,sha256=ryvIxDjM9GJY9T6fFIqJ
51
61
  memra-workflows/text_to_sql/complete_invoice_workflow_with_queries.py,sha256=x4wq3o_ogFnnrI6MQwEhqIiNH-NNwS5SXQUoKd_br7U,7428
52
62
  memra-workflows/text_to_sql/complete_text_to_sql_system.py,sha256=Izj4ucXDXTWFY29SWr2YrEf3ZyXH4QCDEljNk4jlpI0,8991
53
63
  memra-workflows/text_to_sql/file_discovery_demo.py,sha256=4R_QN0Y6OtHmnX6CvtwDXen122XCDrk-MRBOzxb_x_k,5306
54
- memra-0.2.4.dist-info/METADATA,sha256=YDEg2IxnhDLka_MA0Ge_cKx_yO2HMFphcGNxnH85t84,4203
55
- memra-0.2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
56
- memra-0.2.4.dist-info/entry_points.txt,sha256=LBVjwWoxWJRzNLgeByPn6xUvWFIRnqnemvAZgIoSt08,41
57
- memra-0.2.4.dist-info/top_level.txt,sha256=IviXF9qSQY_BidRYund9zFaV-q1VMl6CuizwTAggQks,42
58
- memra-0.2.4.dist-info/RECORD,,
64
+ memra-0.2.5.dist-info/METADATA,sha256=JASskcVQrw_ntJSY3XI5_Ac0Sqi9xC9FpGhsRo3jP08,10736
65
+ memra-0.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
66
+ memra-0.2.5.dist-info/entry_points.txt,sha256=8OKRAUYIh1Eg3s6A8dJCIhoPTcyhe0N5_c_GcLXYs48,45
67
+ memra-0.2.5.dist-info/top_level.txt,sha256=IviXF9qSQY_BidRYund9zFaV-q1VMl6CuizwTAggQks,42
68
+ memra-0.2.5.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ memra = scripts.memra:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Memra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
memra-ops/app.py CHANGED
@@ -12,6 +12,9 @@ import asyncio
12
12
  import hashlib
13
13
  import hmac
14
14
  import aiohttp
15
+ import base64
16
+ import uuid
17
+ from datetime import datetime, timedelta
15
18
  from server_tool_registry import ServerToolRegistry
16
19
 
17
20
  # Add current directory to path for imports
@@ -45,6 +48,16 @@ class ToolExecutionResponse(BaseModel):
45
48
  class ToolDiscoveryResponse(BaseModel):
46
49
  tools: List[Dict[str, str]]
47
50
 
51
+ class FileUploadRequest(BaseModel):
52
+ filename: str
53
+ content: str # base64 encoded
54
+ content_type: str
55
+
56
+ class FileUploadResponse(BaseModel):
57
+ success: bool
58
+ data: Optional[dict] = None
59
+ error: Optional[str] = None
60
+
48
61
  # Authentication
49
62
  def verify_api_key(api_key: str) -> bool:
50
63
  """Verify if the provided API key is valid"""
@@ -75,6 +88,91 @@ async def get_api_key(x_api_key: Optional[str] = Header(None)):
75
88
  logger.info(f"Valid API key used: {x_api_key}")
76
89
  return x_api_key
77
90
 
91
+ # File upload configuration
92
+ UPLOAD_DIR = "/tmp/uploads"
93
+ FILE_EXPIRY_HOURS = 24
94
+
95
+ # Ensure upload directory exists
96
+ os.makedirs(UPLOAD_DIR, exist_ok=True)
97
+
98
+ @app.post("/upload", response_model=FileUploadResponse)
99
+ async def upload_file(
100
+ request: FileUploadRequest,
101
+ api_key: Optional[str] = Depends(get_api_key)
102
+ ):
103
+ """Upload a file to the server for processing"""
104
+ try:
105
+ # Validate file type
106
+ if not request.content_type.startswith("application/pdf"):
107
+ raise HTTPException(status_code=400, detail="Only PDF files are supported")
108
+
109
+ # Validate file size (50MB limit)
110
+ try:
111
+ file_content = base64.b64decode(request.content)
112
+ if len(file_content) > 50 * 1024 * 1024: # 50MB
113
+ raise HTTPException(status_code=400, detail="File too large (max 50MB)")
114
+ except Exception as e:
115
+ raise HTTPException(status_code=400, detail="Invalid base64 content")
116
+
117
+ # Generate unique filename
118
+ file_id = str(uuid.uuid4())
119
+ file_extension = os.path.splitext(request.filename)[1]
120
+ remote_filename = f"{file_id}{file_extension}"
121
+ remote_path = os.path.join(UPLOAD_DIR, remote_filename)
122
+
123
+ # Save file
124
+ with open(remote_path, 'wb') as f:
125
+ f.write(file_content)
126
+
127
+ # Calculate expiry time
128
+ expires_at = datetime.utcnow() + timedelta(hours=FILE_EXPIRY_HOURS)
129
+
130
+ logger.info(f"File uploaded: {request.filename} -> {remote_filename}")
131
+
132
+ return FileUploadResponse(
133
+ success=True,
134
+ data={
135
+ "remote_path": f"/uploads/{remote_filename}",
136
+ "file_id": file_id,
137
+ "expires_at": expires_at.isoformat(),
138
+ "original_filename": request.filename
139
+ }
140
+ )
141
+
142
+ except HTTPException:
143
+ raise
144
+ except Exception as e:
145
+ logger.error(f"Upload failed: {str(e)}")
146
+ return FileUploadResponse(
147
+ success=False,
148
+ error=f"Upload failed: {str(e)}"
149
+ )
150
+
151
+ async def cleanup_expired_files():
152
+ """Remove files older than FILE_EXPIRY_HOURS"""
153
+ while True:
154
+ try:
155
+ current_time = datetime.utcnow()
156
+ for filename in os.listdir(UPLOAD_DIR):
157
+ file_path = os.path.join(UPLOAD_DIR, filename)
158
+ file_time = datetime.fromtimestamp(os.path.getctime(file_path))
159
+
160
+ if current_time - file_time > timedelta(hours=FILE_EXPIRY_HOURS):
161
+ try:
162
+ os.remove(file_path)
163
+ logger.info(f"Cleaned up expired file: {filename}")
164
+ except Exception as e:
165
+ logger.error(f"Failed to clean up {filename}: {e}")
166
+
167
+ except Exception as e:
168
+ logger.error(f"File cleanup error: {e}")
169
+
170
+ await asyncio.sleep(3600) # Run every hour
171
+
172
+ @app.on_event("startup")
173
+ async def start_cleanup():
174
+ asyncio.create_task(cleanup_expired_files())
175
+
78
176
  @app.get("/", response_class=HTMLResponse)
79
177
  async def landing_page():
80
178
  """API documentation landing page"""
@@ -0,0 +1 @@
1
+ # Logic package for Memra API server tools
@@ -0,0 +1,43 @@
1
+ """
2
+ File handling tools for the Memra API server
3
+ """
4
+
5
+ import os
6
+ import logging
7
+ from typing import Dict, Any
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ class FileReader:
12
+ """Read files from the filesystem"""
13
+
14
+ def __init__(self):
15
+ pass
16
+
17
+ def read_file(self, file_path: str) -> Dict[str, Any]:
18
+ """Read a file and return its contents"""
19
+ try:
20
+ if not os.path.exists(file_path):
21
+ return {
22
+ "success": False,
23
+ "error": f"File not found: {file_path}"
24
+ }
25
+
26
+ with open(file_path, 'r', encoding='utf-8') as f:
27
+ content = f.read()
28
+
29
+ return {
30
+ "success": True,
31
+ "data": {
32
+ "file_path": file_path,
33
+ "content": content,
34
+ "size": len(content)
35
+ }
36
+ }
37
+
38
+ except Exception as e:
39
+ logger.error(f"File reading failed: {str(e)}")
40
+ return {
41
+ "success": False,
42
+ "error": str(e)
43
+ }