Skip to content

Models

Pydantic models for the data services return. All of them subclass the shared Model base (parses API date strings, tolerant model_validate, readable __repr__/pretty_print) documented at the bottom of this page.

Bills

Summary

Bases: Model

Congressional Research Service (CRS) summary of a bill.

CRS provides objective, nonpartisan summaries of legislation at various stages of the legislative process. Summaries may be updated as bills progress.

Example

summary = Summary( ... text="This bill amends the Clean Air Act...", ... actionDate=date(2023, 1, 15), ... versionCode="00" ... )

Summaries

Bases: Model

Container for a list of bill summaries.

Represents the collection of all CRS summaries for a bill across different versions and stages of the legislative process.

Example

summaries = Summaries(summaries=[ ... Summary(text="Introduced version summary", versionCode="00"), ... Summary(text="Passed House summary", versionCode="36") ... ])

ConstitutionalAuthorityStatement

Bases: Model

Constitutional authority statement for a bill.

House Rule XII, clause 7(c) requires that each bill or joint resolution include a statement citing the specific constitutional authority for enacting the proposed law.

Example

statement = ConstitutionalAuthorityStatement( ... text="Congress has the power to enact this legislation pursuant to Article I, Section 8...", ... submitted_date=date(2023, 1, 9) ... )

TextVersionFormat

Bases: Model

Format information for a specific version of bill text.

Bill text is available in multiple formats (PDF, XML, HTML, etc.). Each format has a URL for downloading or viewing the text.

Example

format = TextVersionFormat( ... url="https://www.congress.gov/118/bills/hr1/BILLS-118hr1ih.pdf", ... type="PDF" ... )

TextVersionFormats

Bases: Model

Container for available formats of a bill text version.

Groups all available format options (PDF, XML, HTML, etc.) for a specific version of bill text.

Example

formats = TextVersionFormats(formats=[ ... TextVersionFormat(url="http://example.com/bill.pdf", type="PDF"), ... TextVersionFormat(url="http://example.com/bill.xml", type="XML") ... ])

TextVersionItem

Bases: Model

A specific version of bill text.

Bills go through multiple versions as they progress through Congress (Introduced, Engrossed, Enrolled, etc.). Each version represents the bill text at a specific stage of the legislative process.

Common Version Types
  • IH: Introduced in House
  • IS: Introduced in Senate
  • EH: Engrossed in House (passed)
  • ES: Engrossed in Senate (passed)
  • ENR: Enrolled (passed both chambers, sent to President)
Example

version = TextVersionItem( ... type="IH", ... date=date(2023, 1, 9), ... formats=[TextVersionFormat(url="...", type="PDF")] ... )

TextVersions

Bases: Model

Container for all text versions of a bill.

Represents the collection of all text versions for a bill as it progresses through the legislative process. Can handle multiple API response formats.

API Response Forms
  1. Reference form: {"count": N, "url": "..."}
  2. Content form: [{"type": "IH", "date": "...", "formats": [...]}]
  3. Wrapped form: {"textVersions": [...]}
Example

versions = TextVersions(textVersions=[ ... TextVersionItem(type="IH", date=date(2023, 1, 9)), ... TextVersionItem(type="EH", date=date(2023, 3, 15)) ... ])

Bill

Bases: Model, BillProtocol, AsyncBillProtocol

Bill model with sync and async extension method type hints for IDE support.

Bills

Bases: Model, BillsProtocol

Bills collection with extension method type hints for IDE support.

Members

Terms

Bases: Model

Wrapper model for the terms field which comes from the API as {'item': [...]}. This is pure Pydantic - no custom validation needed.

Member

Bases: Model, MemberProtocol, AsyncMemberProtocol

Member model with sync and async extension method type hints for IDE support.

Members

Bases: Model, MembersProtocol

Members collection with extension method type hints for IDE support.

Sponsors & cosponsors

OnBehalfOfSponsors

Bases: Model

A container for a list of OnBehalfOfSponsor objects.

Sponsor

Bases: Model

The primary sponsor of a bill or amendment.

bioguide_id property

bioguide_id: str | None

Shortcut to member.bioguideId

full_name property

full_name: str | None

