Skip to content

Projects

Models

Pydantic models for representing OpenAIRE Project entities and related structures.

This module defines the Pydantic model for an OpenAIRE Project, including nested models for funding details, grants, and H2020 programme information, based on the OpenAIRE data model documentation. Reference: https://graph.openaire.eu/docs/data-model/entities/project

ProjectResponse = ApiResponse[Project] module-attribute

Type alias for an API response containing a list of Project entities.

Funding

Bases: BaseModel

Represents funding information for a project, including the source and stream.

Attributes:

Name Type Description
fundingStream FundingStream | None

A FundingStream object detailing the specific stream.

jurisdiction str | None

The jurisdiction associated with the funding (e.g., country code).

name str | None

The name of the funding body or organization.

shortName str | None

An optional short name or acronym for the funding body.

Source code in src/aireloom/models/project.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Funding(BaseModel):
    """Represents funding information for a project, including the source and stream.

    Attributes:
        fundingStream: A `FundingStream` object detailing the specific stream.
        jurisdiction: The jurisdiction associated with the funding (e.g., country code).
        name: The name of the funding body or organization.
        shortName: An optional short name or acronym for the funding body.
    """

    fundingStream: FundingStream | None = None
    jurisdiction: str | None = None
    name: str | None = None
    shortName: str | None = None
    model_config = ConfigDict(extra="allow")

FundingStream

Bases: BaseModel

Represents details about a specific funding stream for a project.

Attributes:

Name Type Description
description str | None

A description of the funding stream.

id str | None

The unique identifier of the funding stream.

Source code in src/aireloom/models/project.py
18
19
20
21
22
23
24
25
26
27
28
class FundingStream(BaseModel):
    """Represents details about a specific funding stream for a project.

    Attributes:
        description: A description of the funding stream.
        id: The unique identifier of the funding stream.
    """

    description: str | None = None
    id: str | None = None
    model_config = ConfigDict(extra="allow")

Grant

Bases: BaseModel

Represents details about the grant amounts associated with a project.

Attributes:

Name Type Description
currency str | None

The currency code for the amounts (e.g., "EUR", "USD").

fundedAmount float | None

The amount of funding awarded.

totalCost float | None

The total cost of the project.

Source code in src/aireloom/models/project.py
48
49
50
51
52
53
54
55
56
57
58
59
60
class Grant(BaseModel):
    """Represents details about the grant amounts associated with a project.

    Attributes:
        currency: The currency code for the amounts (e.g., "EUR", "USD").
        fundedAmount: The amount of funding awarded.
        totalCost: The total cost of the project.
    """

    currency: str | None = None
    fundedAmount: float | None = None
    totalCost: float | None = None
    model_config = ConfigDict(extra="allow")

H2020Programme

Bases: BaseModel

Represents details about an H2020 programme related to a project.

Attributes:

Name Type Description
code str | None

The code of the H2020 programme.

description str | None

A description of the H2020 programme.

Source code in src/aireloom/models/project.py
63
64
65
66
67
68
69
70
71
72
73
class H2020Programme(BaseModel):
    """Represents details about an H2020 programme related to a project.

    Attributes:
        code: The code of the H2020 programme.
        description: A description of the H2020 programme.
    """

    code: str | None = None
    description: str | None = None
    model_config = ConfigDict(extra="allow")

Project

Bases: BaseEntity

Model representing an OpenAIRE Project entity.

Captures comprehensive information about a research project, including its identifiers, title, funding, duration, and related metadata. Inherits the id field from BaseEntity.

Attributes:

Name Type Description
code str | None

The project code or grant number.

acronym str | None

The acronym of the project.

title str | None

The official title of the project.

callIdentifier str | None

Identifier for the funding call.

fundings list[Funding] | None

A list of Funding objects detailing the project's funding sources.

granted Grant | None

A Grant object with information about the awarded grant amounts.

h2020Programmes list[H2020Programme] | None

A list of H2020Programme objects if the project is part of H2020.

keywords list[str] | str | None

A list of keywords or a single string of keywords describing the project. A validator attempts to parse comma or semicolon-separated strings.

openAccessMandateForDataset bool | None

Boolean indicating if there's an open access mandate for datasets produced by the project.

openAccessMandateForPublications bool | None

Boolean indicating if there's an open access mandate for publications from the project.

startDate str | None

The start date of the project (typically "YYYY-MM-DD" string).

endDate str | None

The end date of the project (typically "YYYY-MM-DD" string).

subjects list[str] | None

A list of subject classifications for the project.

summary str | None

A summary or abstract of the project.

websiteUrl str | None

The URL of the project's official website.

