Skip to content

Commit 80031e2

Browse files
committed
update
1 parent 2821346 commit 80031e2

File tree

2 files changed

+2
-207
lines changed
  • sdk/cognitivelanguage/azure-ai-language-questionanswering

2 files changed

+2
-207
lines changed

sdk/cognitivelanguage/azure-ai-language-questionanswering/CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
* Removed client constructor keyword argument `default_language`. Per-call language control is now done explicitly via the `language` property on `AnswersFromTextOptions` (and related options models). The service default remains `"en"` if a language is not supplied. To change the effective language:
1111
* Pass `language="<bcp-47-code>"` when constructing `AnswersFromTextOptions` (e.g. `"es"`, `"zh-Hans"`).
1212
* Or create / select a project in the desired language in [Language Studio](https://language.azure.com) when authoring knowledge bases.
13-
* For resource/project level language behavior and multi-language strategies see: [Language support for custom question answering and projects](https://learn.microsoft.com/azure/ai-services/language-service/question-answering/language-support).
1413

1514
The previous implicit fallback (client-level `default_language`) has been removed to avoid hidden state and to encourage explicit specification or project-level configuration.
15+
* Removed support for passing metadata as `Dict[str,str]` to `MetadataFilter`. Tuple form `[("key","value"), ...]` and `List[MetadataRecord]` remain supported.
1616

1717
### Features Added
1818

@@ -22,7 +22,6 @@
2222

2323
* Internal refactoring and dependency grooming in preparation for the authoring/runtime split.
2424
* Changed samples and README examples to use explicit `AnswersOptions` / `AnswersFromTextOptions` objects as the first argument when calling `get_answers` and `get_answers_from_text`.
25-
* Restored backwards compatibility for `MetadataFilter.metadata` inputs so legacy dict or `(key, value)` tuple collections continue to work alongside the new `MetadataRecord` model type.
2625

2726
## 1.1.0 (2022-10-13)
2827

sdk/cognitivelanguage/azure-ai-language-questionanswering/azure/ai/language/questionanswering/models/_patch.py

Lines changed: 1 addition & 205 deletions
Original file line numberDiff line numberDiff line change
@@ -8,211 +8,7 @@
88
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
99
"""
1010

11-
from __future__ import annotations
12-
13-
from collections.abc import Iterable, Mapping, MutableMapping
14-
from typing import Any, Optional, Sequence, Tuple, Union, Mapping as TypingMapping, List, overload
15-
16-
from ._models import MetadataFilter as _GeneratedMetadataFilter
17-
from ._models import MetadataRecord
18-
from ._models import AnswersFromTextOptions as _GeneratedAnswersFromTextOptions
19-
from ._models import TextDocument
20-
21-
__all__: list[str] = ["MetadataFilter", "AnswersFromTextOptions"]
22-
23-
_MISSING = object()
24-
25-
26-
def _normalize_metadata_sequence(
27-
metadata: Any,
28-
) -> Optional[list[MetadataRecord]]:
29-
"""Coerce supported metadata inputs into MetadataRecord objects."""
30-
31-
if metadata is None:
32-
return None
33-
34-
# Single MetadataRecord instance
35-
if isinstance(metadata, MetadataRecord):
36-
return [metadata]
37-
38-
# Mapping inputs:
39-
if isinstance(metadata, Mapping):
40-
if "key" in metadata and "value" in metadata and len(metadata) <= 2:
41-
return [MetadataRecord(key=metadata["key"], value=metadata["value"])]
42-
metadata_iterable: Iterable[Any] = metadata.items()
43-
else:
44-
if isinstance(metadata, (str, bytes)):
45-
raise ValueError(
46-
"'metadata' must be provided as key/value pairs, MetadataRecord instances, "
47-
"or mappings; strings are not supported."
48-
)
49-
try:
50-
metadata_iterable = iter(metadata)
51-
except TypeError as exc: # pragma: no cover - defensive guard
52-
raise ValueError("'metadata' must be an iterable of key/value pairs or MetadataRecord instances.") from exc
53-
54-
normalized: list[MetadataRecord] = []
55-
for entry in metadata_iterable:
56-
if isinstance(entry, MetadataRecord):
57-
normalized.append(entry)
58-
continue
59-
if isinstance(entry, Mapping):
60-
if "key" in entry and "value" in entry:
61-
key = entry["key"]
62-
value = entry["value"]
63-
elif len(entry) == 1:
64-
key, value = next(iter(entry.items()))
65-
else:
66-
raise ValueError(
67-
"Mapping entries for 'metadata' must either contain 'key'/'value' keys "
68-
"or represent a single key/value pair."
69-
)
70-
else:
71-
if isinstance(entry, (str, bytes)):
72-
raise ValueError("Invalid metadata entry; expected a 2-item tuple but received a string/bytes value.")
73-
try:
74-
key, value = entry # type: ignore[assignment]
75-
except (TypeError, ValueError) as exc:
76-
raise ValueError(
77-
"Each metadata entry must be a MetadataRecord, a mapping with 'key'/'value', "
78-
"or a 2-item iterable representing (key, value)."
79-
) from exc
80-
normalized.append(MetadataRecord(key=key, value=value))
81-
82-
return normalized
83-
84-
85-
class MetadataFilter(_GeneratedMetadataFilter):
86-
"""Backward compatible MetadataFilter supporting legacy tuple/dict inputs.
87-
88-
Supported ``metadata`` input forms (all normalized to ``List[MetadataRecord]``):
89-
1. ``None`` – leave metadata unset.
90-
2. ``[("key","value"), ("k2","v2")]`` – list of 2-item tuples.
91-
3. ``[MetadataRecord(...), ...]`` – list of generated model records.
92-
4. ``[{"key": "k", "value": "v"}, ...]`` – list of mapping objects with key/value.
93-
5. ``{"k": "v", "k2": "v2"}`` – single mapping; each item becomes a record.
94-
6. ``{"key": "k", "value": "v"}`` – single record mapping.
95-
7. Mixed list: ``[MetadataRecord(...), ("k","v"), {"key":"a","value":"b"}]``.
96-
97-
Invalid inputs raise ``ValueError`` (e.g. plain string, bytes, malformed iterable).
98-
99-
The optional ``logical_operation`` parameter is passed through unchanged.
100-
"""
101-
102-
# Overload stubs to improve type hints and documentation rendering.
103-
@overload
104-
def __init__(self, *, metadata: None = ..., logical_operation: Optional[str] = ...) -> None: ... # noqa: D401,E701
105-
@overload
106-
def __init__(
107-
self, *, metadata: Sequence[Tuple[str, str]], logical_operation: Optional[str] = ...
108-
) -> None: ... # noqa: E701
109-
@overload
110-
def __init__(
111-
self, *, metadata: Sequence[MetadataRecord], logical_operation: Optional[str] = ...
112-
) -> None: ... # noqa: E701
113-
@overload
114-
def __init__(
115-
self, *, metadata: TypingMapping[str, str], logical_operation: Optional[str] = ...
116-
) -> None: ... # noqa: E701
117-
@overload
118-
def __init__(
119-
self,
120-
*,
121-
metadata: Sequence[Union[Tuple[str, str], MetadataRecord, TypingMapping[str, str]]],
122-
logical_operation: Optional[str] = ...,
123-
) -> None: ... # noqa: E701
124-
125-
def __init__(self, *args: Any, **kwargs: Any) -> None:
126-
metadata_kwarg = kwargs.pop("metadata", _MISSING)
127-
args_list = list(args)
128-
129-
if metadata_kwarg is not _MISSING:
130-
kwargs["metadata"] = _normalize_metadata_sequence(metadata_kwarg)
131-
elif args_list and isinstance(args_list[0], MutableMapping):
132-
first_mapping = dict(args_list[0])
133-
if "metadata" in first_mapping:
134-
first_mapping["metadata"] = _normalize_metadata_sequence(first_mapping["metadata"])
135-
args_list[0] = first_mapping
136-
137-
super().__init__(*args_list, **kwargs)
138-
139-
if self.metadata is not None:
140-
self.metadata = _normalize_metadata_sequence(self.metadata)
141-
142-
143-
class AnswersFromTextOptions(_GeneratedAnswersFromTextOptions):
144-
"""Convenience wrapper allowing ``text_documents`` to be a list of either ``str`` or ``TextDocument``.
145-
146-
This subclass accepts mixed inputs and converts plain strings to ``TextDocument`` instances
147-
with auto-generated incremental string IDs ("0", "1", ...). It also sets ``string_index_type``
148-
to ``"UnicodeCodePoint"`` for consistent offset interpretation, exposing it as an extra
149-
serialized field ``stringIndexType``.
150-
151-
Supported ``text_documents`` forms:
152-
1. ``["text one", "text two"]``
153-
2. ``[TextDocument(id="a", text="...")]``
154-
3. Mixed: ``["plain", TextDocument(id="b", text="...")]``
155-
156-
:param question: User question to query against the given text records. Required.
157-
:param text_documents: Text records as list of ``str`` or ``TextDocument``. Required.
158-
:param language: Optional BCP-47 language code, e.g. "en", "zh-Hans", "es".
159-
"""
160-
161-
@overload
162-
def __init__(
163-
self,
164-
*,
165-
question: str,
166-
text_documents: Sequence[str],
167-
language: Optional[str] = None,
168-
) -> None: ... # noqa: E701
169-
170-
@overload
171-
def __init__(
172-
self,
173-
*,
174-
question: str,
175-
text_documents: Sequence[TextDocument],
176-
language: Optional[str] = None,
177-
) -> None: ... # noqa: E701
178-
179-
@overload
180-
def __init__(
181-
self,
182-
*,
183-
question: str,
184-
text_documents: Sequence[Union[str, TextDocument]],
185-
language: Optional[str] = None,
186-
) -> None: ... # noqa: E701
187-
188-
def __init__(
189-
self,
190-
*,
191-
question: str,
192-
text_documents: Sequence[Union[str, TextDocument]],
193-
language: Optional[str] = None,
194-
**kwargs: Any,
195-
) -> None:
196-
# Normalize text_documents into List[TextDocument]
197-
normalized: List[TextDocument] = []
198-
for idx, doc in enumerate(text_documents):
199-
if isinstance(doc, TextDocument):
200-
normalized.append(doc)
201-
elif isinstance(doc, str):
202-
normalized.append(TextDocument(id=str(idx), text=doc))
203-
else:
204-
raise TypeError(
205-
"Each item in 'text_documents' must be either a str or TextDocument; got {}".format(type(doc))
206-
)
207-
super().__init__(question=question, text_documents=normalized, language=language, **kwargs)
208-
# Inject custom string index type attribute/serialization map
209-
self.string_index_type = "UnicodeCodePoint"
210-
# _attribute_map may not exist if underlying generator changed; guard accordingly.
211-
try: # pragma: no cover - defensive
212-
self._attribute_map.update({"string_index_type": {"key": "stringIndexType", "type": "str"}})
213-
except AttributeError:
214-
pass
215-
11+
__all__ = []
21612

21713
def patch_sdk():
21814
"""Do not remove from this file.

0 commit comments

Comments
 (0)