sqlalchemy-serializer-meta 0.2.0__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {sqlalchemy_serializer_meta-0.2.0/sqlalchemy_serializer_meta.egg-info → sqlalchemy_serializer_meta-1.0.0}/PKG-INFO +28 -13
  2. {sqlalchemy_serializer_meta-0.2.0 → sqlalchemy_serializer_meta-1.0.0}/README.md +2 -2
  3. sqlalchemy_serializer_meta-1.0.0/pyproject.toml +66 -0
  4. sqlalchemy_serializer_meta-1.0.0/setup.cfg +4 -0
  5. sqlalchemy_serializer_meta-1.0.0/setup.py +4 -0
  6. sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta/__init__.py +52 -0
  7. sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta/compat.py +14 -0
  8. sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta/exceptions.py +77 -0
  9. sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta/fields.py +62 -0
  10. sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta/serializer.py +703 -0
  11. sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta/transformers.py +62 -0
  12. sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta/validator.py +27 -0
  13. {sqlalchemy_serializer_meta-0.2.0 → sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta.egg-info}/PKG-INFO +28 -13
  14. sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta.egg-info/SOURCES.txt +20 -0
  15. sqlalchemy_serializer_meta-1.0.0/sqlalchemy_serializer_meta.egg-info/requires.txt +13 -0
  16. sqlalchemy_serializer_meta-1.0.0/tests/test_flask_integration.py +94 -0
  17. sqlalchemy_serializer_meta-1.0.0/tests/test_model_serializer.py +238 -0
  18. sqlalchemy_serializer_meta-1.0.0/tests/test_serializers.py +117 -0
  19. sqlalchemy_serializer_meta-1.0.0/tests/test_transformers_and_validators.py +96 -0
  20. sqlalchemy_serializer_meta-0.2.0/setup.cfg +0 -7
  21. sqlalchemy_serializer_meta-0.2.0/setup.py +0 -26
  22. sqlalchemy_serializer_meta-0.2.0/sqlalchemy_serializer_meta/__init__.py +0 -426
  23. sqlalchemy_serializer_meta-0.2.0/sqlalchemy_serializer_meta/serializer.py +0 -199
  24. sqlalchemy_serializer_meta-0.2.0/sqlalchemy_serializer_meta/validator.py +0 -20
  25. sqlalchemy_serializer_meta-0.2.0/sqlalchemy_serializer_meta.egg-info/SOURCES.txt +0 -12
  26. sqlalchemy_serializer_meta-0.2.0/sqlalchemy_serializer_meta.egg-info/requires.txt +0 -3
  27. {sqlalchemy_serializer_meta-0.2.0 → sqlalchemy_serializer_meta-1.0.0}/LICENSE +0 -0
  28. {sqlalchemy_serializer_meta-0.2.0 → sqlalchemy_serializer_meta-1.0.0}/sqlalchemy_serializer_meta.egg-info/dependency_links.txt +0 -0
  29. {sqlalchemy_serializer_meta-0.2.0 → sqlalchemy_serializer_meta-1.0.0}/sqlalchemy_serializer_meta.egg-info/top_level.txt +0 -0
@@ -1,30 +1,45 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: sqlalchemy_serializer_meta
3
- Version: 0.2.0
4
- Summary: A simple serializer for SQLAlchemy models and Flask Models
5
- Home-page: https://github.com/Wehda23/sqlalchemy_serializer_meta
6
- Author: Waheed Khaled Elhariri
7
- Author-email: waheedkhaled95@gmail.com
3
+ Version: 1.0.0
4
+ Summary: High-performance DRF-style serializer for SQLAlchemy and Flask models with Pydantic v2 validation
5
+ Author-email: Waheed Khaled Elhariri <waheedkhaled95@gmail.com>
8
6
  License: MIT