Source code in src/aireloom/models/project.py
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
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
class Project(BaseEntity):
    """Model representing an OpenAIRE Project entity.

    Captures comprehensive information about a research project, including its
    identifiers, title, funding, duration, and related metadata. Inherits the
    `id` field from `BaseEntity`.

    Attributes:
        code: The project code or grant number.
        acronym: The acronym of the project.
        title: The official title of the project.
        callIdentifier: Identifier for the funding call.
        fundings: A list of `Funding` objects detailing the project's funding sources.
        granted: A `Grant` object with information about the awarded grant amounts.
        h2020Programmes: A list of `H2020Programme` objects if the project is part of H2020.
        keywords: A list of keywords or a single string of keywords describing the project.
                  A validator attempts to parse comma or semicolon-separated strings.
        openAccessMandateForDataset: Boolean indicating if there's an open access
                                     mandate for datasets produced by the project.
        openAccessMandateForPublications: Boolean indicating if there's an open access
                                          mandate for publications from the project.
        startDate: The start date of the project (typically "YYYY-MM-DD" string).
        endDate: The end date of the project (typically "YYYY-MM-DD" string).
        subjects: A list of subject classifications for the project.
        summary: A summary or abstract of the project.
        websiteUrl: The URL of the project's official website.
    """

    # id is inherited from BaseEntity
    code: str | None = None
    acronym: str | None = None
    title: str | None = None
    callIdentifier: str | None = None
    fundings: list[Funding] | None = Field(default_factory=list)
    granted: Grant | None = None
    h2020Programmes: list[H2020Programme] | None = Field(default_factory=list)
    # Keywords might be a single string or a delimited string. Attempt parsing.
    keywords: list[str] | str | None = None
    openAccessMandateForDataset: bool | None = None
    openAccessMandateForPublications: bool | None = None
    # Dates are kept as string for safety due to potential missing parts or nulls.
    # Expected format is typically YYYY-MM-DD.
    startDate: str | None = None
    endDate: str | None = None
    subjects: list[str] | None = Field(default_factory=list)
    summary: str | None = None
    websiteUrl: str | None = None

    model_config = ConfigDict(extra="allow")

    @field_validator("keywords", mode="before")
    @classmethod
    def parse_keywords_string(cls, v: Any) -> list[str] | str | None:
        """Attempts to parse a keyword string into a list of strings.

        If the input `v` is a string, this validator tries to split it by common
        delimiters (comma, then semicolon). If splitting results in more than one
        part, a list of stripped parts is returned. Otherwise, the original string
        (or None if empty) is returned. If `v` is not a string (e.g., already a
        list or None), it's returned as is.

        Args:
            v: The value to parse, expected to be a string, list, or None.

        Returns:
            A list of strings if parsing was successful and yielded multiple keywords,
            the original string if no parsing occurred or yielded a single part,
            or None if the input string was empty.
        """
        if isinstance(v, str):
            # Prioritize comma, then semicolon
            delimiters = [",", ";"]
            for delimiter in delimiters:
                parts = [part.strip() for part in v.split(delimiter) if part.strip()]
                if len(parts) > 1:
                    return parts
            # If no split produced multiple parts, return the original string (or None if it was empty)
            return v if v else None
        # If not a string (e.g., already a list or None), return as is
        return v

parse_keywords_string(v) classmethod

Attempts to parse a keyword string into a list of strings.

If the input v is a string, this validator tries to split it by common delimiters (comma, then semicolon). If splitting results in more than one part, a list of stripped parts is returned. Otherwise, the original string (or None if empty) is returned. If v is not a string (e.g., already a list or None), it's returned as is.

Parameters:

Name Type Description Default
v Any

The value to parse, expected to be a string, list, or None.

required

Returns:

Type Description
list[str] | str | None

A list of strings if parsing was successful and yielded multiple keywords,

list[str] | str | None

the original string if no parsing occurred or yielded a single part,

list[str] | str | None

or None if the input string was empty.

Source code in src/aireloom/models/project.py
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
@field_validator("keywords", mode="before")
@classmethod
def parse_keywords_string(cls, v: Any) -> list[str] | str | None:
    """Attempts to parse a keyword string into a list of strings.

    If the input `v` is a string, this validator tries to split it by common
    delimiters (comma, then semicolon). If splitting results in more than one
    part, a list of stripped parts is returned. Otherwise, the original string
    (or None if empty) is returned. If `v` is not a string (e.g., already a
    list or None), it's returned as is.

    Args:
        v: The value to parse, expected to be a string, list, or None.

    Returns:
        A list of strings if parsing was successful and yielded multiple keywords,
        the original string if no parsing occurred or yielded a single part,
        or None if the input string was empty.
    """
    if isinstance(v, str):
        # Prioritize comma, then semicolon
        delimiters = [",", ";"]
        for delimiter in delimiters:
            parts = [part.strip() for part in v.split(delimiter) if part.strip()]
            if len(parts) > 1:
                return parts
        # If no split produced multiple parts, return the original string (or None if it was empty)
        return v if v else None
    # If not a string (e.g., already a list or None), return as is
    return v

Filters

Bases: BaseModel

Filter model for Projects API endpoint.

Attributes:

Name Type Description
search str | None

Search term for the project.

title str | None

Title of the project.

keywords list[str] | None

List of keywords associated with the project.

id str | None

OpenAIRE id for the project.

code str | None

Code of the project.

grantID str | None

Grant ID associated with the project.

acronym str | None

Acronym of the project.

callIdentifier str | None

Call identifier of the project.

fundingStreamId str | None

Funding stream ID associated with the project.

