Skip to content

Commit a8394fa

Browse files
feat(api): add user feedback
1 parent 4bc752b commit a8394fa

File tree

7 files changed

+247
-3
lines changed

7 files changed

+247
-3
lines changed

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
configured_endpoints: 54
1+
configured_endpoints: 55
22
openapi_spec_hash: 7daf4896ba4932714f8fe4fff277d7c7
3-
config_hash: 930284cfa37f835d949c8a1b124f4807
3+
config_hash: bed87752f4056d0c4bf2ddf856307800

api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ Types:
202202
from codex.types.projects import (
203203
QueryLogRetrieveResponse,
204204
QueryLogListResponse,
205+
QueryLogAddUserFeedbackResponse,
205206
QueryLogListByGroupResponse,
206207
QueryLogListGroupsResponse,
207208
QueryLogStartRemediationResponse,
@@ -212,6 +213,7 @@ Methods:
212213

213214
- <code title="get /api/projects/{project_id}/query_logs/{query_log_id}">client.projects.query_logs.<a href="./src/codex/resources/projects/query_logs.py">retrieve</a>(query_log_id, \*, project_id) -> <a href="./src/codex/types/projects/query_log_retrieve_response.py">QueryLogRetrieveResponse</a></code>
214215
- <code title="get /api/projects/{project_id}/query_logs/">client.projects.query_logs.<a href="./src/codex/resources/projects/query_logs.py">list</a>(project_id, \*\*<a href="src/codex/types/projects/query_log_list_params.py">params</a>) -> <a href="./src/codex/types/projects/query_log_list_response.py">SyncOffsetPageQueryLogs[QueryLogListResponse]</a></code>
216+
- <code title="post /api/projects/{project_id}/query_logs/{query_log_id}/user_feedback">client.projects.query_logs.<a href="./src/codex/resources/projects/query_logs.py">add_user_feedback</a>(query_log_id, \*, project_id, \*\*<a href="src/codex/types/projects/query_log_add_user_feedback_params.py">params</a>) -> <a href="./src/codex/types/projects/query_log_add_user_feedback_response.py">QueryLogAddUserFeedbackResponse</a></code>
215217
- <code title="get /api/projects/{project_id}/query_logs/logs_by_group">client.projects.query_logs.<a href="./src/codex/resources/projects/query_logs.py">list_by_group</a>(project_id, \*\*<a href="src/codex/types/projects/query_log_list_by_group_params.py">params</a>) -> <a href="./src/codex/types/projects/query_log_list_by_group_response.py">QueryLogListByGroupResponse</a></code>
216218
- <code title="get /api/projects/{project_id}/query_logs/groups">client.projects.query_logs.<a href="./src/codex/resources/projects/query_logs.py">list_groups</a>(project_id, \*\*<a href="src/codex/types/projects/query_log_list_groups_params.py">params</a>) -> <a href="./src/codex/types/projects/query_log_list_groups_response.py">SyncOffsetPageQueryLogGroups[QueryLogListGroupsResponse]</a></code>
217219
- <code title="post /api/projects/{project_id}/query_logs/{query_log_id}/start_remediation">client.projects.query_logs.<a href="./src/codex/resources/projects/query_logs.py">start_remediation</a>(query_log_id, \*, project_id) -> <a href="./src/codex/types/projects/query_log_start_remediation_response.py">QueryLogStartRemediationResponse</a></code>

src/codex/resources/projects/query_logs.py

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,17 @@
2525
AsyncOffsetPageQueryLogGroups,
2626
)
2727
from ..._base_client import AsyncPaginator, make_request_options
28-
from ...types.projects import query_log_list_params, query_log_list_groups_params, query_log_list_by_group_params
28+
from ...types.projects import (
29+
query_log_list_params,
30+
query_log_list_groups_params,
31+
query_log_list_by_group_params,
32+
query_log_add_user_feedback_params,
33+
)
2934
from ...types.projects.query_log_list_response import QueryLogListResponse
3035
from ...types.projects.query_log_retrieve_response import QueryLogRetrieveResponse
3136
from ...types.projects.query_log_list_groups_response import QueryLogListGroupsResponse
3237
from ...types.projects.query_log_list_by_group_response import QueryLogListByGroupResponse
38+
from ...types.projects.query_log_add_user_feedback_response import QueryLogAddUserFeedbackResponse
3339
from ...types.projects.query_log_start_remediation_response import QueryLogStartRemediationResponse
3440

