From 21854c6a2490ac31ed46dad691a4db1d8e0fd5a2 Mon Sep 17 00:00:00 2001 From: Dev Khant Date: Thu, 9 Jan 2025 20:43:01 +0530 Subject: [PATCH] Add support: MemoryExport API (#2129) Co-authored-by: Deshraj Yadav --- .../memory/create-memory-export.mdx | 6 + .../memory/get-memory-export.mdx | 6 + docs/mint.json | 4 +- docs/openapi.json | 194 ++++++++++++++++++ docs/platform/quickstart.mdx | 171 +++++++++++++++ mem0/client/main.py | 79 ++++++- 6 files changed, 456 insertions(+), 4 deletions(-) create mode 100644 docs/api-reference/memory/create-memory-export.mdx create mode 100644 docs/api-reference/memory/get-memory-export.mdx diff --git a/docs/api-reference/memory/create-memory-export.mdx b/docs/api-reference/memory/create-memory-export.mdx new file mode 100644 index 00000000..9468d188 --- /dev/null +++ b/docs/api-reference/memory/create-memory-export.mdx @@ -0,0 +1,6 @@ +--- +title: 'Create Memory Export' +openapi: post /v1/exports/ +--- + +Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you’re exporting a large number of memories. You can tailor the export by applying various filters (e.g., user_id, agent_id, run_id, or session_id) and by modifying the Pydantic schema to ensure the final data matches your exact needs. diff --git a/docs/api-reference/memory/get-memory-export.mdx b/docs/api-reference/memory/get-memory-export.mdx new file mode 100644 index 00000000..68ef25b0 --- /dev/null +++ b/docs/api-reference/memory/get-memory-export.mdx @@ -0,0 +1,6 @@ +--- +title: 'Get Memory Export' +openapi: get /v1/exports/ +--- + +Retrieve the latest structured memory export after submitting an export job. You can filter the export by `user_id`, `run_id`, `session_id`, or `app_id` to get the most recent export matching your filters. \ No newline at end of file diff --git a/docs/mint.json b/docs/mint.json index 6cfbefb9..55cff309 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -160,7 +160,9 @@ "api-reference/memory/v2-search-memories", "api-reference/memory/history-memory", "api-reference/memory/batch-update", - "api-reference/memory/batch-delete" + "api-reference/memory/batch-delete", + "api-reference/memory/create-memory-export", + "api-reference/memory/get-memory-export" ] }, { diff --git a/docs/openapi.json b/docs/openapi.json index 5da28f3b..acfa8477 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -394,6 +394,200 @@ } } }, + "/v1/exports/": { + "get": { + "tags": [ + "exports" + ], + "summary": "Export data based on filters", + "description": "Get the latest memory export.", + "operationId": "exports_list", + "parameters": [ + { + "name": "user_id", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Filter exports by user ID" + }, + { + "name": "run_id", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Filter exports by run ID" + }, + { + "name": "session_id", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Filter exports by session ID" + }, + { + "name": "app_id", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Filter exports by app ID" + }, + { + "name": "org_id", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Filter exports by organization ID" + }, + { + "name": "project_id", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Filter exports by project ID" + } + ], + "responses": { + "200": { + "description": "Successful export", + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "Export data response" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "One of the filters: app_id, user_id, agent_id, run_id is required!" + } + } + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "No memory export request found" + } + } + } + } + } + } + } + }, + "post": { + "tags": [ + "exports" + ], + "summary": "Create an export job with schema", + "description": "Create a structured export of memories based on a provided schema.", + "operationId": "exports_create", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["schema"], + "properties": { + "schema": { + "type": "object", + "description": "Schema definition for the export" + }, + "user_id": { + "type": "string", + "description": "Filter exports by user ID" + }, + "run_id": { + "type": "string", + "description": "Filter exports by run ID" + }, + "session_id": { + "type": "string", + "description": "Filter exports by session ID" + }, + "app_id": { + "type": "string", + "description": "Filter exports by app ID" + }, + "org_id": { + "type": "string", + "description": "Filter exports by organization ID" + }, + "project_id": { + "type": "string", + "description": "Filter exports by project ID" + } + } + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Export created successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "Memory export request received. The export will be ready in a few seconds." + }, + "id": { + "type": "string", + "format": "uuid", + "example": "550e8400-e29b-41d4-a716-446655440000" + } + }, + "required": ["message", "id"] + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "Schema is required and must be a valid object" + } + } + } + } + } + } + } + } + }, "/v1/memories/": { "get": { "tags": [ diff --git a/docs/platform/quickstart.mdx b/docs/platform/quickstart.mdx index 1b061750..088e717c 100644 --- a/docs/platform/quickstart.mdx +++ b/docs/platform/quickstart.mdx @@ -1630,6 +1630,177 @@ curl -X DELETE "https://api.mem0.ai/v1/memories/batch/" \ ``` +### 4.11 Create Memory Export +Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you’re exporting a large number of memories. You can tailor the export by applying various filters (e.g., `user_id`, `agent_id`, `run_id`, or `session_id`) and by modifying the Pydantic schema to ensure the final data matches your exact needs. + +For example, if you want to extract professional profile information from memories, you can define a schema and export the memories in that structured format: + + + +```python Python +response = client.create_memory_export(schema=json_schema, user_id="user123") +print(response) +``` + +```bash cURL +curl -X POST "https://api.mem0.ai/v1/memories/export/" \ + -H "Authorization: Token your-api-key" \ + -H "Content-Type: application/json" \ + -d '{ + "schema":{json_schema}, + "user_id": "user123" + }' +``` + +```json json_schema +{ + "$defs": { + "EducationLevel": { + "enum": ["high_school", "bachelors", "masters"], + "title": "EducationLevel", + "type": "string" + }, + "EmploymentStatus": { + "enum": ["full_time", "part_time", "student"], + "title": "EmploymentStatus", + "type": "string" + } + }, + "example": { + "current_role": "Senior Software Engineer", + "education_level": "masters", + "employment_status": "full_time", + "full_name": "John Doe", + "skills": ["Python", "AWS", "Machine Learning"], + "years_experience": 8 + }, + "properties": { + "full_name": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 2, + "type": "string" + }, + { + "type": "null" + } + ], + "default": None, + "description": "The professional's full name", + "title": "Full Name" + }, + "current_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": None, + "description": "Current job title or role", + "title": "Current Role" + }, + "years_experience": { + "anyOf": [ + { + "maximum": 70, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "default": None, + "description": "Years of professional experience", + "title": "Years Experience" + }, + "employment_status": { + "anyOf": [ + { + "$ref": "#/$defs/EmploymentStatus" + }, + { + "type": "null" + } + ], + "default": None, + "description": "Current employment status" + }, + "education_level": { + "anyOf": [ + { + "$ref": "#/$defs/EducationLevel" + }, + { + "type": "null" + } + ], + "default": None, + "description": "Highest level of education completed" + }, + "skills": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": None, + "description": "Professional skills and competencies", + "title": "Skills" + } + }, + "title": "ProfessionalProfile", + "type": "object" +} +``` + +```json Output +{ + "message": "Memory export request received. The export will be ready in a few seconds.", + "id": "550e8400-e29b-41d4-a716-446655440000" +} +``` + + + +### 4.12 Get Memory Export +Retrieve the structured export of memories after you have submitted a export job using the previous endpoint. It return the latest memory export. + + + +```python Python +response = client.get_memory_export(user_id="user123") +print(response) +``` + +```bash cURL +curl -X GET "https://api.mem0.ai/v1/memories/export/?user_id=user123" \ + -H "Authorization: Token your-api-key" +``` + +```json Output +{ + "full_name": "John Doe", + "current_role": "Senior Software Engineer", + "years_experience": 8, + "employment_status": "full_time", + "education_level": "masters", + "skills": ["Python", "AWS", "Machine Learning"] +} +``` + + + If you have any questions, please feel free to reach out to us using one of the following methods: \ No newline at end of file diff --git a/mem0/client/main.py b/mem0/client/main.py index 295667ef..ec52cbe1 100644 --- a/mem0/client/main.py +++ b/mem0/client/main.py @@ -48,6 +48,11 @@ class MemoryClient: api_key (str): The API key for authenticating with the Mem0 API. host (str): The base URL for the Mem0 API. client (httpx.Client): The HTTP client used for making API requests. + organization (str, optional): (Deprecated) Organization name. + project (str, optional): (Deprecated) Project name. + org_id (str, optional): Organization ID. + project_id (str, optional): Project ID. + user_id (str): Unique identifier for the user. """ def __init__( @@ -324,7 +329,19 @@ class MemoryClient: @api_error_handler def batch_update(self, memories: List[Dict[str, Any]]) -> Dict[str, Any]: - """Batch update memories.""" + """Batch update memories. + + Args: + memories: List of memory dictionaries to update. Each dictionary must contain: + - memory_id (str): ID of the memory to update + - text (str): New text content for the memory + + Returns: + str: Message indicating the success of the batch update. + + Raises: + APIError: If the API request fails. + """ response = self.client.put("/v1/batch/", json={"memories": memories}) response.raise_for_status() @@ -333,7 +350,18 @@ class MemoryClient: @api_error_handler def batch_delete(self, memories: List[Dict[str, Any]]) -> Dict[str, Any]: - """Batch delete memories.""" + """Batch delete memories. + + Args: + memories: List of memory dictionaries to delete. Each dictionary must contain: + - memory_id (str): ID of the memory to delete + + Returns: + str: Message indicating the success of the batch deletion. + + Raises: + APIError: If the API request fails. + """ response = self.client.request( "DELETE", "/v1/batch/", @@ -344,6 +372,43 @@ class MemoryClient: capture_client_event("client.batch_delete", self) return response.json() + @api_error_handler + def create_memory_export(self, schema: str, **kwargs) -> Dict[str, Any]: + """Create a memory export with the provided schema. + + Args: + schema: JSON schema defining the export structure + **kwargs: Optional filters like user_id, run_id, etc. + + Returns: + Dict containing export request ID and status message + """ + response = self.client.post( + "/v1/exports/", + json={"schema": schema, **self._prepare_params(kwargs)} + ) + response.raise_for_status() + capture_client_event("client.create_memory_export", self, {"schema": schema, "keys": list(kwargs.keys())}) + return response.json() + + @api_error_handler + def get_memory_export(self, **kwargs) -> Dict[str, Any]: + """Get a memory export. + + Args: + **kwargs: Filters like user_id to get specific export + + Returns: + Dict containing the exported data + """ + response = self.client.get( + "/v1/exports/", + params=self._prepare_params(kwargs) + ) + response.raise_for_status() + capture_client_event("client.get_memory_export", self, {"keys": list(kwargs.keys())}) + return response.json() + def chat(self): """Start a chat with the Mem0 AI. (Not implemented) @@ -414,7 +479,15 @@ class MemoryClient: class AsyncMemoryClient: - """Asynchronous client for interacting with the Mem0 API.""" + """Asynchronous client for interacting with the Mem0 API. + + This class provides asynchronous versions of all MemoryClient methods. + It uses httpx.AsyncClient for making non-blocking API requests. + + Attributes: + sync_client (MemoryClient): Underlying synchronous client instance. + async_client (httpx.AsyncClient): Async HTTP client for making API requests. + """ def __init__( self,