Skip to content

Commit fabd447

Browse files
Merge pull request #27 from elumobility/fix/optional-session-fields
fix(2.2.1): make optional Session/ChargingPeriod fields omittable
2 parents 7b8e2ed + 79d70a6 commit fabd447

4 files changed

Lines changed: 14 additions & 9 deletions

File tree

ocpi/modules/cdrs/v_2_2_1/schemas.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ class ChargingPeriod(BaseModel):
5050

5151
start_date_time: DateTime
5252
dimensions: list[CdrDimension]
53-
tariff_id: CiString(36) | None # type: ignore
53+
# Optional per spec: allow it to be omitted entirely (not just null), so a CPO
54+
# that doesn't send tariff_id doesn't trigger a 422.
55+
tariff_id: CiString(36) | None = None # type: ignore
5456

5557

5658
class CdrToken(BaseModel):

ocpi/modules/sessions/v_2_2_1/api/cpo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async def get_sessions(
5858

5959
sessions = []
6060
for data in data_list:
61-
sessions.append(adapter.session_adapter(data).model_dump())
61+
sessions.append(adapter.session_adapter(data, VersionNumber.v_2_2_1).model_dump())
6262
logger.debug(f"Amount of sessions in response: {len(sessions)}")
6363
return OCPIResponse(
6464
data=sessions,

ocpi/modules/sessions/v_2_2_1/api/emsp.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ async def add_or_update_session(
135135
)
136136

137137
return OCPIResponse(
138-
data=[adapter.session_adapter(data).model_dump()],
138+
data=[adapter.session_adapter(data, VersionNumber.v_2_2_1).model_dump()],
139139
**status.OCPI_1000_GENERIC_SUCESS_CODE,
140140
)
141141

@@ -185,7 +185,10 @@ async def partial_update_session(
185185
version=VersionNumber.v_2_2_1,
186186
)
187187
if old_data:
188-
old_session = adapter.session_adapter(old_data)
188+
# Adapt with this receiver's version (2.2.1); the default is the latest
189+
# version, which would re-validate the stored session against a newer,
190+
# stricter schema and 500 on fields optional in 2.2.1.
191+
old_session = adapter.session_adapter(old_data, version=VersionNumber.v_2_2_1)
189192

190193
new_session = copy.deepcopy(old_session)
191194
partially_update_attributes(
@@ -204,7 +207,7 @@ async def partial_update_session(
204207
)
205208

206209
return OCPIResponse(
207-
data=[adapter.session_adapter(data).model_dump()],
210+
data=[adapter.session_adapter(data, VersionNumber.v_2_2_1).model_dump()],
208211
**status.OCPI_1000_GENERIC_SUCESS_CODE,
209212
)
210213
logger.debug(f"Session with id `{session_id}` was not found.")

ocpi/modules/sessions/v_2_2_1/schemas.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ class Session(BaseModel):
1515
party_id: CiString(3) # type: ignore
1616
id: CiString(36) # type: ignore
1717
start_date_time: DateTime
18-
end_date_time: DateTime | None
18+
end_date_time: DateTime | None = None
1919
kwh: Number
2020
cdr_token: CdrToken
2121
auth_method: AuthMethod
22-
authorization_reference: CiString(36) | None # type: ignore
22+
authorization_reference: CiString(36) | None = None # type: ignore
2323
location_id: CiString(36) # type: ignore
2424
evse_uid: CiString(36) # type: ignore
2525
connector_id: CiString(36) # type: ignore
26-
meter_id: String(255) | None # type: ignore
26+
meter_id: String(255) | None = None # type: ignore
2727
currency: String(3) # type: ignore
2828
charging_periods: list[ChargingPeriod] = []
29-
total_cost: Price | None
29+
total_cost: Price | None = None
3030
status: SessionStatus
3131
last_updated: DateTime
3232

0 commit comments

Comments
 (0)