3541
__all__ = ["QueryLogsResource", "AsyncQueryLogsResource"]
@@ -184,6 +190,46 @@ def list(
184190
model=QueryLogListResponse,
185191
)
186192

193+
def add_user_feedback(
194+
self,
195+
query_log_id: str,
196+
*,
197+
project_id: str,
198+
key: str,
199+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
200+
# The extra values given here take precedence over values defined on the client or passed to this method.
201+
extra_headers: Headers | None = None,
202+
extra_query: Query | None = None,
203+
extra_body: Body | None = None,
204+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
205+
) -> QueryLogAddUserFeedbackResponse:
206+
"""
207+
Add User Feedback Route
208+
209+
Args:
210+
key: A key describing the criteria of the feedback, eg 'rating'
211+
212+
extra_headers: Send extra headers
213+
214+
extra_query: Add additional query parameters to the request
215+
216+
extra_body: Add additional JSON properties to the request
217+
218+
timeout: Override the client-level default timeout for this request, in seconds
219+
"""
220+
if not project_id:
221+
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
222+
if not query_log_id:
223+
raise ValueError(f"Expected a non-empty value for `query_log_id` but received {query_log_id!r}")
224+
return self._post(
225+
f"/api/projects/{project_id}/query_logs/{query_log_id}/user_feedback",
226+
body=maybe_transform({"key": key}, query_log_add_user_feedback_params.QueryLogAddUserFeedbackParams),
227+
options=make_request_options(
228+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
229+
),
230+
cast_to=QueryLogAddUserFeedbackResponse,
231+
)
232+
187233
def list_by_group(
188234
self,
189235
project_id: str,
@@ -568,6 +614,48 @@ def list(
568614
model=QueryLogListResponse,
569615
)
570616

617+
async def add_user_feedback(
618+
self,
619+
query_log_id: str,
620+
*,
621+
project_id: str,
622+
key: str,
623+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
624+
# The extra values given here take precedence over values defined on the client or passed to this method.
625+
extra_headers: Headers | None = None,
626+
extra_query: Query | None = None,
627+
extra_body: Body | None = None,
628+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
629+
) -> QueryLogAddUserFeedbackResponse:
630+
"""
631+
Add User Feedback Route
632+
633+
Args:
634+
key: A key describing the criteria of the feedback, eg 'rating'
635+
636+
extra_headers: Send extra headers
637+
638+
extra_query: Add additional query parameters to the request
639+
640+
extra_body: Add additional JSON properties to the request
641+
642+
timeout: Override the client-level default timeout for this request, in seconds
643+
"""
644+
if not project_id:
645+
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
646+
if not query_log_id:
647+
raise ValueError(f"Expected a non-empty value for `query_log_id` but received {query_log_id!r}")
648+
return await self._post(
649+
f"/api/projects/{project_id}/query_logs/{query_log_id}/user_feedback",
650+
body=await async_maybe_transform(
651+
{"key": key}, query_log_add_user_feedback_params.QueryLogAddUserFeedbackParams
652+
),
653+
options=make_request_options(
654+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
655+
),
656+
cast_to=QueryLogAddUserFeedbackResponse,
657+
)
658+
571659
async def list_by_group(
572660
self,
573661
project_id: str,
@@ -813,6 +901,9 @@ def __init__(self, query_logs: QueryLogsResource) -> None:
813901
self.list = to_raw_response_wrapper(
814902
query_logs.list,
815903
)
904+
self.add_user_feedback = to_raw_response_wrapper(
905+
query_logs.add_user_feedback,
906+
)
816907
self.list_by_group = to_raw_response_wrapper(
817908
query_logs.list_by_group,
818909
)
@@ -834,6 +925,9 @@ def __init__(self, query_logs: AsyncQueryLogsResource) -> None:
834925
self.list = async_to_raw_response_wrapper(
835926
query_logs.list,
836927
)
928+
self.add_user_feedback = async_to_raw_response_wrapper(
929+
query_logs.add_user_feedback,
930+
)
837931
self.list_by_group = async_to_raw_response_wrapper(
838932
query_logs.list_by_group,
839933
)
@@ -855,6 +949,9 @@ def __init__(self, query_logs: QueryLogsResource) -> None:
855949
self.list = to_streamed_response_wrapper(
856950
query_logs.list,
857951
)
952+
self.add_user_feedback = to_streamed_response_wrapper(
953+
query_logs.add_user_feedback,
954+
)
858955
self.list_by_group = to_streamed_response_wrapper(
859956
query_logs.list_by_group,
860957
)
@@ -876,6 +973,9 @@ def __init__(self, query_logs: AsyncQueryLogsResource) -> None:
876973
self.list = async_to_streamed_response_wrapper(
877974
query_logs.list,
878975
)
976+
self.add_user_feedback = async_to_streamed_response_wrapper(
977+
query_logs.add_user_feedback,
978+
)
879979
self.list_by_group = async_to_streamed_response_wrapper(
880980
query_logs.list_by_group,
881981
)

src/codex/types/projects/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
from .remediation_edit_answer_params import RemediationEditAnswerParams as RemediationEditAnswerParams
2828
from .query_log_list_by_group_response import QueryLogListByGroupResponse as QueryLogListByGroupResponse
2929
from .remediation_edit_answer_response import RemediationEditAnswerResponse as RemediationEditAnswerResponse
30+
from .query_log_add_user_feedback_params import QueryLogAddUserFeedbackParams as QueryLogAddUserFeedbackParams
31+
from .query_log_add_user_feedback_response import QueryLogAddUserFeedbackResponse as QueryLogAddUserFeedbackResponse
3032
from .query_log_start_remediation_response import QueryLogStartRemediationResponse as QueryLogStartRemediationResponse
3133
from .remediation_edit_draft_answer_params import RemediationEditDraftAnswerParams as RemediationEditDraftAnswerParams
3234
from .remediation_edit_draft_answer_response import (
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import Required, TypedDict
6+
7+
__all__ = ["QueryLogAddUserFeedbackParams"]
8+
9+
10+
class QueryLogAddUserFeedbackParams(TypedDict, total=False):
11+
project_id: Required[str]
12+
13+
key: Required[str]
14+
"""A key describing the criteria of the feedback, eg 'rating'"""
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from ..._models import BaseModel
4+
5+
__all__ = ["QueryLogAddUserFeedbackResponse"]
6+
7+
8+
class QueryLogAddUserFeedbackResponse(BaseModel):
9+
custom_metadata: object
10+
11+
query_log_id: str

tests/api_resources/projects/test_query_logs.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
QueryLogRetrieveResponse,
2222
QueryLogListGroupsResponse,
2323
QueryLogListByGroupResponse,
24+
QueryLogAddUserFeedbackResponse,
2425
QueryLogStartRemediationResponse,
2526
)
2627

@@ -146,6 +147,63 @@ def test_path_params_list(self, client: Codex) -> None:
146147
project_id="",
147148
)
148149

150+
@pytest.mark.skip(reason="Prism tests are disabled")
151+
@parametrize
152+
def test_method_add_user_feedback(self, client: Codex) -> None:
153+
query_log = client.projects.query_logs.add_user_feedback(
154+
query_log_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
155+
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
156+
key="key",
157+
)
158+
assert_matches_type(QueryLogAddUserFeedbackResponse, query_log, path=["response"])
159+
160+
@pytest.mark.skip(reason="Prism tests are disabled")
161+
@parametrize
162+
def test_raw_response_add_user_feedback(self, client: Codex) -> None:
163+
response = client.projects.query_logs.with_raw_response.add_user_feedback(
164+
query_log_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
165+
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
166+
key="key",
167+
)
168+
169+
assert response.is_closed is True
170+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
171+
query_log = response.parse()
172+
assert_matches_type(QueryLogAddUserFeedbackResponse, query_log, path=["response"])
173+
174+
@pytest.mark.skip(reason="Prism tests are disabled")
175+
@parametrize
176+
def test_streaming_response_add_user_feedback(self, client: Codex) -> None:
177+
with client.projects.query_logs.with_streaming_response.add_user_feedback(
178+
query_log_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
179+
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
180+
key="key",
181+
) as response:
182+
assert not response.is_closed
183+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
184+
185+
query_log = response.parse()
186+
assert_matches_type(QueryLogAddUserFeedbackResponse, query_log, path=["response"])
187+
188+
assert cast(Any, response.is_closed) is True
189+
190+
@pytest.mark.skip(reason="Prism tests are disabled")
191+
@parametrize
192+
def test_path_params_add_user_feedback(self, client: Codex) -> None:
193+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
194+
client.projects.query_logs.with_raw_response.add_user_feedback(
195+
query_log_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
196+
project_id="",
197+
key="key",
198+
)
199+
200+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `query_log_id` but received ''"):
201+
client.projects.query_logs.with_raw_response.add_user_feedback(
202+
query_log_id="",
203+
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
204+
key="key",
205+
)
206+
149207
@pytest.mark.skip(reason="Prism tests are disabled")
150208
@parametrize
151209
def test_method_list_by_group(self, client: Codex) -> None:
@@ -451,6 +509,63 @@ async def test_path_params_list(self, async_client: AsyncCodex) -> None:
451509
project_id="",
452510
)
453511

