Search code examples
pythongoogle-cloud-platformdialogflow-es

Dialogflow "export" via API: Missing required json file agent.json


I'm trying to restore a Dialogflow agent using the Python SDK (google-cloud-dialogflow=2.7.1, google-api-core=2.0, Python 3.7):

import os
import base64
import google.cloud.dialogflow as dialogflow

# Authenticate and open session
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = 'test-a.json'
DIALOGFLOW_PROJECT_ID = 'xxxxxxxx'
SESSION_ID = '#'
session_client = dialogflow.SessionsClient()
session = session_client.session_path(DIALOGFLOW_PROJECT_ID, SESSION_ID)

# Get the agent
agent = dialogflow.AgentsClient()

# Read and encode zip file
encoded_file = base64.b64encode(open("test_A.zip", "rb").read())

# Restore agent
request = {
        "parent": f'projects/{DIALOGFLOW_PROJECT_ID}',
        "agent_content": encoded_file
    }
agent.restore_agent(request=request)

Here's what I get:

google.api_core.exceptions.InvalidArgument: 400 com.google.apps.framework.request.BadRequestException: Invalid agent zip. Missing required json file agent.json

But the file agent.json is in the zip file. In fact, the zip file is the exact file I downloaded from the Dialogflow's console export option:

enter image description here


Solution

  • You get this error because your passing base64 encoded data to field agent_content. As per RestoreAgentRequest(), agent_content accepts type: bytes.

    class google.cloud.dialogflow_v2.types.RestoreAgentRequest(mapping=None, *, ignore_unknown_fields=False, **kwargs)

    Bases: proto.message.Message

    The request message for [Agents.RestoreAgent][google.cloud.dialogflow.v2.Agents.RestoreAgent].

    parent

    • Required. The project that the agent to restore is associated with. Format: projects/.
    • Type: str

    agent_uri

    • The URI to a Google Cloud Storage file containing the agent to restore. Note: The URI must start with “gs://”.

    Type: str

    agent_content

    • Zip compressed raw byte content for agent.

    • Type: bytes

    To fix this just remove the conversion to base64. See code below:

    import os
    import base64
    import google.cloud.dialogflow as dialogflow
    
    # Authenticate and open session
    os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = 'your-service-account.json'
    DIALOGFLOW_PROJECT_ID = 'your-project'
    
    # Get the agent
    agent = dialogflow.AgentsClient()
    zip_file="/full/path/of_file.zip"
    # Read and encode zip file
    with open(zip_file, 'rb') as file_data:
        bytes_content = file_data.read()
    
    check_type=type(bytes_content)
    
    print(f"bytes_content: {check_type}" )
    # Restore agent
    request = {
            "parent": f'projects/{DIALOGFLOW_PROJECT_ID}',
            "agent_content": bytes_content
        }
    agent.restore_agent(request=request)
    

    agent.restore_agent() will return an operation afterwards.