Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions ocpi/core/endpoints/v_2_1_1/cpo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from ocpi.core.endpoints.v_2_1_1.utils import cpo_generator
from ocpi.core.enums import ModuleID
from ocpi.modules.versions.v_2_1_1.schemas import Endpoint

# OCPI 2.1.1 Endpoint schema has no InterfaceRole field; credentials SENDER
# role is implicit and not separately advertised (InterfaceRole is 2.2.1+).

CREDENTIALS_AND_REGISTRATION = cpo_generator.generate_endpoint(
ModuleID.credentials_and_registration,
Expand All @@ -15,11 +19,14 @@

TOKENS = cpo_generator.generate_endpoint(ModuleID.tokens)

ENDPOINTS_LIST = {
ModuleID.credentials_and_registration: CREDENTIALS_AND_REGISTRATION,
ModuleID.locations: LOCATIONS,
ModuleID.cdrs: CDRS,
ModuleID.tariffs: TARIFFS,
ModuleID.sessions: SESSIONS,
ModuleID.tokens: TOKENS,
}
COMMANDS = cpo_generator.generate_endpoint(ModuleID.commands)

ENDPOINTS_LIST: list[Endpoint] = [
CREDENTIALS_AND_REGISTRATION,
LOCATIONS,
CDRS,
TARIFFS,
SESSIONS,
TOKENS,
COMMANDS,
]
19 changes: 10 additions & 9 deletions ocpi/core/endpoints/v_2_1_1/emsp.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from ocpi.core.endpoints.v_2_1_1.utils import emsp_generator
from ocpi.core.enums import ModuleID
from ocpi.modules.versions.v_2_1_1.schemas import Endpoint

CREDENTIALS_AND_REGISTRATION = emsp_generator.generate_endpoint(
ModuleID.credentials_and_registration,
Expand All @@ -17,12 +18,12 @@

COMMANDS = emsp_generator.generate_endpoint(ModuleID.commands)

ENDPOINTS_LIST = {
ModuleID.credentials_and_registration: CREDENTIALS_AND_REGISTRATION,
ModuleID.locations: LOCATIONS,
ModuleID.cdrs: CDRS,
ModuleID.tariffs: TARIFFS,
ModuleID.sessions: SESSIONS,
ModuleID.tokens: TOKENS,
ModuleID.commands: COMMANDS,
}
ENDPOINTS_LIST: list[Endpoint] = [
CREDENTIALS_AND_REGISTRATION,
LOCATIONS,
CDRS,
TARIFFS,
SESSIONS,
TOKENS,
COMMANDS,
]
34 changes: 23 additions & 11 deletions ocpi/core/endpoints/v_2_2_1/cpo.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from ocpi.core.endpoints.v_2_2_1.utils import cpo_generator
from ocpi.core.enums import ModuleID
from ocpi.modules.versions.v_2_2_1.schemas import InterfaceRole
from ocpi.modules.versions.v_2_2_1.schemas import Endpoint, InterfaceRole

CREDENTIALS_AND_REGISTRATION = cpo_generator.generate_endpoint(
ModuleID.credentials_and_registration,
InterfaceRole.receiver,
)

CREDENTIALS_SENDER = cpo_generator.generate_endpoint(
ModuleID.credentials_and_registration,
InterfaceRole.sender,
)

LOCATIONS = cpo_generator.generate_endpoint(
ModuleID.locations,
InterfaceRole.sender,
Expand All @@ -32,6 +37,11 @@
InterfaceRole.receiver,
)

COMMANDS = cpo_generator.generate_endpoint(
ModuleID.commands,
InterfaceRole.receiver,
)

HUB_CLIENT_INFO = cpo_generator.generate_endpoint(
ModuleID.hub_client_info,
InterfaceRole.receiver,
Expand All @@ -43,13 +53,15 @@
)


ENDPOINTS_LIST = {
ModuleID.credentials_and_registration: CREDENTIALS_AND_REGISTRATION,
ModuleID.locations: LOCATIONS,
ModuleID.sessions: SESSIONS,
ModuleID.cdrs: CDRS,
ModuleID.tariffs: TARIFFS,
ModuleID.tokens: TOKENS,
ModuleID.hub_client_info: HUB_CLIENT_INFO,
ModuleID.charging_profile: CHARGING_PROFILE,
}
ENDPOINTS_LIST: list[Endpoint] = [
CREDENTIALS_AND_REGISTRATION,
CREDENTIALS_SENDER,
LOCATIONS,
SESSIONS,
CDRS,
TARIFFS,
TOKENS,
COMMANDS,
HUB_CLIENT_INFO,
CHARGING_PROFILE,
]
24 changes: 12 additions & 12 deletions ocpi/core/endpoints/v_2_2_1/emsp.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ocpi.core.endpoints.v_2_2_1.utils import emsp_generator
from ocpi.core.enums import ModuleID
from ocpi.modules.versions.v_2_2_1.schemas import InterfaceRole
from ocpi.modules.versions.v_2_2_1.schemas import Endpoint, InterfaceRole

CREDENTIALS_AND_REGISTRATION = emsp_generator.generate_endpoint(
ModuleID.credentials_and_registration,
Expand Down Expand Up @@ -47,14 +47,14 @@
InterfaceRole.sender,
)

ENDPOINTS_LIST = {
ModuleID.credentials_and_registration: CREDENTIALS_AND_REGISTRATION,
ModuleID.locations: LOCATIONS,
ModuleID.sessions: SESSIONS,
ModuleID.cdrs: CDRS,
ModuleID.tariffs: TARIFFS,
ModuleID.commands: COMMANDS,
ModuleID.tokens: TOKENS,
ModuleID.hub_client_info: HUB_CLIENT_INFO,
ModuleID.charging_profile: CHARGING_PROFILE,
}
ENDPOINTS_LIST: list[Endpoint] = [
CREDENTIALS_AND_REGISTRATION,
LOCATIONS,
SESSIONS,
CDRS,
TARIFFS,
COMMANDS,
TOKENS,
HUB_CLIENT_INFO,
CHARGING_PROFILE,
]
44 changes: 31 additions & 13 deletions ocpi/core/endpoints/v_2_3_0/cpo.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@

from ocpi.core.endpoints.v_2_3_0.utils import cpo_generator
from ocpi.core.enums import ModuleID
from ocpi.modules.versions.v_2_3_0.schemas import InterfaceRole
from ocpi.modules.versions.v_2_3_0.schemas import Endpoint, InterfaceRole

CREDENTIALS_AND_REGISTRATION = cpo_generator.generate_endpoint(
ModuleID.credentials_and_registration,
InterfaceRole.receiver,
)

CREDENTIALS_SENDER = cpo_generator.generate_endpoint(
ModuleID.credentials_and_registration,
InterfaceRole.sender,
)

LOCATIONS = cpo_generator.generate_endpoint(
ModuleID.locations,
InterfaceRole.sender,
Expand All @@ -34,6 +39,11 @@
InterfaceRole.receiver,
)

COMMANDS = cpo_generator.generate_endpoint(
ModuleID.commands,
InterfaceRole.receiver,
)

HUB_CLIENT_INFO = cpo_generator.generate_endpoint(
ModuleID.hub_client_info,
InterfaceRole.receiver,
Expand All @@ -50,22 +60,30 @@
InterfaceRole.receiver,
)

PAYMENTS_SENDER = cpo_generator.generate_endpoint(
ModuleID.payments,
InterfaceRole.sender,
)

# New in OCPI 2.3.0 - Booking extension
BOOKINGS = cpo_generator.generate_endpoint(
ModuleID.bookings,
InterfaceRole.receiver,
)


ENDPOINTS_LIST = {
ModuleID.credentials_and_registration: CREDENTIALS_AND_REGISTRATION,
ModuleID.locations: LOCATIONS,
ModuleID.sessions: SESSIONS,
ModuleID.cdrs: CDRS,
ModuleID.tariffs: TARIFFS,
ModuleID.tokens: TOKENS,
ModuleID.hub_client_info: HUB_CLIENT_INFO,
ModuleID.charging_profile: CHARGING_PROFILE,
ModuleID.payments: PAYMENTS,
ModuleID.bookings: BOOKINGS,
}
ENDPOINTS_LIST: list[Endpoint] = [
CREDENTIALS_AND_REGISTRATION,
CREDENTIALS_SENDER,
LOCATIONS,
SESSIONS,
CDRS,
TARIFFS,
TOKENS,
COMMANDS,
HUB_CLIENT_INFO,
CHARGING_PROFILE,
PAYMENTS,
PAYMENTS_SENDER,
BOOKINGS,
]
26 changes: 13 additions & 13 deletions ocpi/core/endpoints/v_2_3_0/emsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from ocpi.core.endpoints.v_2_3_0.utils import emsp_generator
from ocpi.core.enums import ModuleID
from ocpi.modules.versions.v_2_3_0.schemas import InterfaceRole
from ocpi.modules.versions.v_2_3_0.schemas import Endpoint, InterfaceRole

CREDENTIALS_AND_REGISTRATION = emsp_generator.generate_endpoint(
ModuleID.credentials_and_registration,
Expand Down Expand Up @@ -56,15 +56,15 @@
)


ENDPOINTS_LIST = {
ModuleID.credentials_and_registration: CREDENTIALS_AND_REGISTRATION,
ModuleID.locations: LOCATIONS,
ModuleID.sessions: SESSIONS,
ModuleID.cdrs: CDRS,
ModuleID.tariffs: TARIFFS,
ModuleID.tokens: TOKENS,
ModuleID.commands: COMMANDS,
ModuleID.hub_client_info: HUB_CLIENT_INFO,
ModuleID.charging_profile: CHARGING_PROFILE,
ModuleID.bookings: BOOKINGS,
}
ENDPOINTS_LIST: list[Endpoint] = [
CREDENTIALS_AND_REGISTRATION,
LOCATIONS,
SESSIONS,
CDRS,
TARIFFS,
TOKENS,
COMMANDS,
HUB_CLIENT_INFO,
CHARGING_PROFILE,
BOOKINGS,
]
16 changes: 10 additions & 6 deletions ocpi/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ def get_application(
version_endpoints[version] = []

if RoleEnum.cpo in roles:
cpo_modules_with_router: set[ModuleID] = set()
for module in modules:
cpo_router = mapped_version["cpo_router"].get(module) # type: ignore[attr-defined]
if cpo_router:
Expand All @@ -233,11 +234,13 @@ def get_application(
prefix=f"/{settings.OCPI_PREFIX}/cpo/{version.value}",
tags=[f"CPO {version.value}"],
)
endpoint = ENDPOINTS[version][RoleEnum.cpo].get(module) # type: ignore[index]
if endpoint:
version_endpoints[version].append(endpoint)
cpo_modules_with_router.add(module)
for endpoint in ENDPOINTS[version][RoleEnum.cpo]: # type: ignore[index]
if endpoint.identifier in cpo_modules_with_router:
version_endpoints[version].append(endpoint)

if RoleEnum.emsp in roles:
emsp_modules_with_router: set[ModuleID] = set()
for module in modules:
emsp_router = mapped_version["emsp_router"].get(module) # type: ignore[attr-defined]
if emsp_router:
Expand All @@ -246,9 +249,10 @@ def get_application(
prefix=f"/{settings.OCPI_PREFIX}/emsp/{version.value}",
tags=[f"EMSP {version.value}"],
)
endpoint = ENDPOINTS[version][RoleEnum.emsp].get(module) # type: ignore[index]
if endpoint:
version_endpoints[version].append(endpoint)
emsp_modules_with_router.add(module)
for endpoint in ENDPOINTS[version][RoleEnum.emsp]: # type: ignore[index]
if endpoint.identifier in emsp_modules_with_router:
version_endpoints[version].append(endpoint)

if RoleEnum.ptp in roles:
for module in modules:
Expand Down
6 changes: 5 additions & 1 deletion tests/test_modules/mocks/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
from ocpi.modules.versions.enums import VersionNumber
from ocpi.modules.versions.v_2_2_1.schemas import VersionDetail

_locations_endpoint = next(
e for e in ENDPOINTS[VersionNumber.v_2_2_1][RoleEnum.cpo] if e.identifier == ModuleID.locations
)

fake_endpoints_data = {
"data": VersionDetail(
version=VersionNumber.v_2_2_1,
endpoints=[ENDPOINTS[VersionNumber.v_2_2_1][RoleEnum.cpo][ModuleID.locations]],
endpoints=[_locations_endpoint],
).model_dump(),
}

Expand Down
25 changes: 25 additions & 0 deletions tests/test_modules/test_v_2_1_1/test_versions/test_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,31 @@ async def do(cls, *args, **kwargs):
assert len(response.json()["data"]) == 2


def test_version_details_includes_commands_for_cpo():
"""CPO version details must advertise the commands endpoint (regression: Payter discovery)."""

class MockCrud(Crud):
@classmethod
async def do(cls, *args, **kwargs):
return AUTH_TOKEN

app = get_application(
version_numbers=[VersionNumber.v_2_1_1],
roles=[enums.RoleEnum.cpo],
crud=MockCrud,
authenticator=ClientAuthenticator,
modules=[enums.ModuleID.commands],
)
client = TestClient(app)

response = client.get(VERSION_URL, headers=AUTH_HEADERS)

assert response.status_code == 200
endpoints = response.json()["data"]["endpoints"]
commands_entries = [e for e in endpoints if e["identifier"] == "commands"]
assert len(commands_entries) == 1


def test_get_versions_v_2_1_1_not_authenticated():
class MockCrud(Crud):
@classmethod
Expand Down
Loading