Shortcut to member.firstName + lastName

first_name property

first_name: str | None

Shortcut to member.firstName

middle_name property

middle_name: str | None

Shortcut to member.middleName

last_name property

last_name: str | None

Shortcut to member.lastName

is_by_request property writable

is_by_request: bool | None

Return True if this sponsor is by request.

Sponsors

Bases: Model

A container for a list of Sponsor objects.

Cosponsor

Bases: Model

A cosponsor of a bill, with sponsorship date and withdrawal status.

bioguide_id property

bioguide_id: str | None

Shortcut to member.bioguideId

full_name property

full_name: str | None

Shortcut to member.firstName + lastName

first_name property

first_name: str | None

Shortcut to member.firstName

middle_name property

middle_name: str | None

Shortcut to member.middleName

last_name property

last_name: str | None

Shortcut to member.lastName

sponsorship_date property writable

sponsorship_date: date | None

Return the date this cosponsorship was made.

is_original_cosponsor property writable

is_original_cosponsor: bool | None

Return True if this cosponsor is an original cosponsor.

sponsorship_withdrawn_date property writable

sponsorship_withdrawn_date: date | None

Return the date this cosponsorship was withdrawn, if any.

withdrawal_date property writable

withdrawal_date: date | None

Alias for sponsorship_withdrawn_date.

Amendments

Amendment

Bases: Model, AmendmentProtocol, AsyncAmendmentProtocol

Amendment model with sync and async extension method type hints for IDE support.

Amendments

Bases: Model, AmendmentsProtocol

Amendments collection with extension method type hints for IDE support.

Treaties

Treaty

Bases: Model

A treaty submitted to the Senate: parties, committee referrals, actions, and text.

Congress sessions

CongressSessions

Bases: Model

A container for a list of CongressSession objects.

Congresses

Bases: Model

A container for a list of Congress objects.

Congress

Bases: Model, CongressProtocol, AsyncCongressProtocol

Congress model with sync and async extension method type hints.

congress_number_from_url

congress_number_from_url(url: str | None) -> int | None

Extract a session number from a Congress.gov API URL.

Source code in src/congressgov/models/entities/congress.py
16
17
18
19
20
21
22
23
def congress_number_from_url(url: str | None) -> int | None:
    """Extract a session number from a Congress.gov API URL."""
    if not url:
        return None
    match = _CONGRESS_URL_RE.search(url)
    if match is None:
        return None
    return int(match.group(1))

congress_number_from_name

congress_number_from_name(name: str | None) -> int | None

Extract a session number from labels like 119th Congress.

Source code in src/congressgov/models/entities/congress.py
26
27
28
29
30
31
32
33
def congress_number_from_name(name: str | None) -> int | None:
    """Extract a session number from labels like ``119th Congress``."""
    if not name:
        return None
    match = _CONGRESS_NAME_RE.match(name.strip())
    if match is None:
        return None
    return int(match.group(1))

infer_congress_number

infer_congress_number(*, number: int | None = None, congress: int | None = None, name: str | None = None, url: str | None = None) -> int | None

Resolve a Congress session number from known model fields.

Source code in src/congressgov/models/entities/congress.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
def infer_congress_number(
    *,
    number: int | None = None,
    congress: int | None = None,
    name: str | None = None,
    url: str | None = None,
) -> int | None:
    """Resolve a Congress session number from known model fields."""
    if number is not None:
        return number
    if congress is not None:
        return congress
    from_url = congress_number_from_url(url)
    if from_url is not None:
        return from_url
    return congress_number_from_name(name)

Committees

CommitteeActivities

Bases: Model

A container for a list of CommitteeActivity objects.

CommitteeRef

Bases: Model

A minimal committee reference for linking purposes.

CommitteeShortRef

Bases: Model

An even more minimal committee reference (no url).

Subcommittees

Bases: Model

A container for a list of Committee objects (as subcommittees).

CommitteeReports

Bases: Model

A container for a list of CommitteeReport objects.

CommitteeBills

Bases: Model

A container for a committee's bills, as BillRefs (to avoid a circular import with the full Bill model), with optional url/count metadata.

Committee

Bases: Model, CommitteeProtocol, AsyncCommitteeProtocol

