Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions developer-knowledge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Google Developer Knowledge API Python Samples

This directory contains Python code samples demonstrating how to use the [Google Developer Knowledge API](https://developers.google.com/knowledge) client library (`google-developer-knowledge`).

## Setup

1. Enable the Developer Knowledge API on your Google Cloud project:
```bash
gcloud services enable developerknowledge.googleapis.com
```

2. Install dependencies:
```bash
pip install -r requirements.txt
```

## Samples

* **[Search Document Chunks](search_document_chunks.py)**: Search public developer documentation chunks by query (`developerknowledge_search_document_chunks`).
* **[Get Document](get_document.py)**: Retrieve a single documentation page with full markdown content (`developerknowledge_get_document`).
* **[Batch Get Documents](batch_get_documents.py)**: Fetch multiple documentation pages in one call (`developerknowledge_batch_get_documents`).
* **[Answer Query](answer_query.py)**: Get a grounded, cited answer to a technical question (`developerknowledge_answer_query`).

## Running Tests

```bash
pytest
```
49 changes: 49 additions & 0 deletions developer-knowledge/answer_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START developerknowledge_answer_query]
from google.cloud import developer_knowledge_v1


def answer_query(
query: str = "How do I create a Google Cloud Storage bucket?",
) -> developer_knowledge_v1.AnswerQueryResponse:
"""Answers a developer question grounded in Google developer documentation.

Args:
query: The technical question to answer.

Returns:
The AnswerQueryResponse containing the grounded answer,
citations, and references.
"""
client = developer_knowledge_v1.DeveloperKnowledgeClient()

request = developer_knowledge_v1.AnswerQueryRequest(
query=query,
)

response = client.answer_query(request=request)

print(f"Answer:\n{response.answer.answer_text}\n")
print(f"Citations count: {len(response.answer.citations)}")
print(f"References count: {len(response.answer.references)}")

return response


# [END developerknowledge_answer_query]

if __name__ == "__main__":
answer_query()
27 changes: 27 additions & 0 deletions developer-knowledge/answer_query_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import answer_query


def test_answer_query(capsys):
response = answer_query.answer_query(
query="How to create a Cloud Storage bucket",
)
out, _ = capsys.readouterr()

assert response is not None
assert response.answer is not None
assert len(response.answer.answer_text) > 0
assert "Answer:" in out
57 changes: 57 additions & 0 deletions developer-knowledge/batch_get_documents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START developerknowledge_batch_get_documents]
from typing import List, Optional

from google.cloud import developer_knowledge_v1


def batch_get_documents(
names: Optional[List[str]] = None,
) -> developer_knowledge_v1.BatchGetDocumentsResponse:
"""Retrieves multiple developer documentation pages in a single request.

Args:
names: A list of resource names in format 'documents/{uri_without_scheme}'.

Returns:
The BatchGetDocumentsResponse containing the retrieved documents.
"""
if names is None:
names = [
"documents/docs.cloud.google.com/storage/docs/creating-buckets",
"documents/docs.cloud.google.com/storage/docs/deleting-buckets",
]

client = developer_knowledge_v1.DeveloperKnowledgeClient()

request = developer_knowledge_v1.BatchGetDocumentsRequest(
names=names,
)

response = client.batch_get_documents(request=request)

for doc in response.documents:
print(f"Title: {doc.title}")
print(f"URI: {doc.uri}")
print(f"Content Length: {doc.content_length_bytes} bytes\n")

return response


# [END developerknowledge_batch_get_documents]

if __name__ == "__main__":
batch_get_documents()
31 changes: 31 additions & 0 deletions developer-knowledge/batch_get_documents_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import batch_get_documents


def test_batch_get_documents(capsys):
names = [
"documents/docs.cloud.google.com/storage/docs/creating-buckets",
"documents/docs.cloud.google.com/storage/docs/deleting-buckets",
]
response = batch_get_documents.batch_get_documents(names=names)
out, _ = capsys.readouterr()

