# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.datetime_utils import serialize_datetime
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
from ..errors.forbidden_error import ForbiddenError
from ..errors.internal_server_error import InternalServerError
from ..errors.request_timeout_error import RequestTimeoutError
from ..errors.too_many_requests_error import TooManyRequestsError
from ..errors.unauthorized_error import UnauthorizedError
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.additional_domain_info import AdditionalDomainInfo
from ..types.all_domain_links import AllDomainLinks
from ..types.all_links import AllLinks
from ..types.by_parse_date import ByParseDate
from ..types.clustering_enabled import ClusteringEnabled
from ..types.clustering_threshold import ClusteringThreshold
from ..types.clustering_variable import ClusteringVariable
from ..types.content_sentiment_max import ContentSentimentMax
from ..types.content_sentiment_min import ContentSentimentMin
from ..types.countries import Countries
from ..types.custom_tags import CustomTags
from ..types.error import Error
from ..types.exclude_duplicates import ExcludeDuplicates
from ..types.from_ import From
from ..types.from_rank import FromRank
from ..types.has_nlp import HasNlp
from ..types.iab_tags import IabTags
from ..types.include_nlp_data import IncludeNlpData
from ..types.include_translation_fields import IncludeTranslationFields
from ..types.iptc_tags import IptcTags
from ..types.is_headline import IsHeadline
from ..types.is_news_domain import IsNewsDomain
from ..types.is_opinion import IsOpinion
from ..types.is_paid_content import IsPaidContent
from ..types.lang import Lang
from ..types.loc_entity_name import LocEntityName
from ..types.misc_entity_name import MiscEntityName
from ..types.news_domain_type import NewsDomainType
from ..types.news_type import NewsType
from ..types.not_author_name import NotAuthorName
from ..types.not_countries import NotCountries
from ..types.not_iab_tags import NotIabTags
from ..types.not_iptc_tags import NotIptcTags
from ..types.not_lang import NotLang
from ..types.not_sources import NotSources
from ..types.not_theme import NotTheme
from ..types.org_entity_name import OrgEntityName
from ..types.page import Page
from ..types.page_size import PageSize
from ..types.parent_url import ParentUrl
from ..types.per_entity_name import PerEntityName
from ..types.predefined_sources import PredefinedSources
from ..types.published_date_precision import PublishedDatePrecision
from ..types.q import Q
from ..types.ranked_only import RankedOnly
from ..types.robots_compliant import RobotsCompliant
from ..types.search_in import SearchIn
from ..types.sort_by import SortBy
from ..types.source_name import SourceName
from ..types.sources import Sources
from ..types.theme import Theme
from ..types.title_sentiment_max import TitleSentimentMax
from ..types.title_sentiment_min import TitleSentimentMin
from ..types.to import To
from ..types.to_rank import ToRank
from ..types.word_count_max import WordCountMax
from ..types.word_count_min import WordCountMin
from .types.search_get_request_clustering_variable import SearchGetRequestClusteringVariable
from .types.search_get_request_news_domain_type import SearchGetRequestNewsDomainType
from .types.search_get_request_published_date_precision import SearchGetRequestPublishedDatePrecision
from .types.search_get_request_sort_by import SearchGetRequestSortBy
from .types.search_get_response import SearchGetResponse
from .types.search_post_response import SearchPostResponse

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawSearchClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def get(
        self,
        *,
        q: str,
        search_in: typing.Optional[SearchIn] = None,
        include_translation_fields: typing.Optional[IncludeTranslationFields] = None,
        predefined_sources: typing.Optional[str] = None,
        source_name: typing.Optional[str] = None,
        sources: typing.Optional[str] = None,
        not_sources: typing.Optional[str] = None,
        lang: typing.Optional[str] = None,
        not_lang: typing.Optional[str] = None,
        countries: typing.Optional[str] = None,
        not_countries: typing.Optional[str] = None,
        not_author_name: typing.Optional[str] = None,
        from_: typing.Optional[dt.datetime] = None,
        to: typing.Optional[dt.datetime] = None,
        published_date_precision: typing.Optional[SearchGetRequestPublishedDatePrecision] = None,
        by_parse_date: typing.Optional[bool] = None,
        sort_by: typing.Optional[SearchGetRequestSortBy] = None,
        ranked_only: typing.Optional[bool] = None,
        from_rank: typing.Optional[int] = None,
        to_rank: typing.Optional[int] = None,
        is_headline: typing.Optional[bool] = None,
        is_opinion: typing.Optional[bool] = None,
        is_paid_content: typing.Optional[bool] = None,
        parent_url: typing.Optional[str] = None,
        all_links: typing.Optional[str] = None,
        all_domain_links: typing.Optional[str] = None,
        additional_domain_info: typing.Optional[bool] = None,
        is_news_domain: typing.Optional[bool] = None,
        news_domain_type: typing.Optional[SearchGetRequestNewsDomainType] = None,
        news_type: typing.Optional[str] = None,
        word_count_min: typing.Optional[int] = None,
        word_count_max: typing.Optional[int] = None,
        page: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        clustering_enabled: typing.Optional[bool] = None,
        clustering_variable: typing.Optional[SearchGetRequestClusteringVariable] = None,
        clustering_threshold: typing.Optional[float] = None,
        include_nlp_data: typing.Optional[IncludeNlpData] = None,
        has_nlp: typing.Optional[HasNlp] = None,
        theme: typing.Optional[str] = None,
        not_theme: typing.Optional[str] = None,
        org_entity_name: typing.Optional[str] = None,
        per_entity_name: typing.Optional[str] = None,
        loc_entity_name: typing.Optional[str] = None,
        misc_entity_name: typing.Optional[str] = None,
        title_sentiment_min: typing.Optional[float] = None,
        title_sentiment_max: typing.Optional[float] = None,
        content_sentiment_min: typing.Optional[float] = None,
        content_sentiment_max: typing.Optional[float] = None,
        iptc_tags: typing.Optional[str] = None,
        not_iptc_tags: typing.Optional[str] = None,
        iab_tags: typing.Optional[str] = None,
        not_iab_tags: typing.Optional[str] = None,
        custom_tags: typing.Optional[str] = None,
        exclude_duplicates: typing.Optional[bool] = None,
        robots_compliant: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[SearchGetResponse]:
        """
        Searches for articles based on specified criteria such as keyword, language, country, source, and more.

        Parameters
        ----------
        q : str
            The keyword(s) to search for in articles. Query syntax supports logical operators (`AND`, `OR`, `NOT`) and wildcards:

            - For an exact match, use double quotes. For example, `"technology news"`.
            - Use `*` to search for any keyword.
            - Use `+` to include and `-` to exclude specific words or phrases.
              For example, `+Apple`, `-Google`.
            - Use `AND`, `OR`, and `NOT` to refine search results.
              For example, `technology AND (Apple OR Microsoft) NOT Google`.

            For more details, see [Advanced querying](/docs/v3/documentation/guides-and-concepts/advanced-querying).

        search_in : typing.Optional[SearchIn]

        include_translation_fields : typing.Optional[IncludeTranslationFields]

        predefined_sources : typing.Optional[str]
            Predefined top news sources per country.

            Format: start with the word `top`, followed by the number of desired sources, and then the two-letter country code [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Multiple countries with the number of top sources can be specified as a comma-separated string.

            Examples:
            - `"top 100 US"`
            - `"top 33 AT"`
            - `"top 50 US, top 20 GB"`
            - `"top 33 AT, top 50 IT"`

        source_name : typing.Optional[str]
            Word or phrase to search within the source names. To specify multiple values, use a comma-separated string.

            Example: `"sport, tech"`

            **Note**: The search doesn't require an exact match and returns sources containing the specified terms in their names. You can use any word or phrase, like `"sport"` or `"new york times"`. For example, `"sport"` returns sources such as `"Motorsport"`, `"Dot Esport"`, and `"Tuttosport"`.

        sources : typing.Optional[str]
            One or more news sources to narrow down the search. The format must be a domain URL. Subdomains, such as `finance.yahoo.com`, are also acceptable.To specify multiple sources, use a comma-separated string.

            Examples:
            - `"nytimes.com"`
            - `"theguardian.com, finance.yahoo.com"`

        not_sources : typing.Optional[str]
            The news sources to exclude from the search. To exclude multiple sources, use a comma-separated string.

            Example: `"cnn.com, wsj.com"`

        lang : typing.Optional[str]
            The language(s) of the search. The only accepted format is the two-letter [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) code. To select multiple languages, use a comma-separated string.

            Example: `"en, es"`

            To learn more, see [Enumerated parameters > Language](/docs/v3/api-reference/overview/enumerated-parameters#language-lang-and-not-lang).

        not_lang : typing.Optional[str]
            The language(s) to exclude from the search. The accepted format is the two-letter [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) code. To exclude multiple languages, use a comma-separated string.

            Example: `"fr, de"`

            To learn more, see [Enumerated parameters > Language](/docs/v3/api-reference/overview/enumerated-parameters#language-lang-and-not-lang).

        countries : typing.Optional[str]
            The countries where the news publisher is located. The accepted format is the two-letter [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. To select multiple countries, use a comma-separated string.

            Example: `"US, CA"`

            To learn more, see [Enumerated parameters > Country](/docs/v3/api-reference/overview/enumerated-parameters#country-country-and-not-country).

        not_countries : typing.Optional[str]
            The publisher location countries to exclude from the search. The accepted format is the two-letter [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. To exclude multiple countries, use a comma-separated string.

            Example:`"US, CA"`

            To learn more, see [Enumerated parameters > Country](/docs/v3/api-reference/overview/enumerated-parameters#country-country-and-not-country).

        not_author_name : typing.Optional[str]
            The list of author names to exclude from your search. To exclude articles by specific authors, use a comma-separated string.

            Example: `"John Doe, Jane Doe"`

        from_ : typing.Optional[dt.datetime]
            The starting point in time to search from. Accepts date-time strings in ISO 8601 format and plain text. The default time zone is UTC.

            Formats with examples:
            - YYYY-mm-ddTHH:MM:SS: `2024-07-01T00:00:00`
            - YYYY-MM-dd: `2024-07-01`
            - YYYY/mm/dd HH:MM:SS: `2024/07/01 00:00:00`
            - YYYY/mm/dd: `2024/07/01`
            - English phrases: `7 day ago`, `today`

            **Note**: By default, applied to the publication date of the article. To use the article's parse date instead, set the `by_parse_date` parameter to `true`.

        to : typing.Optional[dt.datetime]
            The ending point in time to search up to. Accepts date-time strings in ISO 8601 format and plain text. The default time zone is UTC.

            Formats with examples:
            - YYYY-mm-ddTHH:MM:SS: `2024-07-01T00:00:00`
            - YYYY-MM-dd: `2024-07-01`
            - YYYY/mm/dd HH:MM:SS: `2024/07/01 00:00:00`
            - YYYY/mm/dd: `2024/07/01`
            - English phrases: `1 day ago`, `now`

            **Note**: By default, applied to the publication date of the article. To use the article's parse date instead, set the `by_parse_date` parameter to `true`.

        published_date_precision : typing.Optional[SearchGetRequestPublishedDatePrecision]
            The precision of the published date. There are three types:
            - `full`: The day and time of an article is correctly identified with the appropriate timezone.
            - `timezone unknown`: The day and time of an article is correctly identified without timezone.
            - `date`: Only the day is identified without an exact time.

        by_parse_date : typing.Optional[bool]
            If true, the `from_` and `to_` parameters use article parse dates instead of published dates. Additionally, the `parse_date` variable is added to the output for each article object.

        sort_by : typing.Optional[SearchGetRequestSortBy]
            The sorting order of the results. Possible values are:
            - `relevancy`: The most relevant results first.
            - `date`: The most recently published results first.
            - `rank`: The results from the highest-ranked sources first.

        ranked_only : typing.Optional[bool]
            If true, limits the search to sources ranked in the top 1 million online websites. If false, includes unranked sources which are assigned a rank of 999999.

        from_rank : typing.Optional[int]
            The lowest boundary of the rank of a news website to filter by. A lower rank indicates a more popular source.

        to_rank : typing.Optional[int]
            The highest boundary of the rank of a news website to filter by. A lower rank indicates a more popular source.

        is_headline : typing.Optional[bool]
            If true, only returns articles that were posted on the home page of a given news domain.

        is_opinion : typing.Optional[bool]
            If true, returns only opinion pieces. If false, excludes opinion-based articles and returns news only.

        is_paid_content : typing.Optional[bool]
            If false, returns only articles that have publicly available complete content. Some publishers partially block content, so this setting ensures that only full articles are retrieved.

        parent_url : typing.Optional[str]
            The categorical URL(s) to filter your search. To filter your search by multiple categorical URLs, use a comma-separated string.

            Example: `"wsj.com/politics, wsj.com/tech"`

        all_links : typing.Optional[str]
            The complete URL(s) mentioned in the article. For multiple URLs, use a comma-separated string.

            Example: `"https://aiindex.stanford.edu/report, https://www.stateof.ai"`

            For more details, see [Search by URL](/docs/v3/documentation/how-to/search-by-url).

        all_domain_links : typing.Optional[str]
            The domain(s) mentioned in the article. For multiple domains, use a comma-separated string.

            Example: `"who.int, nih.gov"`

            For more details, see [Search by URL](/docs/v3/documentation/how-to/search-by-url).

        additional_domain_info : typing.Optional[bool]
            If true, includes additional domain information in the response for each article:
            - `is_news_domain`: Boolean indicating if the source is a news domain.
            - `news_domain_type`: Type of news domain (e.g., `"Original Content"`).
            - `news_type`: Category of news (e.g., `"News and Blogs"`).

        is_news_domain : typing.Optional[bool]
            If true, filters results to include only news domains.

        news_domain_type : typing.Optional[SearchGetRequestNewsDomainType]
            Filters results based on the news domain type. Possible values are:
            - `Original Content`: Sources that produce their own content.
            - `Aggregator`: Sources that collect content from various other sources.
            - `Press Releases`: Sources primarily publishing press releases.
            - `Republisher`: Sources that republish content from other sources.
            - `Other`: Sources that don't fit into main categories.

        news_type : typing.Optional[str]
            Filters results based on the news type. Multiple types can be specified using a comma-separated string.

            Example: `"General News Outlets,Tech News and Updates"`

            For a complete list of available news types, see [Enumerated parameters > News type](/docs/v3/api-reference/overview/enumerated-parameters#news-type-news-type).

        word_count_min : typing.Optional[int]
            The minimum number of words an article must contain. To be used for avoiding articles with small content.

        word_count_max : typing.Optional[int]
            The maximum number of words an article can contain. To be used for avoiding articles with large content.

        page : typing.Optional[int]
            The page number to scroll through the results. Use for pagination, as a single API response can return up to 1,000 articles.

            For details, see [How to paginate large datasets](https://www.newscatcherapi.com/docs/v3/documentation/how-to/paginate-large-datasets).

        page_size : typing.Optional[int]
            The number of articles to return per page.

        clustering_enabled : typing.Optional[bool]
            Determines whether to group similar articles into clusters. If true, the API returns clustered results.

            To learn more, see [Clustering news articles](/docs/v3/documentation/guides-and-concepts/clustering-news-articles).

        clustering_variable : typing.Optional[SearchGetRequestClusteringVariable]
            Specifies which part of the article to use for determining similarity when clustering.

            Possible values are:
            - `content`: Uses the full article content (default).
            - `title`: Uses only the article title.
            - `summary`: Uses the article summary.

            To learn more, see [Clustering news articles](/docs/v3/documentation/guides-and-concepts/clustering-news-articles).

        clustering_threshold : typing.Optional[float]
            Sets the similarity threshold for grouping articles into clusters. A lower value creates more inclusive clusters, while a higher value requires greater similarity between articles.

            Examples:
            - `0.3`: Results in larger, more diverse clusters.
            - `0.6`: Balances cluster size and article similarity (default).
            - `0.9`: Creates smaller, tightly related clusters.

            To learn more, see [Clustering news articles](/docs/v3/documentation/guides-and-concepts/clustering-news-articles).

        include_nlp_data : typing.Optional[IncludeNlpData]

        has_nlp : typing.Optional[HasNlp]

        theme : typing.Optional[str]
            Filters articles based on their general topic, as determined by NLP analysis. To select multiple themes, use a comma-separated string.

            Example: `"Finance, Tech"`

            **Note**: The `theme` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

            Available options: `Business`, `Economics`, `Entertainment`, `Finance`, `Health`, `Politics`, `Science`, `Sports`, `Tech`, `Crime`, `Financial Crime`, `Lifestyle`, `Automotive`, `Travel`, `Weather`, `General`.

        not_theme : typing.Optional[str]
            Inverse of the `theme` parameter. Excludes articles based on their general topic, as determined by NLP analysis. To exclude multiple themes, use a comma-separated string.

            Example: `"Crime, Tech"`

            **Note**: The `not_theme` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        org_entity_name : typing.Optional[str]
            Filters articles that mention specific organization names, as identified by NLP analysis. To specify multiple organizations, use a comma-separated string. To search named entities in translations, combine with the translation options of the `search_in` parameter (e.g., `title_content_translated`).

            Example: `"Apple, Microsoft"`

            **Note**: The `ORG_entity_name` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [Search by entity](/docs/v3/documentation/how-to/search-by-entity).

        per_entity_name : typing.Optional[str]
            Filters articles that mention specific person names, as identified by NLP analysis. To specify multiple names, use a comma-separated string. To search named entities in translations, combine with the translation options of the `search_in` parameter (e.g., `title_content_translated`).

            Example: `"Elon Musk, Jeff Bezos"`

            **Note**: The `PER_entity_name` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [Search by entity](/docs/v3/documentation/how-to/search-by-entity).

        loc_entity_name : typing.Optional[str]
            Filters articles that mention specific location names, as identified by NLP analysis. To specify multiple locations, use a comma-separated string. To search named entities in translations, combine with the translation options of the `search_in` parameter (e.g., `title_content_translated`).

            Example: `"California, New York"`

            **Note**: The `LOC_entity_name` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [Search by entity](/docs/v3/documentation/how-to/search-by-entity).

        misc_entity_name : typing.Optional[str]
            Filters articles that mention other named entities not falling under person, organization, or location categories. Includes events, nationalities, products, works of art, and more. To specify multiple entities, use a comma-separated string. To search named entities in translations, combine with the translation options of the `search_in` parameter (e.g., `title_content_translated`).

            Example: `"Bitcoin, Blockchain"`

            **Note**: The `MISC_entity_name` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [Search by entity](/docs/v3/documentation/how-to/search-by-entity).

        title_sentiment_min : typing.Optional[float]
            Filters articles based on the minimum sentiment score of their titles.

            Range is `-1.0` to `1.0`, where:
            - Negative values indicate negative sentiment.
            - Positive values indicate positive sentiment.
            - Values close to 0 indicate neutral sentiment.

            **Note**: The `title_sentiment_min` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        title_sentiment_max : typing.Optional[float]
            Filters articles based on the maximum sentiment score of their titles.

            Range is `-1.0` to `1.0`, where:
            - Negative values indicate negative sentiment.
            - Positive values indicate positive sentiment.
            - Values close to 0 indicate neutral sentiment.

            **Note**: The `title_sentiment_max` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        content_sentiment_min : typing.Optional[float]
            Filters articles based on the minimum sentiment score of their content.

            Range is `-1.0` to `1.0`, where:
            - Negative values indicate negative sentiment.
            - Positive values indicate positive sentiment.
            - Values close to 0 indicate neutral sentiment.

            **Note**: The `content_sentiment_min` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        content_sentiment_max : typing.Optional[float]
            Filters articles based on the maximum sentiment score of their content.

            Range is `-1.0` to `1.0`, where:
            - Negative values indicate negative sentiment.
            - Positive values indicate positive sentiment.
            - Values close to 0 indicate neutral sentiment.

            **Note**: The `content_sentiment_max` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        iptc_tags : typing.Optional[str]
            Filters articles based on International Press Telecommunications Council (IPTC) media topic tags. To specify multiple IPTC tags, use a comma-separated string of tag IDs.

            Example: `"20000199, 20000209"`

            **Note**: The `iptc_tags` parameter is only available in the `v3_nlp_iptc_tags` subscription plan.

            To learn more, see [IPTC Media Topic NewsCodes](https://www.iptc.org/std/NewsCodes/treeview/mediatopic/mediatopic-en-GB.html).

        not_iptc_tags : typing.Optional[str]
            Inverse of the `iptc_tags` parameter. Excludes articles based on International Press Telecommunications Council (IPTC) media topic tags. To specify multiple IPTC tags to exclude, use a comma-separated string of tag IDs.

            Example: `"20000205, 20000209"`

            **Note**: The `not_iptc_tags` parameter is only available in the `v3_nlp_iptc_tags` subscription plan.

            To learn more, see [IPTC Media Topic NewsCodes](https://www.iptc.org/std/NewsCodes/treeview/mediatopic/mediatopic-en-GB.html).

        iab_tags : typing.Optional[str]
            Filters articles based on Interactive Advertising Bureau (IAB) content categories. These tags provide a standardized taxonomy for digital advertising content categorization. To specify multiple IAB categories, use a comma-separated string.

            Example: `"Business, Events"`

            **Note**: The `iab_tags` parameter is only available in the `v3_nlp_iptc_tags` subscription plan.

            To learn more, see the [IAB Content taxonomy](https://iabtechlab.com/standards/content-taxonomy/).

        not_iab_tags : typing.Optional[str]
            Inverse of the `iab_tags` parameter. Excludes articles based on Interactive Advertising Bureau (IAB) content categories. These tags provide a standardized taxonomy for digital advertising content categorization. To specify multiple IAB categories to exclude, use a comma-separated string.

            Example: `"Agriculture, Metals"`

            **Note**: The `not_iab_tags` parameter is only available in the `v3_nlp_iptc_tags` subscription plan.

            To learn more, see the [IAB Content taxonomy](https://iabtechlab.com/standards/content-taxonomy/).

        custom_tags : typing.Optional[str]
            Filters articles based on provided taxonomy that is tailored to your specific needs and is accessible only with your API key. To specify tags, use the following pattern:

            - `custom_tags.taxonomy=Tag1,Tag2,Tag3`, where `taxonomy` is the taxonomy name and `Tag1,Tag2,Tag3` is a comma-separated list of tags.

            Example: `custom_tags.industry="Manufacturing, Supply Chain, Logistics"`

            To learn more, see the [Custom tags](/docs/v3/documentation/guides-and-concepts/custom-tags).

        exclude_duplicates : typing.Optional[bool]
            If true, excludes duplicate and highly similar articles from the search results. If false, returns all relevant articles, including duplicates.

            To learn more, see [Articles deduplication](/docs/v3/documentation/guides-and-concepts/articles-deduplication).

        robots_compliant : typing.Optional[bool]
            If true, returns only articles/sources that comply with the publisher's robots.txt rules. If false, returns only articles/sources that do not comply with robots.txt rules. If omitted, returns all articles/sources regardless of compliance status.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[SearchGetResponse]
            A successful response containing articles that match the specified search criteria. The response may include clustering information if enabled.
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/search",
            method="GET",
            params={
                "q": q,
                "search_in": search_in,
                "include_translation_fields": include_translation_fields,
                "predefined_sources": predefined_sources,
                "source_name": source_name,
                "sources": sources,
                "not_sources": not_sources,
                "lang": lang,
                "not_lang": not_lang,
                "countries": countries,
                "not_countries": not_countries,
                "not_author_name": not_author_name,
                "from_": serialize_datetime(from_) if from_ is not None else None,
                "to_": serialize_datetime(to) if to is not None else None,
                "published_date_precision": published_date_precision,
                "by_parse_date": by_parse_date,
                "sort_by": sort_by,
                "ranked_only": ranked_only,
                "from_rank": from_rank,
                "to_rank": to_rank,
                "is_headline": is_headline,
                "is_opinion": is_opinion,
                "is_paid_content": is_paid_content,
                "parent_url": parent_url,
                "all_links": all_links,
                "all_domain_links": all_domain_links,
                "additional_domain_info": additional_domain_info,
                "is_news_domain": is_news_domain,
                "news_domain_type": news_domain_type,
                "news_type": news_type,
                "word_count_min": word_count_min,
                "word_count_max": word_count_max,
                "page": page,
                "page_size": page_size,
                "clustering_enabled": clustering_enabled,
                "clustering_variable": clustering_variable,
                "clustering_threshold": clustering_threshold,
                "include_nlp_data": include_nlp_data,
                "has_nlp": has_nlp,
                "theme": theme,
                "not_theme": not_theme,
                "ORG_entity_name": org_entity_name,
                "PER_entity_name": per_entity_name,
                "LOC_entity_name": loc_entity_name,
                "MISC_entity_name": misc_entity_name,
                "title_sentiment_min": title_sentiment_min,
                "title_sentiment_max": title_sentiment_max,
                "content_sentiment_min": content_sentiment_min,
                "content_sentiment_max": content_sentiment_max,
                "iptc_tags": iptc_tags,
                "not_iptc_tags": not_iptc_tags,
                "iab_tags": iab_tags,
                "not_iab_tags": not_iab_tags,
                "custom_tags": custom_tags,
                "exclude_duplicates": exclude_duplicates,
                "robots_compliant": robots_compliant,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchGetResponse,
                    parse_obj_as(
                        type_=SearchGetResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 408:
                raise RequestTimeoutError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def post(
        self,
        *,
        q: Q,
        search_in: typing.Optional[SearchIn] = OMIT,
        include_translation_fields: typing.Optional[IncludeTranslationFields] = OMIT,
        predefined_sources: typing.Optional[PredefinedSources] = OMIT,
        source_name: typing.Optional[SourceName] = OMIT,
        sources: typing.Optional[Sources] = OMIT,
        not_sources: typing.Optional[NotSources] = OMIT,
        lang: typing.Optional[Lang] = OMIT,
        not_lang: typing.Optional[NotLang] = OMIT,
        countries: typing.Optional[Countries] = OMIT,
        not_countries: typing.Optional[NotCountries] = OMIT,
        not_author_name: typing.Optional[NotAuthorName] = OMIT,
        from_: typing.Optional[From] = OMIT,
        to: typing.Optional[To] = OMIT,
        published_date_precision: typing.Optional[PublishedDatePrecision] = OMIT,
        by_parse_date: typing.Optional[ByParseDate] = OMIT,
        sort_by: typing.Optional[SortBy] = OMIT,
        ranked_only: typing.Optional[RankedOnly] = OMIT,
        from_rank: typing.Optional[FromRank] = OMIT,
        to_rank: typing.Optional[ToRank] = OMIT,
        is_headline: typing.Optional[IsHeadline] = OMIT,
        is_opinion: typing.Optional[IsOpinion] = OMIT,
        is_paid_content: typing.Optional[IsPaidContent] = OMIT,
        parent_url: typing.Optional[ParentUrl] = OMIT,
        all_links: typing.Optional[AllLinks] = OMIT,
        all_domain_links: typing.Optional[AllDomainLinks] = OMIT,
        additional_domain_info: typing.Optional[AdditionalDomainInfo] = OMIT,
        is_news_domain: typing.Optional[IsNewsDomain] = OMIT,
        news_domain_type: typing.Optional[NewsDomainType] = OMIT,
        news_type: typing.Optional[NewsType] = OMIT,
        word_count_min: typing.Optional[WordCountMin] = OMIT,
        word_count_max: typing.Optional[WordCountMax] = OMIT,
        page: typing.Optional[Page] = OMIT,
        page_size: typing.Optional[PageSize] = OMIT,
        clustering_enabled: typing.Optional[ClusteringEnabled] = OMIT,
        clustering_variable: typing.Optional[ClusteringVariable] = OMIT,
        clustering_threshold: typing.Optional[ClusteringThreshold] = OMIT,
        include_nlp_data: typing.Optional[IncludeNlpData] = OMIT,
        has_nlp: typing.Optional[HasNlp] = OMIT,
        theme: typing.Optional[Theme] = OMIT,
        not_theme: typing.Optional[NotTheme] = OMIT,
        org_entity_name: typing.Optional[OrgEntityName] = OMIT,
        per_entity_name: typing.Optional[PerEntityName] = OMIT,
        loc_entity_name: typing.Optional[LocEntityName] = OMIT,
        misc_entity_name: typing.Optional[MiscEntityName] = OMIT,
        title_sentiment_min: typing.Optional[TitleSentimentMin] = OMIT,
        title_sentiment_max: typing.Optional[TitleSentimentMax] = OMIT,
        content_sentiment_min: typing.Optional[ContentSentimentMin] = OMIT,
        content_sentiment_max: typing.Optional[ContentSentimentMax] = OMIT,
        iptc_tags: typing.Optional[IptcTags] = OMIT,
        not_iptc_tags: typing.Optional[NotIptcTags] = OMIT,
        iab_tags: typing.Optional[IabTags] = OMIT,
        not_iab_tags: typing.Optional[NotIabTags] = OMIT,
        custom_tags: typing.Optional[CustomTags] = OMIT,
        exclude_duplicates: typing.Optional[ExcludeDuplicates] = OMIT,
        robots_compliant: typing.Optional[RobotsCompliant] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[SearchPostResponse]:
        """
        Searches for articles based on specified criteria such as keyword, language, country, source, and more.

        Parameters
        ----------
        q : Q

        search_in : typing.Optional[SearchIn]

        include_translation_fields : typing.Optional[IncludeTranslationFields]

        predefined_sources : typing.Optional[PredefinedSources]

        source_name : typing.Optional[SourceName]

        sources : typing.Optional[Sources]

        not_sources : typing.Optional[NotSources]

        lang : typing.Optional[Lang]

        not_lang : typing.Optional[NotLang]

        countries : typing.Optional[Countries]

        not_countries : typing.Optional[NotCountries]

        not_author_name : typing.Optional[NotAuthorName]

        from_ : typing.Optional[From]

        to : typing.Optional[To]

        published_date_precision : typing.Optional[PublishedDatePrecision]

        by_parse_date : typing.Optional[ByParseDate]

        sort_by : typing.Optional[SortBy]

        ranked_only : typing.Optional[RankedOnly]

        from_rank : typing.Optional[FromRank]

        to_rank : typing.Optional[ToRank]

        is_headline : typing.Optional[IsHeadline]

        is_opinion : typing.Optional[IsOpinion]

        is_paid_content : typing.Optional[IsPaidContent]

        parent_url : typing.Optional[ParentUrl]

        all_links : typing.Optional[AllLinks]

        all_domain_links : typing.Optional[AllDomainLinks]

        additional_domain_info : typing.Optional[AdditionalDomainInfo]

        is_news_domain : typing.Optional[IsNewsDomain]

        news_domain_type : typing.Optional[NewsDomainType]

        news_type : typing.Optional[NewsType]

        word_count_min : typing.Optional[WordCountMin]

        word_count_max : typing.Optional[WordCountMax]

        page : typing.Optional[Page]

        page_size : typing.Optional[PageSize]

        clustering_enabled : typing.Optional[ClusteringEnabled]

        clustering_variable : typing.Optional[ClusteringVariable]

        clustering_threshold : typing.Optional[ClusteringThreshold]

        include_nlp_data : typing.Optional[IncludeNlpData]

        has_nlp : typing.Optional[HasNlp]

        theme : typing.Optional[Theme]

        not_theme : typing.Optional[NotTheme]

        org_entity_name : typing.Optional[OrgEntityName]

        per_entity_name : typing.Optional[PerEntityName]

        loc_entity_name : typing.Optional[LocEntityName]

        misc_entity_name : typing.Optional[MiscEntityName]

        title_sentiment_min : typing.Optional[TitleSentimentMin]

        title_sentiment_max : typing.Optional[TitleSentimentMax]

        content_sentiment_min : typing.Optional[ContentSentimentMin]

        content_sentiment_max : typing.Optional[ContentSentimentMax]

        iptc_tags : typing.Optional[IptcTags]

        not_iptc_tags : typing.Optional[NotIptcTags]

        iab_tags : typing.Optional[IabTags]

        not_iab_tags : typing.Optional[NotIabTags]

        custom_tags : typing.Optional[CustomTags]

        exclude_duplicates : typing.Optional[ExcludeDuplicates]

        robots_compliant : typing.Optional[RobotsCompliant]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[SearchPostResponse]
            A successful response containing articles that match the specified search criteria. The response may include clustering information if enabled.
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/search",
            method="POST",
            json={
                "q": q,
                "search_in": search_in,
                "include_translation_fields": include_translation_fields,
                "predefined_sources": convert_and_respect_annotation_metadata(
                    object_=predefined_sources, annotation=PredefinedSources, direction="write"
                ),
                "source_name": convert_and_respect_annotation_metadata(
                    object_=source_name, annotation=SourceName, direction="write"
                ),
                "sources": convert_and_respect_annotation_metadata(
                    object_=sources, annotation=Sources, direction="write"
                ),
                "not_sources": convert_and_respect_annotation_metadata(
                    object_=not_sources, annotation=NotSources, direction="write"
                ),
                "lang": convert_and_respect_annotation_metadata(object_=lang, annotation=Lang, direction="write"),
                "not_lang": convert_and_respect_annotation_metadata(
                    object_=not_lang, annotation=NotLang, direction="write"
                ),
                "countries": convert_and_respect_annotation_metadata(
                    object_=countries, annotation=Countries, direction="write"
                ),
                "not_countries": convert_and_respect_annotation_metadata(
                    object_=not_countries, annotation=NotCountries, direction="write"
                ),
                "not_author_name": convert_and_respect_annotation_metadata(
                    object_=not_author_name, annotation=NotAuthorName, direction="write"
                ),
                "from_": convert_and_respect_annotation_metadata(object_=from_, annotation=From, direction="write"),
                "to_": convert_and_respect_annotation_metadata(object_=to, annotation=To, direction="write"),
                "published_date_precision": published_date_precision,
                "by_parse_date": by_parse_date,
                "sort_by": sort_by,
                "ranked_only": ranked_only,
                "from_rank": from_rank,
                "to_rank": to_rank,
                "is_headline": is_headline,
                "is_opinion": is_opinion,
                "is_paid_content": is_paid_content,
                "parent_url": convert_and_respect_annotation_metadata(
                    object_=parent_url, annotation=ParentUrl, direction="write"
                ),
                "all_links": convert_and_respect_annotation_metadata(
                    object_=all_links, annotation=AllLinks, direction="write"
                ),
                "all_domain_links": convert_and_respect_annotation_metadata(
                    object_=all_domain_links, annotation=AllDomainLinks, direction="write"
                ),
                "additional_domain_info": additional_domain_info,
                "is_news_domain": is_news_domain,
                "news_domain_type": news_domain_type,
                "news_type": convert_and_respect_annotation_metadata(
                    object_=news_type, annotation=NewsType, direction="write"
                ),
                "word_count_min": word_count_min,
                "word_count_max": word_count_max,
                "page": page,
                "page_size": page_size,
                "clustering_enabled": clustering_enabled,
                "clustering_variable": clustering_variable,
                "clustering_threshold": clustering_threshold,
                "include_nlp_data": include_nlp_data,
                "has_nlp": has_nlp,
                "theme": convert_and_respect_annotation_metadata(object_=theme, annotation=Theme, direction="write"),
                "not_theme": convert_and_respect_annotation_metadata(
                    object_=not_theme, annotation=NotTheme, direction="write"
                ),
                "ORG_entity_name": org_entity_name,
                "PER_entity_name": per_entity_name,
                "LOC_entity_name": loc_entity_name,
                "MISC_entity_name": misc_entity_name,
                "title_sentiment_min": title_sentiment_min,
                "title_sentiment_max": title_sentiment_max,
                "content_sentiment_min": content_sentiment_min,
                "content_sentiment_max": content_sentiment_max,
                "iptc_tags": convert_and_respect_annotation_metadata(
                    object_=iptc_tags, annotation=IptcTags, direction="write"
                ),
                "not_iptc_tags": convert_and_respect_annotation_metadata(
                    object_=not_iptc_tags, annotation=NotIptcTags, direction="write"
                ),
                "iab_tags": convert_and_respect_annotation_metadata(
                    object_=iab_tags, annotation=IabTags, direction="write"
                ),
                "not_iab_tags": convert_and_respect_annotation_metadata(
                    object_=not_iab_tags, annotation=NotIabTags, direction="write"
                ),
                "custom_tags": convert_and_respect_annotation_metadata(
                    object_=custom_tags, annotation=CustomTags, direction="write"
                ),
                "exclude_duplicates": exclude_duplicates,
                "robots_compliant": robots_compliant,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchPostResponse,
                    parse_obj_as(
                        type_=SearchPostResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 408:
                raise RequestTimeoutError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawSearchClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def get(
        self,
        *,
        q: str,
        search_in: typing.Optional[SearchIn] = None,
        include_translation_fields: typing.Optional[IncludeTranslationFields] = None,
        predefined_sources: typing.Optional[str] = None,
        source_name: typing.Optional[str] = None,
        sources: typing.Optional[str] = None,
        not_sources: typing.Optional[str] = None,
        lang: typing.Optional[str] = None,
        not_lang: typing.Optional[str] = None,
        countries: typing.Optional[str] = None,
        not_countries: typing.Optional[str] = None,
        not_author_name: typing.Optional[str] = None,
        from_: typing.Optional[dt.datetime] = None,
        to: typing.Optional[dt.datetime] = None,
        published_date_precision: typing.Optional[SearchGetRequestPublishedDatePrecision] = None,
        by_parse_date: typing.Optional[bool] = None,
        sort_by: typing.Optional[SearchGetRequestSortBy] = None,
        ranked_only: typing.Optional[bool] = None,
        from_rank: typing.Optional[int] = None,
        to_rank: typing.Optional[int] = None,
        is_headline: typing.Optional[bool] = None,
        is_opinion: typing.Optional[bool] = None,
        is_paid_content: typing.Optional[bool] = None,
        parent_url: typing.Optional[str] = None,
        all_links: typing.Optional[str] = None,
        all_domain_links: typing.Optional[str] = None,
        additional_domain_info: typing.Optional[bool] = None,
        is_news_domain: typing.Optional[bool] = None,
        news_domain_type: typing.Optional[SearchGetRequestNewsDomainType] = None,
        news_type: typing.Optional[str] = None,
        word_count_min: typing.Optional[int] = None,
        word_count_max: typing.Optional[int] = None,
        page: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        clustering_enabled: typing.Optional[bool] = None,
        clustering_variable: typing.Optional[SearchGetRequestClusteringVariable] = None,
        clustering_threshold: typing.Optional[float] = None,
        include_nlp_data: typing.Optional[IncludeNlpData] = None,
        has_nlp: typing.Optional[HasNlp] = None,
        theme: typing.Optional[str] = None,
        not_theme: typing.Optional[str] = None,
        org_entity_name: typing.Optional[str] = None,
        per_entity_name: typing.Optional[str] = None,
        loc_entity_name: typing.Optional[str] = None,
        misc_entity_name: typing.Optional[str] = None,
        title_sentiment_min: typing.Optional[float] = None,
        title_sentiment_max: typing.Optional[float] = None,
        content_sentiment_min: typing.Optional[float] = None,
        content_sentiment_max: typing.Optional[float] = None,
        iptc_tags: typing.Optional[str] = None,
        not_iptc_tags: typing.Optional[str] = None,
        iab_tags: typing.Optional[str] = None,
        not_iab_tags: typing.Optional[str] = None,
        custom_tags: typing.Optional[str] = None,
        exclude_duplicates: typing.Optional[bool] = None,
        robots_compliant: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[SearchGetResponse]:
        """
        Searches for articles based on specified criteria such as keyword, language, country, source, and more.

        Parameters
        ----------
        q : str
            The keyword(s) to search for in articles. Query syntax supports logical operators (`AND`, `OR`, `NOT`) and wildcards:

            - For an exact match, use double quotes. For example, `"technology news"`.
            - Use `*` to search for any keyword.
            - Use `+` to include and `-` to exclude specific words or phrases.
              For example, `+Apple`, `-Google`.
            - Use `AND`, `OR`, and `NOT` to refine search results.
              For example, `technology AND (Apple OR Microsoft) NOT Google`.

            For more details, see [Advanced querying](/docs/v3/documentation/guides-and-concepts/advanced-querying).

        search_in : typing.Optional[SearchIn]

        include_translation_fields : typing.Optional[IncludeTranslationFields]

        predefined_sources : typing.Optional[str]
            Predefined top news sources per country.

            Format: start with the word `top`, followed by the number of desired sources, and then the two-letter country code [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Multiple countries with the number of top sources can be specified as a comma-separated string.

            Examples:
            - `"top 100 US"`
            - `"top 33 AT"`
            - `"top 50 US, top 20 GB"`
            - `"top 33 AT, top 50 IT"`

        source_name : typing.Optional[str]
            Word or phrase to search within the source names. To specify multiple values, use a comma-separated string.

            Example: `"sport, tech"`

            **Note**: The search doesn't require an exact match and returns sources containing the specified terms in their names. You can use any word or phrase, like `"sport"` or `"new york times"`. For example, `"sport"` returns sources such as `"Motorsport"`, `"Dot Esport"`, and `"Tuttosport"`.

        sources : typing.Optional[str]
            One or more news sources to narrow down the search. The format must be a domain URL. Subdomains, such as `finance.yahoo.com`, are also acceptable.To specify multiple sources, use a comma-separated string.

            Examples:
            - `"nytimes.com"`
            - `"theguardian.com, finance.yahoo.com"`

        not_sources : typing.Optional[str]
            The news sources to exclude from the search. To exclude multiple sources, use a comma-separated string.

            Example: `"cnn.com, wsj.com"`

        lang : typing.Optional[str]
            The language(s) of the search. The only accepted format is the two-letter [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) code. To select multiple languages, use a comma-separated string.

            Example: `"en, es"`

            To learn more, see [Enumerated parameters > Language](/docs/v3/api-reference/overview/enumerated-parameters#language-lang-and-not-lang).

        not_lang : typing.Optional[str]
            The language(s) to exclude from the search. The accepted format is the two-letter [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) code. To exclude multiple languages, use a comma-separated string.

            Example: `"fr, de"`

            To learn more, see [Enumerated parameters > Language](/docs/v3/api-reference/overview/enumerated-parameters#language-lang-and-not-lang).

        countries : typing.Optional[str]
            The countries where the news publisher is located. The accepted format is the two-letter [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. To select multiple countries, use a comma-separated string.

            Example: `"US, CA"`

            To learn more, see [Enumerated parameters > Country](/docs/v3/api-reference/overview/enumerated-parameters#country-country-and-not-country).

        not_countries : typing.Optional[str]
            The publisher location countries to exclude from the search. The accepted format is the two-letter [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. To exclude multiple countries, use a comma-separated string.

            Example:`"US, CA"`

            To learn more, see [Enumerated parameters > Country](/docs/v3/api-reference/overview/enumerated-parameters#country-country-and-not-country).

        not_author_name : typing.Optional[str]
            The list of author names to exclude from your search. To exclude articles by specific authors, use a comma-separated string.

            Example: `"John Doe, Jane Doe"`

        from_ : typing.Optional[dt.datetime]
            The starting point in time to search from. Accepts date-time strings in ISO 8601 format and plain text. The default time zone is UTC.

            Formats with examples:
            - YYYY-mm-ddTHH:MM:SS: `2024-07-01T00:00:00`
            - YYYY-MM-dd: `2024-07-01`
            - YYYY/mm/dd HH:MM:SS: `2024/07/01 00:00:00`
            - YYYY/mm/dd: `2024/07/01`
            - English phrases: `7 day ago`, `today`

            **Note**: By default, applied to the publication date of the article. To use the article's parse date instead, set the `by_parse_date` parameter to `true`.

        to : typing.Optional[dt.datetime]
            The ending point in time to search up to. Accepts date-time strings in ISO 8601 format and plain text. The default time zone is UTC.

            Formats with examples:
            - YYYY-mm-ddTHH:MM:SS: `2024-07-01T00:00:00`
            - YYYY-MM-dd: `2024-07-01`
            - YYYY/mm/dd HH:MM:SS: `2024/07/01 00:00:00`
            - YYYY/mm/dd: `2024/07/01`
            - English phrases: `1 day ago`, `now`

            **Note**: By default, applied to the publication date of the article. To use the article's parse date instead, set the `by_parse_date` parameter to `true`.

        published_date_precision : typing.Optional[SearchGetRequestPublishedDatePrecision]
            The precision of the published date. There are three types:
            - `full`: The day and time of an article is correctly identified with the appropriate timezone.
            - `timezone unknown`: The day and time of an article is correctly identified without timezone.
            - `date`: Only the day is identified without an exact time.

        by_parse_date : typing.Optional[bool]
            If true, the `from_` and `to_` parameters use article parse dates instead of published dates. Additionally, the `parse_date` variable is added to the output for each article object.

        sort_by : typing.Optional[SearchGetRequestSortBy]
            The sorting order of the results. Possible values are:
            - `relevancy`: The most relevant results first.
            - `date`: The most recently published results first.
            - `rank`: The results from the highest-ranked sources first.

        ranked_only : typing.Optional[bool]
            If true, limits the search to sources ranked in the top 1 million online websites. If false, includes unranked sources which are assigned a rank of 999999.

        from_rank : typing.Optional[int]
            The lowest boundary of the rank of a news website to filter by. A lower rank indicates a more popular source.

        to_rank : typing.Optional[int]
            The highest boundary of the rank of a news website to filter by. A lower rank indicates a more popular source.

        is_headline : typing.Optional[bool]
            If true, only returns articles that were posted on the home page of a given news domain.

        is_opinion : typing.Optional[bool]
            If true, returns only opinion pieces. If false, excludes opinion-based articles and returns news only.

        is_paid_content : typing.Optional[bool]
            If false, returns only articles that have publicly available complete content. Some publishers partially block content, so this setting ensures that only full articles are retrieved.

        parent_url : typing.Optional[str]
            The categorical URL(s) to filter your search. To filter your search by multiple categorical URLs, use a comma-separated string.

            Example: `"wsj.com/politics, wsj.com/tech"`

        all_links : typing.Optional[str]
            The complete URL(s) mentioned in the article. For multiple URLs, use a comma-separated string.

            Example: `"https://aiindex.stanford.edu/report, https://www.stateof.ai"`

            For more details, see [Search by URL](/docs/v3/documentation/how-to/search-by-url).

        all_domain_links : typing.Optional[str]
            The domain(s) mentioned in the article. For multiple domains, use a comma-separated string.

            Example: `"who.int, nih.gov"`

            For more details, see [Search by URL](/docs/v3/documentation/how-to/search-by-url).

        additional_domain_info : typing.Optional[bool]
            If true, includes additional domain information in the response for each article:
            - `is_news_domain`: Boolean indicating if the source is a news domain.
            - `news_domain_type`: Type of news domain (e.g., `"Original Content"`).
            - `news_type`: Category of news (e.g., `"News and Blogs"`).

        is_news_domain : typing.Optional[bool]
            If true, filters results to include only news domains.

        news_domain_type : typing.Optional[SearchGetRequestNewsDomainType]
            Filters results based on the news domain type. Possible values are:
            - `Original Content`: Sources that produce their own content.
            - `Aggregator`: Sources that collect content from various other sources.
            - `Press Releases`: Sources primarily publishing press releases.
            - `Republisher`: Sources that republish content from other sources.
            - `Other`: Sources that don't fit into main categories.

        news_type : typing.Optional[str]
            Filters results based on the news type. Multiple types can be specified using a comma-separated string.

            Example: `"General News Outlets,Tech News and Updates"`

            For a complete list of available news types, see [Enumerated parameters > News type](/docs/v3/api-reference/overview/enumerated-parameters#news-type-news-type).

        word_count_min : typing.Optional[int]
            The minimum number of words an article must contain. To be used for avoiding articles with small content.

        word_count_max : typing.Optional[int]
            The maximum number of words an article can contain. To be used for avoiding articles with large content.

        page : typing.Optional[int]
            The page number to scroll through the results. Use for pagination, as a single API response can return up to 1,000 articles.

            For details, see [How to paginate large datasets](https://www.newscatcherapi.com/docs/v3/documentation/how-to/paginate-large-datasets).

        page_size : typing.Optional[int]
            The number of articles to return per page.

        clustering_enabled : typing.Optional[bool]
            Determines whether to group similar articles into clusters. If true, the API returns clustered results.

            To learn more, see [Clustering news articles](/docs/v3/documentation/guides-and-concepts/clustering-news-articles).

        clustering_variable : typing.Optional[SearchGetRequestClusteringVariable]
            Specifies which part of the article to use for determining similarity when clustering.

            Possible values are:
            - `content`: Uses the full article content (default).
            - `title`: Uses only the article title.
            - `summary`: Uses the article summary.

            To learn more, see [Clustering news articles](/docs/v3/documentation/guides-and-concepts/clustering-news-articles).

        clustering_threshold : typing.Optional[float]
            Sets the similarity threshold for grouping articles into clusters. A lower value creates more inclusive clusters, while a higher value requires greater similarity between articles.

            Examples:
            - `0.3`: Results in larger, more diverse clusters.
            - `0.6`: Balances cluster size and article similarity (default).
            - `0.9`: Creates smaller, tightly related clusters.

            To learn more, see [Clustering news articles](/docs/v3/documentation/guides-and-concepts/clustering-news-articles).

        include_nlp_data : typing.Optional[IncludeNlpData]

        has_nlp : typing.Optional[HasNlp]

        theme : typing.Optional[str]
            Filters articles based on their general topic, as determined by NLP analysis. To select multiple themes, use a comma-separated string.

            Example: `"Finance, Tech"`

            **Note**: The `theme` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

            Available options: `Business`, `Economics`, `Entertainment`, `Finance`, `Health`, `Politics`, `Science`, `Sports`, `Tech`, `Crime`, `Financial Crime`, `Lifestyle`, `Automotive`, `Travel`, `Weather`, `General`.

        not_theme : typing.Optional[str]
            Inverse of the `theme` parameter. Excludes articles based on their general topic, as determined by NLP analysis. To exclude multiple themes, use a comma-separated string.

            Example: `"Crime, Tech"`

            **Note**: The `not_theme` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        org_entity_name : typing.Optional[str]
            Filters articles that mention specific organization names, as identified by NLP analysis. To specify multiple organizations, use a comma-separated string. To search named entities in translations, combine with the translation options of the `search_in` parameter (e.g., `title_content_translated`).

            Example: `"Apple, Microsoft"`

            **Note**: The `ORG_entity_name` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [Search by entity](/docs/v3/documentation/how-to/search-by-entity).

        per_entity_name : typing.Optional[str]
            Filters articles that mention specific person names, as identified by NLP analysis. To specify multiple names, use a comma-separated string. To search named entities in translations, combine with the translation options of the `search_in` parameter (e.g., `title_content_translated`).

            Example: `"Elon Musk, Jeff Bezos"`

            **Note**: The `PER_entity_name` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [Search by entity](/docs/v3/documentation/how-to/search-by-entity).

        loc_entity_name : typing.Optional[str]
            Filters articles that mention specific location names, as identified by NLP analysis. To specify multiple locations, use a comma-separated string. To search named entities in translations, combine with the translation options of the `search_in` parameter (e.g., `title_content_translated`).

            Example: `"California, New York"`

            **Note**: The `LOC_entity_name` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [Search by entity](/docs/v3/documentation/how-to/search-by-entity).

        misc_entity_name : typing.Optional[str]
            Filters articles that mention other named entities not falling under person, organization, or location categories. Includes events, nationalities, products, works of art, and more. To specify multiple entities, use a comma-separated string. To search named entities in translations, combine with the translation options of the `search_in` parameter (e.g., `title_content_translated`).

            Example: `"Bitcoin, Blockchain"`

            **Note**: The `MISC_entity_name` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [Search by entity](/docs/v3/documentation/how-to/search-by-entity).

        title_sentiment_min : typing.Optional[float]
            Filters articles based on the minimum sentiment score of their titles.

            Range is `-1.0` to `1.0`, where:
            - Negative values indicate negative sentiment.
            - Positive values indicate positive sentiment.
            - Values close to 0 indicate neutral sentiment.

            **Note**: The `title_sentiment_min` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        title_sentiment_max : typing.Optional[float]
            Filters articles based on the maximum sentiment score of their titles.

            Range is `-1.0` to `1.0`, where:
            - Negative values indicate negative sentiment.
            - Positive values indicate positive sentiment.
            - Values close to 0 indicate neutral sentiment.

            **Note**: The `title_sentiment_max` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        content_sentiment_min : typing.Optional[float]
            Filters articles based on the minimum sentiment score of their content.

            Range is `-1.0` to `1.0`, where:
            - Negative values indicate negative sentiment.
            - Positive values indicate positive sentiment.
            - Values close to 0 indicate neutral sentiment.

            **Note**: The `content_sentiment_min` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        content_sentiment_max : typing.Optional[float]
            Filters articles based on the maximum sentiment score of their content.

            Range is `-1.0` to `1.0`, where:
            - Negative values indicate negative sentiment.
            - Positive values indicate positive sentiment.
            - Values close to 0 indicate neutral sentiment.

            **Note**: The `content_sentiment_max` parameter is only available if NLP is included in your subscription plan.

            To learn more, see [NLP features](/docs/v3/documentation/guides-and-concepts/nlp-features).

        iptc_tags : typing.Optional[str]
            Filters articles based on International Press Telecommunications Council (IPTC) media topic tags. To specify multiple IPTC tags, use a comma-separated string of tag IDs.

            Example: `"20000199, 20000209"`

            **Note**: The `iptc_tags` parameter is only available in the `v3_nlp_iptc_tags` subscription plan.

            To learn more, see [IPTC Media Topic NewsCodes](https://www.iptc.org/std/NewsCodes/treeview/mediatopic/mediatopic-en-GB.html).

        not_iptc_tags : typing.Optional[str]
            Inverse of the `iptc_tags` parameter. Excludes articles based on International Press Telecommunications Council (IPTC) media topic tags. To specify multiple IPTC tags to exclude, use a comma-separated string of tag IDs.

            Example: `"20000205, 20000209"`

            **Note**: The `not_iptc_tags` parameter is only available in the `v3_nlp_iptc_tags` subscription plan.

            To learn more, see [IPTC Media Topic NewsCodes](https://www.iptc.org/std/NewsCodes/treeview/mediatopic/mediatopic-en-GB.html).

        iab_tags : typing.Optional[str]
            Filters articles based on Interactive Advertising Bureau (IAB) content categories. These tags provide a standardized taxonomy for digital advertising content categorization. To specify multiple IAB categories, use a comma-separated string.

            Example: `"Business, Events"`

            **Note**: The `iab_tags` parameter is only available in the `v3_nlp_iptc_tags` subscription plan.

            To learn more, see the [IAB Content taxonomy](https://iabtechlab.com/standards/content-taxonomy/).

        not_iab_tags : typing.Optional[str]
            Inverse of the `iab_tags` parameter. Excludes articles based on Interactive Advertising Bureau (IAB) content categories. These tags provide a standardized taxonomy for digital advertising content categorization. To specify multiple IAB categories to exclude, use a comma-separated string.

            Example: `"Agriculture, Metals"`

            **Note**: The `not_iab_tags` parameter is only available in the `v3_nlp_iptc_tags` subscription plan.

            To learn more, see the [IAB Content taxonomy](https://iabtechlab.com/standards/content-taxonomy/).

        custom_tags : typing.Optional[str]
            Filters articles based on provided taxonomy that is tailored to your specific needs and is accessible only with your API key. To specify tags, use the following pattern:

            - `custom_tags.taxonomy=Tag1,Tag2,Tag3`, where `taxonomy` is the taxonomy name and `Tag1,Tag2,Tag3` is a comma-separated list of tags.

            Example: `custom_tags.industry="Manufacturing, Supply Chain, Logistics"`

            To learn more, see the [Custom tags](/docs/v3/documentation/guides-and-concepts/custom-tags).

        exclude_duplicates : typing.Optional[bool]
            If true, excludes duplicate and highly similar articles from the search results. If false, returns all relevant articles, including duplicates.

            To learn more, see [Articles deduplication](/docs/v3/documentation/guides-and-concepts/articles-deduplication).

        robots_compliant : typing.Optional[bool]
            If true, returns only articles/sources that comply with the publisher's robots.txt rules. If false, returns only articles/sources that do not comply with robots.txt rules. If omitted, returns all articles/sources regardless of compliance status.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[SearchGetResponse]
            A successful response containing articles that match the specified search criteria. The response may include clustering information if enabled.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/search",
            method="GET",
            params={
                "q": q,
                "search_in": search_in,
                "include_translation_fields": include_translation_fields,
                "predefined_sources": predefined_sources,
                "source_name": source_name,
                "sources": sources,
                "not_sources": not_sources,
                "lang": lang,
                "not_lang": not_lang,
                "countries": countries,
                "not_countries": not_countries,
                "not_author_name": not_author_name,
                "from_": serialize_datetime(from_) if from_ is not None else None,
                "to_": serialize_datetime(to) if to is not None else None,
                "published_date_precision": published_date_precision,
                "by_parse_date": by_parse_date,
                "sort_by": sort_by,
                "ranked_only": ranked_only,
                "from_rank": from_rank,
                "to_rank": to_rank,
                "is_headline": is_headline,
                "is_opinion": is_opinion,
                "is_paid_content": is_paid_content,
                "parent_url": parent_url,
                "all_links": all_links,
                "all_domain_links": all_domain_links,
                "additional_domain_info": additional_domain_info,
                "is_news_domain": is_news_domain,
                "news_domain_type": news_domain_type,
                "news_type": news_type,
                "word_count_min": word_count_min,
                "word_count_max": word_count_max,
                "page": page,
                "page_size": page_size,
                "clustering_enabled": clustering_enabled,
                "clustering_variable": clustering_variable,
                "clustering_threshold": clustering_threshold,
                "include_nlp_data": include_nlp_data,
                "has_nlp": has_nlp,
                "theme": theme,
                "not_theme": not_theme,
                "ORG_entity_name": org_entity_name,
                "PER_entity_name": per_entity_name,
                "LOC_entity_name": loc_entity_name,
                "MISC_entity_name": misc_entity_name,
                "title_sentiment_min": title_sentiment_min,
                "title_sentiment_max": title_sentiment_max,
                "content_sentiment_min": content_sentiment_min,
                "content_sentiment_max": content_sentiment_max,
                "iptc_tags": iptc_tags,
                "not_iptc_tags": not_iptc_tags,
                "iab_tags": iab_tags,
                "not_iab_tags": not_iab_tags,
                "custom_tags": custom_tags,
                "exclude_duplicates": exclude_duplicates,
                "robots_compliant": robots_compliant,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchGetResponse,
                    parse_obj_as(
                        type_=SearchGetResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 408:
                raise RequestTimeoutError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def post(
        self,
        *,
        q: Q,
        search_in: typing.Optional[SearchIn] = OMIT,
        include_translation_fields: typing.Optional[IncludeTranslationFields] = OMIT,
        predefined_sources: typing.Optional[PredefinedSources] = OMIT,
        source_name: typing.Optional[SourceName] = OMIT,
        sources: typing.Optional[Sources] = OMIT,
        not_sources: typing.Optional[NotSources] = OMIT,
        lang: typing.Optional[Lang] = OMIT,
        not_lang: typing.Optional[NotLang] = OMIT,
        countries: typing.Optional[Countries] = OMIT,
        not_countries: typing.Optional[NotCountries] = OMIT,
        not_author_name: typing.Optional[NotAuthorName] = OMIT,
        from_: typing.Optional[From] = OMIT,
        to: typing.Optional[To] = OMIT,
        published_date_precision: typing.Optional[PublishedDatePrecision] = OMIT,
        by_parse_date: typing.Optional[ByParseDate] = OMIT,
        sort_by: typing.Optional[SortBy] = OMIT,
        ranked_only: typing.Optional[RankedOnly] = OMIT,
        from_rank: typing.Optional[FromRank] = OMIT,
        to_rank: typing.Optional[ToRank] = OMIT,
        is_headline: typing.Optional[IsHeadline] = OMIT,
        is_opinion: typing.Optional[IsOpinion] = OMIT,
        is_paid_content: typing.Optional[IsPaidContent] = OMIT,
        parent_url: typing.Optional[ParentUrl] = OMIT,
        all_links: typing.Optional[AllLinks] = OMIT,
        all_domain_links: typing.Optional[AllDomainLinks] = OMIT,
        additional_domain_info: typing.Optional[AdditionalDomainInfo] = OMIT,
        is_news_domain: typing.Optional[IsNewsDomain] = OMIT,
        news_domain_type: typing.Optional[NewsDomainType] = OMIT,
        news_type: typing.Optional[NewsType] = OMIT,
        word_count_min: typing.Optional[WordCountMin] = OMIT,
        word_count_max: typing.Optional[WordCountMax] = OMIT,
        page: typing.Optional[Page] = OMIT,
        page_size: typing.Optional[PageSize] = OMIT,
        clustering_enabled: typing.Optional[ClusteringEnabled] = OMIT,
        clustering_variable: typing.Optional[ClusteringVariable] = OMIT,
        clustering_threshold: typing.Optional[ClusteringThreshold] = OMIT,
        include_nlp_data: typing.Optional[IncludeNlpData] = OMIT,
        has_nlp: typing.Optional[HasNlp] = OMIT,
        theme: typing.Optional[Theme] = OMIT,
        not_theme: typing.Optional[NotTheme] = OMIT,
        org_entity_name: typing.Optional[OrgEntityName] = OMIT,
        per_entity_name: typing.Optional[PerEntityName] = OMIT,
        loc_entity_name: typing.Optional[LocEntityName] = OMIT,
        misc_entity_name: typing.Optional[MiscEntityName] = OMIT,
        title_sentiment_min: typing.Optional[TitleSentimentMin] = OMIT,
        title_sentiment_max: typing.Optional[TitleSentimentMax] = OMIT,
        content_sentiment_min: typing.Optional[ContentSentimentMin] = OMIT,
        content_sentiment_max: typing.Optional[ContentSentimentMax] = OMIT,
        iptc_tags: typing.Optional[IptcTags] = OMIT,
        not_iptc_tags: typing.Optional[NotIptcTags] = OMIT,
        iab_tags: typing.Optional[IabTags] = OMIT,
        not_iab_tags: typing.Optional[NotIabTags] = OMIT,
        custom_tags: typing.Optional[CustomTags] = OMIT,
        exclude_duplicates: typing.Optional[ExcludeDuplicates] = OMIT,
        robots_compliant: typing.Optional[RobotsCompliant] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[SearchPostResponse]:
        """
        Searches for articles based on specified criteria such as keyword, language, country, source, and more.

        Parameters
        ----------
        q : Q

        search_in : typing.Optional[SearchIn]

        include_translation_fields : typing.Optional[IncludeTranslationFields]

        predefined_sources : typing.Optional[PredefinedSources]

        source_name : typing.Optional[SourceName]

        sources : typing.Optional[Sources]

        not_sources : typing.Optional[NotSources]

        lang : typing.Optional[Lang]

        not_lang : typing.Optional[NotLang]

        countries : typing.Optional[Countries]

        not_countries : typing.Optional[NotCountries]

        not_author_name : typing.Optional[NotAuthorName]

        from_ : typing.Optional[From]

        to : typing.Optional[To]

        published_date_precision : typing.Optional[PublishedDatePrecision]

        by_parse_date : typing.Optional[ByParseDate]

        sort_by : typing.Optional[SortBy]

        ranked_only : typing.Optional[RankedOnly]

        from_rank : typing.Optional[FromRank]

        to_rank : typing.Optional[ToRank]

        is_headline : typing.Optional[IsHeadline]

        is_opinion : typing.Optional[IsOpinion]

        is_paid_content : typing.Optional[IsPaidContent]

        parent_url : typing.Optional[ParentUrl]

        all_links : typing.Optional[AllLinks]

        all_domain_links : typing.Optional[AllDomainLinks]

        additional_domain_info : typing.Optional[AdditionalDomainInfo]

        is_news_domain : typing.Optional[IsNewsDomain]

        news_domain_type : typing.Optional[NewsDomainType]

        news_type : typing.Optional[NewsType]

        word_count_min : typing.Optional[WordCountMin]

        word_count_max : typing.Optional[WordCountMax]

        page : typing.Optional[Page]

        page_size : typing.Optional[PageSize]

        clustering_enabled : typing.Optional[ClusteringEnabled]

        clustering_variable : typing.Optional[ClusteringVariable]

        clustering_threshold : typing.Optional[ClusteringThreshold]

        include_nlp_data : typing.Optional[IncludeNlpData]

        has_nlp : typing.Optional[HasNlp]

        theme : typing.Optional[Theme]

        not_theme : typing.Optional[NotTheme]

        org_entity_name : typing.Optional[OrgEntityName]

        per_entity_name : typing.Optional[PerEntityName]

        loc_entity_name : typing.Optional[LocEntityName]

        misc_entity_name : typing.Optional[MiscEntityName]

        title_sentiment_min : typing.Optional[TitleSentimentMin]

        title_sentiment_max : typing.Optional[TitleSentimentMax]

        content_sentiment_min : typing.Optional[ContentSentimentMin]

        content_sentiment_max : typing.Optional[ContentSentimentMax]

        iptc_tags : typing.Optional[IptcTags]

        not_iptc_tags : typing.Optional[NotIptcTags]

        iab_tags : typing.Optional[IabTags]

        not_iab_tags : typing.Optional[NotIabTags]

        custom_tags : typing.Optional[CustomTags]

        exclude_duplicates : typing.Optional[ExcludeDuplicates]

        robots_compliant : typing.Optional[RobotsCompliant]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[SearchPostResponse]
            A successful response containing articles that match the specified search criteria. The response may include clustering information if enabled.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/search",
            method="POST",
            json={
                "q": q,
                "search_in": search_in,
                "include_translation_fields": include_translation_fields,
                "predefined_sources": convert_and_respect_annotation_metadata(
                    object_=predefined_sources, annotation=PredefinedSources, direction="write"
                ),
                "source_name": convert_and_respect_annotation_metadata(
                    object_=source_name, annotation=SourceName, direction="write"
                ),
                "sources": convert_and_respect_annotation_metadata(
                    object_=sources, annotation=Sources, direction="write"
                ),
                "not_sources": convert_and_respect_annotation_metadata(
                    object_=not_sources, annotation=NotSources, direction="write"
                ),
                "lang": convert_and_respect_annotation_metadata(object_=lang, annotation=Lang, direction="write"),
                "not_lang": convert_and_respect_annotation_metadata(
                    object_=not_lang, annotation=NotLang, direction="write"
                ),
                "countries": convert_and_respect_annotation_metadata(
                    object_=countries, annotation=Countries, direction="write"
                ),
                "not_countries": convert_and_respect_annotation_metadata(
                    object_=not_countries, annotation=NotCountries, direction="write"
                ),
                "not_author_name": convert_and_respect_annotation_metadata(
                    object_=not_author_name, annotation=NotAuthorName, direction="write"
                ),
                "from_": convert_and_respect_annotation_metadata(object_=from_, annotation=From, direction="write"),
                "to_": convert_and_respect_annotation_metadata(object_=to, annotation=To, direction="write"),
                "published_date_precision": published_date_precision,
                "by_parse_date": by_parse_date,
                "sort_by": sort_by,
                "ranked_only": ranked_only,
                "from_rank": from_rank,
                "to_rank": to_rank,
                "is_headline": is_headline,
                "is_opinion": is_opinion,
                "is_paid_content": is_paid_content,
                "parent_url": convert_and_respect_annotation_metadata(
                    object_=parent_url, annotation=ParentUrl, direction="write"
                ),
                "all_links": convert_and_respect_annotation_metadata(
                    object_=all_links, annotation=AllLinks, direction="write"
                ),
                "all_domain_links": convert_and_respect_annotation_metadata(
                    object_=all_domain_links, annotation=AllDomainLinks, direction="write"
                ),
                "additional_domain_info": additional_domain_info,
                "is_news_domain": is_news_domain,
                "news_domain_type": news_domain_type,
                "news_type": convert_and_respect_annotation_metadata(
                    object_=news_type, annotation=NewsType, direction="write"
                ),
                "word_count_min": word_count_min,
                "word_count_max": word_count_max,
                "page": page,
                "page_size": page_size,
                "clustering_enabled": clustering_enabled,
                "clustering_variable": clustering_variable,
                "clustering_threshold": clustering_threshold,
                "include_nlp_data": include_nlp_data,
                "has_nlp": has_nlp,
                "theme": convert_and_respect_annotation_metadata(object_=theme, annotation=Theme, direction="write"),
                "not_theme": convert_and_respect_annotation_metadata(
                    object_=not_theme, annotation=NotTheme, direction="write"
                ),
                "ORG_entity_name": org_entity_name,
                "PER_entity_name": per_entity_name,
                "LOC_entity_name": loc_entity_name,
                "MISC_entity_name": misc_entity_name,
                "title_sentiment_min": title_sentiment_min,
                "title_sentiment_max": title_sentiment_max,
                "content_sentiment_min": content_sentiment_min,
                "content_sentiment_max": content_sentiment_max,
                "iptc_tags": convert_and_respect_annotation_metadata(
                    object_=iptc_tags, annotation=IptcTags, direction="write"
                ),
                "not_iptc_tags": convert_and_respect_annotation_metadata(
                    object_=not_iptc_tags, annotation=NotIptcTags, direction="write"
                ),
                "iab_tags": convert_and_respect_annotation_metadata(
                    object_=iab_tags, annotation=IabTags, direction="write"
                ),
                "not_iab_tags": convert_and_respect_annotation_metadata(
                    object_=not_iab_tags, annotation=NotIabTags, direction="write"
                ),
                "custom_tags": convert_and_respect_annotation_metadata(
                    object_=custom_tags, annotation=CustomTags, direction="write"
                ),
                "exclude_duplicates": exclude_duplicates,
                "robots_compliant": robots_compliant,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchPostResponse,
                    parse_obj_as(
                        type_=SearchPostResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 408:
                raise RequestTimeoutError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