Committee model with sync and async extension method type hints for IDE support.

Committees

Bases: Model, CommitteesProtocol

Committees collection with extension method type hints for IDE support.

Actions

Action

Bases: Model

A single action taken on a bill, amendment, or nomination (e.g. introduced, referred to committee, passed). Uses CommitteeRef rather than the full Committee model to avoid a circular import.

Actions

Bases: Model

A container for a list of Action objects, matching the API's actions/pagination/request response shape.

Lightweight references

Minimal reference models (BillRef, CommitteeRef, MemberRef, etc.) that carry just enough identification to link to an entity without importing its full model. Bill, Committee, Action, and Member all reference each other, so importing the full models directly would create circular imports; these break that cycle.

from models.base.references import BillRef

full_bill = bill_service.get(
    congress=bill_ref.congress,
    bill_type=bill_ref.type,
    bill_number=bill_ref.number,
)

BillRef

Bases: Model

Enough fields to identify a Bill and fetch it later, without the full model's dependency chain. Used by Committee, Action, and Amendment models.

CommitteeRef

Bases: Model

Enough fields to identify a Committee, for use in Bill, Action, Meeting, and Report models.

MemberRef

Bases: Model

Enough fields to identify a Member, for use in Sponsor, Action, Vote, and Committee models.

AmendmentRef

Bases: Model

Enough fields to identify an Amendment, for use in Bill and Action models, and for self-references between amendments.

TreatyRef

Bases: Model

Enough fields to identify a Treaty, for use in Action and Committee models.

NominationRef

Bases: Model

Enough fields to identify a Nomination, for use in Action and Committee models.

bill_to_ref

bill_to_ref(bill: Any) -> BillRef

Convert a full Bill (model instance or dict) to a BillRef.

Source code in src/congressgov/models/base/references.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
def bill_to_ref(bill: Any) -> BillRef:
    """Convert a full `Bill` (model instance or dict) to a `BillRef`."""
    if isinstance(bill, dict):
        return BillRef(**{
            k: v for k, v in bill.items()
            if k in BillRef.model_fields
        })

    return BillRef(
        congress=getattr(bill, 'congress', None),
        type=getattr(bill, 'type', None),
        number=getattr(bill, 'number', None),
        title=getattr(bill, 'title', None),
        url=getattr(bill, 'url', None),
        originChamber=getattr(bill, 'originChamber', None),
        originChamberCode=getattr(bill, 'originChamberCode', None),
        updateDate=getattr(bill, 'updateDate', None),
        latestActionDate=getattr(bill, 'latestActionDate', None) if hasattr(bill, 'latestActionDate') else 
                         getattr(bill, 'latestAction', {}).get('actionDate') if hasattr(bill, 'latestAction') else None,
        latestActionText=getattr(bill, 'latestActionText', None) if hasattr(bill, 'latestActionText') else
                         getattr(bill, 'latestAction', {}).get('text') if hasattr(bill, 'latestAction') else None,
    )

committee_to_ref

committee_to_ref(committee: Any) -> CommitteeRef

Convert a full Committee (model instance or dict) to a CommitteeRef.

Source code in src/congressgov/models/base/references.py
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
def committee_to_ref(committee: Any) -> CommitteeRef:
    """Convert a full `Committee` (model instance or dict) to a `CommitteeRef`."""
    if isinstance(committee, dict):
        return CommitteeRef(**{
            k: v for k, v in committee.items()
            if k in CommitteeRef.model_fields
        })

    return CommitteeRef(
        chamber=getattr(committee, 'chamber', None),
        code=getattr(committee, 'systemCode', None) or getattr(committee, 'code', None),
        name=getattr(committee, 'name', None),
        type=getattr(committee, 'type', None),
        url=getattr(committee, 'url', None),
        updateDate=getattr(committee, 'updateDate', None),
    )

member_to_ref

member_to_ref(member: Any) -> MemberRef

Convert a full Member (model instance or dict) to a MemberRef.