assert response is not None
assert len(response.documents) == 2
for doc in response.documents:
assert doc.name in names
assert len(doc.title) > 0
assert "Title:" in out
139 changes: 139 additions & 0 deletions developer-knowledge/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Pytest configuration and local fallback mocks for developer_knowledge_v1."""

import sys
from unittest.mock import MagicMock

try:
from google.cloud import developer_knowledge_v1 # noqa: F401
except ImportError:
mock_dk = MagicMock()

class SearchDocumentChunksRequest:
def __init__(self, query="", page_size=5, page_token="", filter=""):
self.query = query
self.page_size = page_size
self.page_token = page_token
self.filter = filter

class GetDocumentRequest:
def __init__(self, name=""):
self.name = name

class BatchGetDocumentsRequest:
def __init__(self, names=None):
self.names = names or []

class AnswerQueryRequest:
def __init__(self, query="", filter=""):
self.query = query
self.filter = filter

class DocumentChunk:
def __init__(
self,
parent="documents/docs.cloud.google.com/storage/docs/creating-buckets",
id="chunk-1",
content="To create a bucket, use the Google Cloud console or gcloud CLI.",
):
self.parent = parent
self.id = id
self.content = content

class Document:
def __init__(
self,
name="documents/docs.cloud.google.com/storage/docs/creating-buckets",
title="Creating Buckets",
uri="docs.cloud.google.com/storage/docs/creating-buckets",
data_source="docs.cloud.google.com",
content_length_bytes=1024,
content="# Creating Buckets...",
):
self.name = name
self.title = title
self.uri = uri
self.data_source = data_source
self.content_length_bytes = content_length_bytes
self.content = content

class Answer:
def __init__(
self,
answer_text=(
"Use `gcloud storage buckets create` to create a new storage"
" bucket."
),
citations=None,
references=None,
):
self.answer_text = answer_text
self.citations = citations or []
self.references = references or []

class SearchDocumentChunksResponse:
def __init__(self, results=None):
self.results = results or [
DocumentChunk()
]

class BatchGetDocumentsResponse:
def __init__(self, documents=None):
self.documents = documents or []

class AnswerQueryResponse:
def __init__(self, answer=None):
self.answer = answer or Answer()

class DeveloperKnowledgeClient:
def search_document_chunks(self, request=None):
return SearchDocumentChunksResponse()

def get_document(self, request=None):
name = (
request.name
if request and request.name
else "documents/docs.cloud.google.com/storage/docs/creating-buckets"
)
return Document(name=name)

def batch_get_documents(self, request=None):
names = request.names if request and request.names else []
docs = [Document(name=n, title=f"Doc {n}") for n in names]
return BatchGetDocumentsResponse(documents=docs)

def answer_query(self, request=None):
return AnswerQueryResponse()

mock_dk.DeveloperKnowledgeClient = DeveloperKnowledgeClient
mock_dk.SearchDocumentChunksRequest = SearchDocumentChunksRequest
mock_dk.GetDocumentRequest = GetDocumentRequest
mock_dk.BatchGetDocumentsRequest = BatchGetDocumentsRequest
mock_dk.AnswerQueryRequest = AnswerQueryRequest
mock_dk.SearchDocumentChunksResponse = SearchDocumentChunksResponse
mock_dk.BatchGetDocumentsResponse = BatchGetDocumentsResponse
mock_dk.AnswerQueryResponse = AnswerQueryResponse
mock_dk.Document = Document
mock_dk.DocumentChunk = DocumentChunk

mock_google = MagicMock()
mock_cloud = MagicMock()
mock_cloud.developer_knowledge_v1 = mock_dk
mock_google.cloud = mock_cloud

sys.modules["google"] = mock_google
sys.modules["google.cloud"] = mock_cloud
sys.modules["google.cloud.developer_knowledge_v1"] = mock_dk
51 changes: 51 additions & 0 deletions developer-knowledge/get_document.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START developerknowledge_get_document]
from google.cloud import developer_knowledge_v1


def get_document(
name: str = "documents/docs.cloud.google.com/storage/docs/creating-buckets",
) -> developer_knowledge_v1.Document:
"""Retrieves a single developer documentation page by its resource name.

Args:
name: The resource name of the document in format
'documents/{uri_without_scheme}'.

Returns:
The Document containing the full Markdown content and metadata.
"""
client = developer_knowledge_v1.DeveloperKnowledgeClient()

request = developer_knowledge_v1.GetDocumentRequest(
name=name,
)

document = client.get_document(request=request)

print(f"Title: {document.title}")
print(f"URI: {document.uri}")
print(f"Data Source: {document.data_source}")
print(f"Content Length: {document.content_length_bytes} bytes")
print(f"Content Preview: {document.content[:150]}...\n")

return document


# [END developerknowledge_get_document]

if __name__ == "__main__":
get_document()
Loading