Name | remapper JSON |
Version |
1.0.2
JSON |
| download |
home_page | None |
Summary | Transform objects to and from similar structural mappings. |
upload_time | 2025-07-25 17:44:21 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.8 |
license | None |
keywords |
mapping
dataclass
presentation
models
util
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# remapper



Transform objects to and from similar structural mappings. Useful for translating between sources of truth and presentational models of data.
Supports Python 3.8+. No dependencies.
## Installation
```sh
$ pdm add remapper
# or
$ python -m pip install --user remapper
```
## Usage
> The examples below use dataclasses because they're easy, but `remap` works with any destination type that exposes attributes via its `__init__`.
A trivial example for `remap` is converting one dataclass into another without having to manually pass attributes:
```python
from dataclasses import dataclass
from remapper import remap
@dataclass
class Source:
a: int
b: int
c: int
@dataclass
class Destination:
a: int
b: int
c: int
dest = remap(Source(a=1, b=2, c=3), Destination)
# >> Destination(a=1, b=2, c=3)
```
A more useful example would be in mapping an internal database model to an externally-facing dataclass:
```python
from dataclasses import dataclass
from remapper import remap
from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, mapped_column
class Base(DeclarativeBase, MappedAsDataclass):
pass
class Source(Base):
id: Mapped[int] = mapped_column(init=False, primary_key=True)
a: Mapped[int]
b: Mapped[int]
c: Mapped[int]
@dataclass
class Destination:
a: int
b: int
c: int
@property
def d(self) -> int:
return self.a + self.b + self.c
source = Source(a=1, b=2, c=3)
await session.commit(source)
dest = remap(source, Destination)
dest.d
# >> 6
```
### Overrides
There's a non-zero chance that a destination may require more data than available on a source. In those cases, you can manually provide values via the `overrides` keyword argument. Values in `overrides` will take precedence over values on the source:
```python
from dataclasses import dataclass
from remapper import remap
@dataclass
class Source:
a: int
b: int
@dataclass
class Destination:
a: int
b: int
c: int
dest = remap(Source(a=1, b=2), Destination, overrides={"b": 0, "c": 3})
# >> Destination(a=1, b=0, c=3)
```
### Defaults
If a destination defines more attributes than available on a source, but the destination has default values for those additional attributes, you don't need to supply overrides:
```python
from dataclasses import dataclass
from remapper import remap
@dataclass
class Source:
a: int
b: int
@dataclass
class Destination:
a: int
b: int
c: int = 3
dest = remap(Source(a=1, b=2), Destination)
# >> Destination(a=1, b=2, c=3)
```
### Nested Types
Some complex sources may have attributes that themselves need to be converted. Rather than remapping in several steps, you can use the `nested_types` keyword argument to specify inner types of the destination attributes:
```python
from dataclasses import dataclass
from remapper import remap
@dataclass
class Source:
b: int
@dataclass
class Destination:
b: int
@dataclass
class ParentSource:
a: int
child: Source
@dataclass
class ParentDestination:
a: int
child: Destination
## this works but is kind of clunky
source = ParentSource(a=1, child=Source(b=1))
dest_child = remap(source.child, Destination)
dest = remap(source, ParentDestination, overrides={"child": dest_child})
# >> ParentDestination(a=1,child=Destination(b=1))
## so use this instead
dest = remap(
ParentSource(a=1, child=Source(b=1)),
ParentDestination,
nested_types={"child": Destination},
)
# >> ParentDestination(a=1,child=Destination(b=1))
```
## License
This software is licensed under the [BSD 3-Clause Clear License](LICENSE).
Raw data
{
"_id": null,
"home_page": null,
"name": "remapper",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "mapping, dataclass, presentation, models, util",
"author": null,
"author_email": "Elias Gabriel <oss@eliasfgabriel.com>",
"download_url": "https://files.pythonhosted.org/packages/49/6c/985b35d69b5165dc79403f4d8ddbe9a58ffab1e5eb7f1b37de1c49cdcc55/remapper-1.0.2.tar.gz",
"platform": null,
"description": "# remapper\n\n\n\n\n\nTransform objects to and from similar structural mappings. Useful for translating between sources of truth and presentational models of data.\n\nSupports Python 3.8+. No dependencies.\n\n## Installation\n\n```sh\n$ pdm add remapper\n# or\n$ python -m pip install --user remapper\n```\n\n## Usage\n\n> The examples below use dataclasses because they're easy, but `remap` works with any destination type that exposes attributes via its `__init__`.\n\nA trivial example for `remap` is converting one dataclass into another without having to manually pass attributes:\n\n```python\nfrom dataclasses import dataclass\n\nfrom remapper import remap\n\n\n@dataclass\nclass Source:\n a: int\n b: int\n c: int\n\n\n@dataclass\nclass Destination:\n a: int\n b: int\n c: int\n\n\ndest = remap(Source(a=1, b=2, c=3), Destination)\n# >> Destination(a=1, b=2, c=3)\n```\n\nA more useful example would be in mapping an internal database model to an externally-facing dataclass:\n\n```python\nfrom dataclasses import dataclass\n\nfrom remapper import remap\nfrom sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, mapped_column\n\n\nclass Base(DeclarativeBase, MappedAsDataclass):\n pass\n\n\nclass Source(Base):\n id: Mapped[int] = mapped_column(init=False, primary_key=True)\n\n a: Mapped[int]\n b: Mapped[int]\n c: Mapped[int]\n\n\n@dataclass\nclass Destination:\n a: int\n b: int\n c: int\n\n @property\n def d(self) -> int:\n return self.a + self.b + self.c\n\n\nsource = Source(a=1, b=2, c=3)\nawait session.commit(source)\n\ndest = remap(source, Destination)\ndest.d\n# >> 6\n```\n\n### Overrides\n\nThere's a non-zero chance that a destination may require more data than available on a source. In those cases, you can manually provide values via the `overrides` keyword argument. Values in `overrides` will take precedence over values on the source:\n\n```python\nfrom dataclasses import dataclass\n\nfrom remapper import remap\n\n\n@dataclass\nclass Source:\n a: int\n b: int\n\n\n@dataclass\nclass Destination:\n a: int\n b: int\n c: int\n\n\ndest = remap(Source(a=1, b=2), Destination, overrides={\"b\": 0, \"c\": 3})\n# >> Destination(a=1, b=0, c=3)\n```\n\n### Defaults\n\nIf a destination defines more attributes than available on a source, but the destination has default values for those additional attributes, you don't need to supply overrides:\n\n```python\nfrom dataclasses import dataclass\n\nfrom remapper import remap\n\n\n@dataclass\nclass Source:\n a: int\n b: int\n\n\n@dataclass\nclass Destination:\n a: int\n b: int\n c: int = 3\n\n\ndest = remap(Source(a=1, b=2), Destination)\n# >> Destination(a=1, b=2, c=3)\n```\n\n### Nested Types\n\nSome complex sources may have attributes that themselves need to be converted. Rather than remapping in several steps, you can use the `nested_types` keyword argument to specify inner types of the destination attributes:\n\n```python\nfrom dataclasses import dataclass\n\nfrom remapper import remap\n\n\n@dataclass\nclass Source:\n b: int\n\n\n@dataclass\nclass Destination:\n b: int\n\n\n@dataclass\nclass ParentSource:\n a: int\n child: Source\n\n\n@dataclass\nclass ParentDestination:\n a: int\n child: Destination\n\n\n## this works but is kind of clunky\nsource = ParentSource(a=1, child=Source(b=1))\ndest_child = remap(source.child, Destination)\ndest = remap(source, ParentDestination, overrides={\"child\": dest_child})\n# >> ParentDestination(a=1,child=Destination(b=1))\n\n## so use this instead\ndest = remap(\n ParentSource(a=1, child=Source(b=1)),\n ParentDestination,\n nested_types={\"child\": Destination},\n)\n# >> ParentDestination(a=1,child=Destination(b=1))\n```\n\n## License\n\nThis software is licensed under the [BSD 3-Clause Clear License](LICENSE).\n",
"bugtrack_url": null,
"license": null,
"summary": "Transform objects to and from similar structural mappings.",
"version": "1.0.2",
"project_urls": {
"changelog": "https://github.com/thearchitector/remapper/releases",
"homepage": "https://github.com/thearchitector/remapper",
"issues": "https://github.com/thearchitector/remapper/issues",
"source": "https://github.com/thearchitector/remapper"
},
"split_keywords": [
"mapping",
" dataclass",
" presentation",
" models",
" util"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "326a20c49a32f1b27780605dd760bcc96af01e15a90e494ecfe453c9110392fc",
"md5": "172511c705f8994143bfa4059dd06f67",
"sha256": "cba2e5e54a22da25e6951448ce43bd1d3138cc791d8da92d74dc084de6684ff5"
},
"downloads": -1,
"filename": "remapper-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "172511c705f8994143bfa4059dd06f67",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 5486,
"upload_time": "2025-07-25T17:44:20",
"upload_time_iso_8601": "2025-07-25T17:44:20.953688Z",
"url": "https://files.pythonhosted.org/packages/32/6a/20c49a32f1b27780605dd760bcc96af01e15a90e494ecfe453c9110392fc/remapper-1.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "496c985b35d69b5165dc79403f4d8ddbe9a58ffab1e5eb7f1b37de1c49cdcc55",
"md5": "cfac6cd8368078ed890b572ed025f224",
"sha256": "31abb2794657df4e03a56c7a95b455d436c0158b97c2bc462f13e9725d343498"
},
"downloads": -1,
"filename": "remapper-1.0.2.tar.gz",
"has_sig": false,
"md5_digest": "cfac6cd8368078ed890b572ed025f224",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 5592,
"upload_time": "2025-07-25T17:44:21",
"upload_time_iso_8601": "2025-07-25T17:44:21.842366Z",
"url": "https://files.pythonhosted.org/packages/49/6c/985b35d69b5165dc79403f4d8ddbe9a58ffab1e5eb7f1b37de1c49cdcc55/remapper-1.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-25 17:44:21",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "thearchitector",
"github_project": "remapper",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "remapper"
}