512+
@pytest.mark.skip(reason="Prism tests are disabled")
513+
@parametrize
514+
async def test_method_add_user_feedback(self, async_client: AsyncCodex) -> None:
515+
query_log = await async_client.projects.query_logs.add_user_feedback(
516+
query_log_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
517+
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
518+
key="key",
519+
)
520+
assert_matches_type(QueryLogAddUserFeedbackResponse, query_log, path=["response"])
521+
522+
@pytest.mark.skip(reason="Prism tests are disabled")
523+
@parametrize
524+
async def test_raw_response_add_user_feedback(self, async_client: AsyncCodex) -> None:
525+
response = await async_client.projects.query_logs.with_raw_response.add_user_feedback(
526+
query_log_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
527+
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
528+
key="key",
529+
)
530+
531+
assert response.is_closed is True
532+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
533+
query_log = await response.parse()
534+
assert_matches_type(QueryLogAddUserFeedbackResponse, query_log, path=["response"])
535+
536+
@pytest.mark.skip(reason="Prism tests are disabled")
537+
@parametrize
538+
async def test_streaming_response_add_user_feedback(self, async_client: AsyncCodex) -> None:
539+
async with async_client.projects.query_logs.with_streaming_response.add_user_feedback(
540+
query_log_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
541+
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
542+
key="key",
543+
) as response:
544+
assert not response.is_closed
545+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
546+
547+
query_log = await response.parse()
548+
assert_matches_type(QueryLogAddUserFeedbackResponse, query_log, path=["response"])
549+
550+
assert cast(Any, response.is_closed) is True
551+
552+
@pytest.mark.skip(reason="Prism tests are disabled")
553+
@parametrize
554+
async def test_path_params_add_user_feedback(self, async_client: AsyncCodex) -> None:
555+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"):
556+
await async_client.projects.query_logs.with_raw_response.add_user_feedback(
557+
query_log_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
558+
project_id="",
559+
key="key",
560+
)
561+
562+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `query_log_id` but received ''"):
563+
await async_client.projects.query_logs.with_raw_response.add_user_feedback(
564+
query_log_id="",
565+
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
566+
key="key",
567+
)
568+
454569
@pytest.mark.skip(reason="Prism tests are disabled")
455570
@parametrize
456571
async def test_method_list_by_group(self, async_client: AsyncCodex) -> None:

0 commit comments

Comments
 (0)