9
- Keywords: sqlalchemy serializer pydantic flask
10
- Classifier: Development Status :: 4 - Beta
7
+ Project-URL: Homepage, https://github.com/Wehda23/sqlalchemy_serializer_meta
8
+ Project-URL: Repository, https://github.com/Wehda23/sqlalchemy_serializer_meta
9
+ Project-URL: Issues, https://github.com/Wehda23/sqlalchemy_serializer_meta/issues
10
+ Keywords: sqlalchemy,serializer,pydantic,flask,drf,rest,orm
11
+ Classifier: Development Status :: 5 - Production/Stable
11
12
  Classifier: Intended Audience :: Developers
12
13
  Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
13
16
  Classifier: Programming Language :: Python :: 3.9
14
17
  Classifier: Programming Language :: Python :: 3.10
15
18
  Classifier: Programming Language :: Python :: 3.11
16
19
  Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Framework :: Flask
23
+ Requires-Python: >=3.9
17
24
  Description-Content-Type: text/markdown
18
25
  License-File: LICENSE
19
- Requires-Dist: sqlalchemy
20
- Requires-Dist: pydantic==2.7.4
21
- Requires-Dist: pydantic_core==2.18.4
26
+ Requires-Dist: sqlalchemy>=1.4.0
27
+ Requires-Dist: pydantic>=2.0.0
28
+ Requires-Dist: typing_extensions>=4.6.0; python_version < "3.11"
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.4.0; extra == "dev"
31
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
32
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
33
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
34
+ Requires-Dist: Flask>=2.0.0; extra == "dev"
35
+ Requires-Dist: Flask-SQLAlchemy>=3.0.0; extra == "dev"
36
+ Dynamic: license-file
22
37
 
23
38
  # Serializer Module for Flask Application
24
39
 
25
40
  This module provides a set of serializers for your Flask application, allowing you to easily validate and serialize data. The serializers are built with flexibility and extendability in mind, providing features such as nested serialization and integration with Pydantic models.
26
41
 
