Skip to content

Commit 1cf00b9

Browse files
authored
Support Pydantic v2 environments via falling back to v1 all of the time (#415)
* Support Pydantic v2 * Bump and CHANGELOG
1 parent 3072b35 commit 1cf00b9

File tree

9 files changed

+84
-24
lines changed

9 files changed

+84
-24
lines changed

CHANGELOG.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,11 @@ All notable changes to the [Nucleus Python Client](https://github.com/scaleapi/n
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [0.16.12](https://github.com/scaleapi/nucleus-python-client/releases/tag/v0.16.12) - 2023-11-27
9-
10-
### Added
11-
12-
- Added `num_processes` parameter to `dataset.items_and_annotation_chip_generator()` to specify parallel processing.
13-
148
## [0.16.11](https://github.com/scaleapi/nucleus-python-client/releases/tag/v0.16.11) - 2023-11-22
159

1610
### Added
1711

12+
- Added `num_processes` parameter to `dataset.items_and_annotation_chip_generator()` to specify parallel processing.
1813
- Method to allow for concurrent task fetches for pointcloud data
1914

2015
Example:
@@ -28,6 +23,9 @@ Example:
2823
}
2924
```
3025

26+
### Fixes
27+
- Support environments using pydantic>=2
28+
3129
## [0.16.10](https://github.com/scaleapi/nucleus-python-client/releases/tag/v0.16.10) - 2023-11-22
3230

3331
Allow creating a dataset by crawling all images in a directory, recursively. Also supports privacy mode datasets.

nucleus/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@
4747
import warnings
4848
from typing import Any, Dict, List, Optional, Tuple, Union
4949

50-
import pydantic
50+
try:
51+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
52+
import pydantic.v1 as pydantic
53+
except ImportError:
54+
import pydantic
55+
5156
import requests
5257
import tqdm
5358

nucleus/data_transfer_object/job_status.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
from typing import List, Optional, Union
55

66
from dateutil.parser import ParserError, parse
7-
from pydantic import validator
7+
8+
try:
9+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
10+
from pydantic.v1 import validator
11+
except ImportError:
12+
from pydantic import validator
813

914
from nucleus.constants import JOB_REQ_LIMIT
1015
from nucleus.job import CustomerJobTypes

nucleus/pydantic_base.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
from pydantic import BaseModel # pylint: disable=no-name-in-module
1+
"""
2+
NOTE:
3+
We started using pydantic during v1 and are kind of stuck with it now unless we write a compatibility layers.
4+
As a library we want to support v1 and v2 such that we're not causing downstream problems for our users.
5+
This means we have to do some import shenanigans to support both v1 and v2.
6+
"""
7+
try:
8+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
9+
from pydantic.v1 import BaseModel # pylint: disable=no-name-in-module
10+
except ImportError:
11+
from pydantic import BaseModel
212

313

414
class ImmutableModel(BaseModel):

nucleus/test_launch_integration.py

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,101 @@
22
from typing import Any, Callable, Dict, List, Optional, Type
33

44
from PIL import Image, ImageDraw
5-
from pydantic import BaseModel, Extra, ValidationError
5+
6+
try:
7+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
8+
from pydantic.v1 import BaseModel, Extra, ValidationError
9+
except ImportError:
10+
from pydantic import BaseModel, Extra, ValidationError
611

712
# From scaleapi/server/src/lib/select/api/types.ts
813
# These classes specify how user models must pass output to Launch + Nucleus.
914

1015

11-
class PointModel(BaseModel, extra=Extra.forbid):
16+
class PointModel(BaseModel):
1217
x: float
1318
y: float
1419

20+
class Config:
21+
extra = Extra.forbid
22+
1523

16-
class BoxGeometryModel(BaseModel, extra=Extra.forbid):
24+
class BoxGeometryModel(BaseModel):
1725
x: float
1826
y: float
1927
width: float
2028
height: float
2129

30+
class Config:
31+
extra = Extra.forbid
32+
2233

23-
class BoxAnnotationModel(BaseModel, extra=Extra.forbid):
34+
class BoxAnnotationModel(BaseModel):
2435
geometry: BoxGeometryModel
2536
type: str
2637
label: Optional[str] = None
2738
confidence: Optional[float] = None
2839
classPdf: Optional[Dict[str, float]] = None
2940
metadata: Optional[Dict[str, Any]] = None
3041

42+
class Config:
43+
extra = Extra.forbid
3144

32-
class NoneGeometryModel(BaseModel, extra=Extra.forbid):
33-
pass
3445

46+
class NoneGeometryModel(BaseModel):
47+
class Config:
48+
extra = Extra.forbid
3549

36-
class CategoryAnnotationModel(BaseModel, extra=Extra.forbid):
50+
51+
class CategoryAnnotationModel(BaseModel):
3752
geometry: NoneGeometryModel
3853
type: str
3954
label: Optional[str] = None
4055
confidence: Optional[float] = None
4156
classPdf: Optional[Dict[str, float]] = None
4257
metadata: Optional[Dict[str, Any]] = None
4358

59+
class Config:
60+
extra = Extra.forbid
61+
4462

45-
class LineGeometryModel(BaseModel, extra=Extra.forbid):
63+
class LineGeometryModel(BaseModel):
4664
vertices: List[PointModel]
4765

66+
class Config:
67+
extra = Extra.forbid
4868

49-
class LineAnnotationModel(BaseModel, extra=Extra.forbid):
69+
70+
class LineAnnotationModel(BaseModel):
5071
geometry: LineGeometryModel
5172
type: str
5273
label: Optional[str] = None
5374
confidence: Optional[float] = None
5475
classPdf: Optional[Dict[str, float]] = None
5576
metadata: Optional[Dict[str, Any]] = None
5677

78+
class Config:
79+
extra = Extra.forbid
80+
5781

58-
class PolygonGeometryModel(BaseModel, extra=Extra.forbid):
82+
class PolygonGeometryModel(BaseModel):
5983
vertices: List[PointModel]
6084

85+
class Config:
86+
extra = Extra.forbid
6187

62-
class PolygonAnnotationModel(BaseModel, extra=Extra.forbid):
88+
89+
class PolygonAnnotationModel(BaseModel):
6390
geometry: PolygonGeometryModel
6491
type: str
6592
label: Optional[str] = None
6693
confidence: Optional[float] = None
6794
classPdf: Optional[Dict[str, float]] = None
6895
metadata: Optional[Dict[str, Any]] = None
6996

97+
class Config:
98+
extra = Extra.forbid
99+
70100

71101
def verify_output(
72102
annotation_list: List[Dict[str, Any]],

nucleus/validate/data_transfer_objects/eval_function.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
from typing import Any, Dict, List, Optional
22

3-
from pydantic import validator
3+
try:
4+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
5+
from pydantic.v1 import validator
6+
except ImportError:
7+
from pydantic import validator
48

59
from ...pydantic_base import ImmutableModel
610
from ..constants import ThresholdComparison

nucleus/validate/data_transfer_objects/scenario_test.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
from typing import List
22

3-
from pydantic import validator
3+
try:
4+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
5+
from pydantic.v1 import validator
6+
except ImportError:
7+
from pydantic import validator
48

59
from nucleus.pydantic_base import ImmutableModel
610

nucleus/validate/data_transfer_objects/scenario_test_evaluations.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
from typing import Optional
22

3-
from pydantic import root_validator, validator
3+
try:
4+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
5+
from pydantic.v1 import root_validator, validator
6+
except ImportError:
7+
from pydantic import root_validator, validator
48

59
from nucleus.pydantic_base import ImmutableModel
610

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ ignore = ["E501", "E741", "E731", "F401"] # Easy ignore for getting it running
2525

2626
[tool.poetry]
2727
name = "scale-nucleus"
28-
version = "0.16.10"
28+
version = "0.16.11"
2929
description = "The official Python client library for Nucleus, the Data Platform for AI"
3030
license = "MIT"
3131
authors = ["Scale AI Nucleus Team <nucleusapi@scaleapi.com>"]

0 commit comments

Comments
 (0)