diff --git a/.github/actions/setup-runner/action.yml b/.github/actions/setup-runner/action.yml index cdd438eb2..debbae5c3 100644 --- a/.github/actions/setup-runner/action.yml +++ b/.github/actions/setup-runner/action.yml @@ -4,7 +4,7 @@ inputs: python-version: description: The Python version to use required: false - default: "3.10" + default: "3.11" runs: using: "composite" steps: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 210a0e95b..acaa538e9 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -26,7 +26,7 @@ jobs: # TODO: generate matrix list from tests/integration when fixed test-type: [agents, inference, datasets, inspect, scoring, post_training, providers, tool_runtime, vector_io] client-type: [library, http] - python-version: ["3.10", "3.11", "3.12"] + python-version: ["3.11", "3.12"] fail-fast: false # we want to run all tests regardless of failure steps: diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index fc0459f0f..65e4ba0ff 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -25,7 +25,6 @@ jobs: fail-fast: false matrix: python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/llama_stack/apis/agents/agents.py b/llama_stack/apis/agents/agents.py index cc4ee0648..9bd46a3a6 100644 --- a/llama_stack/apis/agents/agents.py +++ b/llama_stack/apis/agents/agents.py @@ -4,10 +4,9 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -import sys from collections.abc import AsyncIterator from datetime import datetime -from enum import Enum +from enum import StrEnum from typing import Annotated, Any, Literal, Protocol, runtime_checkable from pydantic import BaseModel, ConfigDict, Field @@ -40,14 +39,6 @@ from .openai_responses import ( OpenAIResponseText, ) -# TODO: use enum.StrEnum when we drop support for python 3.10 -if sys.version_info >= (3, 11): - from enum import StrEnum -else: - - class StrEnum(str, Enum): - """Backport of StrEnum for Python 3.10 and below.""" - class Attachment(BaseModel): """An attachment to an agent turn. diff --git a/llama_stack/apis/inference/inference.py b/llama_stack/apis/inference/inference.py index c440794f3..c64a5f750 100644 --- a/llama_stack/apis/inference/inference.py +++ b/llama_stack/apis/inference/inference.py @@ -4,7 +4,6 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -import sys from collections.abc import AsyncIterator from enum import Enum from typing import ( @@ -37,15 +36,7 @@ register_schema(ToolCall) register_schema(ToolParamDefinition) register_schema(ToolDefinition) -# TODO: use enum.StrEnum when we drop support for python 3.10 -if sys.version_info >= (3, 11): - from enum import StrEnum -else: - - class StrEnum(str, Enum): - """Backport of StrEnum for Python 3.10 and below.""" - - pass +from enum import StrEnum @json_schema_type diff --git a/llama_stack/apis/resource.py b/llama_stack/apis/resource.py index 175baa7b9..3731fbf1d 100644 --- a/llama_stack/apis/resource.py +++ b/llama_stack/apis/resource.py @@ -4,21 +4,11 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -import sys -from enum import Enum + +from enum import StrEnum from pydantic import BaseModel, Field -# TODO: use enum.StrEnum when we drop support for python 3.10 -if sys.version_info >= (3, 11): - from enum import StrEnum -else: - - class StrEnum(str, Enum): - """Backport of StrEnum for Python 3.10 and below.""" - - pass - class ResourceType(StrEnum): model = "model" diff --git a/llama_stack/apis/scoring_functions/scoring_functions.py b/llama_stack/apis/scoring_functions/scoring_functions.py index 9cd21b7d1..684041308 100644 --- a/llama_stack/apis/scoring_functions/scoring_functions.py +++ b/llama_stack/apis/scoring_functions/scoring_functions.py @@ -5,8 +5,7 @@ # the root directory of this source tree. # TODO: use enum.StrEnum when we drop support for python 3.10 -import sys -from enum import Enum +from enum import StrEnum from typing import ( Annotated, Any, @@ -21,15 +20,6 @@ from llama_stack.apis.common.type_system import ParamType from llama_stack.apis.resource import Resource, ResourceType from llama_stack.schema_utils import json_schema_type, register_schema, webmethod -if sys.version_info >= (3, 11): - from enum import StrEnum -else: - - class StrEnum(str, Enum): - """Backport of StrEnum for Python 3.10 and below.""" - - pass - # Perhaps more structure can be imposed on these functions. Maybe they could be associated # with standard metrics so they can be rolled up? diff --git a/llama_stack/cli/download.py b/llama_stack/cli/download.py index b96842119..30b6e11e9 100644 --- a/llama_stack/cli/download.py +++ b/llama_stack/cli/download.py @@ -11,7 +11,7 @@ import os import shutil import sys from dataclasses import dataclass -from datetime import datetime, timezone +from datetime import UTC, datetime from functools import partial from pathlib import Path @@ -409,7 +409,7 @@ def _download_from_manifest(manifest_file: str, max_concurrent_downloads: int): d = json.load(f) manifest = Manifest(**d) - if datetime.now(timezone.utc) > manifest.expires_on.astimezone(timezone.utc): + if datetime.now(UTC) > manifest.expires_on.astimezone(UTC): raise ValueError(f"Manifest URLs have expired on {manifest.expires_on}") console = Console() diff --git a/llama_stack/distribution/access_control/datatypes.py b/llama_stack/distribution/access_control/datatypes.py index 3e6c624dc..bc5ed6645 100644 --- a/llama_stack/distribution/access_control/datatypes.py +++ b/llama_stack/distribution/access_control/datatypes.py @@ -5,9 +5,9 @@ # the root directory of this source tree. from enum import Enum +from typing import Self from pydantic import BaseModel, model_validator -from typing_extensions import Self from .conditions import parse_conditions diff --git a/llama_stack/distribution/build.py b/llama_stack/distribution/build.py index 4f9091a5d..edf0abee8 100644 --- a/llama_stack/distribution/build.py +++ b/llama_stack/distribution/build.py @@ -101,7 +101,7 @@ def build_image( template_or_config: str, run_config: str | None = None, ): - container_base = build_config.distribution_spec.container_image or "python:3.10-slim" + container_base = build_config.distribution_spec.container_image or "python:3.11-slim" normal_deps, special_deps = get_provider_dependencies(build_config) normal_deps += SERVER_DEPENDENCIES diff --git a/llama_stack/distribution/build_conda_env.sh b/llama_stack/distribution/build_conda_env.sh index 5deb01752..18fe44875 100755 --- a/llama_stack/distribution/build_conda_env.sh +++ b/llama_stack/distribution/build_conda_env.sh @@ -49,7 +49,7 @@ ensure_conda_env_python310() { local env_name="$1" local pip_dependencies="$2" local special_pip_deps="$3" - local python_version="3.10" + local python_version="3.11" # Check if conda command is available if ! is_command_available conda; then diff --git a/llama_stack/distribution/providers.py b/llama_stack/distribution/providers.py index 29b7109dd..f238e3bba 100644 --- a/llama_stack/distribution/providers.py +++ b/llama_stack/distribution/providers.py @@ -99,7 +99,7 @@ class ProviderImpl(Providers): try: health = await asyncio.wait_for(impl.health(), timeout=timeout) return api_name, health - except (asyncio.TimeoutError, TimeoutError): + except TimeoutError: return ( api_name, HealthResponse( diff --git a/llama_stack/distribution/routers/inference.py b/llama_stack/distribution/routers/inference.py index 4e0a33b59..50c429315 100644 --- a/llama_stack/distribution/routers/inference.py +++ b/llama_stack/distribution/routers/inference.py @@ -615,7 +615,7 @@ class InferenceRouter(Inference): continue health = await asyncio.wait_for(impl.health(), timeout=timeout) health_statuses[provider_id] = health - except (asyncio.TimeoutError, TimeoutError): + except TimeoutError: health_statuses[provider_id] = HealthResponse( status=HealthStatus.ERROR, message=f"Health check timed out after {timeout} seconds", diff --git a/llama_stack/distribution/server/auth_providers.py b/llama_stack/distribution/server/auth_providers.py index 98e51c25a..173434652 100644 --- a/llama_stack/distribution/server/auth_providers.py +++ b/llama_stack/distribution/server/auth_providers.py @@ -9,12 +9,12 @@ import time from abc import ABC, abstractmethod from asyncio import Lock from pathlib import Path +from typing import Self from urllib.parse import parse_qs import httpx from jose import jwt from pydantic import BaseModel, Field, field_validator, model_validator -from typing_extensions import Self from llama_stack.distribution.datatypes import AuthenticationConfig, AuthProviderType, User from llama_stack.log import get_logger diff --git a/llama_stack/distribution/server/quota.py b/llama_stack/distribution/server/quota.py index ddbffae64..1cb850cde 100644 --- a/llama_stack/distribution/server/quota.py +++ b/llama_stack/distribution/server/quota.py @@ -6,7 +6,7 @@ import json import time -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from starlette.types import ASGIApp, Receive, Scope, Send @@ -79,7 +79,7 @@ class QuotaMiddleware: if int(prev) == 0: # Set with expiration datetime when it is the first request in the window. - expiration = datetime.now(timezone.utc) + timedelta(seconds=self.window_seconds) + expiration = datetime.now(UTC) + timedelta(seconds=self.window_seconds) await kv.set(key, str(count), expiration=expiration) else: await kv.set(key, str(count)) diff --git a/llama_stack/distribution/server/server.py b/llama_stack/distribution/server/server.py index 88b64ef2e..83407a25f 100644 --- a/llama_stack/distribution/server/server.py +++ b/llama_stack/distribution/server/server.py @@ -145,7 +145,7 @@ async def shutdown(app): await asyncio.wait_for(impl.shutdown(), timeout=5) else: logger.warning("No shutdown method for %s", impl_name) - except (asyncio.TimeoutError, TimeoutError): + except TimeoutError: logger.exception("Shutdown timeout for %s ", impl_name, exc_info=True) except (Exception, asyncio.CancelledError) as e: logger.exception("Failed to shutdown %s: %s", impl_name, {e}) diff --git a/llama_stack/providers/inline/agents/meta_reference/agent_instance.py b/llama_stack/providers/inline/agents/meta_reference/agent_instance.py index 937bd0341..4d2b9f8bf 100644 --- a/llama_stack/providers/inline/agents/meta_reference/agent_instance.py +++ b/llama_stack/providers/inline/agents/meta_reference/agent_instance.py @@ -11,7 +11,7 @@ import secrets import string import uuid from collections.abc import AsyncGenerator -from datetime import datetime, timezone +from datetime import UTC, datetime import httpx @@ -242,7 +242,7 @@ class ChatAgent(ShieldRunnerMixin): in_progress_tool_call_step = await self.storage.get_in_progress_tool_call_step( request.session_id, request.turn_id ) - now = datetime.now(timezone.utc).isoformat() + now = datetime.now(UTC).isoformat() tool_execution_step = ToolExecutionStep( step_id=(in_progress_tool_call_step.step_id if in_progress_tool_call_step else str(uuid.uuid4())), turn_id=request.turn_id, @@ -267,7 +267,7 @@ class ChatAgent(ShieldRunnerMixin): start_time = last_turn.started_at else: messages.extend(request.messages) - start_time = datetime.now(timezone.utc).isoformat() + start_time = datetime.now(UTC).isoformat() input_messages = request.messages output_message = None @@ -298,7 +298,7 @@ class ChatAgent(ShieldRunnerMixin): input_messages=input_messages, output_message=output_message, started_at=start_time, - completed_at=datetime.now(timezone.utc).isoformat(), + completed_at=datetime.now(UTC).isoformat(), steps=steps, ) await self.storage.add_turn_to_session(request.session_id, turn) @@ -389,7 +389,7 @@ class ChatAgent(ShieldRunnerMixin): return step_id = str(uuid.uuid4()) - shield_call_start_time = datetime.now(timezone.utc).isoformat() + shield_call_start_time = datetime.now(UTC).isoformat() try: yield AgentTurnResponseStreamChunk( event=AgentTurnResponseEvent( @@ -413,7 +413,7 @@ class ChatAgent(ShieldRunnerMixin): turn_id=turn_id, violation=e.violation, started_at=shield_call_start_time, - completed_at=datetime.now(timezone.utc).isoformat(), + completed_at=datetime.now(UTC).isoformat(), ), ) ) @@ -436,7 +436,7 @@ class ChatAgent(ShieldRunnerMixin): turn_id=turn_id, violation=None, started_at=shield_call_start_time, - completed_at=datetime.now(timezone.utc).isoformat(), + completed_at=datetime.now(UTC).isoformat(), ), ) ) @@ -491,7 +491,7 @@ class ChatAgent(ShieldRunnerMixin): client_tools[tool.name] = tool while True: step_id = str(uuid.uuid4()) - inference_start_time = datetime.now(timezone.utc).isoformat() + inference_start_time = datetime.now(UTC).isoformat() yield AgentTurnResponseStreamChunk( event=AgentTurnResponseEvent( payload=AgentTurnResponseStepStartPayload( @@ -603,7 +603,7 @@ class ChatAgent(ShieldRunnerMixin): turn_id=turn_id, model_response=copy.deepcopy(message), started_at=inference_start_time, - completed_at=datetime.now(timezone.utc).isoformat(), + completed_at=datetime.now(UTC).isoformat(), ), ) ) @@ -681,7 +681,7 @@ class ChatAgent(ShieldRunnerMixin): "input": message.model_dump_json(), }, ) as span: - tool_execution_start_time = datetime.now(timezone.utc).isoformat() + tool_execution_start_time = datetime.now(UTC).isoformat() tool_result = await self.execute_tool_call_maybe( session_id, tool_call, @@ -710,7 +710,7 @@ class ChatAgent(ShieldRunnerMixin): ) ], started_at=tool_execution_start_time, - completed_at=datetime.now(timezone.utc).isoformat(), + completed_at=datetime.now(UTC).isoformat(), ) # Yield the step completion event @@ -747,7 +747,7 @@ class ChatAgent(ShieldRunnerMixin): turn_id=turn_id, tool_calls=client_tool_calls, tool_responses=[], - started_at=datetime.now(timezone.utc).isoformat(), + started_at=datetime.now(UTC).isoformat(), ), ) diff --git a/llama_stack/providers/inline/agents/meta_reference/agents.py b/llama_stack/providers/inline/agents/meta_reference/agents.py index 6b05f90dd..6b2acd8f3 100644 --- a/llama_stack/providers/inline/agents/meta_reference/agents.py +++ b/llama_stack/providers/inline/agents/meta_reference/agents.py @@ -7,7 +7,7 @@ import logging import uuid from collections.abc import AsyncGenerator -from datetime import datetime, timezone +from datetime import UTC, datetime from llama_stack.apis.agents import ( Agent, @@ -93,7 +93,7 @@ class MetaReferenceAgentsImpl(Agents): agent_config: AgentConfig, ) -> AgentCreateResponse: agent_id = str(uuid.uuid4()) - created_at = datetime.now(timezone.utc) + created_at = datetime.now(UTC) agent_info = AgentInfo( **agent_config.model_dump(), diff --git a/llama_stack/providers/inline/agents/meta_reference/persistence.py b/llama_stack/providers/inline/agents/meta_reference/persistence.py index 25dbb5df7..717387008 100644 --- a/llama_stack/providers/inline/agents/meta_reference/persistence.py +++ b/llama_stack/providers/inline/agents/meta_reference/persistence.py @@ -7,7 +7,7 @@ import json import logging import uuid -from datetime import datetime, timezone +from datetime import UTC, datetime from llama_stack.apis.agents import AgentConfig, Session, ToolExecutionStep, Turn from llama_stack.distribution.access_control.access_control import AccessDeniedError, is_action_allowed @@ -47,7 +47,7 @@ class AgentPersistence: session_info = AgentSessionInfo( session_id=session_id, session_name=name, - started_at=datetime.now(timezone.utc), + started_at=datetime.now(UTC), owner=user, turns=[], identifier=name, # should this be qualified in any way? diff --git a/llama_stack/providers/inline/post_training/huggingface/recipes/finetune_single_device.py b/llama_stack/providers/inline/post_training/huggingface/recipes/finetune_single_device.py index b6d13b029..bdbe3d608 100644 --- a/llama_stack/providers/inline/post_training/huggingface/recipes/finetune_single_device.py +++ b/llama_stack/providers/inline/post_training/huggingface/recipes/finetune_single_device.py @@ -11,7 +11,7 @@ import multiprocessing import os import signal import sys -from datetime import datetime, timezone +from datetime import UTC, datetime from pathlib import Path from typing import Any @@ -670,7 +670,7 @@ class HFFinetuningSingleDevice: # Create checkpoint checkpoint = Checkpoint( identifier=f"{model}-sft-{config.n_epochs}", - created_at=datetime.now(timezone.utc), + created_at=datetime.now(UTC), epoch=config.n_epochs, post_training_job_id=job_uuid, path=str(output_dir_path / "merged_model"), diff --git a/llama_stack/providers/inline/post_training/torchtune/recipes/lora_finetuning_single_device.py b/llama_stack/providers/inline/post_training/torchtune/recipes/lora_finetuning_single_device.py index f56dd2499..fed19428c 100644 --- a/llama_stack/providers/inline/post_training/torchtune/recipes/lora_finetuning_single_device.py +++ b/llama_stack/providers/inline/post_training/torchtune/recipes/lora_finetuning_single_device.py @@ -7,7 +7,7 @@ import logging import os import time -from datetime import datetime, timezone +from datetime import UTC, datetime from functools import partial from pathlib import Path from typing import Any @@ -537,7 +537,7 @@ class LoraFinetuningSingleDevice: checkpoint_path = await self.save_checkpoint(epoch=curr_epoch) checkpoint = Checkpoint( identifier=f"{self.model_id}-sft-{curr_epoch}", - created_at=datetime.now(timezone.utc), + created_at=datetime.now(UTC), epoch=curr_epoch, post_training_job_id=self.job_uuid, path=checkpoint_path, diff --git a/llama_stack/providers/inline/telemetry/meta_reference/console_span_processor.py b/llama_stack/providers/inline/telemetry/meta_reference/console_span_processor.py index ff1914c15..e187bdb3b 100644 --- a/llama_stack/providers/inline/telemetry/meta_reference/console_span_processor.py +++ b/llama_stack/providers/inline/telemetry/meta_reference/console_span_processor.py @@ -5,7 +5,7 @@ # the root directory of this source tree. import json -from datetime import datetime, timezone +from datetime import UTC, datetime from opentelemetry.sdk.trace import ReadableSpan from opentelemetry.sdk.trace.export import SpanProcessor @@ -34,7 +34,7 @@ class ConsoleSpanProcessor(SpanProcessor): if span.attributes and span.attributes.get("__autotraced__"): return - timestamp = datetime.fromtimestamp(span.start_time / 1e9, tz=timezone.utc).strftime("%H:%M:%S.%f")[:-3] + timestamp = datetime.fromtimestamp(span.start_time / 1e9, tz=UTC).strftime("%H:%M:%S.%f")[:-3] print( f"{COLORS['dim']}{timestamp}{COLORS['reset']} " @@ -46,7 +46,7 @@ class ConsoleSpanProcessor(SpanProcessor): if span.attributes and span.attributes.get("__autotraced__"): return - timestamp = datetime.fromtimestamp(span.end_time / 1e9, tz=timezone.utc).strftime("%H:%M:%S.%f")[:-3] + timestamp = datetime.fromtimestamp(span.end_time / 1e9, tz=UTC).strftime("%H:%M:%S.%f")[:-3] span_context = ( f"{COLORS['dim']}{timestamp}{COLORS['reset']} " @@ -74,7 +74,7 @@ class ConsoleSpanProcessor(SpanProcessor): print(f" {COLORS['dim']}{key}: {str_value}{COLORS['reset']}") for event in span.events: - event_time = datetime.fromtimestamp(event.timestamp / 1e9, tz=timezone.utc).strftime("%H:%M:%S.%f")[:-3] + event_time = datetime.fromtimestamp(event.timestamp / 1e9, tz=UTC).strftime("%H:%M:%S.%f")[:-3] severity = event.attributes.get("severity", "info") message = event.attributes.get("message", event.name) diff --git a/llama_stack/providers/inline/telemetry/meta_reference/sqlite_span_processor.py b/llama_stack/providers/inline/telemetry/meta_reference/sqlite_span_processor.py index e9a003db6..b329a363c 100644 --- a/llama_stack/providers/inline/telemetry/meta_reference/sqlite_span_processor.py +++ b/llama_stack/providers/inline/telemetry/meta_reference/sqlite_span_processor.py @@ -8,7 +8,7 @@ import json import os import sqlite3 import threading -from datetime import datetime, timezone +from datetime import UTC, datetime from opentelemetry.sdk.trace import SpanProcessor from opentelemetry.trace import Span @@ -125,8 +125,8 @@ class SQLiteSpanProcessor(SpanProcessor): trace_id, service_name, (span_id if span.attributes.get("__root_span__") == "true" else None), - datetime.fromtimestamp(span.start_time / 1e9, timezone.utc).isoformat(), - datetime.fromtimestamp(span.end_time / 1e9, timezone.utc).isoformat(), + datetime.fromtimestamp(span.start_time / 1e9, UTC).isoformat(), + datetime.fromtimestamp(span.end_time / 1e9, UTC).isoformat(), ), ) @@ -144,8 +144,8 @@ class SQLiteSpanProcessor(SpanProcessor): trace_id, parent_span_id, span.name, - datetime.fromtimestamp(span.start_time / 1e9, timezone.utc).isoformat(), - datetime.fromtimestamp(span.end_time / 1e9, timezone.utc).isoformat(), + datetime.fromtimestamp(span.start_time / 1e9, UTC).isoformat(), + datetime.fromtimestamp(span.end_time / 1e9, UTC).isoformat(), json.dumps(dict(span.attributes)), span.status.status_code.name, span.kind.name, @@ -162,7 +162,7 @@ class SQLiteSpanProcessor(SpanProcessor): ( span_id, event.name, - datetime.fromtimestamp(event.timestamp / 1e9, timezone.utc).isoformat(), + datetime.fromtimestamp(event.timestamp / 1e9, UTC).isoformat(), json.dumps(dict(event.attributes)), ), ) diff --git a/llama_stack/providers/utils/bedrock/refreshable_boto_session.py b/llama_stack/providers/utils/bedrock/refreshable_boto_session.py index 437d3234e..8dab40424 100644 --- a/llama_stack/providers/utils/bedrock/refreshable_boto_session.py +++ b/llama_stack/providers/utils/bedrock/refreshable_boto_session.py @@ -87,9 +87,7 @@ class RefreshableBotoSession: "access_key": session_credentials.access_key, "secret_key": session_credentials.secret_key, "token": session_credentials.token, - "expiry_time": datetime.datetime.fromtimestamp( - time() + self.session_ttl, datetime.timezone.utc - ).isoformat(), + "expiry_time": datetime.datetime.fromtimestamp(time() + self.session_ttl, datetime.UTC).isoformat(), } return credentials diff --git a/llama_stack/providers/utils/inference/stream_utils.py b/llama_stack/providers/utils/inference/stream_utils.py index a2edbb9c8..bbfac13a3 100644 --- a/llama_stack/providers/utils/inference/stream_utils.py +++ b/llama_stack/providers/utils/inference/stream_utils.py @@ -5,7 +5,7 @@ # the root directory of this source tree. from collections.abc import AsyncIterator -from datetime import datetime, timezone +from datetime import UTC, datetime from typing import Any from llama_stack.apis.inference import ( @@ -122,7 +122,7 @@ async def stream_and_store_openai_completion( final_response = OpenAIChatCompletion( id=id, choices=assembled_choices, - created=created or int(datetime.now(timezone.utc).timestamp()), + created=created or int(datetime.now(UTC).timestamp()), model=model, object="chat.completion", ) diff --git a/llama_stack/providers/utils/scheduler.py b/llama_stack/providers/utils/scheduler.py index 845ab1f02..085ddaafa 100644 --- a/llama_stack/providers/utils/scheduler.py +++ b/llama_stack/providers/utils/scheduler.py @@ -9,7 +9,7 @@ import asyncio import functools import threading from collections.abc import Callable, Coroutine, Iterable -from datetime import datetime, timezone +from datetime import UTC, datetime from enum import Enum from typing import Any, TypeAlias @@ -61,7 +61,7 @@ class Job: self._handler = handler self._artifacts: list[JobArtifact] = [] self._logs: list[LogMessage] = [] - self._state_transitions: list[tuple[datetime, JobStatus]] = [(datetime.now(timezone.utc), JobStatus.new)] + self._state_transitions: list[tuple[datetime, JobStatus]] = [(datetime.now(UTC), JobStatus.new)] @property def handler(self) -> JobHandler: @@ -77,7 +77,7 @@ class Job: raise ValueError(f"Job is already in a completed state ({self.status})") if self.status == status: return - self._state_transitions.append((datetime.now(timezone.utc), status)) + self._state_transitions.append((datetime.now(UTC), status)) @property def artifacts(self) -> list[JobArtifact]: @@ -215,7 +215,7 @@ class Scheduler: self._backend = _get_backend_impl(backend) def _on_log_message_cb(self, job: Job, message: str) -> None: - msg = (datetime.now(timezone.utc), message) + msg = (datetime.now(UTC), message) # At least for the time being, until there's a better way to expose # logs to users, log messages on console logger.info(f"Job {job.id}: {message}") diff --git a/llama_stack/providers/utils/telemetry/tracing.py b/llama_stack/providers/utils/telemetry/tracing.py index 4edfa6516..10081f037 100644 --- a/llama_stack/providers/utils/telemetry/tracing.py +++ b/llama_stack/providers/utils/telemetry/tracing.py @@ -11,7 +11,7 @@ import queue import random import threading from collections.abc import Callable -from datetime import datetime, timezone +from datetime import UTC, datetime from functools import wraps from typing import Any @@ -121,7 +121,7 @@ class TraceContext: span_id=generate_span_id(), trace_id=self.trace_id, name=name, - start_time=datetime.now(timezone.utc), + start_time=datetime.now(UTC), parent_span_id=current_span.span_id if current_span else None, attributes=attributes, ) @@ -239,7 +239,7 @@ class TelemetryHandler(logging.Handler): UnstructuredLogEvent( trace_id=span.trace_id, span_id=span.span_id, - timestamp=datetime.now(timezone.utc), + timestamp=datetime.now(UTC), message=self.format(record), severity=severity(record.levelname), ) diff --git a/pyproject.toml b/pyproject.toml index 5bd0387b1..26b019866 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ version = "0.2.11" authors = [{ name = "Meta Llama", email = "llama-oss@meta.com" }] description = "Llama Stack" readme = "README.md" -requires-python = ">=3.10" +requires-python = ">=3.11" license = { "text" = "MIT" } classifiers = [ "License :: OSI Approved :: MIT License", diff --git a/scripts/unit-tests.sh b/scripts/unit-tests.sh index 771205150..e5bbccd7e 100755 --- a/scripts/unit-tests.sh +++ b/scripts/unit-tests.sh @@ -6,7 +6,7 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -PYTHON_VERSION=${PYTHON_VERSION:-3.10} +PYTHON_VERSION=${PYTHON_VERSION:-3.11} command -v uv >/dev/null 2>&1 || { echo >&2 "uv is required but it's not installed. Exiting."; exit 1; } diff --git a/tests/external-provider/llama-stack-provider-ollama/pyproject.toml b/tests/external-provider/llama-stack-provider-ollama/pyproject.toml index 715fa85e6..477e6a382 100644 --- a/tests/external-provider/llama-stack-provider-ollama/pyproject.toml +++ b/tests/external-provider/llama-stack-provider-ollama/pyproject.toml @@ -40,4 +40,4 @@ name = "llama-stack-provider-ollama" version = "0.1.0" description = "External provider for Ollama using the Llama Stack API" readme = "README.md" -requires-python = ">=3.10" +requires-python = ">=3.11" diff --git a/tests/unit/README.md b/tests/unit/README.md index db2114049..a686961d8 100644 --- a/tests/unit/README.md +++ b/tests/unit/README.md @@ -13,7 +13,7 @@ Any additional arguments are passed to pytest. For example, you can specify a te ./scripts/unit-tests.sh tests/unit/registry/test_registry.py -vvv ``` -If you'd like to run for a non-default version of Python (currently 3.10), pass `PYTHON_VERSION` variable as follows: +If you'd like to run for a non-default version of Python (currently 3.11), pass `PYTHON_VERSION` variable as follows: ``` source .venv/bin/activate diff --git a/uv.lock b/uv.lock index 68ba54ff7..4edd16055 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 2 -requires-python = ">=3.10" +requires-python = ">=3.11" resolution-markers = [ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",