27
- ## 📜 Table of Contents
42
+ ## Table of Contents
28
43
  1. [Installation](#installation)
29
44
  2. [Basic Usage](#usage)
30
45
  3. [Creating Custom Serializers](#custom-serializers)
@@ -36,7 +51,7 @@ This module provides a set of serializers for your Flask application, allowing y
36
51
  To use the serializers in your project, simply include the necessary files in your application directory.
37
52
 
38
53
  ```bash
39
- pip install sqlalchemy-serializer-meta==0.1.0
54
+ pip install sqlalchemy-serializer-meta
40
55
  ```
41
56
 
42
57
  ## Usage
@@ -2,7 +2,7 @@
2
2
 
3
3
  This module provides a set of serializers for your Flask application, allowing you to easily validate and serialize data. The serializers are built with flexibility and extendability in mind, providing features such as nested serialization and integration with Pydantic models.
4
4
 
5
- ## 📜 Table of Contents
5
+ ## Table of Contents
6
6
  1. [Installation](#installation)
7
7
  2. [Basic Usage](#usage)
8
8
  3. [Creating Custom Serializers](#custom-serializers)
@@ -14,7 +14,7 @@ This module provides a set of serializers for your Flask application, allowing y
14
14
  To use the serializers in your project, simply include the necessary files in your application directory.
15
15
 
16
16
  ```bash
17
- pip install sqlalchemy-serializer-meta==0.1.0
17
+ pip install sqlalchemy-serializer-meta
18
18
  ```
19
19
 
20
20
  ## Usage
@@ -0,0 +1,66 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sqlalchemy_serializer_meta"
7
+ version = "1.0.0"
8
+ description = "High-performance DRF-style serializer for SQLAlchemy and Flask models with Pydantic v2 validation"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ authors = [
12
+ { name = "Waheed Khaled Elhariri", email = "waheedkhaled95@gmail.com" }
13
+ ]
14
+ requires-python = ">=3.9"
15
+ keywords = ["sqlalchemy", "serializer", "pydantic", "flask", "drf", "rest", "orm"]
16
+ classifiers = [
17
+ "Development Status :: 5 - Production/Stable",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Software Development :: Libraries :: Python Modules",
28
+ "Framework :: Flask",
29
+ ]
30
+ dependencies = [
31
+ "sqlalchemy>=1.4.0",
32
+ "pydantic>=2.0.0",
33
+ "typing_extensions>=4.6.0; python_version < '3.11'",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "pytest>=7.4.0",
39
+ "pytest-cov>=4.1.0",
40
+ "ruff>=0.4.0",
41
+ "mypy>=1.10.0",
42
+ "Flask>=2.0.0",
43
+ "Flask-SQLAlchemy>=3.0.0",
44
+ ]
45
+
46
+ [project.urls]
47
+ Homepage = "https://github.com/Wehda23/sqlalchemy_serializer_meta"
48
+ Repository = "https://github.com/Wehda23/sqlalchemy_serializer_meta"
49
+ Issues = "https://github.com/Wehda23/sqlalchemy_serializer_meta/issues"
50
+
51
+ [tool.setuptools.packages.find]
52
+ where = ["."]
53
+ include = ["sqlalchemy_serializer_meta*"]
54
+
55
+ [tool.pytest.ini_options]
56
+ minversion = "7.0"
57
+ addopts = "-ra -q --strict-markers"
58
+ testpaths = ["tests"]
59
+
60
+ [tool.ruff]
61
+ line-length = 100
62
+ target-version = "py39"
63
+
64
+ [tool.ruff.lint]
65
+ select = ["E", "F", "W", "I"]
66
+ ignore = ["E501"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ from setuptools import setup
2
+
3
+ if __name__ == "__main__":
4
+ setup()
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+
3
+ """
4
+ sqlalchemy_serializer_meta
5
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
6
+
7
+ A fast, flexible DRF-style serializer for SQLAlchemy and Flask models with Pydantic v2 validation.
8
+ """
9
+
10
+ from .compat import Self
11
+ from .exceptions import SerializerError, ValidationError
12
+ from .fields import Field, SerializerMethodField
13
+ from .serializer import (
14
+ AbstractSerializer,
15
+ Creatable,
16
+ Deletable,
17
+ ExtendsPydantic,
18
+ ModelSerializer,
19
+ Representable,
20
+ Saveable,
21
+ Serializer,
22
+ SerializerInterface,
23
+ ToInstance,
24
+ Updatable,
25
+ Validatable,
26
+ )
27
+ from .transformers import to_jsonable_python
28
+ from .validator import BaseValidator
29
+
30
+ __version__ = "1.0.0"
31
+
32
+ __all__ = [
33
+ "AbstractSerializer",
34
+ "BaseValidator",
35
+ "Creatable",
36
+ "Deletable",
37
+ "ExtendsPydantic",
38
+ "Field",
39
+ "ModelSerializer",
40
+ "Representable",
41
+ "Saveable",
42
+ "Self",
43
+ "Serializer",
44
+ "SerializerError",
45
+ "SerializerInterface",
46
+ "SerializerMethodField",
47
+ "ToInstance",
48
+ "Updatable",
49
+ "Validatable",
50
+ "ValidationError",
51
+ "to_jsonable_python",
52
+ ]
@@ -0,0 +1,14 @@
1
+ from __future__ import annotations
2
+
3
+ """
4
+ Compatibility helpers across Python and dependency versions.
5
+ """
6
+
7
+ import sys
8
+
9
+ if sys.version_info >= (3, 11):
10
+ from typing import Self
11
+ else:
12
+ from typing_extensions import Self
13
+
14
+ __all__ = ["Self"]
@@ -0,0 +1,77 @@
1
+ from __future__ import annotations
2
+
3
+ """
4
+ Custom exception hierarchy for serializers and validation.
5
+ """
6
+
7
+ from typing import Any, Optional
8
+
9
+
10
+ class SerializerError(Exception):
11
+ """
12
+ Standard serializer exception.
13
+
14
+ Supports both conventional exception signatures and legacy two-argument signatures:
15
+ - raise SerializerError("Error message")
16
+ - raise SerializerError(ValueError, "Error message")
17
+ - raise SerializerError("Error message", field="email", code="invalid")
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ *args: Any,
23
+ field: Optional[str] = None,
24
+ code: str = "invalid",
25
+ ) -> None:
26
+ super().__init__(*args)
27
+ self.field = field
28
+ self.code = code
29
+ self.exception_class: Optional[type] = None
30
+
31
+ if len(args) == 1:
32
+ self.message = str(args[0])
33
+ self.exception_class = self.__class__
34
+ elif len(args) >= 2:
35
+ first, second = args[0], args[1]
36
+ if isinstance(first, type) and issubclass(first, BaseException):
37
+ self.exception_class = first
38
+ self.message = str(second)
39
+ else:
40
+ self.message = str(second)
41
+ self.exception_class = self.__class__
42
+ else:
43
+ self.message = "Serializer error"
44
+ self.exception_class = self.__class__
45
+
46
+ def to_dict(self) -> dict:
47
+ type_name = self.exception_class.__name__ if self.exception_class else self.__class__.__name__
48
+ res = {
49
+ "msg": self.message,
50
+ "type": type_name,
51
+ "code": self.code,
52
+ }
53
+ if self.field:
54
+ res["field"] = self.field
55
+ return res
56
+
57
+ def __str__(self) -> str:
58
+ return self.message
59
+
60
+
61
+ class ValidationError(SerializerError):
62
+ """
63
+ Validation error raised when data fails schema or field-level constraints.
64
+ """
65
+
66
+ def __init__(
67
+ self,
68
+ detail: Any,
69
+ field: Optional[str] = None,
70
+ code: str = "invalid",
71
+ ) -> None:
72
+ if isinstance(detail, (dict, list)):
73
+ self.detail = detail
74
+ super().__init__(str(detail), field=field, code=code)
75
+ else:
76
+ self.detail = str(detail)
77
+ super().__init__(str(detail), field=field, code=code)
@@ -0,0 +1,62 @@
1
+ from __future__ import annotations
2
+
3
+ """
4
+ Field definitions and special serializer descriptors.
5
+ """
6
+
7
+ from typing import Any, Callable, Optional
8
+
9
+
10
+ class Field:
11
+ """
12
+ Base representation of a serializer field.
13
+ """
14
+
15
+ def __init__(
16
+ self,
17
+ source: Optional[str] = None,
18
+ read_only: bool = False,
19
+ write_only: bool = False,
20
+ required: bool = True,
21
+ default: Any = None,
22
+ ) -> None:
23
+ self.source = source
24
+ self.read_only = read_only
25
+ self.write_only = write_only
26
+ self.required = required
27
+ self.default = default
28
+ self.field_name: Optional[str] = None
29
+
30
+ def bind(self, field_name: str) -> None:
31
+ self.field_name = field_name
32
+ if self.source is None:
33
+ self.source = field_name
34
+
35
+ def get_attribute(self, instance: Any) -> Any:
36
+ if self.source:
37
+ return getattr(instance, self.source, self.default)
38
+ return self.default
39
+
40
+
41
+ class SerializerMethodField(Field):
42
+ """
43
+ Read-only field that gets its value by calling a method on the serializer class.
44
+ Method defaults to `get_<field_name>(instance)`.
45
+ """
46
+
47
+ def __init__(self, method_name: Optional[str] = None) -> None:
48
+ super().__init__(read_only=True, required=False)
49
+ self.method_name = method_name
50
+
51
+ def bind(self, field_name: str) -> None:
52
+ super().bind(field_name)
53
+ if self.method_name is None:
54
+ self.method_name = f"get_{field_name}"
55
+
56
+ def to_representation(self, serializer: Any, instance: Any) -> Any:
57
+ method: Optional[Callable] = getattr(serializer, self.method_name, None)
58
+ if method is None or not callable(method):
59
+ raise AttributeError(
60
+ f"Serializer '{serializer.__class__.__name__}' is missing method '{self.method_name}'"
61
+ )
62
+ return method(instance)