Source code in src/congressgov/models/base/references.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
def member_to_ref(member: Any) -> MemberRef:
    """Convert a full `Member` (model instance or dict) to a `MemberRef`."""
    if isinstance(member, dict):
        return MemberRef(**{
            k: v for k, v in member.items()
            if k in MemberRef.model_fields
        })

    return MemberRef(
        bioguideId=getattr(member, 'bioguideId', None),
        name=getattr(member, 'name', None) or 
             f"{getattr(member, 'firstName', '')} {getattr(member, 'lastName', '')}".strip(),
        firstName=getattr(member, 'firstName', None),
        middleName=getattr(member, 'middleName', None),
        lastName=getattr(member, 'lastName', None),
        party=getattr(member, 'party', None) or getattr(member, 'partyName', None),
        state=getattr(member, 'state', None),
        district=getattr(member, 'district', None),
        url=getattr(member, 'url', None),
        updateDate=getattr(member, 'updateDate', None),
    )

amendment_to_ref

amendment_to_ref(amendment: Any) -> AmendmentRef

Convert a full Amendment (model instance or dict) to an AmendmentRef.

Source code in src/congressgov/models/base/references.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def amendment_to_ref(amendment: Any) -> AmendmentRef:
    """Convert a full `Amendment` (model instance or dict) to an `AmendmentRef`."""
    if isinstance(amendment, dict):
        return AmendmentRef(**{
            k: v for k, v in amendment.items()
            if k in AmendmentRef.model_fields
        })

    return AmendmentRef(
        congress=getattr(amendment, 'congress', None),
        type=getattr(amendment, 'type', None),
        number=getattr(amendment, 'number', None),
        description=getattr(amendment, 'description', None),
        purpose=getattr(amendment, 'purpose', None),
        chamber=getattr(amendment, 'chamber', None),
        url=getattr(amendment, 'url', None),
        latestActionDate=getattr(amendment, 'latestActionDate', None) if hasattr(amendment, 'latestActionDate') else
                         getattr(amendment, 'latestAction', {}).get('actionDate') if hasattr(amendment, 'latestAction') else None,
        latestActionText=getattr(amendment, 'latestActionText', None) if hasattr(amendment, 'latestActionText') else
                         getattr(amendment, 'latestAction', {}).get('text') if hasattr(amendment, 'latestAction') else None,
        updateDate=getattr(amendment, 'updateDate', None),
    )

treaty_to_ref

treaty_to_ref(treaty: Any) -> TreatyRef

Convert a full Treaty (model instance or dict) to a TreatyRef.

Source code in src/congressgov/models/base/references.py
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
def treaty_to_ref(treaty: Any) -> TreatyRef:
    """Convert a full `Treaty` (model instance or dict) to a `TreatyRef`."""
    if isinstance(treaty, dict):
        return TreatyRef(**{
            k: v for k, v in treaty.items()
            if k in TreatyRef.model_fields
        })

    return TreatyRef(
        congress=getattr(treaty, 'congress', None),
        number=getattr(treaty, 'number', None),
        suffix=getattr(treaty, 'suffix', None),
        title=getattr(treaty, 'title', None),
        topic=getattr(treaty, 'topic', None),
        url=getattr(treaty, 'url', None),
        transmittedDate=getattr(treaty, 'transmittedDate', None),
        updateDate=getattr(treaty, 'updateDate', None),
    )

nomination_to_ref

nomination_to_ref(nomination: Any) -> NominationRef

Convert a full Nomination (model instance or dict) to a NominationRef.

Source code in src/congressgov/models/base/references.py
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
def nomination_to_ref(nomination: Any) -> NominationRef:
    """Convert a full `Nomination` (model instance or dict) to a `NominationRef`."""
    if isinstance(nomination, dict):
        return NominationRef(**{
            k: v for k, v in nomination.items()
            if k in NominationRef.model_fields
        })

    return NominationRef(
        congress=getattr(nomination, 'congress', None),
        number=getattr(nomination, 'number', None),
        partNumber=getattr(nomination, 'partNumber', None),
        citation=getattr(nomination, 'citation', None),
        description=getattr(nomination, 'description', None),
        receivedDate=getattr(nomination, 'receivedDate', None),
        url=getattr(nomination, 'url', None),
        updateDate=getattr(nomination, 'updateDate', None),
    )

Base model

congressgov.models.base.model.Model

