Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚧(project) remove Python 3.8 support #618

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ workflows:
- build:
matrix:
parameters:
python-image: [python:3.8, python:3.9, python:3.10, python:3.11, python:3.12]
python-image: [python:3.9, python:3.10, python:3.11, python:3.12]
filters:
tags:
only: /.*/
Expand All @@ -731,7 +731,7 @@ workflows:
- test:
matrix:
parameters:
python-image: [python:3.8, python:3.9, python:3.10, python:3.11, python:3.12]
python-image: [python:3.9, python:3.10, python:3.11, python:3.12]
requires:
- build
filters:
Expand All @@ -741,7 +741,7 @@ workflows:
matrix:
parameters:
python-image:
[python:3.8, python:3.9, python:3.10, python:3.11, python:3.12]
[python:3.9, python:3.10, python:3.11, python:3.12]
filters:
tags:
only: /.*/
Expand Down
10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12"
]
requires-python = ">=3.8"
requires-python = ">=3.9"
license = { file = "LICENSE.md" }
keywords = ["LRS", "Analytics", "xAPI", "Open edX"]
dependencies = [
Expand Down Expand Up @@ -57,7 +57,7 @@ backend-ldp = [
"requests>=2.0.0",
]
backend-lrs = [
"httpx<0.27.3", # pin as `pytest-httpx<0.23.0` requires `httpx==0.24.*`
"httpx>=0.27,<1.0",
]
backend-mongo = [
"motor[srv]>=3.3.0",
Expand Down Expand Up @@ -105,9 +105,9 @@ dev = [
"polyfactory==2.16.2",
"pyfakefs==5.6.0",
"pymdown-extensions==10.9",
"pytest<8.0.0", # pin as pytest-httpx<0.23.0 is not compatible with pytest 8.0.0
"pytest==8.3.3",
"pytest-cov==5.0.0",
"pytest-httpx<0.23.0", # pin as Python 3.8 is no longer supported from release 0.23.0
"pytest-httpx==0.30.0",
"requests-mock==1.12.1",
"responses==0.25.3",
"ruff==0.6.5",
Expand All @@ -120,7 +120,7 @@ lrs = [
"bcrypt==4.2.0",
"fastapi==0.114.2",
"cachetools==5.5.0",
"httpx<0.27.3", # pin as `pytest-httpx<0.23.0` requires `httpx==0.24.*`
"httpx>=0.27,<1.0",
"sentry_sdk==2.14.0",
"python-jose==3.3.0",
"uvicorn[standard]==0.30.6",
Expand Down
6 changes: 1 addition & 5 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
"commitBodyTable": true,
"ignoreDeps": [
"backend-clickhouse/clickhouse-connect",
"backend-lrs/httpx",
"dev/pytest",
"dev/pytest-httpx",
"dev/responses",
"lrs/httpx"
"dev/responses"
],
"packageRules": [
{
Expand Down
7 changes: 3 additions & 4 deletions src/ralph/backends/data/async_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from pydantic import AnyUrl, PositiveInt
from pydantic_settings import SettingsConfigDict
from websockets.http11 import USER_AGENT
from websockets.asyncio.client import connect, ClientConnection

from ralph.backends.data.base import (
BaseAsyncDataBackend,
Expand Down Expand Up @@ -40,7 +41,6 @@ class WSClientOptions(ClientOptions):
Setting it to `None` disables keepalive pings.
ping_timeout (float): Timeout for keepalive pings in seconds.
Setting it to `None` disables timeouts.
read_limit (int): High-water mark of read buffer in bytes.
user_agent_header (str): Value of the `User-Agent` request header.
It defaults to "Python/x.y.z websockets/X.Y".
Setting it to `None` removes the header.
Expand All @@ -55,7 +55,6 @@ class WSClientOptions(ClientOptions):
origin: Optional[str] = None
ping_interval: Optional[float] = 20
ping_timeout: Optional[float] = 20
read_limit: int = 2**16
user_agent_header: Optional[str] = USER_AGENT
write_limit: int = 2**16

Expand Down Expand Up @@ -93,11 +92,11 @@ def __init__(self, settings: Optional[WSDataBackendSettings] = None):
super().__init__(settings)
self._client = None

async def client(self) -> websockets.WebSocketClientProtocol:
async def client(self) -> ClientConnection:
"""Create a websocket client connected to `settings.URI` if it doesn't exist."""
if not self._client:
try:
self._client = await websockets.connect(
self._client = await connect(
str(self.settings.URI), **self.settings.CLIENT_OPTIONS.model_dump()
)
except (websockets.WebSocketException, OSError, TimeoutError) as error:
Expand Down
5 changes: 3 additions & 2 deletions tests/backends/data/test_async_lrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ async def test_backends_data_async_lrs_read_backend_error(
error = (
"Failed to fetch statements: Server error '500 Internal Server Error' for url "
"'http://fake-lrs.com/xAPI/statements/?limit=500'\nFor more information check: "
"https://httpstatuses.com/500"
"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500"
)
with pytest.raises(BackendException, match=re.escape(error)):
with caplog.at_level(logging.ERROR):
Expand Down Expand Up @@ -660,7 +660,7 @@ async def test_backends_data_async_lrs_write_with_post_exception(
msg = (
"Failed to post statements: Server error '500 Internal Server Error' for url "
"'http://fake-lrs.com/xAPI/statements/'\nFor more information check: "
"https://httpstatuses.com/500"
"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500"
)
assert (
f"ralph.backends.data.{backend.name}",
Expand Down Expand Up @@ -809,3 +809,4 @@ async def simulate_network_latency(_):
# Server side processing time should be 3 times faster with unlimited
assert limited_concurrency_duration > 2.1 * concurrent_duration
assert limited_concurrency_duration <= 3.1 * concurrent_duration

22 changes: 12 additions & 10 deletions tests/backends/test_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,16 @@ def mock_entry_points(group):
),
]

monkeypatch.setattr("ralph.backends.loader.entry_points", mock_entry_points)
with monkeypatch.context() as mocked_context:
mocked_context.setattr("ralph.backends.loader.entry_points", mock_entry_points)
get_lrs_backends.cache_clear()
assert get_lrs_backends() == {
"test_backend": TestBackend,
"async_es": AsyncESLRSBackend,
"async_mongo": AsyncMongoLRSBackend,
"clickhouse": ClickHouseLRSBackend,
"es": ESLRSBackend,
"fs": FSLRSBackend,
"mongo": MongoLRSBackend,
}
get_lrs_backends.cache_clear()
assert get_lrs_backends() == {
"test_backend": TestBackend,
"async_es": AsyncESLRSBackend,
"async_mongo": AsyncMongoLRSBackend,
"clickhouse": ClickHouseLRSBackend,
"es": ESLRSBackend,
"fs": FSLRSBackend,
"mongo": MongoLRSBackend,
}
4 changes: 3 additions & 1 deletion tests/fixtures/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from pymongo import MongoClient
from pymongo.errors import CollectionInvalid

from websockets.asyncio.server import serve

from ralph.backends.data.async_es import AsyncESDataBackend
from ralph.backends.data.async_lrs import AsyncLRSDataBackend
from ralph.backends.data.async_mongo import AsyncMongoDataBackend
Expand Down Expand Up @@ -893,7 +895,7 @@ async def forward(websocket):
await websocket.send(json.dumps(event))
await asyncio.sleep(random.randrange(0, 500) / 10000.0)

async with websockets.serve(forward, "0.0.0.0", WS_TEST_PORT) as server:
async with serve(forward, "0.0.0.0", WS_TEST_PORT) as server:
yield server


Expand Down
2 changes: 1 addition & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from importlib import reload
from pathlib import Path
from typing import Optional, Union

import asyncio
import pytest
from click.exceptions import BadParameter
from click.testing import CliRunner
Expand Down