Common interface for Scrapy items
Project description
itemadapter
The ItemAdapter
class is a wrapper for data container objects, providing a
common interface to handle objects of different types in an uniform manner,
regardless of their underlying implementation.
This package started as an initiative to
support dataclass
objects as items
in Scrapy
. It was extracted out to a
standalone package in order to allow it to be used independently.
Currently supported types are:
- Classes that implement the
MutableMapping
interface, including but not limited to: dataclass
-based classesattrs
-based classes
Requirements
- Python 3.5+
dataclasses
(stdlib in Python 3.7+, or its backport in Python 3.6): optional, needed to interact withdataclass
-based itemsattrs
: optional, needed to interact withattrs
-based items
API
ItemAdapter
class
class itemadapter.ItemAdapter(item: Any)
ItemAdapter
implements the
MutableMapping
interface,
providing a dict
-like API to manipulate data for the object it wraps
(which is modified in-place).
Two additional methods are available:
get_field_meta(field_name: str) -> MappingProxyType
Return a MappingProxyType
object with metadata about the given field, or raise TypeError
if the item class does not
support field metadata.
The returned value is taken from the following sources, depending on the item type:
dataclasses.field.metadata
fordataclass
-based itemsattr.Attribute.metadata
forattrs
-based itemsscrapy.item.Field
forscrapy.item.Item
s
field_names() -> List[str]
Return a list with the names of all the defined fields for the item.
is_item
function
itemadapter.is_item(obj: Any) -> bool
Return True
if the given object belongs to one of the supported types,
False
otherwise.
Metadata support
scrapy.item.Item
, dataclass
and attrs
objects allow the inclusion of
arbitrary field metadata, which can be retrieved with the
ItemAdapter.get_field_meta
method. The definition procedure depends on the
underlying type.
scrapy.item.Item
objects
>>> from scrapy.item import Item, Field
>>> from itemadapter import ItemAdapter
>>> class InventoryItem(Item):
... name = Field(serializer=str)
... value = Field(serializer=int, limit=100)
...
>>> adapter = ItemAdapter(InventoryItem(name="foo", value=10))
>>> adapter.get_field_meta("name")
mappingproxy({'serializer': <class 'str'>})
>>> adapter.get_field_meta("value")
mappingproxy({'serializer': <class 'int'>, 'limit': 100})
dataclass
objects
>>> from dataclasses import dataclass, field
>>> @dataclass
... class InventoryItem:
... name: str = field(metadata={"serializer": str})
... value: int = field(metadata={"serializer": int, "limit": 100})
...
>>> adapter = ItemAdapter(InventoryItem(name="foo", value=10))
>>> adapter.get_field_meta("name")
mappingproxy({'serializer': <class 'str'>})
>>> adapter.get_field_meta("value")
mappingproxy({'serializer': <class 'int'>, 'limit': 100})
attrs
objects
>>> import attr
>>> @attr.s
... class InventoryItem:
... name = attr.ib(metadata={"serializer": str})
... value = attr.ib(metadata={"serializer": int})
...
>>> adapter = ItemAdapter(InventoryItem(name="foo", value=10))
>>> adapter.get_field_meta("name")
mappingproxy({'serializer': <class 'str'>})
>>> adapter.get_field_meta("value")
mappingproxy({'serializer': <class 'int'>})
Other types
In fact, any supported object with a fields
attribute which values are mappings works:
>>> class DictWithFields(dict):
... fields = {
... "name": {"serializer": str},
... "value": {"serializer": int, "limit": 100},
... }
...
>>> adapter = ItemAdapter(DictWithFields(name="foo", value=10))
>>> adapter.get_field_meta("name")
mappingproxy({'serializer': <class 'str'>})
>>> adapter.get_field_meta("value")
mappingproxy({'serializer': <class 'int'>, 'limit': 100})
Examples
scrapy.item.Item
objects
>>> from scrapy.item import Item, Field
>>> from itemadapter import ItemAdapter
>>> class InventoryItem(Item):
... name = Field()
... price = Field()
...
>>> item = InventoryItem(name="foo", price=10)
>>> adapter = ItemAdapter(item)
>>> adapter.item is item
True
>>> adapter["name"]
'foo'
>>> adapter["name"] = "bar"
>>> adapter["price"] = 5
>>> item
{'name': 'bar', 'price': 5}
dict
>>> from itemadapter import ItemAdapter
>>> item = dict(name="foo", price=10)
>>> adapter = ItemAdapter(item)
>>> adapter.item is item
True
>>> adapter["name"]
'foo'
>>> adapter["name"] = "bar"
>>> adapter["price"] = 5
>>> item
{'name': 'bar', 'price': 5}
dataclass
objects
>>> from dataclasses import dataclass
>>> from itemadapter import ItemAdapter
>>> @dataclass
... class InventoryItem:
... name: str
... price: int
...
>>> item = InventoryItem(name="foo", price=10)
>>> adapter = ItemAdapter(item)
>>> adapter.item is item
True
>>> adapter["name"]
'foo'
>>> adapter["name"] = "bar"
>>> adapter["price"] = 5
>>> item
InventoryItem(name='bar', price=5)
attrs
objects
>>> import attr
>>> from itemadapter import ItemAdapter
>>> @attr.s
... class InventoryItem:
... name = attr.ib()
... price = attr.ib()
...
>>> item = InventoryItem(name="foo", price=10)
>>> adapter = ItemAdapter(item)
>>> adapter.item is item
True
>>> adapter["name"]
'foo'
>>> adapter["name"] = "bar"
>>> adapter["price"] = 5
>>> item
InventoryItem(name='bar', price=5)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file itemadapter-0.0.1.tar.gz
.
File metadata
- Download URL: itemadapter-0.0.1.tar.gz
- Upload date:
- Size: 5.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.1.3 requests-toolbelt/0.9.1 tqdm/4.45.0 CPython/3.8.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | be1d38e00d4592ca224a19e7a600c86db8d2637265607d8428265573deded457 |
|
MD5 | 27e295155224894771317ed15fe4394e |
|
BLAKE2b-256 | 369cc6e77bed6aaa60db8cc0d9fddb0e76ee383ca1a35a6a27e55c23bf036e7e |
Provenance
File details
Details for the file itemadapter-0.0.1-py3-none-any.whl
.
File metadata
- Download URL: itemadapter-0.0.1-py3-none-any.whl
- Upload date:
- Size: 5.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.1.3 requests-toolbelt/0.9.1 tqdm/4.45.0 CPython/3.8.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e00b84c0b1b8303c3c23afd379d94fa30434022922ab43b70610a6fdae27607b |
|
MD5 | fd510909a95db789c1b701ff5e75b33e |
|
BLAKE2b-256 | ba6135e07e37bd2c16b974a0bef24e90be37cbfbc63f7d2cdeda9053efb5db40 |