Bases: BaseModel

pretty_print

pretty_print(indent: int = 0, max_width: int = 120) -> str

Pretty print the model and its nested fields in a readable, indented format. Handles nested models, lists, dicts, and basic types.

Source code in src/congressgov/models/base/model.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
def pretty_print(self, indent: int = 0, max_width: int = 120) -> str:
    """
    Pretty print the model and its nested fields in a readable, indented format.
    Handles nested models, lists, dicts, and basic types.
    """
    from collections.abc import Mapping, Sequence

    def _is_model(obj):
        # Accepts both pydantic BaseModel and our Model
        return hasattr(obj, "__fields__") or hasattr(obj, "model_fields")

    def _pretty(obj, level):
        pad = "    " * level
        if _is_model(obj):
            cls_name = obj.__class__.__name__
            items = []
            # Use model_fields for pydantic v2, __fields__ for v1
            fields = getattr(obj, "model_fields", None) or getattr(obj, "__fields__", None)
            if fields is None:
                # fallback: dir(obj)
                fields = {k: None for k in dir(obj) if not k.startswith("_")}
            for k in fields:
                v = getattr(obj, k, None)
                if v is not None:
                    pretty_v = _pretty(v, level + 1)
                    items.append(f"{pad}    {k}={pretty_v}")
            if not items:
                return f"{cls_name}()"
            return f"{cls_name}(\n" + ",\n".join(items) + f"\n{pad})"
        elif isinstance(obj, Mapping):
            if not obj:
                return "{}"
            items = []
            for k, v in obj.items():
                pretty_v = _pretty(v, level + 1)
                items.append(f"{pad}    {repr(k)}: {pretty_v}")
            return "{\n" + ",\n".join(items) + f"\n{pad}}}"
        elif isinstance(obj, str):
            # Show long strings as triple-quoted if they contain newlines
            if "\n" in obj:
                return f'"""{obj}"""'
            return repr(obj)
        elif isinstance(obj, Sequence) and not isinstance(obj, (str, bytes, bytearray)):
            if not obj:
                return "[]"
            items = [_pretty(v, level + 1) for v in obj]
            return "[\n" + ",\n".join(f"{pad}    {item}" for item in items) + f"\n{pad}]"
        elif isinstance(obj, (datetime, )):
            return repr(obj)
        else:
            return repr(obj)

    return _pretty(self, indent)

model_validate classmethod

model_validate(obj, debug: bool = False, **kwargs)

BaseModel.model_validate, plus: pass debug=True to print field-by-field diagnostics, and if validation fails (or succeeds with every field None), retry by unwrapping a single top-level key before giving up.