fromStartDate date | None

Start date of the project (inclusive).

toStartDate date | None

End date of the project (inclusive).

fromEndDate date | None

End date of the project (inclusive).

toEndDate date | None

End date of the project (inclusive).

relOrganizationName str | None

Name of the related organization.

relOrganizationId str | None

ID of the related organization.

relCommunityId str | None

ID of the related community.

relOrganizationCountryCode str | None

Country code of the related organization.

relCollectedFromDatasourceId str | None

ID of the datasource from which this was collected.

Source code in src/aireloom/endpoints.py
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
class ProjectsFilters(BaseModel):
    """Filter model for Projects API endpoint.

    Attributes:
        search (str | None): Search term for the project.
        title (str | None): Title of the project.
        keywords (list[str] | None): List of keywords associated with the project.
        id (str | None): OpenAIRE id for the project.
        code (str | None): Code of the project.
        grantID (str | None): Grant ID associated with the project.
        acronym (str | None): Acronym of the project.
        callIdentifier (str | None): Call identifier of the project.
        fundingStreamId (str | None): Funding stream ID associated with the project.
        fromStartDate (date | None): Start date of the project (inclusive).
        toStartDate (date | None): End date of the project (inclusive).
        fromEndDate (date | None): End date of the project (inclusive).
        toEndDate (date | None): End date of the project (inclusive).
        relOrganizationName (str | None): Name of the related organization.
        relOrganizationId (str | None): ID of the related organization.
        relCommunityId (str | None): ID of the related community.
        relOrganizationCountryCode (str | None): Country code of the related organization.
        relCollectedFromDatasourceId (str | None): ID of the datasource from which this was collected.


    """

    search: str | None = None
    title: str | None = None
    keywords: list[str] | None = None
    id: str | None = None
    code: str | None = None
    grantID: str | None = None
    acronym: str | None = None
    callIdentifier: str | None = None
    fundingStreamId: str | None = None
    fromStartDate: date | None = None
    toStartDate: date | None = None
    fromEndDate: date | None = None
    toEndDate: date | None = None
    relOrganizationName: str | None = None
    relOrganizationId: str | None = None
    relCommunityId: str | None = None
    relOrganizationCountryCode: str | None = None
    relCollectedFromDatasourceId: str | None = None

    model_config = ConfigDict(extra="forbid")

Client

Client for interacting with the OpenAIRE Projects API endpoint.

This module provides the ProjectsClient, enabling access to OpenAIRE's project data. It utilizes generic mixins from bibliofabric.resources for standard API operations like fetching, searching, and iterating through project entities.

ProjectsClient

Bases: GettableMixin, SearchableMixin, CursorIterableMixin, BaseResourceClient

Client for the OpenAIRE Projects API endpoint.

This client offers standardized methods (get, search, iterate) for accessing project data by inheriting from bibliofabric mixins. It is configured with the API path and Pydantic models specific to OpenAIRE project entities.

Attributes:

Name Type Description
_entity_path str

The API path for projects.

_entity_model type[Project]

Pydantic model for a single project.

_search_response_model type[ProjectResponse]

Pydantic model for the search response envelope.

_valid_sort_fields set[str]

Valid sort fields for this endpoint.

Source code in src/aireloom/resources/projects_client.py
26
27
28
29
30
31
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
58
59
60
61
62
63
64
65
class ProjectsClient(
    GettableMixin, SearchableMixin, CursorIterableMixin, BaseResourceClient
):
    """Client for the OpenAIRE Projects API endpoint.

    This client offers standardized methods (`get`, `search`, `iterate`) for
    accessing project data by inheriting from `bibliofabric` mixins.
    It is configured with the API path and Pydantic models specific to
    OpenAIRE project entities.

    Attributes:
        _entity_path (str): The API path for projects.
        _entity_model (type[Project]): Pydantic model for a single project.
        _search_response_model (type[ProjectResponse]): Pydantic model for the
                                                        search response envelope.
        _valid_sort_fields (set[str]): Valid sort fields for this endpoint.
    """

    _entity_path: str = PROJECTS
    _entity_model: type[Project] = Project
    _search_response_model: type[ProjectResponse] = ProjectResponse
    _valid_sort_fields = {
        "acronym",
        "code",
        "enddate",
        "fundinglevel",
        "fundingtree",
        "id",
        "startdate",
        "title",
    }

    def __init__(self, api_client: "AireloomClient"):
        """Initializes the ProjectsClient.

        Args:
            api_client: An instance of AireloomClient.
        """
        super().__init__(api_client)
        logger.debug(f"ProjectsClient initialized for path: {self._entity_path}")

__init__(api_client)

Initializes the ProjectsClient.

Parameters:

Name Type Description Default
api_client AireloomClient

An instance of AireloomClient.

required
Source code in src/aireloom/resources/projects_client.py
58
59
60
61
62
63
64
65
def __init__(self, api_client: "AireloomClient"):
    """Initializes the ProjectsClient.

    Args:
        api_client: An instance of AireloomClient.
    """
    super().__init__(api_client)
    logger.debug(f"ProjectsClient initialized for path: {self._entity_path}")