diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index fcee693d0..8efce8e41 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -25,7 +25,7 @@ env: WEAVIATE_131: 1.31.19 WEAVIATE_132: 1.32.16 WEAVIATE_133: 1.33.4 - WEAVIATE_134: 1.34.0 + WEAVIATE_134: 1.34.1 jobs: lint-and-format: @@ -59,7 +59,7 @@ jobs: strategy: fail-fast: false matrix: - version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + version: ["3.10", "3.11", "3.12", "3.13", "3.14"] folder: ["weaviate", "integration", "integration_embedded"] steps: - uses: actions/checkout@v4 @@ -79,7 +79,7 @@ jobs: strategy: fail-fast: false matrix: - version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + version: ["3.10", "3.11", "3.12", "3.13", "3.14"] folder: ["test", "mock_tests"] steps: - uses: actions/checkout@v4 @@ -122,7 +122,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + version: ["3.10", "3.11", "3.12", "3.13", "3.14"] optional_dependencies: [false] steps: - uses: actions/checkout@v4 @@ -153,11 +153,11 @@ jobs: fail-fast: false matrix: versions: [ - { py: "3.9", weaviate: $WEAVIATE_132, grpc: "1.59.0"}, - { py: "3.10", weaviate: $WEAVIATE_132, grpc: "1.66.0"}, - { py: "3.11", weaviate: $WEAVIATE_132, grpc: "1.70.0"}, - { py: "3.12", weaviate: $WEAVIATE_132, grpc: "1.72.1"}, - { py: "3.13", weaviate: $WEAVIATE_132, grpc: "1.74.0"} + { py: "3.10", weaviate: $WEAVIATE_132, grpc: "1.59.0"}, + { py: "3.11", weaviate: $WEAVIATE_132, grpc: "1.66.0"}, + { py: "3.12", weaviate: $WEAVIATE_132, grpc: "1.70.0"}, + { py: "3.13", weaviate: $WEAVIATE_132, grpc: "1.72.1"}, + { py: "3.14", weaviate: $WEAVIATE_132, grpc: "1.76.0"} ] optional_dependencies: [false] steps: @@ -208,11 +208,11 @@ jobs: fail-fast: false matrix: versions: [ - { py: "3.9", weaviate: $WEAVIATE_132}, { py: "3.10", weaviate: $WEAVIATE_132}, { py: "3.11", weaviate: $WEAVIATE_132}, { py: "3.12", weaviate: $WEAVIATE_132}, - { py: "3.13", weaviate: $WEAVIATE_132} + { py: "3.13", weaviate: $WEAVIATE_132}, + { py: "3.14", weaviate: $WEAVIATE_132} ] optional_dependencies: [false] steps: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4b897b920..fb73a7012 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.11.7 + rev: v0.14.7 hooks: # Run the linter. - id: ruff @@ -19,24 +19,24 @@ repos: args: [ weaviate, integration, test, mock_tests, journey_tests ] - repo: https://github.com/PyCQA/flake8 - rev: 7.1.0 + rev: 7.3.0 hooks: - id: flake8 name: linting additional_dependencies: [ - 'flake8-bugbear==22.10.27', - 'flake8-comprehensions==3.10.1', - 'flake8-builtins==2.0.1' + 'flake8-bugbear==24.12.12', + 'flake8-comprehensions==3.17.0', + 'flake8-builtins==3.0.0' ] - id: flake8 name: docstrings additional_dependencies: [ 'flake8-docstrings==1.7.0', - 'pydoclint==0.6.5', + 'pydoclint==0.7.3', ] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v6.0.0 hooks: - id: no-commit-to-branch - id: trailing-whitespace diff --git a/requirements-devel.txt b/requirements-devel.txt index 9c9771707..c4d6a7192 100644 --- a/requirements-devel.txt +++ b/requirements-devel.txt @@ -1,10 +1,10 @@ httpx==0.26.0 validators==0.34.0 authlib==1.6.5 -grpcio==1.66.2 -grpcio-tools==1.66.2 -grpcio-health-checking==1.66.2 -pydantic==2.8.0 +grpcio==1.75.1 +grpcio-tools==1.75.1 +grpcio-health-checking==1.75.1 +pydantic==2.12.0 deprecation==2.1.0 build diff --git a/setup.cfg b/setup.cfg index 882700b4f..3e8ae6aec 100644 --- a/setup.cfg +++ b/setup.cfg @@ -37,11 +37,11 @@ install_requires = httpx>=0.26.0,<0.29.0 validators>=0.34.0,<1.0.0 authlib>=1.2.1,<2.0.0 - pydantic>=2.8.0,<3.0.0 + pydantic>=2.12.0,<3.0.0 grpcio>=1.59.5,<1.80.0 protobuf>=4.21.6,<7.0.0 deprecation>=2.1.0,<3.0.0 -python_requires = >=3.9 +python_requires = >=3.10 [options.extras_require] agents = diff --git a/weaviate/collections/classes/generative.py b/weaviate/collections/classes/generative.py index b69163d3a..dafa2498e 100644 --- a/weaviate/collections/classes/generative.py +++ b/weaviate/collections/classes/generative.py @@ -4,7 +4,7 @@ from pathlib import Path from typing import List, Optional, Union -from pydantic import AnyHttpUrl, AnyUrl, BaseModel, Field +from pydantic import AnyHttpUrl, BaseModel, Field, TypeAdapter from weaviate.collections.classes.config import ( AWSService, @@ -503,7 +503,7 @@ def anthropic( top_p: The top P to use. Defaults to `None`, which uses the server-defined default """ return _GenerativeAnthropic( - base_url=AnyUrl(base_url) if base_url is not None else None, + base_url=TypeAdapter(AnyHttpUrl).validate_python(base_url), model=model, max_tokens=max_tokens, stop_sequences=stop_sequences, @@ -527,7 +527,9 @@ def anyscale( temperature: The temperature to use. Defaults to `None`, which uses the server-defined default """ return _GenerativeAnyscale( - base_url=AnyUrl(base_url) if base_url is not None else None, + base_url=TypeAdapter(AnyHttpUrl).validate_python(base_url) + if base_url is not None + else None, model=model, temperature=temperature, ) @@ -564,7 +566,9 @@ def aws( max_tokens=max_tokens, region=region, service=service, - endpoint=AnyUrl(endpoint) if endpoint is not None else None, + endpoint=TypeAdapter(AnyHttpUrl).validate_python(endpoint) + if endpoint is not None + else None, target_model=target_model, target_variant=target_variant, temperature=temperature, @@ -598,7 +602,9 @@ def cohere( temperature: The temperature to use. Defaults to `None`, which uses the server-defined default """ return _GenerativeCohere( - base_url=AnyUrl(base_url) if base_url is not None else None, + base_url=TypeAdapter(AnyHttpUrl).validate_python(base_url) + if base_url is not None + else None, k=k, max_tokens=max_tokens, model=model, @@ -671,7 +677,7 @@ def databricks( top_p: The top P value to use. Defaults to `None`, which uses the server-defined default """ return _GenerativeDatabricks( - endpoint=AnyUrl(endpoint), + endpoint=TypeAdapter(AnyHttpUrl).validate_python(endpoint), frequency_penalty=frequency_penalty, log_probs=log_probs, max_tokens=max_tokens, @@ -710,7 +716,9 @@ def friendliai( top_p: The top P value to use. Defaults to `None`, which uses the server-defined default """ return _GenerativeFriendliai( - base_url=AnyUrl(base_url) if base_url is not None else None, + base_url=TypeAdapter(AnyHttpUrl).validate_python(base_url) + if base_url is not None + else None, max_tokens=max_tokens, model=model, n=n, @@ -754,7 +762,9 @@ def google( top_p: The top P to use. Defaults to `None`, which uses the server-defined default """ return _GenerativeGoogle( - api_endpoint=AnyUrl(api_endpoint) if api_endpoint is not None else None, + api_endpoint=TypeAdapter(AnyHttpUrl).validate_python(api_endpoint) + if api_endpoint is not None + else None, endpoint_id=endpoint_id, frequency_penalty=frequency_penalty, max_tokens=max_tokens, @@ -787,7 +797,9 @@ def mistral( top_p: The top P value to use. Defaults to `None`, which uses the server-defined default """ return _GenerativeMistral( - base_url=AnyUrl(base_url) if base_url is not None else None, + base_url=TypeAdapter(AnyHttpUrl).validate_python(base_url) + if base_url is not None + else None, max_tokens=max_tokens, model=model, temperature=temperature, @@ -813,7 +825,9 @@ def nvidia( top_p: The top P value to use. Defaults to `None`, which uses the server-defined default """ return _GenerativeNvidia( - base_url=AnyUrl(base_url) if base_url is not None else None, + base_url=TypeAdapter(AnyHttpUrl).validate_python(base_url) + if base_url is not None + else None, max_tokens=max_tokens, model=model, temperature=temperature, @@ -840,7 +854,9 @@ def ollama( The number of images passed to the prompt will match the value of `limit` in the search query. """ return _GenerativeOllama( - api_endpoint=AnyUrl(api_endpoint) if api_endpoint is not None else None, + api_endpoint=TypeAdapter(AnyHttpUrl).validate_python(api_endpoint) + if api_endpoint is not None + else None, model=model, temperature=temperature, ) @@ -884,7 +900,9 @@ def openai( """ return _GenerativeOpenAI( api_version=api_version, - base_url=AnyUrl(base_url) if base_url is not None else None, + base_url=TypeAdapter(AnyHttpUrl).validate_python(base_url) + if base_url is not None + else None, deployment_id=deployment_id, frequency_penalty=frequency_penalty, max_tokens=max_tokens, @@ -934,7 +952,9 @@ def azure_openai( """ return _GenerativeOpenAI( api_version=api_version, - base_url=AnyUrl(base_url) if base_url is not None else None, + base_url=TypeAdapter(AnyHttpUrl).validate_python(base_url) + if base_url is not None + else None, deployment_id=deployment_id, frequency_penalty=frequency_penalty, max_tokens=max_tokens, @@ -971,7 +991,9 @@ def xai( top_p: The top P to use. Defaults to `None`, which uses the server-defined default """ return _GenerativeXAI( - base_url=AnyUrl(base_url) if base_url is not None else None, + base_url=TypeAdapter(AnyHttpUrl).validate_python(base_url) + if base_url is not None + else None, max_tokens=max_tokens, model=model, temperature=temperature, diff --git a/weaviate/util.py b/weaviate/util.py index 77840f3ba..f9b8e9385 100644 --- a/weaviate/util.py +++ b/weaviate/util.py @@ -731,8 +731,9 @@ def _datetime_from_weaviate_str(string: str) -> datetime.datetime: return datetime.datetime.strptime(string, date_format) except ValueError as e: # note that the year 9999 is valid and does not need to be handled. for 5 digit years only the first - # 4 digits are considered and it wrapps around - if "year 0 is out of range" in str(e): + # 4 digits are considered and it wrapps around. The datetime library changed the error message in python 3.14 + # to include "year must be in ...", so we check for both messages here. + if "year 0 is out of range" in str(e) or "year must be in" in str(e): _Warnings.datetime_year_zero(string) return datetime.datetime.min raise e