Source code in src/congressgov/models/base/model.py
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
@classmethod
def model_validate(cls, obj, debug: bool = False, **kwargs):
    """`BaseModel.model_validate`, plus: pass `debug=True` to print field-by-field
    diagnostics, and if validation fails (or succeeds with every field `None`),
    retry by unwrapping a single top-level key before giving up.
    """
    if debug:
        aliases = cls.get_aliases()
        print(f"[DEBUG][model_validate] Aliases: {aliases}")
        print(f"[DEBUG][model_validate] Called for {cls.__name__}")
        print(f"[DEBUG][model_validate] Input object type: {type(obj)}")
        print(f"[DEBUG][model_validate] Input object value: {repr(obj)}")
        if isinstance(obj, dict):
            print(f"[DEBUG][model_validate] Input dict keys: {list(obj.keys())}")
        if hasattr(cls, '__annotations__'):
            print(f"[DEBUG][model_validate] Class annotations: {cls.__annotations__}")
        else:
            print(f"[DEBUG][model_validate] No __annotations__ found for {cls.__name__}")
        if hasattr(cls, 'model_config'):
            print(f"[DEBUG][model_validate] model_config: {getattr(cls, 'model_config', None)}")
        else:
            print(f"[DEBUG][model_validate] No model_config found for {cls.__name__}")

        # Print per-field input values if possible
        if isinstance(obj, dict) and hasattr(cls, '__annotations__'):
            print(f"[DEBUG][model_validate] Per-field input values for {cls.__name__}:")
            for field in cls.__annotations__:
                value = obj.get(field, None)
                print(f"    [DEBUG][model_validate][field] {field}: {repr(value)}")
        elif hasattr(obj, '__dict__') and hasattr(cls, '__annotations__'):
            print(f"[DEBUG][model_validate] Per-field input values for {cls.__name__} (from __dict__):")
            for field in cls.__annotations__:
                value = getattr(obj, field, None)
                print(f"    [DEBUG][model_validate][field] {field}: {repr(value)}")
        else:
            print(f"[DEBUG][model_validate] Unable to print per-field input values for {cls.__name__}")

    try:
        # Call BaseModel's model_validate to perform actual validation
        result = super().model_validate.__func__(cls, obj, **kwargs)

        # Check if all attributes are None
        if hasattr(result, '__dict__'):
            all_none = all(v is None for v in result.__dict__.values())
            if all_none:
                if debug:
                    print(f"[DEBUG][model_validate] All attributes are None for {cls.__name__}, trying unwrapping")
                # Try unwrapping single top-level key
                if isinstance(obj, dict) and len(obj) == 1:
                    single_key = next(iter(obj))
                    single_value = obj[single_key]
                    if debug:
                        print(f"[DEBUG][model_validate] Trying to unwrap single key '{single_key}' with value: {repr(single_value)}")
                    return super().model_validate.__func__(cls, single_value, **kwargs)

        return result

    except Exception as e:
        if debug:
            print(f"[DEBUG][model_validate] Validation failed for {cls.__name__}: {e}")

        # If validation fails and obj is a dict with single key, try unwrapping
        if isinstance(obj, dict) and len(obj) == 1:
            single_key = next(iter(obj))
            single_value = obj[single_key]
            if debug:
                print(f"[DEBUG][model_validate] Trying to unwrap single key '{single_key}' with value: {repr(single_value)}")
            try:
                return super().model_validate.__func__(cls, single_value, **kwargs)
            except Exception as unwrap_e:
                if debug:
                    print(f"[DEBUG][model_validate] Unwrapping also failed: {unwrap_e}")
                raise e  # Re-raise original exception

        raise

CountRef

Bases: Model

A count + URL pair, used where the API gives a total instead of the full list.

URL

Bases: Model

A URL value that accepts a plain string, a {"url": ...} dict, or another URL instance, and normalizes all of them to the same shape. Any model field typed as URL gets this conversion automatically via the core schema hook below.

model_validate classmethod

model_validate(value: Any) -> 'URL'

Accept a string, dict, URL instance, or list of any of those.

Source code in src/congressgov/models/base/types.py
19
20
21
22
23
24
25
26
27
28
29
30
@classmethod
def model_validate(cls, value: Any) -> "URL":
    """Accept a string, dict, `URL` instance, or list of any of those."""
    if isinstance(value, list):
        return [cls.model_validate(item) for item in value]
    if isinstance(value, cls):
        return value
    if isinstance(value, str):
        return cls(url=value)
    if isinstance(value, dict):
        return super().model_validate(value)
    return super().model_validate(value)

__get_pydantic_core_schema__ classmethod

__get_pydantic_core_schema__(source_type: Any, handler)

Wrap the standard model schema with a before-validator so any field typed as URL accepts a plain string or dict, not just a URL instance.

Source code in src/congressgov/models/base/types.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@classmethod
def __get_pydantic_core_schema__(cls, source_type: Any, handler):
    """Wrap the standard model schema with a before-validator so any field
    typed as `URL` accepts a plain string or dict, not just a `URL` instance.
    """
    from pydantic_core import core_schema

    def validate_url(value: Any) -> Any:
        if value is None:
            return None
        if isinstance(value, cls):
            return value
        if isinstance(value, str):
            return cls(url=value)
        if isinstance(value, dict):
            return value
        return value

    python_schema = handler(source_type)
    return core_schema.no_info_before_validator_function(
        validate_url,
        python_schema,
        serialization=core_schema.plain_serializer_function_ser_schema(
            lambda instance: instance.url if isinstance(instance, cls) else instance
        ),
    )

PolicyArea

Bases: Model

Policy area classification (e.g. "Health", "Agriculture and Food").